Compare commits
33 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
21623b24f0 | |
|
|
d2fe0f47c3 | |
|
|
f5bd481975 | |
|
|
efe995e247 | |
|
|
b553eb434a | |
|
|
4f72d75642 | |
|
|
a829e7224c | |
|
|
23202e7a7b | |
|
|
06c605344f | |
|
|
015447dc57 | |
|
|
59af2e0a29 | |
|
|
8de753aac5 | |
|
|
0febac8b3c | |
|
|
2c1892303e | |
|
|
0df3a7c647 | |
|
|
3bae819cb2 | |
|
|
d020e94ac0 | |
|
|
f2fad336a3 | |
|
|
6495c49022 | |
|
|
6dd6c2e3d6 | |
|
|
04638e650d | |
|
|
d1439b3f09 | |
|
|
994880f454 | |
|
|
9795c83583 | |
|
|
f4318b2464 | |
|
|
fd3a8db71d | |
|
|
994da62aac | |
|
|
07069e25a8 | |
|
|
0f3313902c | |
|
|
5f94e931a0 | |
|
|
cb99962074 | |
|
|
8b06a83361 | |
|
|
91a7884a4d |
|
|
@ -0,0 +1,21 @@
|
|||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"commonjs": true,
|
||||
"jquery": true,
|
||||
"es6": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"globals": {
|
||||
"Atomics": "readonly",
|
||||
"SharedArrayBuffer": "readonly"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"no-console": "off",
|
||||
"semi": "warn",
|
||||
}
|
||||
};
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
# Road Map
|
||||
|
||||
- [x] Block castling through check (middle square needs to be clear of check).
|
||||
- [ ] Notifications for games other than the currently selected game.
|
||||
- [x] Notifications for games other than the currently selected game.
|
||||
- [ ] Protocol and UI for offering and accepting a draw.
|
||||
- [ ] In-browser local, private games.
|
||||
- [ ] Password-protected user accounts.
|
||||
|
|
|
|||
730
css/chess.css
730
css/chess.css
|
|
@ -2,92 +2,375 @@
|
|||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body, #page {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#page {
|
||||
body > #page {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: 'Vollkorn', serif;
|
||||
font-size: 2em;
|
||||
line-height: 1.4em;
|
||||
height: 1.4em;
|
||||
margin-top: 8px;
|
||||
margin-left: 8px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
a.plain-link {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
background-color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
.media-button-svg {
|
||||
width: 12pt;
|
||||
height: 12pt;
|
||||
}
|
||||
|
||||
button:disabled .silhouette {
|
||||
fill: #c0c0c0;
|
||||
}
|
||||
|
||||
#content {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
}
|
||||
|
||||
#cb_outer2 {
|
||||
flex: 1 1 auto;
|
||||
#board_ui {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: stretch;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
max-width: calc(100vh - (8px + 2.8em + 8px));
|
||||
margin-left: 8px;
|
||||
height: 100%;
|
||||
background-color: #FFFFF0;
|
||||
}
|
||||
|
||||
#cb_outer {
|
||||
#page.horizontal-layout #board_ui {
|
||||
border-left: 10px solid #C4B28F;
|
||||
border-image:
|
||||
linear-gradient(
|
||||
to right,
|
||||
#C4B28F,
|
||||
#F5DEB3 15%,
|
||||
#C4B28F 45%,
|
||||
#FFFFF0 80%,
|
||||
#C4B28F) 1 100%;
|
||||
}
|
||||
|
||||
#header {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
flex: 0 0 auto;
|
||||
width: 100%;
|
||||
max-width: calc(100vw - (8px + 24px));
|
||||
height: 2.5rem;
|
||||
font-size: 2rem;
|
||||
line-height: 2.4rem;
|
||||
margin: 0;
|
||||
background-image: linear-gradient(#FFFFF0, #F5DEB3);
|
||||
border-bottom: 1px solid black;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#header > h1 {
|
||||
font-family: 'Vollkorn', serif;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
line-height: 2.4rem;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-top: 0.1rem;
|
||||
height: 2.5rem;
|
||||
white-space: nowrap;
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
|
||||
#header > button {
|
||||
flex: 0 0 auto;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
border: none;
|
||||
background: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#header > button:active {
|
||||
background-image: linear-gradient(#F5DEB3, #FFFFF0);
|
||||
}
|
||||
|
||||
input.image-checkbox {
|
||||
display: inline-block;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
input.image-checkbox:checked {
|
||||
color: #00f;
|
||||
}
|
||||
|
||||
input.image-checkbox:focus {
|
||||
outline: blue solid medium;
|
||||
outline: -webkit-focus-ring-color solid medium;
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
#header > .checkbox-container {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
button#settings, button#cb_choose_game {
|
||||
border-right: 1px solid #DCC8A1;
|
||||
}
|
||||
|
||||
#header > .checkbox-container, button#help {
|
||||
border-left: 1px solid #DCC8A1;
|
||||
}
|
||||
|
||||
#cb_container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding-top: 100%;
|
||||
flex: 1 1 auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#cb_inner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
#page.horizontal-layout #cb_container {
|
||||
flex: 0 0.5 auto;
|
||||
}
|
||||
|
||||
#cb_board {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
border-collapse: collapse;
|
||||
border-style: hidden;
|
||||
padding-top: 100%;
|
||||
box-shadow: 0 0 0 1px black, 2px 2px 4px #00000080;
|
||||
border-radius: 6pt;
|
||||
overflow: hidden;
|
||||
background-color: #FAEED2;
|
||||
}
|
||||
|
||||
#cb_status {
|
||||
display: flex;
|
||||
position: relative;
|
||||
flex-flow: column nowrap;
|
||||
width: 100%;
|
||||
padding-top: 0.25rem;
|
||||
padding-left: 0.25rem;
|
||||
padding-right: 0.25rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
#page.horizontal-layout #cb_status {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
#cb_status::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 1.5em;
|
||||
left: 0;
|
||||
bottom: 0.5rem;
|
||||
background: linear-gradient(rgba(255,255,240,0),rgba(255,255,240,1));
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#cb_message {
|
||||
height: 1.2em;
|
||||
margin-bottom: 0.1rem;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
#cb_explain_check {
|
||||
color: red;
|
||||
height: 2.4em;
|
||||
margin-bottom: 0.1em;
|
||||
}
|
||||
|
||||
#cb_scrollable {
|
||||
flex: 0 0 auto;
|
||||
overflow: auto;
|
||||
height: 4.8em;
|
||||
padding-bottom: 1.2em;
|
||||
}
|
||||
|
||||
#page.horizontal-layout #cb_scrollable {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
#cb_history {
|
||||
color: black;
|
||||
}
|
||||
|
||||
#cb_history_future {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
#cb_times {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
white-space: nowrap;
|
||||
justify-content: stretch;
|
||||
align-items: flex-end;
|
||||
width: 100%;
|
||||
padding-left: 3rem;
|
||||
padding-right: 3rem;
|
||||
}
|
||||
|
||||
#cb_times.cb-hide-times {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#cb_light_time, #cb_dark_time {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#cb_light_time {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#cb_dark_time {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#cb_names {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
white-space: nowrap;
|
||||
justify-content: stretch;
|
||||
align-items: flex-end;
|
||||
font-size: 1.5rem;
|
||||
width: 100%;
|
||||
height: 3rem;
|
||||
padding-left: 2rem;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
#cb_names_text {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
white-space: nowrap;
|
||||
justify-content: stretch;
|
||||
align-items: baseline;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#cb_names::before {
|
||||
content: '';
|
||||
display: block;
|
||||
background-image: url(../svg/pacosako-theme.svg#light_king_left);
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0.5rem;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
#cb_names.cb-light-turn::before {
|
||||
filter: drop-shadow(0 0 5px blue);
|
||||
-webkit-filter: drop-shadow(0 0 5px blue);
|
||||
}
|
||||
|
||||
#cb_names.cb-light-won::before {
|
||||
filter: drop-shadow(0 0 5px darkviolet);
|
||||
-webkit-filter: drop-shadow(0 0 5px darkviolet);
|
||||
}
|
||||
|
||||
#cb_names::after {
|
||||
content: '';
|
||||
display: block;
|
||||
background-image: url(../svg/pacosako-theme.svg#dark_king_right);
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0.5rem;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
#cb_names.cb-dark-turn::after {
|
||||
filter: drop-shadow(0 0 5px blue);
|
||||
-webkit-filter: drop-shadow(0 0 5px blue);
|
||||
}
|
||||
|
||||
#cb_names.cb-dark-won::after {
|
||||
filter: drop-shadow(0 0 5px darkviolet);
|
||||
-webkit-filter: drop-shadow(0 0 5px darkviolet);
|
||||
}
|
||||
|
||||
#cb_names .cb-names-vs {
|
||||
padding-left: 0.25em;
|
||||
padding-right: 0.25em;
|
||||
}
|
||||
|
||||
#cb_names input {
|
||||
flex: 1 1 auto;
|
||||
width: 4em;
|
||||
background-color: inherit;
|
||||
border: none;
|
||||
margin: 2px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#cb_names input:focus {
|
||||
outline: 1px solid blue;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
#cb_dark_name {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#cb_navigate {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: stretch;
|
||||
justify-content: stretch;
|
||||
border-top: 1px solid black;
|
||||
background-image: linear-gradient(#FFFFF0, #F5DEB3);
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
flex: 0 1 auto;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
#cb_navigate .nav-spacer {
|
||||
flex: 1 1 auto;
|
||||
min-width: 1rem;
|
||||
width: 100%;
|
||||
background: none;
|
||||
background-color: #DCC8A140;
|
||||
}
|
||||
|
||||
#cb_navigate button {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
width: 2rem;
|
||||
min-width: 2rem;
|
||||
min-height: 2rem;
|
||||
background: none;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
#cb_navigate button:active {
|
||||
background-image: linear-gradient(#F5DEB3, #FFFFF0);
|
||||
}
|
||||
|
||||
#cb_navigate > .nav-spacer, #cb_navigate > button {
|
||||
border-left: 1px solid #DCC8A1;
|
||||
}
|
||||
|
||||
#cb_navigate > .nav-spacer:first-child, #cb_navigate > button:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
#cb_board tr {
|
||||
position: relative;
|
||||
}
|
||||
|
|
@ -97,163 +380,14 @@ button:disabled .silhouette {
|
|||
position: relative;
|
||||
}
|
||||
|
||||
#cb_light_name, #cb_dark_name {
|
||||
width: 8em;
|
||||
}
|
||||
|
||||
#cb_control_container {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
flex: 0 1000 auto;
|
||||
margin-left: 1em;
|
||||
width: 100%;
|
||||
min-width: 24em;
|
||||
max-height: calc(100vh - (8px + 2.8em));
|
||||
padding-right: calc(3.25em + 10px);
|
||||
}
|
||||
|
||||
#cb_control_form {
|
||||
flex: 0 1 auto;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
margin-right: auto;
|
||||
border-radius: 6pt;
|
||||
padding: 1.125em;
|
||||
background-color: #FFFFF0;
|
||||
box-shadow: 0 0 0 1px black, 2px 2px 4px #00000080;
|
||||
}
|
||||
|
||||
#cb_controls, #cb_theme, #cb_names, #cb_navigate {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#cb_theme, #cb_names, #cb_navigate {
|
||||
margin-top: 1.125em;
|
||||
}
|
||||
|
||||
#cb_names input {
|
||||
background-color: inherit;
|
||||
border: none;
|
||||
border-bottom: 1px solid black;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
#cb_names input:focus {
|
||||
outline: 1px solid blue;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
#cb_scrollable {
|
||||
flex: 1 1000 auto;
|
||||
padding-bottom: 0.5em;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#cb_message {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
#cb_theme {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.cb-spacer {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
#cb_choose_game {
|
||||
margin-left: 0.2em;
|
||||
}
|
||||
|
||||
#cb_theme label {
|
||||
flex: 0 0 auto;
|
||||
padding-right: 0.2em;
|
||||
}
|
||||
|
||||
#cb_undo {
|
||||
margin-left: auto;
|
||||
margin-right: 0.1em;
|
||||
}
|
||||
|
||||
#cb_redo {
|
||||
margin-left: 0.1em;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
#cb_resign {
|
||||
margin-left: 0.1em;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
#cb_navigate {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-items: center;
|
||||
justify-content: center;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
#cb_navigate button {
|
||||
margin-left: 0.1em;
|
||||
margin-right: 0.1em;
|
||||
}
|
||||
|
||||
#cb_navigate button:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
#cb_navigate button:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
#cb_history {
|
||||
max-width: 7.5in;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
#cb_history_future {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
#cb_explain_check {
|
||||
color: red;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.cb-hbox {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cb-vbox {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cb-align-start {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.cb-align-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.cb-square {
|
||||
position: relative;
|
||||
width: calc((100% - 16pt) / 8);
|
||||
height: calc((100% - 16pt) / 8);
|
||||
border: 1px solid black;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.cb-horiz-label {
|
||||
position: relative;
|
||||
width: calc((100% - 16pt) / 8);
|
||||
height: 8pt;
|
||||
border: 1px solid black;
|
||||
padding: 0;
|
||||
|
|
@ -261,7 +395,7 @@ button:disabled .silhouette {
|
|||
|
||||
.cb-horiz-label div {
|
||||
position: absolute;
|
||||
top: calc(50% - (1em / 2));
|
||||
top: calc(50% - 3pt);
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
|
|
@ -273,7 +407,6 @@ button:disabled .silhouette {
|
|||
.cb-vert-label {
|
||||
position: relative;
|
||||
width: 8pt;
|
||||
height: calc((100% - 16pt) / 8);
|
||||
border: 1px solid black;
|
||||
padding: 0;
|
||||
}
|
||||
|
|
@ -393,13 +526,62 @@ button:disabled .silhouette {
|
|||
z-index: 1;
|
||||
}
|
||||
|
||||
.badges {
|
||||
position: fixed;
|
||||
bottom: 5px;
|
||||
right: 5px;
|
||||
margin: 0;
|
||||
.cb-private .cb-hide-if-private {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.cb-show-if-private {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.cb-private .cb-show-if-private {
|
||||
display: initial !important;
|
||||
}
|
||||
|
||||
div.hbox {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: stretch;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.private-link {
|
||||
flex: 0 1 auto;
|
||||
margin: 0.1em;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.private-link:visited {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.private-link:hover {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.jBox-wrapper.jBox-hasTitle > .jBox-container {
|
||||
padding: 4px; /* same as border-radius */
|
||||
}
|
||||
|
||||
.jBox-title h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.rules {
|
||||
display: block;
|
||||
max-width: 80vw;
|
||||
}
|
||||
|
||||
.badges {
|
||||
position: static;
|
||||
bottom: auto;
|
||||
right: auto;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
margin-left: auto;
|
||||
margin-right: 5px;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
|
@ -409,23 +591,31 @@ button:disabled .silhouette {
|
|||
}
|
||||
|
||||
.badge img {
|
||||
width: 3em;
|
||||
height: 3em;
|
||||
opacity: 0.5;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.badge.game-link-badge img {
|
||||
width: 1.8em;
|
||||
height: 1.8em;
|
||||
margin: 0.6em;
|
||||
#cb_theme {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: baseline;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
#cb_theme label {
|
||||
flex: 0 0 auto;
|
||||
padding-right: 0.2rem;
|
||||
}
|
||||
|
||||
.game-tiles {
|
||||
max-width: 80vw;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
text-align: center;
|
||||
width: calc(100vw - 6rem);
|
||||
max-width: calc(100vw - 6rem);
|
||||
max-height: calc(100vh - 12rem);
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(15em, auto));
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
}
|
||||
|
||||
.game-tiles > * {
|
||||
|
|
@ -434,14 +624,14 @@ button:disabled .silhouette {
|
|||
|
||||
.game-tile {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 14em;
|
||||
height: 14em;
|
||||
box-shadow: 0 0 0 1px black, 5px 5px 3px #00000080;
|
||||
margin: 1em;
|
||||
margin: 0.5em;
|
||||
padding: 0.5em;
|
||||
border-radius: 6pt;
|
||||
background-color: #FFFFF0;
|
||||
|
|
@ -474,6 +664,7 @@ button:disabled .silhouette {
|
|||
font-size: 3em;
|
||||
text-shadow: 2px 2px 4px #000000c0;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.new-game-text::before {
|
||||
|
|
@ -596,77 +787,46 @@ button:disabled .silhouette {
|
|||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.game-tile {
|
||||
font-size: calc(12in * 0.015);
|
||||
.game-tiles {
|
||||
font-size: calc(12in * 0.014);
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 6in) and (max-width: 12in) {
|
||||
.game-tile {
|
||||
font-size: 1.5vw;
|
||||
.game-tiles {
|
||||
font-size: 1.4vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 6in) {
|
||||
.game-tile {
|
||||
font-size: calc(6in * 0.015);
|
||||
.game-tiles {
|
||||
font-size: calc(6in * 0.014);
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-aspect-ratio: 3/2) {
|
||||
#content {
|
||||
flex-flow: column nowrap;
|
||||
}
|
||||
.cb-dk-piece.cb-king { content: url(../svg/pacosako-theme.svg#dark_king_right); }
|
||||
.cb-dk-piece.cb-queen { content: url(../svg/pacosako-theme.svg#dark_queen_right); }
|
||||
.cb-dk-piece.cb-bishop { content: url(../svg/pacosako-theme.svg#dark_bishop_right); }
|
||||
.cb-dk-piece.cb-knight { content: url(../svg/pacosako-theme.svg#dark_knight_right); }
|
||||
.cb-dk-piece.cb-rook { content: url(../svg/pacosako-theme.svg#dark_rook_right); }
|
||||
.cb-dk-piece.cb-pawn { content: url(../svg/pacosako-theme.svg#dark_pawn_right); }
|
||||
.cb-lt-piece.cb-king { content: url(../svg/pacosako-theme.svg#light_king_left); }
|
||||
.cb-lt-piece.cb-queen { content: url(../svg/pacosako-theme.svg#light_queen_left); }
|
||||
.cb-lt-piece.cb-bishop { content: url(../svg/pacosako-theme.svg#light_bishop_left); }
|
||||
.cb-lt-piece.cb-knight { content: url(../svg/pacosako-theme.svg#light_knight_left); }
|
||||
.cb-lt-piece.cb-rook { content: url(../svg/pacosako-theme.svg#light_rook_left); }
|
||||
.cb-lt-piece.cb-pawn { content: url(../svg/pacosako-theme.svg#light_pawn_left); }
|
||||
|
||||
#cb_outer2 {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
#cb_control_container {
|
||||
margin-top: 1em;
|
||||
margin-left: 8px;
|
||||
max-height: none;
|
||||
overflow: visible;
|
||||
width: 100%;
|
||||
max-width: calc(100vw - (8px + 24px));
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.badges {
|
||||
position: static;
|
||||
bottom: auto;
|
||||
right: auto;
|
||||
margin-left: auto;
|
||||
margin-right: 5px;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
.cb-dk-piece.cb-king { content: url(../svg/traditional-theme.svg#dark_king_right); }
|
||||
.cb-dk-piece.cb-queen { content: url(../svg/traditional-theme.svg#dark_queen_right); }
|
||||
.cb-dk-piece.cb-bishop { content: url(../svg/traditional-theme.svg#dark_bishop_right); }
|
||||
.cb-dk-piece.cb-knight { content: url(../svg/traditional-theme.svg#dark_knight_right); }
|
||||
.cb-dk-piece.cb-rook { content: url(../svg/traditional-theme.svg#dark_rook_right); }
|
||||
.cb-dk-piece.cb-pawn { content: url(../svg/traditional-theme.svg#dark_pawn_right); }
|
||||
.cb-lt-piece.cb-king { content: url(../svg/traditional-theme.svg#light_king_left); }
|
||||
.cb-lt-piece.cb-queen { content: url(../svg/traditional-theme.svg#light_queen_left); }
|
||||
.cb-lt-piece.cb-bishop { content: url(../svg/traditional-theme.svg#light_bishop_left); }
|
||||
.cb-lt-piece.cb-knight { content: url(../svg/traditional-theme.svg#light_knight_left); }
|
||||
.cb-lt-piece.cb-rook { content: url(../svg/traditional-theme.svg#light_rook_left); }
|
||||
.cb-lt-piece.cb-pawn { content: url(../svg/traditional-theme.svg#light_pawn_left); }
|
||||
|
||||
.cb-reversed .cb-dk-piece.cb-king { content: url(../svg/traditional-theme.svg#dark_king_left); }
|
||||
.cb-reversed .cb-dk-piece.cb-queen { content: url(../svg/traditional-theme.svg#dark_queen_left); }
|
||||
.cb-reversed .cb-dk-piece.cb-bishop { content: url(../svg/traditional-theme.svg#dark_bishop_left); }
|
||||
.cb-reversed .cb-dk-piece.cb-knight { content: url(../svg/traditional-theme.svg#dark_knight_left); }
|
||||
.cb-reversed .cb-dk-piece.cb-rook { content: url(../svg/traditional-theme.svg#dark_rook_left); }
|
||||
.cb-reversed .cb-dk-piece.cb-pawn { content: url(../svg/traditional-theme.svg#dark_pawn_left); }
|
||||
.cb-reversed .cb-lt-piece.cb-king { content: url(../svg/traditional-theme.svg#light_king_right); }
|
||||
.cb-reversed .cb-lt-piece.cb-queen { content: url(../svg/traditional-theme.svg#light_queen_right); }
|
||||
.cb-reversed .cb-lt-piece.cb-bishop { content: url(../svg/traditional-theme.svg#light_bishop_right); }
|
||||
.cb-reversed .cb-lt-piece.cb-knight { content: url(../svg/traditional-theme.svg#light_knight_right); }
|
||||
.cb-reversed .cb-lt-piece.cb-rook { content: url(../svg/traditional-theme.svg#light_rook_right); }
|
||||
.cb-reversed .cb-lt-piece.cb-pawn { content: url(../svg/traditional-theme.svg#light_pawn_right); }
|
||||
.cb-reversed .cb-dk-piece.cb-king { content: url(../svg/pacosako-theme.svg#dark_king_left); }
|
||||
.cb-reversed .cb-dk-piece.cb-queen { content: url(../svg/pacosako-theme.svg#dark_queen_left); }
|
||||
.cb-reversed .cb-dk-piece.cb-bishop { content: url(../svg/pacosako-theme.svg#dark_bishop_left); }
|
||||
.cb-reversed .cb-dk-piece.cb-knight { content: url(../svg/pacosako-theme.svg#dark_knight_left); }
|
||||
.cb-reversed .cb-dk-piece.cb-rook { content: url(../svg/pacosako-theme.svg#dark_rook_left); }
|
||||
.cb-reversed .cb-dk-piece.cb-pawn { content: url(../svg/pacosako-theme.svg#dark_pawn_left); }
|
||||
.cb-reversed .cb-lt-piece.cb-king { content: url(../svg/pacosako-theme.svg#light_king_right); }
|
||||
.cb-reversed .cb-lt-piece.cb-queen { content: url(../svg/pacosako-theme.svg#light_queen_right); }
|
||||
.cb-reversed .cb-lt-piece.cb-bishop { content: url(../svg/pacosako-theme.svg#light_bishop_right); }
|
||||
.cb-reversed .cb-lt-piece.cb-knight { content: url(../svg/pacosako-theme.svg#light_knight_right); }
|
||||
.cb-reversed .cb-lt-piece.cb-rook { content: url(../svg/pacosako-theme.svg#light_rook_right); }
|
||||
.cb-reversed .cb-lt-piece.cb-pawn { content: url(../svg/pacosako-theme.svg#light_pawn_right); }
|
||||
|
||||
/* vim: set expandtab sw=3 ts=8: */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
.cb-theme-traditional .cb-dk-piece.cb-king { content: url(../../svg/traditional-theme.svg#dark_king_right); }
|
||||
.cb-theme-traditional .cb-dk-piece.cb-queen { content: url(../../svg/traditional-theme.svg#dark_queen_right); }
|
||||
.cb-theme-traditional .cb-dk-piece.cb-bishop { content: url(../../svg/traditional-theme.svg#dark_bishop_right); }
|
||||
.cb-theme-traditional .cb-dk-piece.cb-knight { content: url(../../svg/traditional-theme.svg#dark_knight_right); }
|
||||
.cb-theme-traditional .cb-dk-piece.cb-rook { content: url(../../svg/traditional-theme.svg#dark_rook_right); }
|
||||
.cb-theme-traditional .cb-dk-piece.cb-pawn { content: url(../../svg/traditional-theme.svg#dark_pawn_right); }
|
||||
.cb-theme-traditional .cb-lt-piece.cb-king { content: url(../../svg/traditional-theme.svg#light_king_left); }
|
||||
.cb-theme-traditional .cb-lt-piece.cb-queen { content: url(../../svg/traditional-theme.svg#light_queen_left); }
|
||||
.cb-theme-traditional .cb-lt-piece.cb-bishop { content: url(../../svg/traditional-theme.svg#light_bishop_left); }
|
||||
.cb-theme-traditional .cb-lt-piece.cb-knight { content: url(../../svg/traditional-theme.svg#light_knight_left); }
|
||||
.cb-theme-traditional .cb-lt-piece.cb-rook { content: url(../../svg/traditional-theme.svg#light_rook_left); }
|
||||
.cb-theme-traditional .cb-lt-piece.cb-pawn { content: url(../../svg/traditional-theme.svg#light_pawn_left); }
|
||||
|
||||
.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-king { content: url(../../svg/traditional-theme.svg#dark_king_left); }
|
||||
.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-queen { content: url(../../svg/traditional-theme.svg#dark_queen_left); }
|
||||
.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-bishop { content: url(../../svg/traditional-theme.svg#dark_bishop_left); }
|
||||
.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-knight { content: url(../../svg/traditional-theme.svg#dark_knight_left); }
|
||||
.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-rook { content: url(../../svg/traditional-theme.svg#dark_rook_left); }
|
||||
.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-pawn { content: url(../../svg/traditional-theme.svg#dark_pawn_left); }
|
||||
.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-king { content: url(../../svg/traditional-theme.svg#light_king_right); }
|
||||
.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-queen { content: url(../../svg/traditional-theme.svg#light_queen_right); }
|
||||
.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-bishop { content: url(../../svg/traditional-theme.svg#light_bishop_right); }
|
||||
.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-knight { content: url(../../svg/traditional-theme.svg#light_knight_right); }
|
||||
.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-rook { content: url(../../svg/traditional-theme.svg#light_rook_right); }
|
||||
.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-pawn { content: url(../../svg/traditional-theme.svg#light_pawn_right); }
|
||||
420
index.html
420
index.html
|
|
@ -1,3 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
|
|
@ -14,246 +15,215 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="page">
|
||||
<h1><a href="." class="plain-link">Paco Ŝako</a></h1>
|
||||
|
||||
<div id="content">
|
||||
<div id="cb_outer2">
|
||||
<div id="cb_outer">
|
||||
<div id="cb_container">
|
||||
<div id="cb_inner">
|
||||
<table id="cb_board" class="noselect">
|
||||
<tr id="cb_row9">
|
||||
<td id="cb_L9" class="cb-corner"></td>
|
||||
<td id="cb_a9" class="cb-horiz-label"><div>A</div></td>
|
||||
<td id="cb_b9" class="cb-horiz-label"><div>B</div></td>
|
||||
<td id="cb_c9" class="cb-horiz-label"><div>C</div></td>
|
||||
<td id="cb_d9" class="cb-horiz-label"><div>D</div></td>
|
||||
<td id="cb_e9" class="cb-horiz-label"><div>E</div></td>
|
||||
<td id="cb_f9" class="cb-horiz-label"><div>F</div></td>
|
||||
<td id="cb_g9" class="cb-horiz-label"><div>G</div></td>
|
||||
<td id="cb_h9" class="cb-horiz-label"><div>H</div></td>
|
||||
<td id="cb_R9" class="cb-corner"></td>
|
||||
</tr>
|
||||
<tr id="cb_row8">
|
||||
<td id="cb_L8" class="cb-vert-label"><div>8</div></td>
|
||||
<td id="cb_a8" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_b8" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_c8" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_d8" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_e8" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_f8" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_g8" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_h8" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_R8" class="cb-vert-label"><div>8</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row7">
|
||||
<td id="cb_L7" class="cb-vert-label"><div>7</div></td>
|
||||
<td id="cb_a7" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_b7" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_c7" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_d7" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_e7" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_f7" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_g7" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_h7" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_R7" class="cb-vert-label"><div>7</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row6">
|
||||
<td id="cb_L6" class="cb-vert-label"><div>6</div></td>
|
||||
<td id="cb_a6" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_b6" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_c6" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_d6" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_e6" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_f6" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_g6" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_h6" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_R6" class="cb-vert-label"><div>6</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row5">
|
||||
<td id="cb_L5" class="cb-vert-label"><div>5</div></td>
|
||||
<td id="cb_a5" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_b5" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_c5" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_d5" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_e5" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_f5" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_g5" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_h5" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_R5" class="cb-vert-label"><div>5</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row4">
|
||||
<td id="cb_L4" class="cb-vert-label"><div>4</div></td>
|
||||
<td id="cb_a4" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_b4" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_c4" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_d4" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_e4" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_f4" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_g4" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_h4" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_R4" class="cb-vert-label"><div>4</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row3">
|
||||
<td id="cb_L3" class="cb-vert-label"><div>3</div></td>
|
||||
<td id="cb_a3" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_b3" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_c3" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_d3" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_e3" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_f3" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_g3" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_h3" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_R3" class="cb-vert-label"><div>3</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row2">
|
||||
<td id="cb_L2" class="cb-vert-label"><div>2</div></td>
|
||||
<td id="cb_a2" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_b2" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_c2" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_d2" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_e2" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_f2" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_g2" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_h2" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_R2" class="cb-vert-label"><div>2</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row1">
|
||||
<td id="cb_L1" class="cb-vert-label"><div>1</div></td>
|
||||
<td id="cb_a1" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_b1" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_c1" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_d1" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_e1" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_f1" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_g1" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_h1" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_R1" class="cb-vert-label"><div>1</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row0">
|
||||
<td id="cb_L0" class="cb-corner"></td>
|
||||
<td id="cb_a0" class="cb-horiz-label"><div>A</div></td>
|
||||
<td id="cb_b0" class="cb-horiz-label"><div>B</div></td>
|
||||
<td id="cb_c0" class="cb-horiz-label"><div>C</div></td>
|
||||
<td id="cb_d0" class="cb-horiz-label"><div>D</div></td>
|
||||
<td id="cb_e0" class="cb-horiz-label"><div>E</div></td>
|
||||
<td id="cb_f0" class="cb-horiz-label"><div>F</div></td>
|
||||
<td id="cb_g0" class="cb-horiz-label"><div>G</div></td>
|
||||
<td id="cb_h0" class="cb-horiz-label"><div>H</div></td>
|
||||
<td id="cb_R0" class="cb-corner"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="board_ui">
|
||||
<div id="header">
|
||||
<button id="settings" title="Settings" type="button"><span class="fas fa-cog"></span></button>
|
||||
<button id="cb_choose_game" title="Choose Game" type="button" class="cb-hide-if-private"><span class="fas fa-list"></span></button>
|
||||
<h1>Paco Ŝako<span class="cb-show-if-private" style="display: none"> - Private Mode</span></h1>
|
||||
<div class="checkbox-container"><input id="cb_reverse" title="Reverse Board" type="checkbox" autocomplete="off" class="image-checkbox fas fa-sync"></div>
|
||||
<div class="checkbox-container cb-hide-if-private"><input id="cb_notify" title="Notify" type="checkbox" autocomplete="off" class="image-checkbox fas fa-bell-slash"></div>
|
||||
<button id="help" title="Help" type="button"><span class="fas fa-question-circle"></span></button>
|
||||
</div>
|
||||
|
||||
<div id="cb_control_container">
|
||||
<form id="cb_control_form" autocomplete="off" onsubmit="return false;">
|
||||
<div id="cb_controls">
|
||||
<div class="cb-hbox">
|
||||
<div class="cb-vbox cb-align-start">
|
||||
<div><input id="cb_notify" type="checkbox"><label for="cb_notify">Notify</label></div>
|
||||
<div><input id="cb_sound" type="checkbox"><label for="cb_sound">Sound</label></div>
|
||||
<div><input id="cb_reverse" type="checkbox"><label for="cb_reverse">Reverse</label></div>
|
||||
</div>
|
||||
<div class="cb-spacer"></div>
|
||||
<div class="cb-vbox cb-align-stretch">
|
||||
<div class="cb-hbox">
|
||||
<button id="cb_undo" type="button" disabled="true">Undo</button>
|
||||
<button id="cb_redo" type="button" disabled="true">Redo</button>
|
||||
<button id="cb_resign" type="button" disabled="true">Resign</button>
|
||||
</div>
|
||||
<div id="cb_navigate">
|
||||
<button id="cb_nav_first" title="View First Turn" type="button" disabled="true">
|
||||
<svg viewBox="0 0 144 144" class="media-button-svg silhouette">
|
||||
<path d="M 6 24 H 24 V 120 H 6"/>
|
||||
<path d="M 18 72 L 90 24 V 120"/>
|
||||
<path d="M 66 72 L 138 24 V 120"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button id="cb_nav_prev_turn" title="View Prior Turn" type="button" disabled="true">
|
||||
<svg viewBox="0 0 144 144" class="media-button-svg silhouette">
|
||||
<path d="M 12 72 L 84 24 V 120"/>
|
||||
<path d="M 60 72 L 132 24 V 120"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button id="cb_nav_prev_state" title="View Prior State" type="button" disabled="true">
|
||||
<svg viewBox="0 0 144 144" class="media-button-svg silhouette">
|
||||
<path d="M 36 72 L 108 24 V 120"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button id="cb_nav_next_state" title="View Next State" type="button" disabled="true">
|
||||
<svg viewBox="0 0 144 144" class="media-button-svg silhouette">
|
||||
<path d="M 108 72 L 36 24 V 120"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button id="cb_nav_next_turn" title="View Next Turn" type="button" disabled="true">
|
||||
<svg viewBox="0 0 144 144" class="media-button-svg silhouette">
|
||||
<path d="M 84 72 L 12 24 V 120"/>
|
||||
<path d="M 132 72 L 60 24 V 120"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button id="cb_nav_last" title="View Current Move" type="button" disabled="true">
|
||||
<svg viewBox="0 0 144 144" class="media-button-svg silhouette">
|
||||
<path d="M 78 72 L 6 24 V 120"/>
|
||||
<path d="M 126 72 L 54 24 V 120"/>
|
||||
<path d="M 138 24 H 120 V 120 H 138"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="cb_theme">
|
||||
<label for="cb_select_theme">Theme:</label>
|
||||
<select id="cb_select_theme">
|
||||
<option value="traditional">Traditional</option>
|
||||
<option value="pacosako">Paco Ŝako</option>
|
||||
</select>
|
||||
<div class="cb-spacer"></div>
|
||||
<button id="cb_choose_game">Choose Game…</button>
|
||||
</div>
|
||||
<div id="cb_names">
|
||||
<label for="cb_light_name">Players:</label>
|
||||
<input id="cb_light_name" placeholder="Light"> vs. <input id="cb_dark_name" placeholder="Dark">
|
||||
</div>
|
||||
</form>
|
||||
<div id="cb_message"></div>
|
||||
<div id="cb_container">
|
||||
<table id="cb_board" class="noselect cb-theme-pacosako" style="visibility: hidden">
|
||||
<tr id="cb_row9">
|
||||
<td id="cb_L9" class="cb-corner"></td>
|
||||
<td id="cb_a9" class="cb-horiz-label"><div>A</div></td>
|
||||
<td id="cb_b9" class="cb-horiz-label"><div>B</div></td>
|
||||
<td id="cb_c9" class="cb-horiz-label"><div>C</div></td>
|
||||
<td id="cb_d9" class="cb-horiz-label"><div>D</div></td>
|
||||
<td id="cb_e9" class="cb-horiz-label"><div>E</div></td>
|
||||
<td id="cb_f9" class="cb-horiz-label"><div>F</div></td>
|
||||
<td id="cb_g9" class="cb-horiz-label"><div>G</div></td>
|
||||
<td id="cb_h9" class="cb-horiz-label"><div>H</div></td>
|
||||
<td id="cb_R9" class="cb-corner"></td>
|
||||
</tr>
|
||||
<tr id="cb_row8">
|
||||
<td id="cb_L8" class="cb-vert-label"><div>8</div></td>
|
||||
<td id="cb_a8" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_b8" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_c8" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_d8" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_e8" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_f8" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_g8" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_h8" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_R8" class="cb-vert-label"><div>8</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row7">
|
||||
<td id="cb_L7" class="cb-vert-label"><div>7</div></td>
|
||||
<td id="cb_a7" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_b7" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_c7" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_d7" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_e7" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_f7" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_g7" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_h7" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_R7" class="cb-vert-label"><div>7</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row6">
|
||||
<td id="cb_L6" class="cb-vert-label"><div>6</div></td>
|
||||
<td id="cb_a6" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_b6" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_c6" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_d6" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_e6" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_f6" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_g6" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_h6" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_R6" class="cb-vert-label"><div>6</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row5">
|
||||
<td id="cb_L5" class="cb-vert-label"><div>5</div></td>
|
||||
<td id="cb_a5" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_b5" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_c5" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_d5" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_e5" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_f5" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_g5" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_h5" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_R5" class="cb-vert-label"><div>5</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row4">
|
||||
<td id="cb_L4" class="cb-vert-label"><div>4</div></td>
|
||||
<td id="cb_a4" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_b4" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_c4" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_d4" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_e4" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_f4" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_g4" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_h4" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_R4" class="cb-vert-label"><div>4</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row3">
|
||||
<td id="cb_L3" class="cb-vert-label"><div>3</div></td>
|
||||
<td id="cb_a3" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_b3" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_c3" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_d3" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_e3" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_f3" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_g3" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_h3" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_R3" class="cb-vert-label"><div>3</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row2">
|
||||
<td id="cb_L2" class="cb-vert-label"><div>2</div></td>
|
||||
<td id="cb_a2" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_b2" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_c2" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_d2" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_e2" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_f2" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_g2" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_h2" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_R2" class="cb-vert-label"><div>2</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row1">
|
||||
<td id="cb_L1" class="cb-vert-label"><div>1</div></td>
|
||||
<td id="cb_a1" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_b1" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_c1" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_d1" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_e1" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_f1" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_g1" class="cb-square cb-dk-bg"></td>
|
||||
<td id="cb_h1" class="cb-square cb-lt-bg"></td>
|
||||
<td id="cb_R1" class="cb-vert-label"><div>1</div></td>
|
||||
</tr>
|
||||
<tr id="cb_row0">
|
||||
<td id="cb_L0" class="cb-corner"></td>
|
||||
<td id="cb_a0" class="cb-horiz-label"><div>A</div></td>
|
||||
<td id="cb_b0" class="cb-horiz-label"><div>B</div></td>
|
||||
<td id="cb_c0" class="cb-horiz-label"><div>C</div></td>
|
||||
<td id="cb_d0" class="cb-horiz-label"><div>D</div></td>
|
||||
<td id="cb_e0" class="cb-horiz-label"><div>E</div></td>
|
||||
<td id="cb_f0" class="cb-horiz-label"><div>F</div></td>
|
||||
<td id="cb_g0" class="cb-horiz-label"><div>G</div></td>
|
||||
<td id="cb_h0" class="cb-horiz-label"><div>H</div></td>
|
||||
<td id="cb_R0" class="cb-corner"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div id="cb_status">
|
||||
<div class="hbox">
|
||||
<div id="cb_message"></div>
|
||||
<div class="cb-hide-if-private"><a class="private-link" target="_blank" title="Open Private Copy"><span class="fas fa-copy"></span></a></div>
|
||||
</div>
|
||||
<div id="cb_explain_check"></div>
|
||||
<div id="cb_scrollable">
|
||||
<div id="cb_history">
|
||||
<span id="cb_history_past"></span><span id="cb_history_future"></span>
|
||||
<div id="cb_explain_check"></div>
|
||||
</div>
|
||||
<details>
|
||||
<summary>Rule Reference</summary>
|
||||
<p>The basic movement for each piece is the same as traditional chess.</p>
|
||||
<p>Pieces are never removed from the board. Instead, the capturing piece shares the square with the captured piece, and the two pieces become a joined pair.</p>
|
||||
<p>When either piece moves from a square containing two pieces, the other piece moves with it.
|
||||
Each player can only move a joined pair according to the rules for their own piece. Joined pieces cannot capture other pieces.</p>
|
||||
<p>A free (non-joined) piece may move into a square occupied by pieces of both colors.
|
||||
When it does, the other piece of the same color becomes a free piece and must move to a new location following the normal movement rules.
|
||||
This process may be repeated multiple times in the same turn.</p>
|
||||
<p>Ŝako (checkmate) occurs when an opposing piece joins with the king.
|
||||
<strong>Important:</strong> The king is not permitted to join with (capture) other pieces.</p>
|
||||
<p>Due to joined movement, it is possible for a pawn to be moved backward to, or past, its starting row.
|
||||
Pawns may move forward two spaces from either of the first two rows on their own side of the board.</p>
|
||||
<p>When a pawn is captured <i>en passant</i> while joined with another piece, the captured pawn moves back one square to become joined with the capturing pawn
|
||||
and the joined piece from the capturing side moves to a new location from its original position as with any other capture.</p>
|
||||
<p>Pawns are promoted when they reach the final row on the opposite side of the board, even if they were moved there by the other player as part of a joined pair.</p>
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="cb_names" class="cb-hide-if-private">
|
||||
<div id="cb_names_text">
|
||||
<input id="cb_light_name" autocomplete="off" placeholder="Light">
|
||||
<span class="cb-names-vs">vs.</span>
|
||||
<input id="cb_dark_name" autocomplete="off" placeholder="Dark">
|
||||
</div>
|
||||
</div>
|
||||
<div id="cb_times" class="cb-hide-if-private">
|
||||
<div id="cb_light_time">0:00:00</div>
|
||||
<div id="cb_dark_time">0:00:00</div>
|
||||
</div>
|
||||
<div id="cb_navigate">
|
||||
<button id="cb_undo" title="Undo" type="button" disabled="true"><span class="fas fa-undo"></span></button>
|
||||
<button id="cb_redo" title="Redo" type="button" disabled="true"><span class="fas fa-redo"></span></button>
|
||||
<div class="nav-spacer"></div>
|
||||
<button id="cb_resign" title="Resign" type="button" disabled="true"><span class="fas fa-flag"></span></button>
|
||||
<div class="nav-spacer"></div>
|
||||
<button id="cb_nav_first" title="View First Turn" type="button" disabled="true"><span class="fas fa-fast-backward"></span></button>
|
||||
<button id="cb_nav_prev_turn" title="View Prior Turn" type="button" disabled="true"><span class="fas fa-backward"></span></button>
|
||||
<button id="cb_nav_prev_state" title="View Prior Move" type="button" disabled="true"><span class="fas fa-play fa-flip-horizontal"></span></button>
|
||||
<button id="cb_nav_next_state" title="View Next Move" type="button" disabled="true"><span class="fas fa-play"></span></button>
|
||||
<button id="cb_nav_next_turn" title="View Next Turn" type="button" disabled="true"><span class="fas fa-forward"></span></button>
|
||||
<button id="cb_nav_last" title="View Current Move" type="button" disabled="true"><span class="fas fa-fast-forward"></span></button>
|
||||
</div>
|
||||
</div> <!-- board_ui -->
|
||||
</div>
|
||||
|
||||
<div id="rules_content" style="display: none">
|
||||
<div id="rules" class="rules">
|
||||
<p>The basic movement for each piece is the same as traditional chess.</p>
|
||||
<p>Pieces are never removed from the board. Instead, the capturing piece shares the square with the captured piece, and the two pieces become a joined pair.</p>
|
||||
<p>When either piece moves from a square containing two pieces, the other piece moves with it.
|
||||
Each player can only move a joined pair according to the rules for their own piece. Joined pieces cannot capture other pieces.</p>
|
||||
<p>A free (non-joined) piece may move into a square occupied by pieces of both colors.
|
||||
When it does, the other piece of the same color becomes a free piece and must move to a new location following the normal movement rules.
|
||||
This process may be repeated multiple times in the same turn.</p>
|
||||
<p>Ŝako (checkmate) occurs when an opposing piece joins with the king.
|
||||
<strong>Important:</strong> The king is not permitted to join with (capture) other pieces.</p>
|
||||
<p>Due to joined movement, it is possible for a pawn to be moved backward to, or past, its starting row.
|
||||
Pawns may move forward two spaces from either of the first two rows on their own side of the board.</p>
|
||||
<p>When a pawn is captured <i>en passant</i> while joined with another piece, the captured pawn moves back one square to become joined with the capturing pawn
|
||||
and the joined piece from the capturing side moves to a new location from its original position as with any other capture.</p>
|
||||
<p>Pawns are promoted when they reach the final row on the opposite side of the board, even if they were moved there by the other player as part of a joined pair.</p>
|
||||
</div>
|
||||
<div class="badges">
|
||||
<!-- "external-link-alt" by Font Awesome (fontawesome.com/icons/external-link-alt?style=solid) / CC BY 4.0 (creativecommons.org/licenses/by/4.0) -->
|
||||
<div class="badge game-link-badge"><a id="game_link" href="#" rel="noopener noreferer" target="_blank"><img src="<%=require('./svg/external-link-alt-solid.svg')%>" alt="This Game" title="Link to This Game"></a></div>
|
||||
<div class="badge official-badge"><a href="https://pacosako.com/" rel="noopener noreferer" target="_blank"><img src="<%=require('./svg/pacosako-logo.svg')%>" alt="Official Site" title="Official Site"></a></div>
|
||||
<div class="badge jitsi-badge"><a id="jitsi_link" href="https://meet.jit.si/PacoSako" rel="noopener noreferer" target="_blank"><img src="<%=require('./svg/jitsi-logo-blue.svg')%>" alt="Jitsi Meet" title="Jitsi Meet"></a></div>
|
||||
<div class="badge gogs-badge"><a href="https://jessemcdonald.info/gogs/nybble/paco_sako" rel="noopener noreferer" target="_blank"><img src="<%=require('./png/gogs.png')%>" alt="Source Code" title="Source Code"></a></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="settings_content" style="display: none">
|
||||
<div id="settings">
|
||||
<div><input id="cb_sound" type="checkbox"><label for="cb_sound">Sound</label></div>
|
||||
<div id="cb_theme">
|
||||
<label for="cb_select_theme">Theme:</label>
|
||||
<select id="cb_select_theme">
|
||||
<option value="pacosako">Paco Ŝako</option>
|
||||
<option value="traditional">Traditional</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<!-- vim:set noexpandtab sw=2 ts=2: -->
|
||||
|
|
|
|||
4
index.js
4
index.js
|
|
@ -1,4 +1,8 @@
|
|||
import './css/chess.css';
|
||||
import './css/theme/pacosako.css';
|
||||
import './css/theme/traditional.css';
|
||||
|
||||
import '@fortawesome/fontawesome-free/css/fontawesome.css';
|
||||
import '@fortawesome/fontawesome-free/css/solid.css';
|
||||
|
||||
import './js/pacosako_ui.js';
|
||||
|
|
|
|||
|
|
@ -90,6 +90,9 @@ export class Iterator {
|
|||
}
|
||||
|
||||
flatMap(f) {
|
||||
if (typeof f === 'undefined') {
|
||||
f = identity;
|
||||
}
|
||||
const next = this.next;
|
||||
let innerNext;
|
||||
|
||||
|
|
@ -108,7 +111,8 @@ export class Iterator {
|
|||
return z;
|
||||
}
|
||||
|
||||
const iter = y.value.__proto__[Symbol.iterator].call(y.value);
|
||||
const mapped = f(z.value);
|
||||
const iter = mapped.__proto__[Symbol.iterator].call(mapped);
|
||||
innerNext = iter.next.bind(iter);
|
||||
}
|
||||
});
|
||||
|
|
@ -194,6 +198,6 @@ export class Iterator {
|
|||
strictlyIncludes(x) {
|
||||
return this.some(function matches(y) { return y === x; });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default Iterator;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import {Iterator} from './iterator.js';
|
||||
import {Buffer} from 'buffer';
|
||||
|
||||
/* Game states */
|
||||
const PLAYING = 'playing';
|
||||
|
|
@ -271,7 +272,7 @@ class Board {
|
|||
|
||||
function testFunction(getPiece, match) {
|
||||
if (match === undefined) {
|
||||
return function(here) { return true; }
|
||||
return function(/*here*/) { return true; };
|
||||
} else if (match === false) {
|
||||
return function(here) { return getPiece(here) === EMPTY; };
|
||||
} else if (match === true) {
|
||||
|
|
@ -286,7 +287,7 @@ class Board {
|
|||
const test = function(here) { return testSide(here) && testOther(here); };
|
||||
|
||||
if (this._phantom && this._phantom.side === side) {
|
||||
const getPhantom = (here) => this._phantom.type;
|
||||
const getPhantom = (/*here*/) => this._phantom.type;
|
||||
const testPhantom = testFunction(getPhantom, type);
|
||||
if (testPhantom(PHANTOM)) {
|
||||
yield this._phantom.from;
|
||||
|
|
@ -315,8 +316,8 @@ const KNIGHT_DIR =
|
|||
[-1, -2], [ 1, -2]];
|
||||
|
||||
const NBSP = '\u00a0'; /* non-breaking space */
|
||||
const SHY = '\u00ad' /* soft hyphen */
|
||||
const ZWSP = '\u200b'; /* zero-width space */
|
||||
const SHY = '\u00ad'; /* soft hyphen */
|
||||
/* const ZWSP = '\u200b'; */ /* zero-width space */
|
||||
|
||||
function addHistory(game) {
|
||||
const prior = game._undo;
|
||||
|
|
@ -572,7 +573,30 @@ class Game {
|
|||
return this._version;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
toJSON(style) {
|
||||
function shrinkMove(move) {
|
||||
if (move.resign) {
|
||||
return { side: move.side, resign: true };
|
||||
} else if (move.phantom) {
|
||||
return { side: move.side, phantom: true, to: move.to };
|
||||
} else {
|
||||
return { side: move.side, from: move.from, to: move.to };
|
||||
}
|
||||
}
|
||||
|
||||
if (style === 'minify') {
|
||||
/* Just the fields that are used by the constructor to replay the game */
|
||||
/* Omits metadata and extra annotation fields */
|
||||
const state = { past: [], future: [], version: this._version };
|
||||
for (const move of this._moves) {
|
||||
state.past.push(shrinkMove(move));
|
||||
}
|
||||
for (const move of this._redo) {
|
||||
state.future.push(shrinkMove(move));
|
||||
}
|
||||
return JSON.stringify(state);
|
||||
}
|
||||
|
||||
return JSON.stringify({
|
||||
past: this._moves,
|
||||
future: this._redo,
|
||||
|
|
@ -748,8 +772,6 @@ class Game {
|
|||
/* if a piece has few moves (king, pawn, knight) then just enumerate them */
|
||||
/* if movement is more extensive (bishop, rook, queen) then we can do better */
|
||||
if (type === BISHOP || type === ROOK || type === QUEEN) {
|
||||
const ortho = (type === ROOK || type === QUEEN);
|
||||
const diag = (type === BISHOP || type === QUEEN);
|
||||
const fromIndex = squareIndex(fromSquare);
|
||||
const toIndex = squareIndex(to);
|
||||
const rowsDiff = (toIndex >>> 3) - (fromIndex >>> 3);
|
||||
|
|
@ -833,7 +855,7 @@ class Game {
|
|||
try {
|
||||
sim.move(from, king);
|
||||
check = diffHistory(this, sim) || true;
|
||||
} catch(err) {}
|
||||
} catch(err) {/*ignore*/}
|
||||
}
|
||||
return recordCheck(this, check);
|
||||
}
|
||||
|
|
@ -889,7 +911,7 @@ class Game {
|
|||
try {
|
||||
game2.move(PHANTOM, king);
|
||||
check = diffHistory(this, game2) || true;
|
||||
} catch(err) {}
|
||||
} catch(err) {/*ignore*/}
|
||||
}
|
||||
return recordCheck(this, check);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const meta = {
|
|||
};
|
||||
|
||||
const stateListeners = {};
|
||||
const stateNextId = 1;
|
||||
let stateNextId = 1;
|
||||
|
||||
/* One-time request, no caching or polling */
|
||||
function getGameState(gameId, retries) {
|
||||
|
|
@ -37,7 +37,7 @@ function getGameState(gameId, retries) {
|
|||
url: `${API_BASE}/game/${gameId}`,
|
||||
cache: false,
|
||||
timeout: SHORT_TIMEOUT,
|
||||
}).done((data, textStatus, jqXHR) => {
|
||||
}).done((data/*, textStatus, jqXHR*/) => {
|
||||
resolve(data);
|
||||
}).fail((jqXHR, textStatus, errorThrown) => {
|
||||
if ((!jqXHR.status || jqXHR.status < 400 || jqXHR.status > 499) && retries > 0) {
|
||||
|
|
@ -63,7 +63,7 @@ function getGameMeta(gameId, retries) {
|
|||
url: `${API_BASE}/meta/${gameId}`,
|
||||
cache: false,
|
||||
timeout: SHORT_TIMEOUT,
|
||||
}).done((data, textStatus, jqXHR) => {
|
||||
}).done((data/*, textStatus, jqXHR*/) => {
|
||||
resolve(data);
|
||||
}).fail((jqXHR, textStatus, errorThrown) => {
|
||||
if ((!jqXHR.status || jqXHR.status < 400 || jqXHR.status > 499) && retries > 0) {
|
||||
|
|
@ -106,7 +106,7 @@ function onGameUpdate(gameId, callback) {
|
|||
stopGamePoll(gameId);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function getCachedGame(gameId) {
|
||||
|
|
@ -150,7 +150,7 @@ function onMetaUpdate(callback) {
|
|||
stopMetaPoll();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function sendUpdate(gameId, data, retries) {
|
||||
|
|
@ -306,7 +306,7 @@ function startGamePoll(gameId, afterTime) {
|
|||
setConnectionState(game, 'polling');
|
||||
startGamePoll(gameId, afterTime);
|
||||
}
|
||||
}).fail((jqXHR, textStatus, errorThrown) => {
|
||||
}).fail((/*jqXHR, textStatus, errorThrown*/) => {
|
||||
if (game.currentRequest === thisRequest) {
|
||||
setConnectionState(game, 'failed');
|
||||
setTimeout(() => {
|
||||
|
|
@ -370,9 +370,9 @@ function startMetaPoll(afterTime) {
|
|||
const thisRequest = meta.currentRequest = $.ajax({
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
url: `${API_BASE}/games${!afterTime ? '' : `/poll/${afterTime}`}`,
|
||||
url: `${API_BASE}/games${(afterTime === undefined) ? '' : `/poll/${afterTime}`}`,
|
||||
cache: false,
|
||||
timeout: afterTime ? LONG_TIMEOUT : SHORT_TIMEOUT,
|
||||
timeout: (afterTime === undefined) ? SHORT_TIMEOUT : LONG_TIMEOUT,
|
||||
}).done((data, textStatus, jqXHR) => {
|
||||
if (meta.currentRequest === thisRequest) {
|
||||
meta.currentRequest = null;
|
||||
|
|
@ -383,7 +383,7 @@ function startMetaPoll(afterTime) {
|
|||
setConnectionState('polling');
|
||||
startMetaPoll(afterTime);
|
||||
}
|
||||
}).fail((jqXHR, textStatus, errorThrown) => {
|
||||
}).fail((/*jqXHR, textStatus, errorThrown*/) => {
|
||||
if (meta.currentRequest === thisRequest) {
|
||||
setConnectionState('failed');
|
||||
setTimeout(() => {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import deepEqual from 'deep-equal';
|
|||
import 'webpack-jquery-ui/draggable';
|
||||
import 'webpack-jquery-ui/droppable';
|
||||
import 'webpack-jquery-ui/selectmenu';
|
||||
import 'webpack-jquery-ui/fold-effect';
|
||||
import 'webpack-jquery-ui/clip-effect';
|
||||
import 'webpack-jquery-ui/css';
|
||||
|
||||
import 'jquery-ui-touch-punch';
|
||||
|
|
@ -20,8 +20,15 @@ import 'jbox/dist/jBox.all.css';
|
|||
|
||||
import {Workbox, messageSW} from 'workbox-window';
|
||||
|
||||
import {ResizeSensor, ElementQueries} from 'css-element-queries';
|
||||
ElementQueries.listen();
|
||||
|
||||
import {Buffer} from 'buffer';
|
||||
import pako from 'pako';
|
||||
import {sprintf} from 'sprintf-js';
|
||||
|
||||
/* "Waterdrop" by Porphyr (freesound.org/people/Porphyr) / CC BY 3.0 (creativecommons.org/licenses/by/3.0) */
|
||||
import Waterdrop from '../wav/191678__porphyr__waterdrop.wav';
|
||||
import Waterdrop from '../mp3/191678__porphyr__waterdrop.mp3';
|
||||
|
||||
$(function (){
|
||||
function debug() {
|
||||
|
|
@ -94,7 +101,7 @@ $(function (){
|
|||
square.hide().appendTo('body').droppable({
|
||||
accept: '.cb-piece',
|
||||
disabled: true,
|
||||
deactivate: function(ev, ui){
|
||||
deactivate: function(/*ev, ui*/) {
|
||||
$(this).droppable('disable');
|
||||
},
|
||||
drop: squareDropDestination,
|
||||
|
|
@ -102,7 +109,7 @@ $(function (){
|
|||
}
|
||||
return square;
|
||||
} else if (where.match(/^[a-h][1-8]$/)) {
|
||||
return $('#cb_' + where).first()
|
||||
return $('#cb_' + where).first();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -136,7 +143,6 @@ $(function (){
|
|||
|
||||
function pieceStartMove(piece, event) {
|
||||
const side = piece.data('side');
|
||||
const type = piece.data('type');
|
||||
const from = piece.data('location');
|
||||
const legals = currentGame.legalMoves(side, from);
|
||||
for (const there of legals) {
|
||||
|
|
@ -145,7 +151,7 @@ $(function (){
|
|||
}
|
||||
|
||||
const square = cbSquare(there);
|
||||
square.addClass('cb-legal')
|
||||
square.addClass('cb-legal');
|
||||
if (event === 'drag') {
|
||||
square.droppable('enable');
|
||||
} else if (event === 'click') {
|
||||
|
|
@ -174,7 +180,7 @@ $(function (){
|
|||
putState();
|
||||
}
|
||||
|
||||
function squareClickDestination(ev, ui) {
|
||||
function squareClickDestination(/*ev, ui*/) {
|
||||
let selected = $('#cb_board .cb-selected');
|
||||
if (selected.length !== 1) {
|
||||
renderBoard();
|
||||
|
|
@ -193,11 +199,11 @@ $(function (){
|
|||
}
|
||||
}
|
||||
|
||||
function squareClickUnselect(ev, ui) {
|
||||
function squareClickUnselect(/*ev, ui*/) {
|
||||
renderBoard();
|
||||
}
|
||||
|
||||
function squareClickSelect(ev, ui) {
|
||||
function squareClickSelect(/*ev, ui*/) {
|
||||
renderBoard();
|
||||
const clicked = $(this).children('.cb-piece.ui-draggable').not('.ui-draggable-disabled');
|
||||
clicked.addClass('cb-selected');
|
||||
|
|
@ -211,7 +217,7 @@ $(function (){
|
|||
}
|
||||
}
|
||||
|
||||
function pieceStartDrag(ev, ui) {
|
||||
function pieceStartDrag(/*ev, ui*/) {
|
||||
const dragged = $(this);
|
||||
$('#cb_board .cb-selected').removeClass('cb-selected');
|
||||
$('#cb_board .cb-legal').removeClass('cb-legal');
|
||||
|
|
@ -220,7 +226,7 @@ $(function (){
|
|||
pieceStartMove(dragged, 'drag');
|
||||
}
|
||||
|
||||
function pieceStopDrag(ev, ui) {
|
||||
function pieceStopDrag(/*ev, ui*/) {
|
||||
const dragged = $(this);
|
||||
dragged.attr('style', dragged.data('saved-style'));
|
||||
dragged.removeData('saved-style');
|
||||
|
|
@ -249,6 +255,81 @@ $(function (){
|
|||
return piece;
|
||||
}
|
||||
|
||||
function updatePlayerTimes() {
|
||||
let lightTime = 0;
|
||||
let darkTime = 0;
|
||||
|
||||
let moveStartTime = undefined;
|
||||
|
||||
for (const move of visibleGame.moves) {
|
||||
if (!move.meta || !Number.isInteger(move.meta.timestamp)) {
|
||||
lightTime = darkTime = undefined;
|
||||
break;
|
||||
}
|
||||
|
||||
if (move.replaced) {
|
||||
/* not the final move in the chain */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* start counting when the dark player finishes their first move */
|
||||
if (moveStartTime === undefined) {
|
||||
if (move.side === PS.DARK) {
|
||||
moveStartTime = move.meta.timestamp;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const moveTime = move.meta.timestamp - moveStartTime;
|
||||
|
||||
if (moveTime > 0) {
|
||||
if (move.side === PS.LIGHT) {
|
||||
lightTime += moveTime;
|
||||
} else {
|
||||
darkTime += moveTime;
|
||||
}
|
||||
}
|
||||
|
||||
moveStartTime = move.meta.timestamp;
|
||||
}
|
||||
|
||||
if (moveStartTime === undefined) {
|
||||
$('#cb_light_time, #cb_dark_time').text('0:00:00');
|
||||
$('#cb_times').addClass('cb-hide-times');
|
||||
return;
|
||||
}
|
||||
|
||||
if (visibleGame.status === PS.PLAYING) {
|
||||
if (!visibleGame.canRedo) {
|
||||
const currentMoveTime = +new Date() - moveStartTime;
|
||||
if (currentMoveTime > 0) {
|
||||
if (visibleGame.player === PS.LIGHT) {
|
||||
lightTime += currentMoveTime;
|
||||
} else {
|
||||
darkTime += currentMoveTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$('#cb_times').removeClass('cb-hide-times');
|
||||
|
||||
function formatTime(milliseconds) {
|
||||
let seconds = milliseconds / 1000;
|
||||
const hours = seconds / 3600;
|
||||
seconds %= 3600;
|
||||
const minutes = seconds / 60;
|
||||
seconds %= 60;
|
||||
return sprintf('%d:%02d:%02d', hours, minutes, seconds);
|
||||
}
|
||||
|
||||
$('#cb_light_time').text(formatTime(lightTime));
|
||||
$('#cb_dark_time').text(formatTime(darkTime));
|
||||
}
|
||||
|
||||
setInterval(() => { updatePlayerTimes(); }, 250);
|
||||
|
||||
function renderBoard(animate) {
|
||||
$('#cb_board').removeData('dragging_from');
|
||||
$('#cb_board .cb-piece').remove();
|
||||
|
|
@ -259,6 +340,8 @@ $(function (){
|
|||
$('#cb_board .cb-end').removeClass('cb-end');
|
||||
$('#cb_board .cb-legal').removeClass('cb-legal');
|
||||
$('#cb_explain_check').text('');
|
||||
$('#cb_names').removeClass('cb-light-turn').removeClass('cb-dark-turn');
|
||||
$('#cb_names').removeClass('cb-light-won').removeClass('cb-dark-won');
|
||||
$('#cb_phantom').remove();
|
||||
|
||||
const game = visibleGame;
|
||||
|
|
@ -337,7 +420,7 @@ $(function (){
|
|||
pieceStartMove(piece, 'click');
|
||||
}
|
||||
} else if (liveView && playing) {
|
||||
const pieces = $('#cb_board .' + clss)
|
||||
const pieces = $('#cb_board .' + clss);
|
||||
pieces.parent().on('click.select', squareClickSelect);
|
||||
pieces.draggable('enable');
|
||||
}
|
||||
|
|
@ -384,6 +467,20 @@ $(function (){
|
|||
} else {
|
||||
$('#cb_board').removeClass('cb-live').addClass('cb-archive');
|
||||
}
|
||||
|
||||
if (game.status === PS.PLAYING) {
|
||||
if (game.player === PS.LIGHT) {
|
||||
$('#cb_names').addClass('cb-light-turn');
|
||||
} else {
|
||||
$('#cb_names').addClass('cb-dark-turn');
|
||||
}
|
||||
} else if (game.winner === PS.LIGHT) {
|
||||
$('#cb_names').addClass('cb-light-won');
|
||||
} else if (game.winner === PS.DARK) {
|
||||
$('#cb_names').addClass('cb-dark-won');
|
||||
}
|
||||
|
||||
updatePlayerTimes();
|
||||
}
|
||||
|
||||
function applyTheme(theme) {
|
||||
|
|
@ -406,6 +503,14 @@ $(function (){
|
|||
function setCurrentGame(game, animate) {
|
||||
currentGame = game;
|
||||
setVisibleGame(game, animate);
|
||||
const state = game.toJSON('minify');
|
||||
const deflated = pako.deflate(Buffer.from(state));
|
||||
const encoded = Buffer.from(deflated).toString('base64');
|
||||
if ($('#page').hasClass('cb-private')) {
|
||||
history.replaceState(null, document.title, `#/private/${encoded}`);
|
||||
} else {
|
||||
$('.private-link').attr('href', `#/private/${encoded}`);
|
||||
}
|
||||
}
|
||||
|
||||
function randomId(){
|
||||
|
|
@ -460,9 +565,10 @@ $(function (){
|
|||
head: 0, /* next item to be sent */
|
||||
tail: 0, /* ID to assign to the next update added to the queue */
|
||||
sending: false,
|
||||
idle: Promise.resolve(true), /* resolves to true if updates succeeded */
|
||||
signal_idle: function() {},
|
||||
|
||||
add(gameId, data, modified) {
|
||||
const wasEmpty = this.isEmpty();
|
||||
data = Object.assign({}, data, { modified });
|
||||
|
||||
this[this.tail] = { gameId, data };
|
||||
|
|
@ -471,6 +577,9 @@ $(function (){
|
|||
if (!this.sending) {
|
||||
openNoticeBox('Saving...');
|
||||
this.sending = true;
|
||||
this.idle = new Promise((resolve) => {
|
||||
this.signal_idle = resolve;
|
||||
});
|
||||
this.sendNext();
|
||||
}
|
||||
},
|
||||
|
|
@ -540,6 +649,7 @@ $(function (){
|
|||
|
||||
if (queue.isEmpty()) {
|
||||
queue.sending = false;
|
||||
queue.signal_idle(true);
|
||||
/* close the Saving... notice*/
|
||||
noticeBox.close({ ignoreDelay: true });
|
||||
} else {
|
||||
|
|
@ -556,6 +666,7 @@ $(function (){
|
|||
}
|
||||
|
||||
queue.sending = false;
|
||||
queue.signal_idle(false);
|
||||
|
||||
/* force a reset back to the latest server data */
|
||||
if (update.gameId === $('#cb_board').data('gameId')) {
|
||||
|
|
@ -567,7 +678,6 @@ $(function (){
|
|||
|
||||
function putState() {
|
||||
const boardElem = $('#cb_board');
|
||||
const gameId = boardElem.data('gameId');
|
||||
notifyLocalMove(currentGame, boardElem.data('gameId'));
|
||||
putMeta({ board: JSON.parse(currentGame.toJSON()) });
|
||||
}
|
||||
|
|
@ -576,7 +686,12 @@ $(function (){
|
|||
function player(side) {
|
||||
return (side === PS.LIGHT ? 'light' : 'dark');
|
||||
}
|
||||
|
||||
const gameId = $('#cb_board').data('gameId');
|
||||
if (gameId === 'private') {
|
||||
return;
|
||||
}
|
||||
|
||||
const lightName = $('#cb_light_name').val();
|
||||
const darkName = $('#cb_dark_name').val();
|
||||
const turns = currentGame.turns;
|
||||
|
|
@ -604,6 +719,16 @@ $(function (){
|
|||
updateQueue.add(gameId, meta, $('#cb_board').data('modified'));
|
||||
}
|
||||
|
||||
function setNotifyChecked(doNotify) {
|
||||
const cbNotify = $('#cb_notify');
|
||||
cbNotify.prop('checked', doNotify);
|
||||
if (doNotify) {
|
||||
cbNotify.removeClass('fa-bell-slash').addClass('fa-bell');
|
||||
} else {
|
||||
cbNotify.removeClass('fa-bell').addClass('fa-bell-slash');
|
||||
}
|
||||
}
|
||||
|
||||
function switchGameId(newId, force) {
|
||||
const boardElem = $('#cb_board');
|
||||
const gameId = boardElem.data('gameId');
|
||||
|
|
@ -629,36 +754,49 @@ $(function (){
|
|||
$('#cb_light_name').val('');
|
||||
$('#cb_dark_name').val('');
|
||||
|
||||
cancelGameCallback = IO.onGameUpdate(newId, function(data, gameId) {
|
||||
if (data.modified > $('#cb_board').data('modified')) {
|
||||
try {
|
||||
const newGame = new PS.Game(JSON.stringify(data.board));
|
||||
const newState = JSON.parse(newGame.toJSON());
|
||||
const oldState = JSON.parse(currentGame.toJSON());
|
||||
if (newId === 'private') {
|
||||
cancelGameCallback = function() {};
|
||||
} else {
|
||||
cancelGameCallback = IO.onGameUpdate(newId, function(data/*, gameId*/) {
|
||||
updateQueue.idle.then(() => {
|
||||
if (data.modified > $('#cb_board').data('modified')) {
|
||||
try {
|
||||
const newGame = new PS.Game(JSON.stringify(data.board));
|
||||
const newState = JSON.parse(newGame.toJSON());
|
||||
const oldState = JSON.parse(currentGame.toJSON());
|
||||
|
||||
if (!deepEqual(newState, oldState)) {
|
||||
debug('got board', newGame.moves);
|
||||
setCurrentGame(newGame, newGame.moves.length > currentGame.moves.length);
|
||||
if (!deepEqual(newState, oldState)) {
|
||||
debug('got board', newGame.moves);
|
||||
setCurrentGame(newGame, newGame.moves.length > currentGame.moves.length);
|
||||
}
|
||||
} catch (err) {
|
||||
debug('Error parsing board data', err);
|
||||
}
|
||||
|
||||
const d = data || {};
|
||||
$('#cb_board').data('lightName', shortenName(String(d.lightName || 'Light')));
|
||||
$('#cb_board').data('darkName', shortenName(String(d.darkName || 'Dark')));
|
||||
$('#cb_light_name').val(String(d.lightName || ''));
|
||||
$('#cb_dark_name').val(String(d.darkName || ''));
|
||||
|
||||
$('#cb_board').data('modified', data.modified);
|
||||
|
||||
updateSelectGameMeta(data, newId);
|
||||
}
|
||||
} catch (err) {
|
||||
debug('Error parsing board data', err);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const d = data || {};
|
||||
$('#cb_board').data('lightName', shortenName(String(d.lightName || 'Light')));
|
||||
$('#cb_board').data('darkName', shortenName(String(d.darkName || 'Dark')));
|
||||
$('#cb_light_name').val(String(d.lightName || ''));
|
||||
$('#cb_dark_name').val(String(d.darkName || ''));
|
||||
|
||||
$('#cb_board').data('modified', data.modified);
|
||||
const notifyList = $('#cb_notify').data('gameList');
|
||||
const doNotify = notifyList.includes('*') || notifyList.includes(newId);
|
||||
setNotifyChecked(doNotify);
|
||||
if (doNotify) {
|
||||
requestNotify();
|
||||
}
|
||||
});
|
||||
|
||||
const notifyList = $('#cb_notify').data('gameList');
|
||||
const doNotify = notifyList.includes('*') || notifyList.includes(newId);
|
||||
$('#cb_notify').prop('checked', doNotify);
|
||||
if (doNotify) {
|
||||
requestNotify();
|
||||
/* Ensure that the selected game is in the list (for new games). */
|
||||
if ($('#game_tile_' + newId).length < 1) {
|
||||
updateSelectGameMeta({}, newId);
|
||||
}
|
||||
}
|
||||
|
||||
const reverseList = $('#cb_reverse').data('gameList');
|
||||
|
|
@ -666,14 +804,6 @@ $(function (){
|
|||
$('#cb_reverse').prop('checked', doReverse);
|
||||
arrangeBoard(doReverse);
|
||||
|
||||
$('#jitsi_link').attr('href', 'https://meet.jit.si/PacoSaco_' + newId);
|
||||
$('#game_link').attr('href', location.href);
|
||||
|
||||
/* Ensure that the selected game is in the list (for new games). */
|
||||
if ($('#game_tile_' + newId).length < 1) {
|
||||
updateSelectGameMeta({}, newId);
|
||||
}
|
||||
|
||||
/* This is in case the old tile no longer qualifies to be in the list. */
|
||||
const oldGameTile = $('#game_tile_' + gameId);
|
||||
if (oldGameTile.length >= 1) {
|
||||
|
|
@ -685,7 +815,7 @@ $(function (){
|
|||
}
|
||||
|
||||
function disableNotify(){
|
||||
$('#cb_notify')[0].checked = false;
|
||||
setNotifyChecked(false);
|
||||
$('#cb_notify').attr('disabled', true);
|
||||
}
|
||||
|
||||
|
|
@ -704,7 +834,7 @@ $(function (){
|
|||
const notifyAudio = new Audio(Waterdrop);
|
||||
|
||||
function playNotifySound(){
|
||||
try { notifyAudio.play(); } catch (err) {}
|
||||
try { notifyAudio.play(); } catch (err) {/*ignore*/}
|
||||
}
|
||||
|
||||
function notify(body) {
|
||||
|
|
@ -737,7 +867,7 @@ $(function (){
|
|||
notification.close();
|
||||
}
|
||||
}
|
||||
} catch (err) {}
|
||||
} catch (err) {/*ignore*/}
|
||||
}
|
||||
|
||||
function arrangeBoard(reversed) {
|
||||
|
|
@ -767,33 +897,43 @@ $(function (){
|
|||
|
||||
Promise.resolve().then(async () => {
|
||||
const wb = new Workbox('sw.js');
|
||||
let latest_sw = null;
|
||||
|
||||
function showSkipWaitingPrompt(event) {
|
||||
if (confirmBox) {
|
||||
confirmBox.close({ ignoreDelay: true });
|
||||
latest_sw = event.sw;
|
||||
|
||||
if (!confirmBox) {
|
||||
confirmBox = new jBox('Confirm', {
|
||||
attach: null,
|
||||
content: "A new version is available. Update the page?",
|
||||
confirmButton: `<span class="update-confirm-button">Update</span>`,
|
||||
cancelButton: 'Not now',
|
||||
closeOnConfirm: false,
|
||||
async confirm() {
|
||||
/* The SW should signal us to reload, but do it after 20s regardless. */
|
||||
setTimeout(() => { window.location.reload(); }, 20000);
|
||||
messageSW(latest_sw, {type: 'SKIP_WAITING'});
|
||||
$('.update-confirm-button').text('Updating…');
|
||||
},
|
||||
onClose() {
|
||||
if (confirmBox === this) {
|
||||
confirmBox = null;
|
||||
}
|
||||
},
|
||||
onCloseComplete() {
|
||||
this.destroy();
|
||||
},
|
||||
});
|
||||
|
||||
confirmBox.open();
|
||||
}
|
||||
|
||||
confirmBox = new jBox('Confirm', {
|
||||
attach: null,
|
||||
content: "A new version is available. Update the page?",
|
||||
confirmButton: `<span class="update-confirm-button">Update</span>`,
|
||||
cancelButton: 'Not now',
|
||||
closeOnConfirm: false,
|
||||
confirm() {
|
||||
/* The SW should signal us to reload, but do it after 20s regardless. */
|
||||
setTimeout(() => { window.location.reload(); }, 20000);
|
||||
messageSW(event.sw, {type: 'SKIP_WAITING'});
|
||||
$('.update-confirm-button').text('Updating…');
|
||||
},
|
||||
onCloseComplete() {
|
||||
this.destroy();
|
||||
},
|
||||
});
|
||||
|
||||
confirmBox.open();
|
||||
}
|
||||
|
||||
wb.addEventListener('installed', (event) => {
|
||||
function reloadForUpdate(/*event*/) {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
wb.addEventListener('installed', (/*event*/) => {
|
||||
try {
|
||||
if (Notification.permission === 'denied') {
|
||||
disableNotify();
|
||||
|
|
@ -803,23 +943,19 @@ $(function (){
|
|||
}
|
||||
});
|
||||
|
||||
wb.addEventListener('controlling', (event) => {
|
||||
if (event.isUpdate) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
|
||||
wb.addEventListener('waiting', showSkipWaitingPrompt);
|
||||
wb.addEventListener('externalwaiting', showSkipWaitingPrompt);
|
||||
|
||||
const registration = await wb.register();
|
||||
wb.addEventListener('controlling', reloadForUpdate);
|
||||
wb.addEventListener('externalactivated', reloadForUpdate);
|
||||
|
||||
if ('update' in registration) {
|
||||
/* Check for updates every 4h without reloading the page. */
|
||||
setInterval(() => { registration.update(); }, 4*3600*1000);
|
||||
} else {
|
||||
console.log('service worker update method not supported, disabling update checks');
|
||||
}
|
||||
const registration = await wb.register();
|
||||
await registration.ready;
|
||||
|
||||
/* Check for updates every 4h without reloading the page. */
|
||||
setInterval(() => { wb.update(); }, 4*3600*1000);
|
||||
|
||||
window.Admin.workbox = wb;
|
||||
}).catch((err) => {
|
||||
console.error('failed to register the service worker', err);
|
||||
disableNotify();
|
||||
|
|
@ -837,8 +973,8 @@ $(function (){
|
|||
let gameList = undefined;
|
||||
const gameId = $('#cb_board').data('gameId');
|
||||
if (value === 'on') {
|
||||
gameList = ['*']
|
||||
} else if (value === 'off') {
|
||||
gameList = ['*'];
|
||||
} else if (value === null || value === 'off') {
|
||||
gameList = [];
|
||||
} else {
|
||||
try {
|
||||
|
|
@ -869,6 +1005,7 @@ $(function (){
|
|||
debug('from localStorage', { key, value });
|
||||
if (key === LS_KEY_NOTIFY) {
|
||||
updatePerGameFlag(key, value, '#cb_notify', (enabled) => {
|
||||
setNotifyChecked(enabled);
|
||||
if (enabled) {
|
||||
requestNotify();
|
||||
}
|
||||
|
|
@ -882,17 +1019,20 @@ $(function (){
|
|||
arrangeBoard(enabled);
|
||||
});
|
||||
} else if (key === LS_KEY_THEME) {
|
||||
if (value === null) {
|
||||
value = 'pacosako';
|
||||
}
|
||||
const cb_theme = $('#cb_select_theme');
|
||||
if (value !== cb_theme.val()) {
|
||||
cb_theme.val(value);
|
||||
if (!cb_theme.val()) {
|
||||
value = 'traditional';
|
||||
value = 'pacosako';
|
||||
cb_theme.val(value);
|
||||
}
|
||||
applyTheme(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$(window).on('storage', function(event){
|
||||
fromStorage(event.originalEvent.key, event.originalEvent.newValue);
|
||||
|
|
@ -900,16 +1040,14 @@ $(function (){
|
|||
|
||||
for (const key of [LS_KEY_NOTIFY, LS_KEY_SOUND, LS_KEY_REVERSE, LS_KEY_THEME]) {
|
||||
const value = window.localStorage.getItem(key);
|
||||
if (value !== null) {
|
||||
fromStorage(key, value);
|
||||
}
|
||||
fromStorage(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
$('.cb-square').droppable({
|
||||
accept: '.cb-piece',
|
||||
disabled: true,
|
||||
deactivate: function(ev, ui){
|
||||
deactivate: function(/*ev, ui*/){
|
||||
$(this).droppable('disable');
|
||||
},
|
||||
drop: squareDropDestination,
|
||||
|
|
@ -940,6 +1078,7 @@ $(function (){
|
|||
|
||||
$('#cb_notify').on('change', function(){
|
||||
perGameFlagChanged(LS_KEY_NOTIFY, this);
|
||||
setNotifyChecked(this.checked);
|
||||
if (this.checked) {
|
||||
requestNotify();
|
||||
}
|
||||
|
|
@ -1056,6 +1195,36 @@ $(function (){
|
|||
}
|
||||
});
|
||||
|
||||
let helpBox = null;
|
||||
$('#help').on('click', function() {
|
||||
helpBox = helpBox || new jBox('Modal', {
|
||||
title: '<h2>Rule Reference</h2>',
|
||||
content: $('#rules_content'),
|
||||
blockScroll: false,
|
||||
blockScrollAdjust: false,
|
||||
isolateScroll: false,
|
||||
footer: `<div id="help_badges"></div>`,
|
||||
closeButton: 'title',
|
||||
onCreated() {
|
||||
$('.badges').appendTo('#help_badges');
|
||||
},
|
||||
});
|
||||
helpBox.open();
|
||||
});
|
||||
|
||||
let settingBox = null;
|
||||
$('#settings').on('click', function() {
|
||||
settingBox = settingBox || new jBox('Modal', {
|
||||
title: '<h2>Settings</h2>',
|
||||
content: $('#settings_content'),
|
||||
blockScroll: false,
|
||||
blockScrollAdjust: false,
|
||||
isolateScroll: false,
|
||||
closeButton: 'title',
|
||||
});
|
||||
settingBox.open();
|
||||
});
|
||||
|
||||
$('#cb_light_name, #cb_dark_name').on('input', function() { putMeta(); });
|
||||
|
||||
let gameSelectContent = $(`<div style="display: none"></div>`).appendTo('body');
|
||||
|
|
@ -1069,6 +1238,7 @@ $(function (){
|
|||
|
||||
var selectBoxIntervalID = undefined;
|
||||
var selectBox = new jBox('Modal', {
|
||||
title: '<h2>Recent Games</h2>',
|
||||
content: gameSelectContent,
|
||||
blockScroll: false,
|
||||
blockScrollAdjust: false,
|
||||
|
|
@ -1138,11 +1308,6 @@ $(function (){
|
|||
}
|
||||
|
||||
function updateSelectGameMeta(data, gameId) {
|
||||
data = Object.assign({}, data, {
|
||||
gameId: gameId || data.gameId,
|
||||
timestamp: data.timestamp || +new Date(),
|
||||
});
|
||||
|
||||
if (typeof gameId !== 'string' || !gameId.match(/^[0-9a-f]{16}$/)) {
|
||||
debug('invalid game ID', gameId);
|
||||
return;
|
||||
|
|
@ -1152,10 +1317,11 @@ $(function (){
|
|||
const oldTile = $('#game_tile_' + gameId).first();
|
||||
|
||||
if (!data.lightName && !data.darkName && !data.moves && gameId !== currentGameId) {
|
||||
oldTile.removeAttr('id');
|
||||
if (oldTile.length >= 1) {
|
||||
oldTile.removeAttr('id');
|
||||
oldTile.hide({
|
||||
effect: "fold",
|
||||
effect: "clip",
|
||||
direction: "horizontal",
|
||||
complete() {
|
||||
oldTile.remove();
|
||||
},
|
||||
|
|
@ -1164,6 +1330,13 @@ $(function (){
|
|||
return;
|
||||
}
|
||||
|
||||
if (oldTile.length && data.modified && oldTile.data('gameMeta').modified >= data.modified) {
|
||||
return;
|
||||
}
|
||||
|
||||
data = Object.assign({ gameId, timestamp: +new Date(), modified: 0 }, data);
|
||||
delete data.board;
|
||||
|
||||
const tile = oldTile.length ? oldTile :
|
||||
$(`<div class="game-tile existing-game-tile"></div>`).hide();
|
||||
tile.attr('id', 'game_tile_' + gameId).data('gameMeta', data).empty();
|
||||
|
|
@ -1213,13 +1386,14 @@ $(function (){
|
|||
$(list).appendTo(gameTiles);
|
||||
updateTileAges();
|
||||
|
||||
tile.show("fold");
|
||||
tile.show({
|
||||
effect: "clip",
|
||||
direction: "horizontal",
|
||||
});
|
||||
|
||||
selectBox.setContent(gameSelectContent);
|
||||
}
|
||||
|
||||
IO.onMetaUpdate(updateSelectGameMeta);
|
||||
|
||||
const lastNotifyState = {};
|
||||
|
||||
function notifyForGame(meta, gameId) {
|
||||
|
|
@ -1288,22 +1462,92 @@ $(function (){
|
|||
}
|
||||
}
|
||||
|
||||
IO.onMetaUpdate(notifyForGame);
|
||||
|
||||
window.onpopstate = function(event){
|
||||
window.onhashchange = function(/*event*/){
|
||||
const foundId = location.hash.match(/^#\/([0-9a-f]{16}\b)/);
|
||||
if (foundId) {
|
||||
switchGameId(foundId[1]);
|
||||
}
|
||||
};
|
||||
|
||||
const foundId = location.hash.match(/^#\/([0-9a-f]{16}\b)/);
|
||||
if (foundId) {
|
||||
switchGameId(foundId[1]);
|
||||
const foundPrivate = location.hash.match(/^#\/private((\/(.*)?)?)$/);
|
||||
if (foundPrivate) {
|
||||
switchGameId('private');
|
||||
$('#page').addClass('cb-private');
|
||||
let state;
|
||||
try {
|
||||
const decoded = Buffer.from(foundPrivate[1].slice(1), 'base64');
|
||||
const inflated = pako.inflate(decoded);
|
||||
state = JSON.parse(Buffer.from(inflated).toString());
|
||||
} catch(err) {/*ignore*/}
|
||||
if (state) {
|
||||
setCurrentGame(new PS.Game(JSON.stringify(state)));
|
||||
}
|
||||
} else {
|
||||
switchGameId(randomId());
|
||||
const foundId = location.hash.match(/^#\/([0-9a-f]{16}\b)/);
|
||||
if (foundId) {
|
||||
switchGameId(foundId[1]);
|
||||
} else {
|
||||
switchGameId(randomId());
|
||||
}
|
||||
|
||||
IO.onMetaUpdate(async (meta, gameId) => {
|
||||
await updateQueue.idle;
|
||||
updateSelectGameMeta(meta, gameId);
|
||||
notifyForGame(meta, gameId);
|
||||
});
|
||||
}
|
||||
|
||||
function adjustBoardSize() {
|
||||
let container = $('#cb_container');
|
||||
let outerWidth = container.width();
|
||||
let outerHeight = container.height();
|
||||
let size = ((outerWidth < outerHeight) ? outerWidth : outerHeight) - 24;
|
||||
$('#cb_board').css({
|
||||
width: size + 'px',
|
||||
height: size + 'px',
|
||||
top: ((outerHeight - size) / 2) + 'px',
|
||||
left: ((outerWidth - size) / 2) + 'px',
|
||||
visibility: '',
|
||||
});
|
||||
}
|
||||
|
||||
new ResizeSensor($('#cb_container'), adjustBoardSize);
|
||||
adjustBoardSize();
|
||||
|
||||
(function() {
|
||||
const body = $('body').first();
|
||||
let horizontal = false;
|
||||
|
||||
function updateLayout() {
|
||||
const oldHorizontal = horizontal;
|
||||
horizontal = body.width() >= (1.5 * body.height());
|
||||
if (horizontal !== oldHorizontal) {
|
||||
if (horizontal) {
|
||||
$('#cb_container').prependTo('#page');
|
||||
$('#header').appendTo('#board_ui');
|
||||
$('#cb_status').appendTo('#board_ui');
|
||||
$('#cb_names').appendTo('#board_ui');
|
||||
$('#cb_times').appendTo('#board_ui');
|
||||
$('#cb_navigate').appendTo('#board_ui');
|
||||
$('#board_ui').appendTo('#page');
|
||||
$('#page').removeClass('vertical-layout').addClass('horizontal-layout');
|
||||
} else {
|
||||
$('#header').appendTo('#board_ui');
|
||||
$('#cb_container').appendTo('#board_ui');
|
||||
$('#cb_status').appendTo('#board_ui');
|
||||
$('#cb_names').appendTo('#board_ui');
|
||||
$('#cb_times').appendTo('#board_ui');
|
||||
$('#cb_navigate').appendTo('#board_ui');
|
||||
$('#board_ui').appendTo('#page');
|
||||
$('#page').removeClass('horizontal-layout').addClass('vertical-layout');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new ResizeSensor(body, updateLayout);
|
||||
updateLayout();
|
||||
})();
|
||||
|
||||
/* Low-level commands to be run from the JS console */
|
||||
window.Admin = {
|
||||
getGameId() { return $('#cb_board').data('gameId'); },
|
||||
|
|
@ -1320,25 +1564,6 @@ $(function (){
|
|||
$,
|
||||
};
|
||||
|
||||
/*
|
||||
* Safari uses the container's *height* instead of its *width* as
|
||||
* required by W3C standards for relative margin/padding values.
|
||||
* This breaks the CSS that should be ensuring a 1:1 aspect ratio.
|
||||
*/
|
||||
function fixSafariPadding() {
|
||||
let squares = $('#cb_board .cb-square');
|
||||
for (let square of squares) {
|
||||
square = $(square);
|
||||
const width = square.width();
|
||||
square.css('height', width + 'px');
|
||||
}
|
||||
}
|
||||
|
||||
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
|
||||
$(window).on('resize', fixSafariPadding);
|
||||
fixSafariPadding();
|
||||
}
|
||||
|
||||
(function() {
|
||||
const match = location.href.match('^https://jessemcdonald.info/~nybble/paco_sako/(.*)');
|
||||
if (match) {
|
||||
|
|
|
|||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
39
package.json
39
package.json
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "paco-sako",
|
||||
"version": "0.6.1",
|
||||
"version": "0.8.7",
|
||||
"description": "Online version of the Paco Ŝako chess variation",
|
||||
"keywords": [
|
||||
"game",
|
||||
|
|
@ -31,28 +31,35 @@
|
|||
"url": "https://jessemcdonald.info/gogs/nybble/paco_sako.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"copy-webpack-plugin": "^5.1.1",
|
||||
"@fortawesome/fontawesome-free": "^5.13.0",
|
||||
"buffer": "^6.0.3",
|
||||
"clean-webpack-plugin": "^4.0.0",
|
||||
"copy-webpack-plugin": "^6.4.1",
|
||||
"css-element-queries": "^1.2.3",
|
||||
"deep-equal": "git+https://jessemcdonald.info/gogs/nybble/node-deep-equal",
|
||||
"extract-loader": "^5.0.1",
|
||||
"html-webpack-plugin": "^4.3.0",
|
||||
"html-webpack-plugin": "^4.5.2",
|
||||
"jbox": "^1.2.0",
|
||||
"jquery-ui-touch-punch": "^0.2.3",
|
||||
"lodash": "^4.17.15",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
||||
"svgo": "^1.3.2",
|
||||
"svgo-loader": "^2.2.1",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"mini-css-extract-plugin": "^1.6.2",
|
||||
"optimize-css-assets-webpack-plugin": "^6.0.1",
|
||||
"pako": "^2.0.4",
|
||||
"sprintf-js": "^1.0.3",
|
||||
"svgo": "^2.7.0",
|
||||
"svgo-loader": "^3.0.0",
|
||||
"webpack": "^4.46.0",
|
||||
"webpack-cli": "^4.8.0",
|
||||
"webpack-jquery-ui": "^2.0.1",
|
||||
"workbox-precaching": "^5.1.3",
|
||||
"workbox-routing": "^5.1.3",
|
||||
"workbox-strategies": "^5.1.3",
|
||||
"workbox-webpack-plugin": "^5.1.3",
|
||||
"workbox-window": "^5.1.3"
|
||||
"workbox-precaching": "^6.3.0",
|
||||
"workbox-routing": "^6.3.0",
|
||||
"workbox-strategies": "^6.3.0",
|
||||
"workbox-webpack-plugin": "^6.3.0",
|
||||
"workbox-window": "^6.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"paco-sako-server": "git+https://jessemcdonald.info/gogs/nybble/paco_sako_server"
|
||||
},
|
||||
"dependencies": {},
|
||||
"optionalDependencies": {
|
||||
"paco-sako-server": "git+https://jessemcdonald.info/gogs/nybble/paco_sako_server"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="external-link-alt" class="svg-inline--fa fa-external-link-alt fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"></path></svg>
|
||||
|
Before Width: | Height: | Size: 597 B |
|
|
@ -1,160 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="160"
|
||||
height="160"
|
||||
viewBox="0 0 150 150.00001"
|
||||
id="svg3526"
|
||||
version="1.1"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||
inkscape:export-filename="/Users/ystamcheva/Dropbox/Designs/appLogo.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"
|
||||
sodipodi:docname="jitsi-logo-blue.svg">
|
||||
<defs
|
||||
id="defs3528">
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Blur"
|
||||
id="filter921">
|
||||
<feGaussianBlur
|
||||
stdDeviation="4 4"
|
||||
result="blur"
|
||||
id="feGaussianBlur919" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="89.185304"
|
||||
inkscape:cy="80.953412"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="999"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:snap-page="true"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:pagecheckerboard="true" />
|
||||
<metadata
|
||||
id="metadata3531">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-902.36211)"
|
||||
style="opacity:1">
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.91489375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;filter:url(#filter921)"
|
||||
d="M 142.5,977.36212 A 67.499998,67.499998 0 0 1 74.999998,1044.8621 67.499998,67.499998 0 0 1 7.5,977.36212 a 67.499998,67.499998 0 0 1 67.499998,-67.5 67.499998,67.499998 0 0 1 67.500002,67.5 z"
|
||||
id="path1006-7"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="matrix(0.97916666,0,0,0.97916666,1.562503,20.361715)" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.87500012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
|
||||
d="M 141.09375,977.36212 A 66.09375,66.09375 0 0 1 75.000003,1043.4558 66.09375,66.09375 0 0 1 8.9062529,977.36212 66.09375,66.09375 0 0 1 75.000003,911.26837 66.09375,66.09375 0 0 1 141.09375,977.36212 Z"
|
||||
id="path1006"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
id="g1247"
|
||||
transform="matrix(0.93034217,0,0,0.93034217,4.9699418,67.566622)"
|
||||
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3618"
|
||||
d=""
|
||||
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333" />
|
||||
<path
|
||||
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path35"
|
||||
d="m 66.150479,984.58608 c 3.546945,0 11.036812,-2.11769 15.990996,-3.51965 0.720489,-0.20282 1.392044,-0.39263 2.002303,-0.56287 0.09877,-0.0272 0.194448,-0.0519 0.284976,-0.0746 -0.27828,-0.27544 -0.741093,-0.6937 -1.495321,-1.32572 -3.300213,-2.23667 -6.416409,-3.27807 -9.805606,-3.27807 -0.73929,0 -1.507554,0.0453 -2.344712,0.14011 -2.869465,0.32644 -5.26015,1.01023 -6.408683,1.33796 -0.582186,0.16689 -0.757576,0.21672 -0.939018,0.21672 -0.346144,0 -0.643483,-0.20591 -0.759765,-0.52398 -0.116412,-0.31974 -0.01674,-0.67258 0.253555,-0.89897 l 0.01635,-0.0131 c 1.980412,-1.65899 5.670166,-4.74737 12.67005,-6.12731 1.214078,-0.23862 2.512891,-0.36006 3.859091,-0.36006 3.133581,0 6.378164,0.64722 9.641162,1.92195 4.444111,1.7351 7.480982,3.9625 9.923563,5.75233 1.31491,0.96438 2.45057,1.79755 3.43891,2.2556 0.25252,0.11744 0.38361,0.15053 0.44465,0.15916 0.0449,-0.0582 0.14243,-0.21891 0.28575,-0.64052 0.0384,-0.11165 0.31588,-1.29018 -1.67496,-7.99311 -1.15703,-3.89116 -2.552556,-7.86512 -3.279226,-9.62945 -1.405694,-3.41366 -1.060709,-5.83293 -0.62803,-7.2479 -1.190899,0.4377 -2.408198,1.11879 -3.688853,2.05948 l -0.07984,0.059 c -0.639877,0.4744 -1.29173,1.01126 -1.993675,1.63864 -4.13029,3.69813 -7.224723,5.62613 -9.201529,5.73095 l -0.05447,0.003 -0.05421,-0.005 c -1.741536,-0.14783 -4.380754,-2.68287 -5.460393,-3.96636 -0.224453,-0.15054 -0.480197,-0.21879 -0.817713,-0.21879 -0.338933,0 -0.718944,0.0712 -1.086593,0.14101 -0.267463,0.0507 -0.543168,0.10237 -0.816555,0.13006 -0.871412,0.0874 -2.092831,0.36919 -3.271626,0.64052 -0.568278,0.13058 -1.154714,0.26566 -1.690799,0.37628 -0.01017,0.002 -0.240292,0.0492 -0.651595,0.15762 -2.913377,0.86188 -5.108841,1.85073 -6.182685,2.78512 -0.01172,0.0102 -0.04636,0.0371 -0.101603,0.0777 -0.726284,0.51625 -2.472327,1.98916 -2.99914,4.4951 l -0.0055,0.0209 c -1.099856,4.61487 0.567635,10.33796 2.783445,13.60701 1.042166,1.53653 2.165202,2.49512 3.083359,2.62956 0.228573,0.0324 0.502861,0.0497 0.813978,0.0497 z" />
|
||||
<path
|
||||
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path39"
|
||||
d="m 82.429799,960.11108 c 0.0707,0.0139 0.15337,0.0209 0.24467,0.0209 1.90392,0 6.155901,-2.75679 6.942451,-4.01838 l 0.06258,-0.10045 0.08937,-0.0787 c 0.268236,-0.26476 1.042938,-1.65925 1.418958,-2.49396 -4.032164,-1.2097 -4.477077,-3.3928 -4.870352,-5.33252 -0.04572,-0.22523 -0.08589,-0.42804 -0.12182,-0.60936 -0.04597,-0.2372 -0.09413,-0.47813 -0.13547,-0.66434 -6.00678,1.99226 -7.842965,3.1104 -8.845083,3.94189 -0.518572,0.43075 -0.823894,1.65577 0.671555,5.04652 0.763886,1.7284 3.397825,4.06809 4.543138,4.28842 z" />
|
||||
<path
|
||||
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path43"
|
||||
d="m 51.013383,1000.8062 c -0.746759,-0.88008 -1.063414,-1.98921 -0.939147,-3.29974 0.528616,-6.36104 -0.19638,-7.8977 -0.532093,-8.26238 -0.081,-0.0882 -0.124782,-0.0882 -0.159422,-0.0882 -0.01301,0 -0.02511,7.7e-4 -0.03812,0.002 -0.623265,0.14899 -4.821418,2.98729 -5.748203,11.46142 -0.446973,4.0896 0.336228,9.3415 1.003663,12.5359 0.536342,-1.886 1.383287,-3.9635 3.023994,-6.1018 1.527514,-1.9888 3.193718,-3.5571 5.260665,-4.9318 -0.642581,-0.2672 -1.332293,-0.6791 -1.87134,-1.3155 z" />
|
||||
<path
|
||||
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path47"
|
||||
d="m 95.474451,928.32276 c -0.501702,3.30962 -1.318514,6.4535 -2.842938,9.77174 1.661697,-1.88125 2.63278,-3.92515 2.958062,-6.21925 0.135341,-0.95035 0.263342,-1.85937 -0.115124,-3.55249 z" />
|
||||
<path
|
||||
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path51"
|
||||
d="m 86.212271,943.73132 c 2.97918,-2.69331 4.792959,-7.14115 5.547315,-9.78307 -2.594662,2.49911 -5.747945,3.84003 -7.771624,4.70178 -0.696924,0.29721 -1.29804,0.55309 -1.658349,0.76312 -0.151695,0.0882 -0.304807,0.17693 -0.459851,0.26643 -1.2276,0.71019 -3.080783,1.78352 -3.35095,2.44503 l -0.0077,0.0215 -0.01004,0.0213 c -0.840764,1.76678 -1.314522,4.42364 -1.466347,5.94729 1.948991,-1.19013 3.958248,-1.98441 5.627284,-2.6436 1.549149,-0.61206 2.888653,-1.14132 3.550293,-1.73973 z" />
|
||||
<path
|
||||
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path55"
|
||||
d="m 89.217464,946.05955 c -0.01816,0.046 -0.0376,0.0895 -0.05859,0.13096 -0.49359,1.43492 0.186206,3.38675 1.445743,4.12295 0.335069,0.19599 0.660866,0.31575 0.9734,0.35696 0.04301,0.002 0.08576,0.003 0.128903,0.003 0.978809,0 1.777206,-0.71599 2.369437,-2.12722 0.372929,-1.07397 0.425983,-2.34754 0.14487,-3.49724 -0.2184,-0.89317 -0.783459,-1.95929 -1.143511,-2.49087 -0.67207,0.46127 -2.000242,1.47601 -2.912218,2.28136 -0.636915,0.61515 -0.867034,1.0025 -0.948032,1.21962 z" />
|
||||
<path
|
||||
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path59"
|
||||
d="m 97.64004,982.53162 c 1.082085,-0.29489 1.941393,-0.53634 2.57522,-0.72409 -1.305382,-0.90928 -2.816414,-2.04055 -4.870613,-3.63825 -5.034538,-3.91524 -10.43312,-5.90119 -16.043535,-5.90119 -3.07267,0 -5.749361,0.59133 -7.867818,1.30719 0.528101,-0.0328 1.065087,-0.0485 1.616625,-0.0485 0.655201,0 1.341823,0.0231 2.040034,0.0697 2.182586,0.14628 7.80575,1.139 12.891025,7.20244 1.024524,1.21936 2.125668,2.22869 5.257575,2.22869 1.117627,0 2.420431,-0.12453 3.980783,-0.38104 0.09645,-0.0269 0.242352,-0.0667 0.420704,-0.11487 z" />
|
||||
<path
|
||||
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path63"
|
||||
d="m 104.77707,956.11317 c -0.99864,-1.55082 -2.25329,-2.51418 -3.27214,-2.51418 -0.18853,0 -0.36855,0.0332 -0.53493,0.0985 -0.54587,0.21531 -1.41033,2.70966 -1.027486,4.52331 0.260506,1.23391 1.760336,5.40335 2.480436,7.40707 0.27584,0.76723 0.4095,1.14209 0.45419,1.28142 0.0354,0.10985 0.0863,0.26747 0.15066,0.46629 0.58168,1.77257 2.07468,6.32859 2.51908,10.0177 0.92395,-3.93455 1.44728,-8.6742 1.24228,-14.34655 -0.0931,-2.60111 -0.80793,-5.06378 -2.01209,-6.93357 z" />
|
||||
<path
|
||||
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path67"
|
||||
d="m 86.080664,982.55557 c -0.0197,-0.0258 -0.03863,-0.0511 -0.0573,-0.0753 -0.07907,0.0129 -0.208099,0.0411 -0.410145,0.0999 l -0.0846,0.0254 c -1.031607,0.37988 -2.924066,1.01834 -5.111545,1.75647 -2.625311,0.88468 -5.598697,1.88769 -8.088022,2.78087 -3.167319,1.18021 -4.194419,1.64586 -4.516482,1.80901 -0.05846,0.15685 -0.124009,0.35696 -0.197024,0.57768 -0.749077,2.27994 -2.4646,7.4985 -10.924006,11.1469 1.747203,1.7699 5.550278,4.9468 13.037055,4.9468 0.648376,0 1.320961,-0.024 1.99522,-0.073 5.652653,-0.4019 10.966115,-2.903 14.964283,-7.04037 3.635669,-3.76149 5.699397,-8.45284 5.731333,-12.97525 -0.884804,-0.0735 -2.384761,-0.29373 -3.7732,-0.95292 -0.0161,-0.008 -1.602847,-0.7729 -2.565559,-2.02626 z" />
|
||||
<path
|
||||
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path71"
|
||||
d="m 53.890317,990.77391 c -0.01571,1.33075 -0.191744,2.60703 -0.363142,3.85124 -0.0922,0.67168 -0.188525,1.36693 -0.25935,2.06566 -0.09607,1.40544 0.207583,1.89516 0.342409,2.03836 0.07353,0.081 0.194835,0.17333 0.455344,0.17333 0.20063,0 0.440149,-0.0556 0.693189,-0.1611 2.51199,-1.05285 4.897523,-2.88028 6.044254,-3.8945 -1.76008,-0.78488 -4.467033,-2.48018 -6.912704,-4.07299 z" />
|
||||
<path
|
||||
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path75"
|
||||
d="m 95.375553,985.509 c -0.07108,0.93464 -0.22368,2.69768 -0.467577,4.04066 -0.295536,1.62628 -0.784876,3.00172 -1.069466,3.72015 0.508012,0.46976 1.014479,0.93077 1.342981,1.2218 1.321863,-0.8651 5.661019,-4.15901 8.654629,-11.63703 -0.95898,0.64774 -2.30583,1.21769 -4.051869,1.71682 -1.776691,0.50595 -3.503161,0.80213 -4.408698,0.9376 z" />
|
||||
<path
|
||||
d="m 113.82909,953.6111 c -1.81082,-3.78531 -4.33568,-5.69644 -6.07954,-6.80467 -1.46622,-0.93142 -3.15225,-1.60825 -5.02372,-2.01878 -0.20887,-1.30809 -0.56622,-2.64527 -1.05569,-3.9464 3.15586,-4.70424 3.91563,-9.99349 2.19019,-15.35151 -1.32521,-4.11947 -2.35412,-6.77569 -3.23905,-8.36102 -1.911774,-3.42899 -4.56065,-4.14858 -6.446413,-4.14858 -1.943196,0 -3.803719,0.8257 -5.108069,2.26771 -1.335383,1.47601 -1.959035,3.40761 -1.755701,5.43786 0.173716,1.73149 -0.280469,4.87692 -0.581928,6.00008 -0.0052,0.0151 -0.541108,1.51644 -4.528716,3.44908 -0.09606,0.0345 -0.3003,0.10443 -0.614637,0.20977 -2.293718,0.76814 -6.556258,2.19714 -9.395719,5.9518 -2.169451,2.62788 -2.702317,5.23194 -3.317984,8.24615 -0.368036,1.79704 -0.752812,4.14484 -0.65739,6.92095 -7.127627,1.58275 -12.26261,4.80815 -15.273726,9.59879 -3.116711,4.96037 -3.657432,11.10957 -1.605551,18.28497 l 0.01803,0.0533 c 0.0376,0.13058 0.07726,0.26064 0.118601,0.39019 -0.350007,-0.06 -0.703749,-0.11049 -1.066891,-0.15054 -0.317942,-0.0366 -0.6458,-0.0541 -0.970954,-0.0541 -3.558791,0 -7.345641,2.23693 -10.130116,5.98463 -2.115366,2.84564 -4.655943,7.87207 -4.74557,15.65802 -0.06735,5.7826 0.551023,11.1139 1.839276,15.8461 0.96078,3.526 2.032564,5.6921 2.443997,6.4503 l 8.729958,16.3644 3.999713,-18.1224 c 1.365002,-6.1728 2.712748,-8.7931 4.451837,-10.525 4.046715,2.4388 8.826282,3.7217 13.899968,3.7217 5.655614,0 11.552937,-1.6311 16.603314,-4.5923 3.280769,-1.9257 6.07722,-4.2913 8.322519,-7.0385 0.03039,0 0.06039,0 0.09066,0 h 0.239133 c 1.388438,-0.047 3.286563,-0.7336 5.206829,-1.884 1.5995,-0.9571 4.01092,-2.71815 6.43174,-5.67428 2.43963,-2.98176 4.43007,-6.60919 5.91407,-10.78236 1.73845,-4.88554 2.79658,-10.57425 3.1426,-16.90438 0.41889,-5.88793 -0.2676,-10.75686 -2.04507,-14.47211 z m -4.00796,14.09132 c -0.31098,5.76971 -1.2549,10.90199 -2.80263,15.25209 -1.25078,3.51578 -2.89766,6.53385 -4.89404,8.97425 -3.437747,4.19944 -6.797068,5.32543 -7.153514,5.3396 h -0.02833 c -0.32554,0 -0.51664,-0.1329 -1.428745,-0.7711 -0.254843,-0.17758 -0.639877,-0.44646 -0.957562,-0.65352 -1.907525,3.7101 -5.040848,6.91526 -9.099024,9.29556 -4.13338,2.424 -8.941019,3.7604 -13.534121,3.7604 -5.453826,0 -10.241634,-1.8001 -13.887219,-5.2144 -4.973371,3.1622 -7.962467,5.8005 -10.38586,16.7757 l -0.458692,2.0806 -1.002762,-1.8788 c -0.25304,-0.4625 -1.121233,-2.1754 -1.938946,-5.1807 -1.14042,-4.19 -1.688224,-8.9624 -1.627314,-14.1831 0.121563,-10.41898 5.714078,-15.64835 8.811602,-15.64835 0.101988,0 0.203205,0.005 0.299785,0.0165 2.936041,0.3285 4.854641,1.59705 8.337456,3.90069 0.360052,0.23862 0.739162,0.48934 1.138747,0.75178 1.247817,0.819 3.011631,1.81893 3.455643,1.90469 0.845014,-0.0491 1.672256,-1.94178 1.912677,-3.69748 0.01468,-0.10675 0.0291,-0.20578 0.04301,-0.29811 0.01893,-0.20758 0.02923,-0.39019 0.03477,-0.54008 -0.147317,-0.0514 -0.300429,-0.1119 -0.45676,-0.18067 l -0.03477,-0.0117 c -2.190699,-0.75422 -5.3915,-4.45879 -7.002459,-9.83638 -1.555716,-5.43554 -1.247947,-9.93129 0.914164,-13.37058 3.505351,-5.57951 11.114077,-6.89132 13.630573,-7.3222 0.786679,-0.15633 1.609414,-0.30275 2.446573,-0.435 0.390828,-0.0981 0.658033,-0.18015 0.830462,-0.25471 0.07469,-0.0519 0.107526,-0.10727 0.05653,-0.30945 l 0.06825,-0.0191 -0.06606,0.0148 c -0.03052,-0.13714 -0.07276,-0.29759 -0.121176,-0.48328 -0.06709,-0.25717 -0.142037,-0.54807 -0.219559,-0.89318 -0.779081,-3.49505 -0.381428,-6.42375 0.111132,-8.8286 0.553341,-2.70669 0.859951,-4.20523 2.138288,-5.70197 1.693632,-2.33119 4.73926,-3.35134 6.561409,-3.96237 0.508399,-0.17024 0.947646,-0.31704 1.201588,-0.43938 5.581569,-2.67707 7.358776,-5.49168 7.866917,-7.38105 0.402675,-1.49918 1.041007,-5.44108 0.763757,-8.19387 -0.03078,-0.31228 0.04198,-0.56931 0.218271,-0.76428 0.156461,-0.17268 0.378853,-0.27094 0.611418,-0.27094 0.52295,0 1.23919,0 3.91176,8.30308 1.409944,4.37779 0.358635,8.48207 -3.12199,12.20002 -0.04468,0.0483 -0.09014,0.0956 -0.133925,0.14101 -0.09504,0.0979 -0.237974,0.24583 -0.257419,0.29953 7.73e-4,0 -0.0062,0.13418 0.225998,0.51909 1.47124,2.42918 2.270668,5.45009 2.038746,7.6959 -0.05524,0.52308 -0.155301,1.02646 -0.241966,1.46944 -0.05151,0.25343 -0.113192,0.56364 -0.144999,0.80368 0.01429,0 0.0291,0 0.04468,0 0.397654,-0.0421 1.013064,-0.0901 1.754929,-0.0901 1.745657,0 4.245547,0.26747 6.245917,1.53898 1.20816,0.76646 2.73709,1.94925 3.86077,4.30156 1.32392,2.76503 1.81519,6.62579 1.46402,11.47554 z"
|
||||
id="path87"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 16 KiB |
4
sw.js
4
sw.js
|
|
@ -14,3 +14,7 @@ addEventListener('message', (event) => {
|
|||
skipWaiting();
|
||||
}
|
||||
});
|
||||
|
||||
self.addEventListener('activate', (event) => {
|
||||
event.waitUntil(clients.claim());
|
||||
});
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ module.exports = {
|
|||
loaders: [MiniCssExtractPlugin.loader, "css-loader"]
|
||||
},
|
||||
{
|
||||
test: { and: [ /\.(jpe?g|png|gif|svg)$/i, /jquery-ui/i ] },
|
||||
test: { and: [ /\.(jpe?g|png|gif|svg|ttf|eot|woff2?)$/i, /jquery-ui/i ] },
|
||||
loader: "file-loader",
|
||||
options: {
|
||||
name: '[name].[contenthash].[ext]',
|
||||
|
|
@ -31,7 +31,7 @@ module.exports = {
|
|||
}
|
||||
},
|
||||
{
|
||||
test: { and: [ /\.(jpe?g|png|gif|mp3|wav)$/i, { not: [ /jquery-ui/i ] } ] },
|
||||
test: { and: [ /\.(jpe?g|png|gif|mp3|wav|ttf|eot|woff2?)$/i, { not: [ /jquery-ui/i ] } ] },
|
||||
loader: "file-loader",
|
||||
options: {
|
||||
name: '[path][name].[contenthash].[ext]',
|
||||
|
|
@ -52,7 +52,14 @@ module.exports = {
|
|||
loader: "svgo-loader",
|
||||
options: {
|
||||
plugins: [
|
||||
{ cleanupIDs: false }
|
||||
{
|
||||
name: "preset-default",
|
||||
params: {
|
||||
overrides: {
|
||||
cleanupIDs: false,
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -88,12 +95,14 @@ module.exports = {
|
|||
"window.jQuery": "jquery'",
|
||||
"window.$": "jquery"
|
||||
}),
|
||||
new CopyPlugin([
|
||||
{ from: '.htaccess' },
|
||||
]),
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
{ from: '.htaccess' },
|
||||
],
|
||||
}),
|
||||
new InjectManifest({
|
||||
swSrc: './sw.js',
|
||||
dontCacheBustURLsMatching: /\.[0-9a-f]{16,}\.(css|js|svg|png|jpg|wav)$/,
|
||||
dontCacheBustURLsMatching: /\.[0-9a-f]{16,}\.\w{2,4}$/,
|
||||
exclude: [ /(^|[/\\])\.htaccess$/ ],
|
||||
}),
|
||||
],
|
||||
|
|
|
|||
Loading…
Reference in New Issue