wip
Browse files- css/chessboard-1.0.0.css +54 -0
- css/chessboard-1.0.0.min.css +2 -0
- ggml-tiny.en.bin +0 -3
- img/chesspieces/wikipedia/bB.png +0 -0
- img/chesspieces/wikipedia/bK.png +0 -0
- img/chesspieces/wikipedia/bN.png +0 -0
- img/chesspieces/wikipedia/bP.png +0 -0
- img/chesspieces/wikipedia/bQ.png +0 -0
- img/chesspieces/wikipedia/bR.png +0 -0
- img/chesspieces/wikipedia/wB.png +0 -0
- img/chesspieces/wikipedia/wK.png +0 -0
- img/chesspieces/wikipedia/wN.png +0 -0
- img/chesspieces/wikipedia/wP.png +0 -0
- img/chesspieces/wikipedia/wQ.png +0 -0
- img/chesspieces/wikipedia/wR.png +0 -0
- index.html +432 -877
- js/chess.js +0 -0
- js/chessboard-1.0.0.js +1817 -0
- js/chessboard-1.0.0.min.js +2 -0
- helpers.js → js/helpers.js +21 -9
- js/jquery-3.7.1.min.js +2 -0
- js/wchess.wasm.js +0 -0
- js/wchess.wasm.worker.js +1 -0
- libmain.worker.js +0 -1
- libwhisper.worker.js +0 -1
- models/.gitattributes +0 -51
- models/README.md +0 -24
- models/ggml-base.bin +0 -3
- models/ggml-base.en.bin +0 -3
- models/ggml-tiny.bin +0 -3
- models/ggml-tiny.en.bin +0 -3
css/chessboard-1.0.0.css
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*! chessboard.js v1.0.0 | (c) 2019 Chris Oakman | MIT License chessboardjs.com/license */
|
| 2 |
+
|
| 3 |
+
.clearfix-7da63 {
|
| 4 |
+
clear: both;
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
.board-b72b1 {
|
| 8 |
+
border: 2px solid #404040;
|
| 9 |
+
box-sizing: content-box;
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
.square-55d63 {
|
| 13 |
+
float: left;
|
| 14 |
+
position: relative;
|
| 15 |
+
|
| 16 |
+
/* disable any native browser highlighting */
|
| 17 |
+
-webkit-touch-callout: none;
|
| 18 |
+
-webkit-user-select: none;
|
| 19 |
+
-khtml-user-select: none;
|
| 20 |
+
-moz-user-select: none;
|
| 21 |
+
-ms-user-select: none;
|
| 22 |
+
user-select: none;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
.white-1e1d7 {
|
| 26 |
+
background-color: #f0d9b5;
|
| 27 |
+
color: #b58863;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
.black-3c85d {
|
| 31 |
+
background-color: #b58863;
|
| 32 |
+
color: #f0d9b5;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
.highlight1-32417, .highlight2-9c5d2 {
|
| 36 |
+
box-shadow: inset 0 0 3px 3px yellow;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
.notation-322f9 {
|
| 40 |
+
cursor: default;
|
| 41 |
+
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
| 42 |
+
font-size: 14px;
|
| 43 |
+
position: absolute;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
.alpha-d2270 {
|
| 47 |
+
bottom: 1px;
|
| 48 |
+
right: 3px;
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
.numeric-fc462 {
|
| 52 |
+
top: 2px;
|
| 53 |
+
left: 2px;
|
| 54 |
+
}
|
css/chessboard-1.0.0.min.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*! chessboard.js v1.0.0 | (c) 2019 Chris Oakman | MIT License chessboardjs.com/license */
|
| 2 |
+
.clearfix-7da63{clear:both}.board-b72b1{border:2px solid #404040;box-sizing:content-box}.square-55d63{float:left;position:relative;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.white-1e1d7{background-color:#f0d9b5;color:#b58863}.black-3c85d{background-color:#b58863;color:#f0d9b5}.highlight1-32417,.highlight2-9c5d2{box-shadow:inset 0 0 3px 3px #ff0}.notation-322f9{cursor:default;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;position:absolute}.alpha-d2270{bottom:1px;right:3px}.numeric-fc462{top:2px;left:2px}
|
ggml-tiny.en.bin
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:921e4cf8686fdd993dcd081a5da5b6c365bfde1162e72b08d75ac75289920b1f
|
| 3 |
-
size 77704715
|
|
|
|
|
|
|
|
|
|
|
|
img/chesspieces/wikipedia/bB.png
ADDED
|
img/chesspieces/wikipedia/bK.png
ADDED
|
img/chesspieces/wikipedia/bN.png
ADDED
|
img/chesspieces/wikipedia/bP.png
ADDED
|
img/chesspieces/wikipedia/bQ.png
ADDED
|
img/chesspieces/wikipedia/bR.png
ADDED
|
img/chesspieces/wikipedia/wB.png
ADDED
|
img/chesspieces/wikipedia/wK.png
ADDED
|
img/chesspieces/wikipedia/wN.png
ADDED
|
img/chesspieces/wikipedia/wP.png
ADDED
|
img/chesspieces/wikipedia/wQ.png
ADDED
|
img/chesspieces/wikipedia/wR.png
ADDED
|
index.html
CHANGED
|
@@ -1,886 +1,441 @@
|
|
| 1 |
<!doctype html>
|
| 2 |
<html lang="en-us">
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
id="file"
|
| 171 |
-
name="input"
|
| 172 |
-
value="file"
|
| 173 |
-
checked="checked"
|
| 174 |
-
onchange="changeInput('file')"
|
| 175 |
-
/>
|
| 176 |
-
<label for="file">File</label>
|
| 177 |
-
<input
|
| 178 |
-
type="radio"
|
| 179 |
-
id="mic"
|
| 180 |
-
name="input"
|
| 181 |
-
value="mic"
|
| 182 |
-
onchange="changeInput('mic')"
|
| 183 |
-
/>
|
| 184 |
-
<label for="mic">Microphone</label>
|
| 185 |
-
</div>
|
| 186 |
-
|
| 187 |
-
<br />
|
| 188 |
-
|
| 189 |
-
<div id="input_file">
|
| 190 |
-
Audio file:
|
| 191 |
-
<input type="file" id="file" name="file" onchange="loadAudio(event)" />
|
| 192 |
-
</div>
|
| 193 |
-
|
| 194 |
-
<div id="input_mic" style="display: none">
|
| 195 |
-
Microphone:
|
| 196 |
-
<button id="start" onclick="startRecording()">Start</button>
|
| 197 |
-
<button id="stop" onclick="stopRecording()" disabled>Stop</button>
|
| 198 |
-
|
| 199 |
-
<!-- progress bar to show recording progress -->
|
| 200 |
-
<br /><br />
|
| 201 |
-
<div id="progress" style="display: none">
|
| 202 |
-
<div
|
| 203 |
-
id="progress-bar"
|
| 204 |
-
style="width: 0%; height: 10px; background-color: #4caf50"
|
| 205 |
-
></div>
|
| 206 |
-
<div id="progress-text">0%</div>
|
| 207 |
</div>
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
<option value="it">Italian</option>
|
| 254 |
-
<option value="ja">Japanese</option>
|
| 255 |
-
<option value="kn">Kannada</option>
|
| 256 |
-
<option value="ko">Korean</option>
|
| 257 |
-
<option value="la">Latin</option>
|
| 258 |
-
<option value="lv">Latvian</option>
|
| 259 |
-
<option value="lt">Lithuanian</option>
|
| 260 |
-
<option value="mk">Macedonian</option>
|
| 261 |
-
<option value="ms">Malay</option>
|
| 262 |
-
<option value="mt">Maltese</option>
|
| 263 |
-
<option value="no">Norwegian</option>
|
| 264 |
-
<option value="fa">Persian</option>
|
| 265 |
-
<option value="pl">Polish</option>
|
| 266 |
-
<option value="pt">Portuguese</option>
|
| 267 |
-
<option value="ro">Romanian</option>
|
| 268 |
-
<option value="ru">Russian</option>
|
| 269 |
-
<option value="sr">Serbian</option>
|
| 270 |
-
<option value="sk">Slovak</option>
|
| 271 |
-
<option value="sl">Slovenian</option>
|
| 272 |
-
<option value="es">Spanish</option>
|
| 273 |
-
<option value="sw">Swahili</option>
|
| 274 |
-
<option value="sv">Swedish</option>
|
| 275 |
-
<option value="ta">Tamil</option>
|
| 276 |
-
<option value="te">Telugu</option>
|
| 277 |
-
<option value="th">Thai</option>
|
| 278 |
-
<option value="tr">Turkish</option>
|
| 279 |
-
<option value="uk">Ukrainian</option>
|
| 280 |
-
<option value="ur">Urdu</option>
|
| 281 |
-
<option value="vi">Vietnamese</option>
|
| 282 |
-
<option value="cy">Welsh</option>
|
| 283 |
-
<option value="yi">Yiddish</option>
|
| 284 |
-
</select>
|
| 285 |
-
</td>
|
| 286 |
-
<!-- Slider to select number of threads between 1 and 16 -->
|
| 287 |
-
<td>
|
| 288 |
-
Threads:
|
| 289 |
-
<input
|
| 290 |
-
type="range"
|
| 291 |
-
id="threads"
|
| 292 |
-
name="threads"
|
| 293 |
-
min="1"
|
| 294 |
-
max="16"
|
| 295 |
-
value="8"
|
| 296 |
-
onchange="changeThreads(this.value)"
|
| 297 |
-
/>
|
| 298 |
-
<span id="threads-value">8</span>
|
| 299 |
-
</td>
|
| 300 |
-
<td>
|
| 301 |
-
<button onclick="onProcess(false);">Transcribe</button>
|
| 302 |
-
</td>
|
| 303 |
-
<td>
|
| 304 |
-
<button onclick="onProcess(true);">Translate</button>
|
| 305 |
-
</td>
|
| 306 |
-
</tr>
|
| 307 |
-
</table>
|
| 308 |
-
|
| 309 |
-
<br />
|
| 310 |
-
|
| 311 |
-
<!-- textarea with height filling the rest of the page -->
|
| 312 |
-
<textarea id="output" rows="20"></textarea>
|
| 313 |
-
|
| 314 |
-
<br /><br />
|
| 315 |
-
|
| 316 |
-
<div class="cell-version">
|
| 317 |
-
<span>
|
| 318 |
-
| Build time: <span class="nav-link">@GIT_DATE@</span> | Commit hash:
|
| 319 |
-
<a target="_blank"
|
| 320 |
-
class="nav-link"
|
| 321 |
-
href="https://github.com/ggerganov/whisper.cpp/commit/@GIT_SHA1@"
|
| 322 |
-
>@GIT_SHA1@</a
|
| 323 |
-
>
|
| 324 |
-
| Commit subject: <span class="nav-link">@GIT_COMMIT_SUBJECT@</span> |
|
| 325 |
-
<a target="_blank"
|
| 326 |
-
class="nav-link"
|
| 327 |
-
href="https://github.com/ggerganov/whisper.cpp/tree/master/examples/whisper.wasm"
|
| 328 |
-
>Source Code</a
|
| 329 |
-
>
|
| 330 |
-
|
|
| 331 |
-
</span>
|
| 332 |
-
</div>
|
| 333 |
-
</div>
|
| 334 |
-
|
| 335 |
-
<script type="text/javascript" src="helpers.js"></script>
|
| 336 |
-
<script type="text/javascript">
|
| 337 |
-
document.addEventListener("DOMContentLoaded", () => {
|
| 338 |
-
//check is shared array buffer is supported
|
| 339 |
-
if (!window.SharedArrayBuffer) {
|
| 340 |
-
document.querySelector("#warning").style.display = "block";
|
| 341 |
-
}
|
| 342 |
-
});
|
| 343 |
-
// TODO: convert audio buffer to WAV
|
| 344 |
-
function setAudio(audio) {
|
| 345 |
-
//if (audio) {
|
| 346 |
-
// // convert to 16-bit PCM
|
| 347 |
-
// var blob = new Blob([audio], { type: 'audio/wav' });
|
| 348 |
-
// var url = URL.createObjectURL(blob);
|
| 349 |
-
// document.getElementById('source').src = url;
|
| 350 |
-
// document.getElementById('audio').hidden = false;
|
| 351 |
-
// document.getElementById('audio').loop = false;
|
| 352 |
-
// document.getElementById('audio').load();
|
| 353 |
-
//} else {
|
| 354 |
-
// document.getElementById('audio').hidden = true;
|
| 355 |
-
//}
|
| 356 |
-
}
|
| 357 |
-
|
| 358 |
-
function changeInput(input) {
|
| 359 |
-
if (input == "file") {
|
| 360 |
-
document.getElementById("input_file").style.display = "block";
|
| 361 |
-
document.getElementById("input_mic").style.display = "none";
|
| 362 |
-
document.getElementById("progress").style.display = "none";
|
| 363 |
-
} else {
|
| 364 |
-
document.getElementById("input_file").style.display = "none";
|
| 365 |
-
document.getElementById("input_mic").style.display = "block";
|
| 366 |
-
document.getElementById("progress").style.display = "block";
|
| 367 |
-
}
|
| 368 |
-
}
|
| 369 |
-
|
| 370 |
-
var Module = {
|
| 371 |
-
print: printTextarea,
|
| 372 |
-
printErr: printTextarea,
|
| 373 |
-
setStatus: function (text) {
|
| 374 |
-
printTextarea("js: " + text);
|
| 375 |
-
},
|
| 376 |
-
monitorRunDependencies: function (left) {},
|
| 377 |
-
};
|
| 378 |
-
|
| 379 |
-
// web audio context
|
| 380 |
-
var context = null;
|
| 381 |
-
|
| 382 |
-
// audio data
|
| 383 |
-
var audio = null;
|
| 384 |
-
|
| 385 |
-
// the whisper instance
|
| 386 |
-
var instance = null;
|
| 387 |
-
var model_whisper = "";
|
| 388 |
-
|
| 389 |
-
// helper function
|
| 390 |
-
function convertTypedArray(src, type) {
|
| 391 |
-
var buffer = new ArrayBuffer(src.byteLength);
|
| 392 |
-
var baseView = new src.constructor(buffer).set(src);
|
| 393 |
-
return new type(buffer);
|
| 394 |
-
}
|
| 395 |
-
|
| 396 |
-
//
|
| 397 |
-
// load model
|
| 398 |
-
//
|
| 399 |
-
|
| 400 |
-
let dbVersion = 1;
|
| 401 |
-
let dbName = "whisper.ggerganov.com";
|
| 402 |
-
let indexedDB =
|
| 403 |
-
window.indexedDB ||
|
| 404 |
-
window.mozIndexedDB ||
|
| 405 |
-
window.webkitIndexedDB ||
|
| 406 |
-
window.msIndexedDB;
|
| 407 |
-
|
| 408 |
-
function storeFS(fname, buf) {
|
| 409 |
-
// write to WASM file using FS_createDataFile
|
| 410 |
-
// if the file exists, delete it
|
| 411 |
-
try {
|
| 412 |
-
Module.FS_unlink(fname);
|
| 413 |
-
} catch (e) {
|
| 414 |
-
// ignore
|
| 415 |
-
}
|
| 416 |
-
|
| 417 |
-
Module.FS_createDataFile("/", fname, buf, true, true);
|
| 418 |
-
|
| 419 |
-
//model_whisper = fname;
|
| 420 |
-
|
| 421 |
-
document.getElementById("model-whisper-status").innerHTML =
|
| 422 |
-
'loaded "' + model_whisper + '"!';
|
| 423 |
-
|
| 424 |
-
printTextarea(
|
| 425 |
-
"storeFS: stored model: " + fname + " size: " + buf.length
|
| 426 |
-
);
|
| 427 |
-
|
| 428 |
-
document.getElementById("model").innerHTML =
|
| 429 |
-
"Model fetched: " + model_whisper;
|
| 430 |
-
}
|
| 431 |
-
|
| 432 |
-
function loadFile(event, fname) {
|
| 433 |
-
var file = event.target.files[0] || null;
|
| 434 |
-
if (file == null) {
|
| 435 |
-
return;
|
| 436 |
-
}
|
| 437 |
-
|
| 438 |
-
printTextarea(
|
| 439 |
-
"loadFile: loading model: " +
|
| 440 |
-
file.name +
|
| 441 |
-
", size: " +
|
| 442 |
-
file.size +
|
| 443 |
-
" bytes"
|
| 444 |
-
);
|
| 445 |
-
printTextarea("loadFile: please wait ...");
|
| 446 |
-
|
| 447 |
-
var reader = new FileReader();
|
| 448 |
-
reader.onload = function (event) {
|
| 449 |
-
var buf = new Uint8Array(reader.result);
|
| 450 |
-
storeFS(fname, buf);
|
| 451 |
-
};
|
| 452 |
-
reader.readAsArrayBuffer(file);
|
| 453 |
-
|
| 454 |
-
document.getElementById("fetch-whisper-tiny-en").style.display = "none";
|
| 455 |
-
document.getElementById("fetch-whisper-base-en").style.display = "none";
|
| 456 |
-
document.getElementById("fetch-whisper-small-en").style.display =
|
| 457 |
-
"none";
|
| 458 |
-
document.getElementById("fetch-whisper-tiny").style.display = "none";
|
| 459 |
-
document.getElementById("fetch-whisper-base").style.display = "none";
|
| 460 |
-
document.getElementById("fetch-whisper-small").style.display = "none";
|
| 461 |
-
|
| 462 |
-
document.getElementById("fetch-whisper-tiny-en-q5_1").style.display =
|
| 463 |
-
"none";
|
| 464 |
-
document.getElementById("fetch-whisper-tiny-q5_1").style.display =
|
| 465 |
-
"none";
|
| 466 |
-
document.getElementById("fetch-whisper-base-en-q5_1").style.display =
|
| 467 |
-
"none";
|
| 468 |
-
document.getElementById("fetch-whisper-base-q5_1").style.display =
|
| 469 |
-
"none";
|
| 470 |
-
document.getElementById("fetch-whisper-small-en-q5_1").style.display =
|
| 471 |
-
"none";
|
| 472 |
-
document.getElementById("fetch-whisper-small-q5_1").style.display =
|
| 473 |
-
"none";
|
| 474 |
-
document.getElementById("fetch-whisper-medium-en-q5_0").style.display =
|
| 475 |
-
"none";
|
| 476 |
-
document.getElementById("fetch-whisper-medium-q5_0").style.display =
|
| 477 |
-
"none";
|
| 478 |
-
document.getElementById("fetch-whisper-large-q5_0").style.display =
|
| 479 |
-
"none";
|
| 480 |
-
|
| 481 |
-
document.getElementById("whisper-file").style.display = "none";
|
| 482 |
-
document.getElementById("model-whisper-status").innerHTML =
|
| 483 |
-
"loaded model: " + file.name;
|
| 484 |
-
}
|
| 485 |
-
|
| 486 |
-
function loadWhisper(model) {
|
| 487 |
-
const baseURL =
|
| 488 |
-
"https://huggingface.co/ggerganov/whisper.cpp/resolve/main";
|
| 489 |
-
let urls = {
|
| 490 |
-
"tiny.en": `${baseURL}/ggml-tiny.en.bin`,
|
| 491 |
-
tiny: `${baseURL}/ggml-tiny.bin`,
|
| 492 |
-
"base.en": `${baseURL}/ggml-base.en.bin`,
|
| 493 |
-
base: `${baseURL}/ggml-base.bin`,
|
| 494 |
-
"small.en": `${baseURL}/ggml-small.en.bin`,
|
| 495 |
-
small: `${baseURL}/ggml-small.bin`,
|
| 496 |
-
|
| 497 |
-
"tiny-en-q5_1": `${baseURL}/ggml-model-whisper-tiny.en-q5_1.bin`,
|
| 498 |
-
"tiny-q5_1": `${baseURL}/ggml-model-whisper-tiny-q5_1.bin`,
|
| 499 |
-
"base-en-q5_1": `${baseURL}/ggml-model-whisper-base.en-q5_1.bin`,
|
| 500 |
-
"base-q5_1": `${baseURL}/ggml-model-whisper-base-q5_1.bin`,
|
| 501 |
-
"small-en-q5_1": `${baseURL}/ggml-model-whisper-small.en-q5_1.bin`,
|
| 502 |
-
"small-q5_1": `${baseURL}/ggml-model-whisper-small-q5_1.bin`,
|
| 503 |
-
"medium-en-q5_0": `${baseURL}/ggml-model-whisper-medium.en-q5_0.bin`,
|
| 504 |
-
"medium-q5_0": `${baseURL}/ggml-model-whisper-medium-q5_0.bin`,
|
| 505 |
-
"large-q5_0": `${baseURL}/ggml-model-whisper-large-q5_0.bin`,
|
| 506 |
-
};
|
| 507 |
-
|
| 508 |
-
let sizes = {
|
| 509 |
-
"tiny.en": 75,
|
| 510 |
-
tiny: 75,
|
| 511 |
-
"base.en": 142,
|
| 512 |
-
base: 142,
|
| 513 |
-
"small.en": 466,
|
| 514 |
-
small: 466,
|
| 515 |
-
|
| 516 |
-
"tiny-en-q5_1": 31,
|
| 517 |
-
"tiny-q5_1": 31,
|
| 518 |
-
"base-en-q5_1": 57,
|
| 519 |
-
"base-q5_1": 57,
|
| 520 |
-
"small-en-q5_1": 182,
|
| 521 |
-
"small-q5_1": 182,
|
| 522 |
-
"medium-en-q5_0": 515,
|
| 523 |
-
"medium-q5_0": 515,
|
| 524 |
-
"large-q5_0": 1030,
|
| 525 |
-
};
|
| 526 |
-
|
| 527 |
-
let url = urls[model];
|
| 528 |
-
let dst = "whisper.bin";
|
| 529 |
-
let size_mb = sizes[model];
|
| 530 |
-
|
| 531 |
-
model_whisper = model;
|
| 532 |
-
|
| 533 |
-
document.getElementById("fetch-whisper-tiny-en").style.display = "none";
|
| 534 |
-
document.getElementById("fetch-whisper-base-en").style.display = "none";
|
| 535 |
-
document.getElementById("fetch-whisper-small-en").style.display =
|
| 536 |
-
"none";
|
| 537 |
-
document.getElementById("fetch-whisper-tiny").style.display = "none";
|
| 538 |
-
document.getElementById("fetch-whisper-base").style.display = "none";
|
| 539 |
-
document.getElementById("fetch-whisper-small").style.display = "none";
|
| 540 |
-
|
| 541 |
-
document.getElementById("fetch-whisper-tiny-en-q5_1").style.display =
|
| 542 |
-
"none";
|
| 543 |
-
document.getElementById("fetch-whisper-tiny-q5_1").style.display =
|
| 544 |
-
"none";
|
| 545 |
-
document.getElementById("fetch-whisper-base-en-q5_1").style.display =
|
| 546 |
-
"none";
|
| 547 |
-
document.getElementById("fetch-whisper-base-q5_1").style.display =
|
| 548 |
-
"none";
|
| 549 |
-
document.getElementById("fetch-whisper-small-en-q5_1").style.display =
|
| 550 |
-
"none";
|
| 551 |
-
document.getElementById("fetch-whisper-small-q5_1").style.display =
|
| 552 |
-
"none";
|
| 553 |
-
document.getElementById("fetch-whisper-medium-en-q5_0").style.display =
|
| 554 |
-
"none";
|
| 555 |
-
document.getElementById("fetch-whisper-medium-q5_0").style.display =
|
| 556 |
-
"none";
|
| 557 |
-
document.getElementById("fetch-whisper-large-q5_0").style.display =
|
| 558 |
-
"none";
|
| 559 |
-
|
| 560 |
-
document.getElementById("whisper-file").style.display = "none";
|
| 561 |
-
document.getElementById("model-whisper-status").innerHTML =
|
| 562 |
-
"loading model: " + model;
|
| 563 |
-
|
| 564 |
-
cbProgress = function (p) {
|
| 565 |
-
let el = document.getElementById("fetch-whisper-progress");
|
| 566 |
-
el.innerHTML = Math.round(100 * p) + "%";
|
| 567 |
-
};
|
| 568 |
-
|
| 569 |
-
cbCancel = function () {
|
| 570 |
-
var el;
|
| 571 |
-
|
| 572 |
-
el = document.getElementById("fetch-whisper-tiny-en");
|
| 573 |
-
if (el) el.style.display = "inline-block";
|
| 574 |
-
el = document.getElementById("fetch-whisper-base-en");
|
| 575 |
-
if (el) el.style.display = "inline-block";
|
| 576 |
-
el = document.getElementById("fetch-whisper-small-en");
|
| 577 |
-
if (el) el.style.display = "inline-block";
|
| 578 |
-
el = document.getElementById("fetch-whisper-tiny");
|
| 579 |
-
if (el) el.style.display = "inline-block";
|
| 580 |
-
el = document.getElementById("fetch-whisper-base");
|
| 581 |
-
if (el) el.style.display = "inline-block";
|
| 582 |
-
el = document.getElementById("fetch-whisper-small");
|
| 583 |
-
if (el) el.style.display = "inline-block";
|
| 584 |
-
|
| 585 |
-
el = document.getElementById("fetch-whisper-tiny-en-q5_1");
|
| 586 |
-
if (el) el.style.display = "inline-block";
|
| 587 |
-
el = document.getElementById("fetch-whisper-tiny-q5_1");
|
| 588 |
-
if (el) el.style.display = "inline-block";
|
| 589 |
-
el = document.getElementById("fetch-whisper-base-en-q5_1");
|
| 590 |
-
if (el) el.style.display = "inline-block";
|
| 591 |
-
el = document.getElementById("fetch-whisper-base-q5_1");
|
| 592 |
-
if (el) el.style.display = "inline-block";
|
| 593 |
-
el = document.getElementById("fetch-whisper-small-en-q5_1");
|
| 594 |
-
if (el) el.style.display = "inline-block";
|
| 595 |
-
el = document.getElementById("fetch-whisper-small-q5_1");
|
| 596 |
-
if (el) el.style.display = "inline-block";
|
| 597 |
-
el = document.getElementById("fetch-whisper-medium-en-q5_0");
|
| 598 |
-
if (el) el.style.display = "inline-block";
|
| 599 |
-
el = document.getElementById("fetch-whisper-medium-q5_0");
|
| 600 |
-
if (el) el.style.display = "inline-block";
|
| 601 |
-
el = document.getElementById("fetch-whisper-large-q5_0");
|
| 602 |
-
if (el) el.style.display = "inline-block";
|
| 603 |
-
|
| 604 |
-
el = document.getElementById("whisper-file");
|
| 605 |
-
if (el) el.style.display = "inline-block";
|
| 606 |
-
el = document.getElementById("model-whisper-status");
|
| 607 |
-
if (el) el.innerHTML = "";
|
| 608 |
-
};
|
| 609 |
-
|
| 610 |
-
loadRemote(
|
| 611 |
-
url,
|
| 612 |
-
dst,
|
| 613 |
-
size_mb,
|
| 614 |
-
cbProgress,
|
| 615 |
-
storeFS,
|
| 616 |
-
cbCancel,
|
| 617 |
-
printTextarea
|
| 618 |
-
);
|
| 619 |
-
}
|
| 620 |
-
|
| 621 |
-
//
|
| 622 |
-
// audio file
|
| 623 |
-
//
|
| 624 |
-
|
| 625 |
-
const kMaxAudio_s = 30 * 60;
|
| 626 |
-
const kMaxRecording_s = 2 * 60;
|
| 627 |
-
const kSampleRate = 16000;
|
| 628 |
-
|
| 629 |
-
window.AudioContext = window.AudioContext || window.webkitAudioContext;
|
| 630 |
-
window.OfflineAudioContext =
|
| 631 |
-
window.OfflineAudioContext || window.webkitOfflineAudioContext;
|
| 632 |
-
|
| 633 |
-
function loadAudio(event) {
|
| 634 |
-
if (!context) {
|
| 635 |
-
context = new AudioContext({
|
| 636 |
-
sampleRate: kSampleRate,
|
| 637 |
-
channelCount: 1,
|
| 638 |
-
echoCancellation: false,
|
| 639 |
-
autoGainControl: true,
|
| 640 |
-
noiseSuppression: true,
|
| 641 |
-
});
|
| 642 |
-
}
|
| 643 |
-
|
| 644 |
-
var file = event.target.files[0] || null;
|
| 645 |
-
if (file == null) {
|
| 646 |
-
return;
|
| 647 |
-
}
|
| 648 |
-
|
| 649 |
-
printTextarea(
|
| 650 |
-
"js: loading audio: " + file.name + ", size: " + file.size + " bytes"
|
| 651 |
-
);
|
| 652 |
-
printTextarea("js: please wait ...");
|
| 653 |
-
|
| 654 |
-
var reader = new FileReader();
|
| 655 |
-
reader.onload = function (event) {
|
| 656 |
-
var buf = new Uint8Array(reader.result);
|
| 657 |
-
|
| 658 |
-
context.decodeAudioData(
|
| 659 |
-
buf.buffer,
|
| 660 |
-
function (audioBuffer) {
|
| 661 |
-
var offlineContext = new OfflineAudioContext(
|
| 662 |
-
audioBuffer.numberOfChannels,
|
| 663 |
-
audioBuffer.length,
|
| 664 |
-
audioBuffer.sampleRate
|
| 665 |
-
);
|
| 666 |
-
var source = offlineContext.createBufferSource();
|
| 667 |
-
source.buffer = audioBuffer;
|
| 668 |
-
source.connect(offlineContext.destination);
|
| 669 |
-
source.start(0);
|
| 670 |
-
|
| 671 |
-
offlineContext.startRendering().then(function (renderedBuffer) {
|
| 672 |
-
audio = renderedBuffer.getChannelData(0);
|
| 673 |
-
printTextarea("js: audio loaded, size: " + audio.length);
|
| 674 |
-
|
| 675 |
-
// truncate to first 30 seconds
|
| 676 |
-
if (audio.length > kMaxAudio_s * kSampleRate) {
|
| 677 |
-
audio = audio.slice(0, kMaxAudio_s * kSampleRate);
|
| 678 |
-
printTextarea(
|
| 679 |
-
"js: truncated audio to first " + kMaxAudio_s + " seconds"
|
| 680 |
-
);
|
| 681 |
}
|
|
|
|
| 682 |
|
| 683 |
-
|
| 684 |
-
|
| 685 |
-
},
|
| 686 |
-
function (e) {
|
| 687 |
-
printTextarea("js: error decoding audio: " + e);
|
| 688 |
-
audio = null;
|
| 689 |
-
setAudio(audio);
|
| 690 |
}
|
| 691 |
-
|
| 692 |
-
|
| 693 |
-
|
| 694 |
-
|
| 695 |
-
|
| 696 |
-
|
| 697 |
-
|
| 698 |
-
|
| 699 |
-
|
| 700 |
-
|
| 701 |
-
|
| 702 |
-
|
| 703 |
-
|
| 704 |
-
|
| 705 |
-
|
| 706 |
-
|
| 707 |
-
|
| 708 |
-
|
| 709 |
-
|
| 710 |
-
|
| 711 |
-
|
| 712 |
-
|
| 713 |
-
|
| 714 |
-
|
| 715 |
-
|
| 716 |
-
|
| 717 |
-
|
| 718 |
-
|
| 719 |
-
|
| 720 |
-
|
| 721 |
-
|
| 722 |
-
|
| 723 |
-
|
| 724 |
-
|
| 725 |
-
|
| 726 |
-
|
| 727 |
-
|
| 728 |
-
|
| 729 |
-
|
| 730 |
-
|
| 731 |
-
|
| 732 |
-
|
| 733 |
-
|
| 734 |
-
|
| 735 |
-
|
| 736 |
-
|
| 737 |
-
|
| 738 |
-
|
| 739 |
-
|
| 740 |
-
|
| 741 |
-
}
|
| 742 |
-
|
| 743 |
-
|
| 744 |
-
|
| 745 |
-
|
| 746 |
-
|
| 747 |
-
|
| 748 |
-
|
| 749 |
-
|
| 750 |
-
|
| 751 |
-
|
| 752 |
-
|
| 753 |
-
|
| 754 |
-
|
| 755 |
-
|
| 756 |
-
|
| 757 |
-
|
| 758 |
-
|
| 759 |
-
|
| 760 |
-
|
| 761 |
-
|
| 762 |
-
|
| 763 |
-
|
| 764 |
-
|
| 765 |
-
|
| 766 |
-
|
| 767 |
-
|
| 768 |
-
|
| 769 |
-
|
| 770 |
-
|
| 771 |
-
|
| 772 |
-
|
| 773 |
-
|
| 774 |
-
|
| 775 |
-
|
| 776 |
-
|
| 777 |
-
|
| 778 |
-
|
| 779 |
-
|
| 780 |
-
|
| 781 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 782 |
}
|
| 783 |
-
|
| 784 |
-
|
| 785 |
-
|
| 786 |
-
|
| 787 |
-
|
| 788 |
-
|
| 789 |
-
|
| 790 |
-
|
| 791 |
-
);
|
| 792 |
-
};
|
| 793 |
-
|
| 794 |
-
reader.readAsArrayBuffer(blob);
|
| 795 |
-
};
|
| 796 |
-
mediaRecorder.start();
|
| 797 |
-
})
|
| 798 |
-
.catch(function (err) {
|
| 799 |
-
printTextarea("js: error getting audio stream: " + err);
|
| 800 |
-
});
|
| 801 |
-
|
| 802 |
-
var interval = setInterval(function () {
|
| 803 |
-
if (!doRecording) {
|
| 804 |
-
clearInterval(interval);
|
| 805 |
-
mediaRecorder.stop();
|
| 806 |
-
stream.getTracks().forEach(function (track) {
|
| 807 |
-
track.stop();
|
| 808 |
-
});
|
| 809 |
-
}
|
| 810 |
-
|
| 811 |
-
document.getElementById("progress-bar").style.width =
|
| 812 |
-
(100 * (Date.now() - startTime)) / 1000 / kMaxRecording_s + "%";
|
| 813 |
-
document.getElementById("progress-text").innerHTML =
|
| 814 |
-
((100 * (Date.now() - startTime)) / 1000 / kMaxRecording_s).toFixed(
|
| 815 |
-
0
|
| 816 |
-
) + "%";
|
| 817 |
-
}, 1000);
|
| 818 |
-
|
| 819 |
-
printTextarea("js: recording ...");
|
| 820 |
-
|
| 821 |
-
setTimeout(function () {
|
| 822 |
-
if (doRecording) {
|
| 823 |
-
printTextarea(
|
| 824 |
-
"js: recording stopped after " + kMaxRecording_s + " seconds"
|
| 825 |
-
);
|
| 826 |
-
stopRecording();
|
| 827 |
-
}
|
| 828 |
-
}, kMaxRecording_s * 1000);
|
| 829 |
-
}
|
| 830 |
-
|
| 831 |
-
//
|
| 832 |
-
// transcribe
|
| 833 |
-
//
|
| 834 |
-
|
| 835 |
-
var nthreads = 8;
|
| 836 |
-
|
| 837 |
-
function changeThreads(value) {
|
| 838 |
-
nthreads = value;
|
| 839 |
-
document.getElementById("threads-value").innerHTML = nthreads;
|
| 840 |
-
}
|
| 841 |
-
|
| 842 |
-
function onProcess(translate) {
|
| 843 |
-
if (!instance) {
|
| 844 |
-
instance = Module.init("whisper.bin");
|
| 845 |
-
|
| 846 |
-
if (instance) {
|
| 847 |
-
printTextarea("js: whisper initialized, instance: " + instance);
|
| 848 |
-
document.getElementById("model").innerHTML =
|
| 849 |
-
"Model loaded: " + model_whisper;
|
| 850 |
-
}
|
| 851 |
-
}
|
| 852 |
-
|
| 853 |
-
if (!instance) {
|
| 854 |
-
printTextarea("js: failed to initialize whisper");
|
| 855 |
-
return;
|
| 856 |
-
}
|
| 857 |
-
|
| 858 |
-
if (!audio) {
|
| 859 |
-
printTextarea("js: no audio data");
|
| 860 |
-
return;
|
| 861 |
-
}
|
| 862 |
-
|
| 863 |
-
if (instance) {
|
| 864 |
-
printTextarea("");
|
| 865 |
-
printTextarea("js: processing - this might take a while ...");
|
| 866 |
-
printTextarea("");
|
| 867 |
-
|
| 868 |
-
setTimeout(function () {
|
| 869 |
-
var ret = Module.full_default(
|
| 870 |
-
instance,
|
| 871 |
-
audio,
|
| 872 |
-
document.getElementById("language").value,
|
| 873 |
-
nthreads,
|
| 874 |
-
translate
|
| 875 |
-
);
|
| 876 |
-
console.log("js: full_default returned: " + ret);
|
| 877 |
-
if (ret) {
|
| 878 |
-
printTextarea("js: whisper returned: " + ret);
|
| 879 |
}
|
| 880 |
-
|
| 881 |
-
|
| 882 |
-
|
| 883 |
-
</
|
| 884 |
-
<script type="text/javascript" src="main.js"></script>
|
| 885 |
-
</body>
|
| 886 |
</html>
|
|
|
|
| 1 |
<!doctype html>
|
| 2 |
<html lang="en-us">
|
| 3 |
+
<head>
|
| 4 |
+
<title>wchess : voice-controlled chess using Whisper + WebAssembly</title>
|
| 5 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.1/iframeResizer.contentWindow.min.js"></script>
|
| 6 |
+
|
| 7 |
+
<meta name="viewport" content="width=device-width, initial-scale=0.4, maximum-scale=1, minimum-scale=1, user-scalable=no"/>
|
| 8 |
+
<meta name="apple-mobile-web-app-capable" content="yes" />
|
| 9 |
+
|
| 10 |
+
<style>
|
| 11 |
+
#output {
|
| 12 |
+
width: 100%;
|
| 13 |
+
height: 100%;
|
| 14 |
+
margin: 0 auto;
|
| 15 |
+
margin-top: 10px;
|
| 16 |
+
border-left: 0px;
|
| 17 |
+
border-right: 0px;
|
| 18 |
+
padding-left: 0px;
|
| 19 |
+
padding-right: 0px;
|
| 20 |
+
display: block;
|
| 21 |
+
background-color: black;
|
| 22 |
+
color: white;
|
| 23 |
+
font-size: 10px;
|
| 24 |
+
font-family: 'Lucida Console', Monaco, monospace;
|
| 25 |
+
outline: none;
|
| 26 |
+
white-space: pre;
|
| 27 |
+
overflow-wrap: normal;
|
| 28 |
+
overflow-x: scroll;
|
| 29 |
+
}
|
| 30 |
+
.button {
|
| 31 |
+
background-color: #000000;
|
| 32 |
+
color: #FFFFFF;
|
| 33 |
+
padding: 20px;
|
| 34 |
+
border-radius: 10px;
|
| 35 |
+
-moz-border-radius: 10px;
|
| 36 |
+
-webkit-border-radius: 10px;
|
| 37 |
+
margin:10px;
|
| 38 |
+
width: 100px;
|
| 39 |
+
height: 50px;
|
| 40 |
+
-webkit-touch-callout: none; /* Safari */
|
| 41 |
+
-webkit-user-select: none; /* Chrome */
|
| 42 |
+
-moz-user-select: none; /* Firefox */
|
| 43 |
+
-ms-user-select: none; /* Internet Explorer/Edge */
|
| 44 |
+
user-select: none;
|
| 45 |
+
}
|
| 46 |
+
.center {
|
| 47 |
+
display: flex;
|
| 48 |
+
justify-content: center;
|
| 49 |
+
align-items: center;
|
| 50 |
+
width: 300px;
|
| 51 |
+
}
|
| 52 |
+
</style>
|
| 53 |
+
<link rel="stylesheet" href="css/chessboard-1.0.0.min.css" integrity="sha384-q94+BZtLrkL1/ohfjR8c6L+A6qzNH9R2hBLwyoAfu3i/WCvQjzL2RQJ3uNHDISdU" crossorigin="anonymous">
|
| 54 |
+
</head>
|
| 55 |
+
<body onload="loadWhisper()">
|
| 56 |
+
<div id="main-container">
|
| 57 |
+
<b>wchess : voice-controlled chess using Whisper + WebAssembly</b>
|
| 58 |
+
|
| 59 |
+
<br><br>
|
| 60 |
+
|
| 61 |
+
This is a demonstration of using Whisper to recognize voice commands in the browser.
|
| 62 |
+
|
| 63 |
+
<br><br>
|
| 64 |
+
|
| 65 |
+
Usage:<br>
|
| 66 |
+
|
| 67 |
+
<ul>
|
| 68 |
+
<li>Hold the button and say a chess move (e.g. "e2-e4")</li>
|
| 69 |
+
<li>Release the button and wait for the move to be recognized</li>
|
| 70 |
+
<li>Repeat</li>
|
| 71 |
+
</ul>
|
| 72 |
+
|
| 73 |
+
Examples:<br>
|
| 74 |
+
|
| 75 |
+
<ul>
|
| 76 |
+
<li><b>"d4"</b></li>
|
| 77 |
+
<li><b>"e2 e4"</b></li>
|
| 78 |
+
<li><b>"Knight to f3"</b></li>
|
| 79 |
+
<li><b>"Bishop to b5"</b></li>
|
| 80 |
+
</ul>
|
| 81 |
+
|
| 82 |
+
Note that not all chess moves are supported. For example, castling and pawn promotion<br>
|
| 83 |
+
currently do not work, but can be easily implemented. The main purpose of this example<br>
|
| 84 |
+
is to demonstrate the capabilities of Whisper and it's application in the browser.
|
| 85 |
+
|
| 86 |
+
<br><br>
|
| 87 |
+
|
| 88 |
+
Features:<br>
|
| 89 |
+
|
| 90 |
+
<ul>
|
| 91 |
+
<li>Model quantization for reduced memory footprint (~42MB)</li>
|
| 92 |
+
<li><a href="https://github.com/ggerganov/whisper.cpp/pull/1229">Grammar-based sampling</a> for improved recognition accuracy</li>
|
| 93 |
+
</ul>
|
| 94 |
+
|
| 95 |
+
You can find more about this project on <a href="https://github.com/ggerganov/whisper.cpp/tree/master/examples/wchess">GitHub</a>.
|
| 96 |
+
|
| 97 |
+
<br><br>
|
| 98 |
+
|
| 99 |
+
<b>More examples:</b>
|
| 100 |
+
<a href="https://whisper.ggerganov.com/">main</a> |
|
| 101 |
+
<a href="https://whisper.ggerganov.com/bench">bench</a> |
|
| 102 |
+
<a href="https://whisper.ggerganov.com/stream">stream</a> |
|
| 103 |
+
<a href="https://whisper.ggerganov.com/command">command</a> |
|
| 104 |
+
<a href="https://whisper.ggerganov.com/talk">talk</a> |
|
| 105 |
+
|
| 106 |
+
<br><br>
|
| 107 |
+
|
| 108 |
+
<hr>
|
| 109 |
+
|
| 110 |
+
<div id="model-whisper">
|
| 111 |
+
Whisper model: <span id="model-whisper-status"></span>
|
| 112 |
+
<span id="fetch-whisper-progress"></span>
|
| 113 |
+
<br><br>
|
| 114 |
+
<button id="clear" onclick="clearCache()">Clear Cache</button>
|
| 115 |
+
<!--
|
| 116 |
+
<input type="file" id="file" name="file" onchange="loadFile(event, 'whisper.bin')" />
|
| 117 |
+
-->
|
| 118 |
+
</div>
|
| 119 |
+
|
| 120 |
+
<br>
|
| 121 |
+
<div id="chessboard" style="width: 300px"></div>
|
| 122 |
+
<script src="js/jquery-3.7.1.min.js"></script>
|
| 123 |
+
<script src="js/chessboard-1.0.0.min.js"></script>
|
| 124 |
+
<script>
|
| 125 |
+
var board = Chessboard('chessboard', 'start')
|
| 126 |
+
var move_count = 0;
|
| 127 |
+
</script>
|
| 128 |
+
|
| 129 |
+
<br>
|
| 130 |
+
|
| 131 |
+
<div id="input" class="center">
|
| 132 |
+
<button id="toggler" class="button" onselectstart="return false" disabled>Hold</button>
|
| 133 |
+
</div>
|
| 134 |
+
|
| 135 |
+
<br>
|
| 136 |
+
|
| 137 |
+
<div id="state">
|
| 138 |
+
Status: <b><span id="state-status">not started</span></b>
|
| 139 |
+
|
| 140 |
+
<pre id="state-moves">[The moves will be displayed here]</pre>
|
| 141 |
+
</div>
|
| 142 |
+
|
| 143 |
+
<hr>
|
| 144 |
+
|
| 145 |
+
Debug output:
|
| 146 |
+
<textarea id="output" rows="20"></textarea>
|
| 147 |
+
|
| 148 |
+
<br>
|
| 149 |
+
|
| 150 |
+
<b>Troubleshooting</b>
|
| 151 |
+
|
| 152 |
+
<br><br>
|
| 153 |
+
|
| 154 |
+
The page does some heavy computations, so make sure:
|
| 155 |
+
|
| 156 |
+
<ul>
|
| 157 |
+
<li>To use a modern web browser (e.g. Chrome, Firefox)</li>
|
| 158 |
+
<li>Your browser supports WASM <a href="https://webassembly.org/roadmap/">Fixed-width SIMD</a></li>
|
| 159 |
+
</ul>
|
| 160 |
+
|
| 161 |
+
<div class="cell-version">
|
| 162 |
+
<span>
|
| 163 |
+
|
|
| 164 |
+
Build time: <span class="nav-link">Fri Dec 8 10:03:41 2023</span> |
|
| 165 |
+
Commit hash: <a class="nav-link" href="https://github.com/ggerganov/whisper.cpp/commit/be5cd736">be5cd736</a> |
|
| 166 |
+
Commit subject: <span class="nav-link">wchess: touchstart, touchend events</span> |
|
| 167 |
+
<a class="nav-link" href="https://github.com/ggerganov/whisper.cpp/tree/master/examples/command.wasm">Source Code</a> |
|
| 168 |
+
</span>
|
| 169 |
+
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
</div>
|
| 171 |
+
|
| 172 |
+
<script type="text/javascript" src="js/helpers.js"></script>
|
| 173 |
+
<script type='text/javascript'>
|
| 174 |
+
// web audio context
|
| 175 |
+
var context = null;
|
| 176 |
+
|
| 177 |
+
// the command instance
|
| 178 |
+
var instance = null;
|
| 179 |
+
|
| 180 |
+
// model name
|
| 181 |
+
var model_whisper = null;
|
| 182 |
+
var model_file = null;
|
| 183 |
+
|
| 184 |
+
var module_ready = null;
|
| 185 |
+
|
| 186 |
+
var Module = {
|
| 187 |
+
print: printTextarea,
|
| 188 |
+
printErr: printTextarea,
|
| 189 |
+
setStatus: function(text) {
|
| 190 |
+
printTextarea('js: ' + text);
|
| 191 |
+
},
|
| 192 |
+
monitorRunDependencies: function(left) {
|
| 193 |
+
},
|
| 194 |
+
preRun: function() {
|
| 195 |
+
printTextarea('js: Preparing ...');
|
| 196 |
+
},
|
| 197 |
+
postRun: function() {
|
| 198 |
+
printTextarea('js: Module initialized successfully!');
|
| 199 |
+
module_ready = true;
|
| 200 |
+
initInstance();
|
| 201 |
+
}
|
| 202 |
+
};
|
| 203 |
+
|
| 204 |
+
function initInstance() {
|
| 205 |
+
if (!module_ready || !model_file || instance) return
|
| 206 |
+
|
| 207 |
+
instance = Module.init(model_file);
|
| 208 |
+
|
| 209 |
+
if (instance) {
|
| 210 |
+
document.getElementById('toggler').disabled = false;
|
| 211 |
+
setStatus('Ready');
|
| 212 |
+
printTextarea("js: whisper initialized, instance: " + instance);
|
| 213 |
+
}
|
| 214 |
+
else {
|
| 215 |
+
printTextarea("js: failed to initialize whisper");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 216 |
}
|
| 217 |
+
}
|
| 218 |
|
| 219 |
+
function setStatus(text) {
|
| 220 |
+
document.getElementById('state-status').innerHTML = text;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 221 |
}
|
| 222 |
+
|
| 223 |
+
//
|
| 224 |
+
// fetch models
|
| 225 |
+
//
|
| 226 |
+
|
| 227 |
+
let dbVersion = 1
|
| 228 |
+
let dbName = 'whisper.ggerganov.com';
|
| 229 |
+
let indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB
|
| 230 |
+
|
| 231 |
+
function storeFS(fname, buf) {
|
| 232 |
+
// write to WASM file using FS_createDataFile
|
| 233 |
+
// if the file exists, delete it
|
| 234 |
+
try {
|
| 235 |
+
Module.FS_unlink(fname);
|
| 236 |
+
} catch (e) {
|
| 237 |
+
// ignore
|
| 238 |
+
}
|
| 239 |
+
|
| 240 |
+
Module.FS_createDataFile("/", fname, buf, true, true);
|
| 241 |
+
|
| 242 |
+
printTextarea('storeFS: stored model: ' + fname + ' size: ' + buf.length);
|
| 243 |
+
|
| 244 |
+
document.getElementById('model-whisper-status').innerHTML = 'loaded "' + model_whisper + '"!';
|
| 245 |
+
|
| 246 |
+
model_file = fname;
|
| 247 |
+
initInstance();
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
function loadWhisper() {
|
| 251 |
+
setStatus('Loading')
|
| 252 |
+
//let url = 'https://whisper.ggerganov.com/ggml-model-whisper-tiny.en-q8_0.bin';
|
| 253 |
+
let url = 'https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en-q8_0.bin';
|
| 254 |
+
let dst = 'whisper.bin';
|
| 255 |
+
let size_mb = 42;
|
| 256 |
+
|
| 257 |
+
model_whisper = 'tiny.en-q8_0';
|
| 258 |
+
|
| 259 |
+
document.getElementById('model-whisper-status').innerHTML = 'loading "' + model_whisper + '" ... ';
|
| 260 |
+
|
| 261 |
+
cbProgress = function(p) {
|
| 262 |
+
let el = document.getElementById('fetch-whisper-progress');
|
| 263 |
+
el.innerHTML = Math.round(100*p) + '%';
|
| 264 |
+
};
|
| 265 |
+
|
| 266 |
+
cbCancel = function() {
|
| 267 |
+
var el;
|
| 268 |
+
el = document.getElementById('model-whisper-status'); if (el) el.innerHTML = '';
|
| 269 |
+
};
|
| 270 |
+
|
| 271 |
+
loadRemote(url, dst, size_mb, cbProgress, storeFS, cbCancel, printTextarea);
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
//
|
| 275 |
+
// microphone
|
| 276 |
+
//
|
| 277 |
+
|
| 278 |
+
const kSampleRate = 16000;
|
| 279 |
+
const kRestartRecording_s = 120;
|
| 280 |
+
const kIntervalAudio_ms = 250; // pass the recorded audio to the C++ instance at this rate
|
| 281 |
+
|
| 282 |
+
var mediaRecorder = null;
|
| 283 |
+
var doRecording = false;
|
| 284 |
+
var startTime = 0;
|
| 285 |
+
|
| 286 |
+
window.AudioContext = window.AudioContext || window.webkitAudioContext;
|
| 287 |
+
window.OfflineAudioContext = window.OfflineAudioContext || window.webkitOfflineAudioContext;
|
| 288 |
+
|
| 289 |
+
function stopRecording() {
|
| 290 |
+
mediaRecorder.stop();
|
| 291 |
+
}
|
| 292 |
+
|
| 293 |
+
function startRecording() {
|
| 294 |
+
if (!context) {
|
| 295 |
+
context = new AudioContext({
|
| 296 |
+
sampleRate: kSampleRate,
|
| 297 |
+
channelCount: 1,
|
| 298 |
+
echoCancellation: false,
|
| 299 |
+
autoGainControl: true,
|
| 300 |
+
noiseSuppression: true,
|
| 301 |
+
});
|
| 302 |
+
}
|
| 303 |
+
|
| 304 |
+
startTime = Date.now();
|
| 305 |
+
|
| 306 |
+
var chunks = [];
|
| 307 |
+
var stream = null;
|
| 308 |
+
|
| 309 |
+
navigator.mediaDevices.getUserMedia({audio: true, video: false})
|
| 310 |
+
.then(function(s) {
|
| 311 |
+
stream = s;
|
| 312 |
+
mediaRecorder = new MediaRecorder(stream);
|
| 313 |
+
mediaRecorder.ondataavailable = function(e) {
|
| 314 |
+
chunks.push(e.data);
|
| 315 |
+
|
| 316 |
+
var blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
|
| 317 |
+
var reader = new FileReader();
|
| 318 |
+
|
| 319 |
+
reader.onload = function(event) {
|
| 320 |
+
var buf = new Uint8Array(reader.result);
|
| 321 |
+
context.decodeAudioData(buf.buffer, function(audioBuffer) {
|
| 322 |
+
var offlineContext = new OfflineAudioContext(audioBuffer.numberOfChannels, audioBuffer.length, audioBuffer.sampleRate);
|
| 323 |
+
var source = offlineContext.createBufferSource();
|
| 324 |
+
source.buffer = audioBuffer;
|
| 325 |
+
source.connect(offlineContext.destination);
|
| 326 |
+
source.start(0);
|
| 327 |
+
|
| 328 |
+
offlineContext.startRendering().then(function(renderedBuffer) {
|
| 329 |
+
let audio = renderedBuffer.getChannelData(0);
|
| 330 |
+
printTextarea('js: number of samples: ' + audio.length);
|
| 331 |
+
Module.set_audio(instance, audio);
|
| 332 |
+
});
|
| 333 |
+
|
| 334 |
+
mediaRecorder = null;
|
| 335 |
+
context = null;
|
| 336 |
+
});
|
| 337 |
+
}
|
| 338 |
+
|
| 339 |
+
reader.readAsArrayBuffer(blob);
|
| 340 |
+
};
|
| 341 |
+
|
| 342 |
+
mediaRecorder.onstop = function(e) {
|
| 343 |
+
stream.getTracks().forEach(function(track) {
|
| 344 |
+
track.stop();
|
| 345 |
+
});
|
| 346 |
+
};
|
| 347 |
+
|
| 348 |
+
mediaRecorder.start();
|
| 349 |
+
})
|
| 350 |
+
.catch(function(err) {
|
| 351 |
+
printTextarea('js: error getting audio stream: ' + err);
|
| 352 |
+
});
|
| 353 |
+
}
|
| 354 |
+
|
| 355 |
+
//
|
| 356 |
+
// main
|
| 357 |
+
//
|
| 358 |
+
|
| 359 |
+
var nLines = 0;
|
| 360 |
+
var movesAll = '';
|
| 361 |
+
|
| 362 |
+
// document.body.addEventListener('keydown', function(event) {
|
| 363 |
+
// if (event.keyCode === 32) {
|
| 364 |
+
// document.getElementById('toggler').innerText = "";
|
| 365 |
+
// onStart();
|
| 366 |
+
// }
|
| 367 |
+
// }, true);
|
| 368 |
+
|
| 369 |
+
// document.body.addEventListener('keyup', function(event) {
|
| 370 |
+
// if (event.keyCode === 32) {
|
| 371 |
+
// document.getElementById('toggler').innerText = "Hold";
|
| 372 |
+
// onStop();
|
| 373 |
+
// }
|
| 374 |
+
// }, true);
|
| 375 |
+
|
| 376 |
+
document.getElementById('toggler').addEventListener("touchstart", function(event){
|
| 377 |
+
this.innerText = "";
|
| 378 |
+
onStart();
|
| 379 |
+
}, true);
|
| 380 |
+
|
| 381 |
+
document.getElementById('toggler').addEventListener("touchend", function(event){
|
| 382 |
+
this.innerText = "Hold";
|
| 383 |
+
onStop();
|
| 384 |
+
}, true)
|
| 385 |
+
|
| 386 |
+
document.getElementById('toggler').addEventListener('mousedown', function(event) {
|
| 387 |
+
this.innerText = "";
|
| 388 |
+
onStart();
|
| 389 |
+
}, true);
|
| 390 |
+
|
| 391 |
+
document.getElementById('toggler').addEventListener('mouseup', function(event) {
|
| 392 |
+
this.innerText = "Hold";
|
| 393 |
+
onStop();
|
| 394 |
+
}, true);
|
| 395 |
+
|
| 396 |
+
function onStart() {
|
| 397 |
+
if (!instance) return;
|
| 398 |
+
setStatus('Listening');
|
| 399 |
+
|
| 400 |
+
startRecording();
|
| 401 |
+
}
|
| 402 |
+
|
| 403 |
+
function onStop() {
|
| 404 |
+
setStatus('Processing');
|
| 405 |
+
printTextarea('js: stopping recording ...');
|
| 406 |
+
stopRecording();
|
| 407 |
+
}
|
| 408 |
+
|
| 409 |
+
function setMove(move, prob) {
|
| 410 |
+
if (move != null && move.length > 1) {
|
| 411 |
+
let gameOver = move[move.length - 1] === '#';
|
| 412 |
+
if (gameOver) {
|
| 413 |
+
move = move.substring(0, move.length - 1);
|
| 414 |
+
document.getElementById('toggler').disabled = true;
|
| 415 |
+
}
|
| 416 |
+
board.move(move);
|
| 417 |
+
|
| 418 |
+
movesAll += move + ', prob = ' + prob.toFixed(2) + '% <br>';
|
| 419 |
+
nLines++;
|
| 420 |
+
|
| 421 |
+
// if more than 10 lines, remove the first line
|
| 422 |
+
if (nLines > 10) {
|
| 423 |
+
var i = movesAll.indexOf('<br>');
|
| 424 |
+
if (i > 0) {
|
| 425 |
+
movesAll = movesAll.substring(i + 4);
|
| 426 |
+
nLines--;
|
| 427 |
}
|
| 428 |
+
}
|
| 429 |
+
++move_count;
|
| 430 |
+
setStatus(gameOver ? 'Done' : move_count % 2 ? 'Black\'s turn' : 'White\'s turn');
|
| 431 |
+
document.getElementById('state-moves').innerHTML = movesAll;
|
| 432 |
+
}
|
| 433 |
+
else {
|
| 434 |
+
setStatus('Failed. ' + (move_count % 2 ? 'Black\'s turn' : 'White\'s turn'));
|
| 435 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 436 |
}
|
| 437 |
+
|
| 438 |
+
</script>
|
| 439 |
+
<script type="text/javascript" src="js/chess.js"></script>
|
| 440 |
+
</body>
|
|
|
|
|
|
|
| 441 |
</html>
|
js/chess.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
js/chessboard-1.0.0.js
ADDED
|
@@ -0,0 +1,1817 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// chessboard.js v1.0.0
|
| 2 |
+
// https://github.com/oakmac/chessboardjs/
|
| 3 |
+
//
|
| 4 |
+
// Copyright (c) 2019, Chris Oakman
|
| 5 |
+
// Released under the MIT license
|
| 6 |
+
// https://github.com/oakmac/chessboardjs/blob/master/LICENSE.md
|
| 7 |
+
|
| 8 |
+
// start anonymous scope
|
| 9 |
+
;(function () {
|
| 10 |
+
'use strict'
|
| 11 |
+
|
| 12 |
+
var $ = window['jQuery']
|
| 13 |
+
|
| 14 |
+
// ---------------------------------------------------------------------------
|
| 15 |
+
// Constants
|
| 16 |
+
// ---------------------------------------------------------------------------
|
| 17 |
+
|
| 18 |
+
var COLUMNS = 'abcdefgh'.split('')
|
| 19 |
+
var DEFAULT_DRAG_THROTTLE_RATE = 20
|
| 20 |
+
var ELLIPSIS = '…'
|
| 21 |
+
var MINIMUM_JQUERY_VERSION = '1.8.3'
|
| 22 |
+
var RUN_ASSERTS = false
|
| 23 |
+
var START_FEN = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR'
|
| 24 |
+
var START_POSITION = fenToObj(START_FEN)
|
| 25 |
+
|
| 26 |
+
// default animation speeds
|
| 27 |
+
var DEFAULT_APPEAR_SPEED = 200
|
| 28 |
+
var DEFAULT_MOVE_SPEED = 200
|
| 29 |
+
var DEFAULT_SNAPBACK_SPEED = 60
|
| 30 |
+
var DEFAULT_SNAP_SPEED = 30
|
| 31 |
+
var DEFAULT_TRASH_SPEED = 100
|
| 32 |
+
|
| 33 |
+
// use unique class names to prevent clashing with anything else on the page
|
| 34 |
+
// and simplify selectors
|
| 35 |
+
// NOTE: these should never change
|
| 36 |
+
var CSS = {}
|
| 37 |
+
CSS['alpha'] = 'alpha-d2270'
|
| 38 |
+
CSS['black'] = 'black-3c85d'
|
| 39 |
+
CSS['board'] = 'board-b72b1'
|
| 40 |
+
CSS['chessboard'] = 'chessboard-63f37'
|
| 41 |
+
CSS['clearfix'] = 'clearfix-7da63'
|
| 42 |
+
CSS['highlight1'] = 'highlight1-32417'
|
| 43 |
+
CSS['highlight2'] = 'highlight2-9c5d2'
|
| 44 |
+
CSS['notation'] = 'notation-322f9'
|
| 45 |
+
CSS['numeric'] = 'numeric-fc462'
|
| 46 |
+
CSS['piece'] = 'piece-417db'
|
| 47 |
+
CSS['row'] = 'row-5277c'
|
| 48 |
+
CSS['sparePieces'] = 'spare-pieces-7492f'
|
| 49 |
+
CSS['sparePiecesBottom'] = 'spare-pieces-bottom-ae20f'
|
| 50 |
+
CSS['sparePiecesTop'] = 'spare-pieces-top-4028b'
|
| 51 |
+
CSS['square'] = 'square-55d63'
|
| 52 |
+
CSS['white'] = 'white-1e1d7'
|
| 53 |
+
|
| 54 |
+
// ---------------------------------------------------------------------------
|
| 55 |
+
// Misc Util Functions
|
| 56 |
+
// ---------------------------------------------------------------------------
|
| 57 |
+
|
| 58 |
+
function throttle (f, interval, scope) {
|
| 59 |
+
var timeout = 0
|
| 60 |
+
var shouldFire = false
|
| 61 |
+
var args = []
|
| 62 |
+
|
| 63 |
+
var handleTimeout = function () {
|
| 64 |
+
timeout = 0
|
| 65 |
+
if (shouldFire) {
|
| 66 |
+
shouldFire = false
|
| 67 |
+
fire()
|
| 68 |
+
}
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
var fire = function () {
|
| 72 |
+
timeout = window.setTimeout(handleTimeout, interval)
|
| 73 |
+
f.apply(scope, args)
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
return function (_args) {
|
| 77 |
+
args = arguments
|
| 78 |
+
if (!timeout) {
|
| 79 |
+
fire()
|
| 80 |
+
} else {
|
| 81 |
+
shouldFire = true
|
| 82 |
+
}
|
| 83 |
+
}
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
// function debounce (f, interval, scope) {
|
| 87 |
+
// var timeout = 0
|
| 88 |
+
// return function (_args) {
|
| 89 |
+
// window.clearTimeout(timeout)
|
| 90 |
+
// var args = arguments
|
| 91 |
+
// timeout = window.setTimeout(function () {
|
| 92 |
+
// f.apply(scope, args)
|
| 93 |
+
// }, interval)
|
| 94 |
+
// }
|
| 95 |
+
// }
|
| 96 |
+
|
| 97 |
+
function uuid () {
|
| 98 |
+
return 'xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx'.replace(/x/g, function (c) {
|
| 99 |
+
var r = (Math.random() * 16) | 0
|
| 100 |
+
return r.toString(16)
|
| 101 |
+
})
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
function deepCopy (thing) {
|
| 105 |
+
return JSON.parse(JSON.stringify(thing))
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
function parseSemVer (version) {
|
| 109 |
+
var tmp = version.split('.')
|
| 110 |
+
return {
|
| 111 |
+
major: parseInt(tmp[0], 10),
|
| 112 |
+
minor: parseInt(tmp[1], 10),
|
| 113 |
+
patch: parseInt(tmp[2], 10)
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
// returns true if version is >= minimum
|
| 118 |
+
function validSemanticVersion (version, minimum) {
|
| 119 |
+
version = parseSemVer(version)
|
| 120 |
+
minimum = parseSemVer(minimum)
|
| 121 |
+
|
| 122 |
+
var versionNum = (version.major * 100000 * 100000) +
|
| 123 |
+
(version.minor * 100000) +
|
| 124 |
+
version.patch
|
| 125 |
+
var minimumNum = (minimum.major * 100000 * 100000) +
|
| 126 |
+
(minimum.minor * 100000) +
|
| 127 |
+
minimum.patch
|
| 128 |
+
|
| 129 |
+
return versionNum >= minimumNum
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
function interpolateTemplate (str, obj) {
|
| 133 |
+
for (var key in obj) {
|
| 134 |
+
if (!obj.hasOwnProperty(key)) continue
|
| 135 |
+
var keyTemplateStr = '{' + key + '}'
|
| 136 |
+
var value = obj[key]
|
| 137 |
+
while (str.indexOf(keyTemplateStr) !== -1) {
|
| 138 |
+
str = str.replace(keyTemplateStr, value)
|
| 139 |
+
}
|
| 140 |
+
}
|
| 141 |
+
return str
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
if (RUN_ASSERTS) {
|
| 145 |
+
console.assert(interpolateTemplate('abc', {a: 'x'}) === 'abc')
|
| 146 |
+
console.assert(interpolateTemplate('{a}bc', {}) === '{a}bc')
|
| 147 |
+
console.assert(interpolateTemplate('{a}bc', {p: 'q'}) === '{a}bc')
|
| 148 |
+
console.assert(interpolateTemplate('{a}bc', {a: 'x'}) === 'xbc')
|
| 149 |
+
console.assert(interpolateTemplate('{a}bc{a}bc', {a: 'x'}) === 'xbcxbc')
|
| 150 |
+
console.assert(interpolateTemplate('{a}{a}{b}', {a: 'x', b: 'y'}) === 'xxy')
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
// ---------------------------------------------------------------------------
|
| 154 |
+
// Predicates
|
| 155 |
+
// ---------------------------------------------------------------------------
|
| 156 |
+
|
| 157 |
+
function isString (s) {
|
| 158 |
+
return typeof s === 'string'
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
function isFunction (f) {
|
| 162 |
+
return typeof f === 'function'
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
function isInteger (n) {
|
| 166 |
+
return typeof n === 'number' &&
|
| 167 |
+
isFinite(n) &&
|
| 168 |
+
Math.floor(n) === n
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
function validAnimationSpeed (speed) {
|
| 172 |
+
if (speed === 'fast' || speed === 'slow') return true
|
| 173 |
+
if (!isInteger(speed)) return false
|
| 174 |
+
return speed >= 0
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
function validThrottleRate (rate) {
|
| 178 |
+
return isInteger(rate) &&
|
| 179 |
+
rate >= 1
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
function validMove (move) {
|
| 183 |
+
// move should be a string
|
| 184 |
+
if (!isString(move)) return false
|
| 185 |
+
|
| 186 |
+
// move should be in the form of "e2-e4", "f6-d5"
|
| 187 |
+
var squares = move.split('-')
|
| 188 |
+
if (squares.length !== 2) return false
|
| 189 |
+
|
| 190 |
+
return validSquare(squares[0]) && validSquare(squares[1])
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
function validSquare (square) {
|
| 194 |
+
return isString(square) && square.search(/^[a-h][1-8]$/) !== -1
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
if (RUN_ASSERTS) {
|
| 198 |
+
console.assert(validSquare('a1'))
|
| 199 |
+
console.assert(validSquare('e2'))
|
| 200 |
+
console.assert(!validSquare('D2'))
|
| 201 |
+
console.assert(!validSquare('g9'))
|
| 202 |
+
console.assert(!validSquare('a'))
|
| 203 |
+
console.assert(!validSquare(true))
|
| 204 |
+
console.assert(!validSquare(null))
|
| 205 |
+
console.assert(!validSquare({}))
|
| 206 |
+
}
|
| 207 |
+
|
| 208 |
+
function validPieceCode (code) {
|
| 209 |
+
return isString(code) && code.search(/^[bw][KQRNBP]$/) !== -1
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
if (RUN_ASSERTS) {
|
| 213 |
+
console.assert(validPieceCode('bP'))
|
| 214 |
+
console.assert(validPieceCode('bK'))
|
| 215 |
+
console.assert(validPieceCode('wK'))
|
| 216 |
+
console.assert(validPieceCode('wR'))
|
| 217 |
+
console.assert(!validPieceCode('WR'))
|
| 218 |
+
console.assert(!validPieceCode('Wr'))
|
| 219 |
+
console.assert(!validPieceCode('a'))
|
| 220 |
+
console.assert(!validPieceCode(true))
|
| 221 |
+
console.assert(!validPieceCode(null))
|
| 222 |
+
console.assert(!validPieceCode({}))
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
+
function validFen (fen) {
|
| 226 |
+
if (!isString(fen)) return false
|
| 227 |
+
|
| 228 |
+
// cut off any move, castling, etc info from the end
|
| 229 |
+
// we're only interested in position information
|
| 230 |
+
fen = fen.replace(/ .+$/, '')
|
| 231 |
+
|
| 232 |
+
// expand the empty square numbers to just 1s
|
| 233 |
+
fen = expandFenEmptySquares(fen)
|
| 234 |
+
|
| 235 |
+
// FEN should be 8 sections separated by slashes
|
| 236 |
+
var chunks = fen.split('/')
|
| 237 |
+
if (chunks.length !== 8) return false
|
| 238 |
+
|
| 239 |
+
// check each section
|
| 240 |
+
for (var i = 0; i < 8; i++) {
|
| 241 |
+
if (chunks[i].length !== 8 ||
|
| 242 |
+
chunks[i].search(/[^kqrnbpKQRNBP1]/) !== -1) {
|
| 243 |
+
return false
|
| 244 |
+
}
|
| 245 |
+
}
|
| 246 |
+
|
| 247 |
+
return true
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
if (RUN_ASSERTS) {
|
| 251 |
+
console.assert(validFen(START_FEN))
|
| 252 |
+
console.assert(validFen('8/8/8/8/8/8/8/8'))
|
| 253 |
+
console.assert(validFen('r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R'))
|
| 254 |
+
console.assert(validFen('3r3r/1p4pp/2nb1k2/pP3p2/8/PB2PN2/p4PPP/R4RK1 b - - 0 1'))
|
| 255 |
+
console.assert(!validFen('3r3z/1p4pp/2nb1k2/pP3p2/8/PB2PN2/p4PPP/R4RK1 b - - 0 1'))
|
| 256 |
+
console.assert(!validFen('anbqkbnr/8/8/8/8/8/PPPPPPPP/8'))
|
| 257 |
+
console.assert(!validFen('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/'))
|
| 258 |
+
console.assert(!validFen('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBN'))
|
| 259 |
+
console.assert(!validFen('888888/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR'))
|
| 260 |
+
console.assert(!validFen('888888/pppppppp/74/8/8/8/PPPPPPPP/RNBQKBNR'))
|
| 261 |
+
console.assert(!validFen({}))
|
| 262 |
+
}
|
| 263 |
+
|
| 264 |
+
function validPositionObject (pos) {
|
| 265 |
+
if (!$.isPlainObject(pos)) return false
|
| 266 |
+
|
| 267 |
+
for (var i in pos) {
|
| 268 |
+
if (!pos.hasOwnProperty(i)) continue
|
| 269 |
+
|
| 270 |
+
if (!validSquare(i) || !validPieceCode(pos[i])) {
|
| 271 |
+
return false
|
| 272 |
+
}
|
| 273 |
+
}
|
| 274 |
+
|
| 275 |
+
return true
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
if (RUN_ASSERTS) {
|
| 279 |
+
console.assert(validPositionObject(START_POSITION))
|
| 280 |
+
console.assert(validPositionObject({}))
|
| 281 |
+
console.assert(validPositionObject({e2: 'wP'}))
|
| 282 |
+
console.assert(validPositionObject({e2: 'wP', d2: 'wP'}))
|
| 283 |
+
console.assert(!validPositionObject({e2: 'BP'}))
|
| 284 |
+
console.assert(!validPositionObject({y2: 'wP'}))
|
| 285 |
+
console.assert(!validPositionObject(null))
|
| 286 |
+
console.assert(!validPositionObject('start'))
|
| 287 |
+
console.assert(!validPositionObject(START_FEN))
|
| 288 |
+
}
|
| 289 |
+
|
| 290 |
+
function isTouchDevice () {
|
| 291 |
+
return 'ontouchstart' in document.documentElement
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
+
function validJQueryVersion () {
|
| 295 |
+
return typeof window.$ &&
|
| 296 |
+
$.fn &&
|
| 297 |
+
$.fn.jquery &&
|
| 298 |
+
validSemanticVersion($.fn.jquery, MINIMUM_JQUERY_VERSION)
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
// ---------------------------------------------------------------------------
|
| 302 |
+
// Chess Util Functions
|
| 303 |
+
// ---------------------------------------------------------------------------
|
| 304 |
+
|
| 305 |
+
// convert FEN piece code to bP, wK, etc
|
| 306 |
+
function fenToPieceCode (piece) {
|
| 307 |
+
// black piece
|
| 308 |
+
if (piece.toLowerCase() === piece) {
|
| 309 |
+
return 'b' + piece.toUpperCase()
|
| 310 |
+
}
|
| 311 |
+
|
| 312 |
+
// white piece
|
| 313 |
+
return 'w' + piece.toUpperCase()
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
+
// convert bP, wK, etc code to FEN structure
|
| 317 |
+
function pieceCodeToFen (piece) {
|
| 318 |
+
var pieceCodeLetters = piece.split('')
|
| 319 |
+
|
| 320 |
+
// white piece
|
| 321 |
+
if (pieceCodeLetters[0] === 'w') {
|
| 322 |
+
return pieceCodeLetters[1].toUpperCase()
|
| 323 |
+
}
|
| 324 |
+
|
| 325 |
+
// black piece
|
| 326 |
+
return pieceCodeLetters[1].toLowerCase()
|
| 327 |
+
}
|
| 328 |
+
|
| 329 |
+
// convert FEN string to position object
|
| 330 |
+
// returns false if the FEN string is invalid
|
| 331 |
+
function fenToObj (fen) {
|
| 332 |
+
if (!validFen(fen)) return false
|
| 333 |
+
|
| 334 |
+
// cut off any move, castling, etc info from the end
|
| 335 |
+
// we're only interested in position information
|
| 336 |
+
fen = fen.replace(/ .+$/, '')
|
| 337 |
+
|
| 338 |
+
var rows = fen.split('/')
|
| 339 |
+
var position = {}
|
| 340 |
+
|
| 341 |
+
var currentRow = 8
|
| 342 |
+
for (var i = 0; i < 8; i++) {
|
| 343 |
+
var row = rows[i].split('')
|
| 344 |
+
var colIdx = 0
|
| 345 |
+
|
| 346 |
+
// loop through each character in the FEN section
|
| 347 |
+
for (var j = 0; j < row.length; j++) {
|
| 348 |
+
// number / empty squares
|
| 349 |
+
if (row[j].search(/[1-8]/) !== -1) {
|
| 350 |
+
var numEmptySquares = parseInt(row[j], 10)
|
| 351 |
+
colIdx = colIdx + numEmptySquares
|
| 352 |
+
} else {
|
| 353 |
+
// piece
|
| 354 |
+
var square = COLUMNS[colIdx] + currentRow
|
| 355 |
+
position[square] = fenToPieceCode(row[j])
|
| 356 |
+
colIdx = colIdx + 1
|
| 357 |
+
}
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
currentRow = currentRow - 1
|
| 361 |
+
}
|
| 362 |
+
|
| 363 |
+
return position
|
| 364 |
+
}
|
| 365 |
+
|
| 366 |
+
// position object to FEN string
|
| 367 |
+
// returns false if the obj is not a valid position object
|
| 368 |
+
function objToFen (obj) {
|
| 369 |
+
if (!validPositionObject(obj)) return false
|
| 370 |
+
|
| 371 |
+
var fen = ''
|
| 372 |
+
|
| 373 |
+
var currentRow = 8
|
| 374 |
+
for (var i = 0; i < 8; i++) {
|
| 375 |
+
for (var j = 0; j < 8; j++) {
|
| 376 |
+
var square = COLUMNS[j] + currentRow
|
| 377 |
+
|
| 378 |
+
// piece exists
|
| 379 |
+
if (obj.hasOwnProperty(square)) {
|
| 380 |
+
fen = fen + pieceCodeToFen(obj[square])
|
| 381 |
+
} else {
|
| 382 |
+
// empty space
|
| 383 |
+
fen = fen + '1'
|
| 384 |
+
}
|
| 385 |
+
}
|
| 386 |
+
|
| 387 |
+
if (i !== 7) {
|
| 388 |
+
fen = fen + '/'
|
| 389 |
+
}
|
| 390 |
+
|
| 391 |
+
currentRow = currentRow - 1
|
| 392 |
+
}
|
| 393 |
+
|
| 394 |
+
// squeeze the empty numbers together
|
| 395 |
+
fen = squeezeFenEmptySquares(fen)
|
| 396 |
+
|
| 397 |
+
return fen
|
| 398 |
+
}
|
| 399 |
+
|
| 400 |
+
if (RUN_ASSERTS) {
|
| 401 |
+
console.assert(objToFen(START_POSITION) === START_FEN)
|
| 402 |
+
console.assert(objToFen({}) === '8/8/8/8/8/8/8/8')
|
| 403 |
+
console.assert(objToFen({a2: 'wP', 'b2': 'bP'}) === '8/8/8/8/8/8/Pp6/8')
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
function squeezeFenEmptySquares (fen) {
|
| 407 |
+
return fen.replace(/11111111/g, '8')
|
| 408 |
+
.replace(/1111111/g, '7')
|
| 409 |
+
.replace(/111111/g, '6')
|
| 410 |
+
.replace(/11111/g, '5')
|
| 411 |
+
.replace(/1111/g, '4')
|
| 412 |
+
.replace(/111/g, '3')
|
| 413 |
+
.replace(/11/g, '2')
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
function expandFenEmptySquares (fen) {
|
| 417 |
+
return fen.replace(/8/g, '11111111')
|
| 418 |
+
.replace(/7/g, '1111111')
|
| 419 |
+
.replace(/6/g, '111111')
|
| 420 |
+
.replace(/5/g, '11111')
|
| 421 |
+
.replace(/4/g, '1111')
|
| 422 |
+
.replace(/3/g, '111')
|
| 423 |
+
.replace(/2/g, '11')
|
| 424 |
+
}
|
| 425 |
+
|
| 426 |
+
// returns the distance between two squares
|
| 427 |
+
function squareDistance (squareA, squareB) {
|
| 428 |
+
var squareAArray = squareA.split('')
|
| 429 |
+
var squareAx = COLUMNS.indexOf(squareAArray[0]) + 1
|
| 430 |
+
var squareAy = parseInt(squareAArray[1], 10)
|
| 431 |
+
|
| 432 |
+
var squareBArray = squareB.split('')
|
| 433 |
+
var squareBx = COLUMNS.indexOf(squareBArray[0]) + 1
|
| 434 |
+
var squareBy = parseInt(squareBArray[1], 10)
|
| 435 |
+
|
| 436 |
+
var xDelta = Math.abs(squareAx - squareBx)
|
| 437 |
+
var yDelta = Math.abs(squareAy - squareBy)
|
| 438 |
+
|
| 439 |
+
if (xDelta >= yDelta) return xDelta
|
| 440 |
+
return yDelta
|
| 441 |
+
}
|
| 442 |
+
|
| 443 |
+
// returns the square of the closest instance of piece
|
| 444 |
+
// returns false if no instance of piece is found in position
|
| 445 |
+
function findClosestPiece (position, piece, square) {
|
| 446 |
+
// create array of closest squares from square
|
| 447 |
+
var closestSquares = createRadius(square)
|
| 448 |
+
|
| 449 |
+
// search through the position in order of distance for the piece
|
| 450 |
+
for (var i = 0; i < closestSquares.length; i++) {
|
| 451 |
+
var s = closestSquares[i]
|
| 452 |
+
|
| 453 |
+
if (position.hasOwnProperty(s) && position[s] === piece) {
|
| 454 |
+
return s
|
| 455 |
+
}
|
| 456 |
+
}
|
| 457 |
+
|
| 458 |
+
return false
|
| 459 |
+
}
|
| 460 |
+
|
| 461 |
+
// returns an array of closest squares from square
|
| 462 |
+
function createRadius (square) {
|
| 463 |
+
var squares = []
|
| 464 |
+
|
| 465 |
+
// calculate distance of all squares
|
| 466 |
+
for (var i = 0; i < 8; i++) {
|
| 467 |
+
for (var j = 0; j < 8; j++) {
|
| 468 |
+
var s = COLUMNS[i] + (j + 1)
|
| 469 |
+
|
| 470 |
+
// skip the square we're starting from
|
| 471 |
+
if (square === s) continue
|
| 472 |
+
|
| 473 |
+
squares.push({
|
| 474 |
+
square: s,
|
| 475 |
+
distance: squareDistance(square, s)
|
| 476 |
+
})
|
| 477 |
+
}
|
| 478 |
+
}
|
| 479 |
+
|
| 480 |
+
// sort by distance
|
| 481 |
+
squares.sort(function (a, b) {
|
| 482 |
+
return a.distance - b.distance
|
| 483 |
+
})
|
| 484 |
+
|
| 485 |
+
// just return the square code
|
| 486 |
+
var surroundingSquares = []
|
| 487 |
+
for (i = 0; i < squares.length; i++) {
|
| 488 |
+
surroundingSquares.push(squares[i].square)
|
| 489 |
+
}
|
| 490 |
+
|
| 491 |
+
return surroundingSquares
|
| 492 |
+
}
|
| 493 |
+
|
| 494 |
+
// given a position and a set of moves, return a new position
|
| 495 |
+
// with the moves executed
|
| 496 |
+
function calculatePositionFromMoves (position, moves) {
|
| 497 |
+
var newPosition = deepCopy(position)
|
| 498 |
+
|
| 499 |
+
for (var i in moves) {
|
| 500 |
+
if (!moves.hasOwnProperty(i)) continue
|
| 501 |
+
|
| 502 |
+
// skip the move if the position doesn't have a piece on the source square
|
| 503 |
+
if (!newPosition.hasOwnProperty(i)) continue
|
| 504 |
+
|
| 505 |
+
var piece = newPosition[i]
|
| 506 |
+
delete newPosition[i]
|
| 507 |
+
newPosition[moves[i]] = piece
|
| 508 |
+
}
|
| 509 |
+
|
| 510 |
+
return newPosition
|
| 511 |
+
}
|
| 512 |
+
|
| 513 |
+
// TODO: add some asserts here for calculatePositionFromMoves
|
| 514 |
+
|
| 515 |
+
// ---------------------------------------------------------------------------
|
| 516 |
+
// HTML
|
| 517 |
+
// ---------------------------------------------------------------------------
|
| 518 |
+
|
| 519 |
+
function buildContainerHTML (hasSparePieces) {
|
| 520 |
+
var html = '<div class="{chessboard}">'
|
| 521 |
+
|
| 522 |
+
if (hasSparePieces) {
|
| 523 |
+
html += '<div class="{sparePieces} {sparePiecesTop}"></div>'
|
| 524 |
+
}
|
| 525 |
+
|
| 526 |
+
html += '<div class="{board}"></div>'
|
| 527 |
+
|
| 528 |
+
if (hasSparePieces) {
|
| 529 |
+
html += '<div class="{sparePieces} {sparePiecesBottom}"></div>'
|
| 530 |
+
}
|
| 531 |
+
|
| 532 |
+
html += '</div>'
|
| 533 |
+
|
| 534 |
+
return interpolateTemplate(html, CSS)
|
| 535 |
+
}
|
| 536 |
+
|
| 537 |
+
// ---------------------------------------------------------------------------
|
| 538 |
+
// Config
|
| 539 |
+
// ---------------------------------------------------------------------------
|
| 540 |
+
|
| 541 |
+
function expandConfigArgumentShorthand (config) {
|
| 542 |
+
if (config === 'start') {
|
| 543 |
+
config = {position: deepCopy(START_POSITION)}
|
| 544 |
+
} else if (validFen(config)) {
|
| 545 |
+
config = {position: fenToObj(config)}
|
| 546 |
+
} else if (validPositionObject(config)) {
|
| 547 |
+
config = {position: deepCopy(config)}
|
| 548 |
+
}
|
| 549 |
+
|
| 550 |
+
// config must be an object
|
| 551 |
+
if (!$.isPlainObject(config)) config = {}
|
| 552 |
+
|
| 553 |
+
return config
|
| 554 |
+
}
|
| 555 |
+
|
| 556 |
+
// validate config / set default options
|
| 557 |
+
function expandConfig (config) {
|
| 558 |
+
// default for orientation is white
|
| 559 |
+
if (config.orientation !== 'black') config.orientation = 'white'
|
| 560 |
+
|
| 561 |
+
// default for showNotation is true
|
| 562 |
+
if (config.showNotation !== false) config.showNotation = true
|
| 563 |
+
|
| 564 |
+
// default for draggable is false
|
| 565 |
+
if (config.draggable !== true) config.draggable = false
|
| 566 |
+
|
| 567 |
+
// default for dropOffBoard is 'snapback'
|
| 568 |
+
if (config.dropOffBoard !== 'trash') config.dropOffBoard = 'snapback'
|
| 569 |
+
|
| 570 |
+
// default for sparePieces is false
|
| 571 |
+
if (config.sparePieces !== true) config.sparePieces = false
|
| 572 |
+
|
| 573 |
+
// draggable must be true if sparePieces is enabled
|
| 574 |
+
if (config.sparePieces) config.draggable = true
|
| 575 |
+
|
| 576 |
+
// default piece theme is wikipedia
|
| 577 |
+
if (!config.hasOwnProperty('pieceTheme') ||
|
| 578 |
+
(!isString(config.pieceTheme) && !isFunction(config.pieceTheme))) {
|
| 579 |
+
config.pieceTheme = 'img/chesspieces/wikipedia/{piece}.png'
|
| 580 |
+
}
|
| 581 |
+
|
| 582 |
+
// animation speeds
|
| 583 |
+
if (!validAnimationSpeed(config.appearSpeed)) config.appearSpeed = DEFAULT_APPEAR_SPEED
|
| 584 |
+
if (!validAnimationSpeed(config.moveSpeed)) config.moveSpeed = DEFAULT_MOVE_SPEED
|
| 585 |
+
if (!validAnimationSpeed(config.snapbackSpeed)) config.snapbackSpeed = DEFAULT_SNAPBACK_SPEED
|
| 586 |
+
if (!validAnimationSpeed(config.snapSpeed)) config.snapSpeed = DEFAULT_SNAP_SPEED
|
| 587 |
+
if (!validAnimationSpeed(config.trashSpeed)) config.trashSpeed = DEFAULT_TRASH_SPEED
|
| 588 |
+
|
| 589 |
+
// throttle rate
|
| 590 |
+
if (!validThrottleRate(config.dragThrottleRate)) config.dragThrottleRate = DEFAULT_DRAG_THROTTLE_RATE
|
| 591 |
+
|
| 592 |
+
return config
|
| 593 |
+
}
|
| 594 |
+
|
| 595 |
+
// ---------------------------------------------------------------------------
|
| 596 |
+
// Dependencies
|
| 597 |
+
// ---------------------------------------------------------------------------
|
| 598 |
+
|
| 599 |
+
// check for a compatible version of jQuery
|
| 600 |
+
function checkJQuery () {
|
| 601 |
+
if (!validJQueryVersion()) {
|
| 602 |
+
var errorMsg = 'Chessboard Error 1005: Unable to find a valid version of jQuery. ' +
|
| 603 |
+
'Please include jQuery ' + MINIMUM_JQUERY_VERSION + ' or higher on the page' +
|
| 604 |
+
'\n\n' +
|
| 605 |
+
'Exiting' + ELLIPSIS
|
| 606 |
+
window.alert(errorMsg)
|
| 607 |
+
return false
|
| 608 |
+
}
|
| 609 |
+
|
| 610 |
+
return true
|
| 611 |
+
}
|
| 612 |
+
|
| 613 |
+
// return either boolean false or the $container element
|
| 614 |
+
function checkContainerArg (containerElOrString) {
|
| 615 |
+
if (containerElOrString === '') {
|
| 616 |
+
var errorMsg1 = 'Chessboard Error 1001: ' +
|
| 617 |
+
'The first argument to Chessboard() cannot be an empty string.' +
|
| 618 |
+
'\n\n' +
|
| 619 |
+
'Exiting' + ELLIPSIS
|
| 620 |
+
window.alert(errorMsg1)
|
| 621 |
+
return false
|
| 622 |
+
}
|
| 623 |
+
|
| 624 |
+
// convert containerEl to query selector if it is a string
|
| 625 |
+
if (isString(containerElOrString) &&
|
| 626 |
+
containerElOrString.charAt(0) !== '#') {
|
| 627 |
+
containerElOrString = '#' + containerElOrString
|
| 628 |
+
}
|
| 629 |
+
|
| 630 |
+
// containerEl must be something that becomes a jQuery collection of size 1
|
| 631 |
+
var $container = $(containerElOrString)
|
| 632 |
+
if ($container.length !== 1) {
|
| 633 |
+
var errorMsg2 = 'Chessboard Error 1003: ' +
|
| 634 |
+
'The first argument to Chessboard() must be the ID of a DOM node, ' +
|
| 635 |
+
'an ID query selector, or a single DOM node.' +
|
| 636 |
+
'\n\n' +
|
| 637 |
+
'Exiting' + ELLIPSIS
|
| 638 |
+
window.alert(errorMsg2)
|
| 639 |
+
return false
|
| 640 |
+
}
|
| 641 |
+
|
| 642 |
+
return $container
|
| 643 |
+
}
|
| 644 |
+
|
| 645 |
+
// ---------------------------------------------------------------------------
|
| 646 |
+
// Constructor
|
| 647 |
+
// ---------------------------------------------------------------------------
|
| 648 |
+
|
| 649 |
+
function constructor (containerElOrString, config) {
|
| 650 |
+
// first things first: check basic dependencies
|
| 651 |
+
if (!checkJQuery()) return null
|
| 652 |
+
var $container = checkContainerArg(containerElOrString)
|
| 653 |
+
if (!$container) return null
|
| 654 |
+
|
| 655 |
+
// ensure the config object is what we expect
|
| 656 |
+
config = expandConfigArgumentShorthand(config)
|
| 657 |
+
config = expandConfig(config)
|
| 658 |
+
|
| 659 |
+
// DOM elements
|
| 660 |
+
var $board = null
|
| 661 |
+
var $draggedPiece = null
|
| 662 |
+
var $sparePiecesTop = null
|
| 663 |
+
var $sparePiecesBottom = null
|
| 664 |
+
|
| 665 |
+
// constructor return object
|
| 666 |
+
var widget = {}
|
| 667 |
+
|
| 668 |
+
// -------------------------------------------------------------------------
|
| 669 |
+
// Stateful
|
| 670 |
+
// -------------------------------------------------------------------------
|
| 671 |
+
|
| 672 |
+
var boardBorderSize = 2
|
| 673 |
+
var currentOrientation = 'white'
|
| 674 |
+
var currentPosition = {}
|
| 675 |
+
var draggedPiece = null
|
| 676 |
+
var draggedPieceLocation = null
|
| 677 |
+
var draggedPieceSource = null
|
| 678 |
+
var isDragging = false
|
| 679 |
+
var sparePiecesElsIds = {}
|
| 680 |
+
var squareElsIds = {}
|
| 681 |
+
var squareElsOffsets = {}
|
| 682 |
+
var squareSize = 16
|
| 683 |
+
|
| 684 |
+
// -------------------------------------------------------------------------
|
| 685 |
+
// Validation / Errors
|
| 686 |
+
// -------------------------------------------------------------------------
|
| 687 |
+
|
| 688 |
+
function error (code, msg, obj) {
|
| 689 |
+
// do nothing if showErrors is not set
|
| 690 |
+
if (
|
| 691 |
+
config.hasOwnProperty('showErrors') !== true ||
|
| 692 |
+
config.showErrors === false
|
| 693 |
+
) {
|
| 694 |
+
return
|
| 695 |
+
}
|
| 696 |
+
|
| 697 |
+
var errorText = 'Chessboard Error ' + code + ': ' + msg
|
| 698 |
+
|
| 699 |
+
// print to console
|
| 700 |
+
if (
|
| 701 |
+
config.showErrors === 'console' &&
|
| 702 |
+
typeof console === 'object' &&
|
| 703 |
+
typeof console.log === 'function'
|
| 704 |
+
) {
|
| 705 |
+
console.log(errorText)
|
| 706 |
+
if (arguments.length >= 2) {
|
| 707 |
+
console.log(obj)
|
| 708 |
+
}
|
| 709 |
+
return
|
| 710 |
+
}
|
| 711 |
+
|
| 712 |
+
// alert errors
|
| 713 |
+
if (config.showErrors === 'alert') {
|
| 714 |
+
if (obj) {
|
| 715 |
+
errorText += '\n\n' + JSON.stringify(obj)
|
| 716 |
+
}
|
| 717 |
+
window.alert(errorText)
|
| 718 |
+
return
|
| 719 |
+
}
|
| 720 |
+
|
| 721 |
+
// custom function
|
| 722 |
+
if (isFunction(config.showErrors)) {
|
| 723 |
+
config.showErrors(code, msg, obj)
|
| 724 |
+
}
|
| 725 |
+
}
|
| 726 |
+
|
| 727 |
+
function setInitialState () {
|
| 728 |
+
currentOrientation = config.orientation
|
| 729 |
+
|
| 730 |
+
// make sure position is valid
|
| 731 |
+
if (config.hasOwnProperty('position')) {
|
| 732 |
+
if (config.position === 'start') {
|
| 733 |
+
currentPosition = deepCopy(START_POSITION)
|
| 734 |
+
} else if (validFen(config.position)) {
|
| 735 |
+
currentPosition = fenToObj(config.position)
|
| 736 |
+
} else if (validPositionObject(config.position)) {
|
| 737 |
+
currentPosition = deepCopy(config.position)
|
| 738 |
+
} else {
|
| 739 |
+
error(
|
| 740 |
+
7263,
|
| 741 |
+
'Invalid value passed to config.position.',
|
| 742 |
+
config.position
|
| 743 |
+
)
|
| 744 |
+
}
|
| 745 |
+
}
|
| 746 |
+
}
|
| 747 |
+
|
| 748 |
+
// -------------------------------------------------------------------------
|
| 749 |
+
// DOM Misc
|
| 750 |
+
// -------------------------------------------------------------------------
|
| 751 |
+
|
| 752 |
+
// calculates square size based on the width of the container
|
| 753 |
+
// got a little CSS black magic here, so let me explain:
|
| 754 |
+
// get the width of the container element (could be anything), reduce by 1 for
|
| 755 |
+
// fudge factor, and then keep reducing until we find an exact mod 8 for
|
| 756 |
+
// our square size
|
| 757 |
+
function calculateSquareSize () {
|
| 758 |
+
var containerWidth = parseInt($container.width(), 10)
|
| 759 |
+
|
| 760 |
+
// defensive, prevent infinite loop
|
| 761 |
+
if (!containerWidth || containerWidth <= 0) {
|
| 762 |
+
return 0
|
| 763 |
+
}
|
| 764 |
+
|
| 765 |
+
// pad one pixel
|
| 766 |
+
var boardWidth = containerWidth - 1
|
| 767 |
+
|
| 768 |
+
while (boardWidth % 8 !== 0 && boardWidth > 0) {
|
| 769 |
+
boardWidth = boardWidth - 1
|
| 770 |
+
}
|
| 771 |
+
|
| 772 |
+
return boardWidth / 8
|
| 773 |
+
}
|
| 774 |
+
|
| 775 |
+
// create random IDs for elements
|
| 776 |
+
function createElIds () {
|
| 777 |
+
// squares on the board
|
| 778 |
+
for (var i = 0; i < COLUMNS.length; i++) {
|
| 779 |
+
for (var j = 1; j <= 8; j++) {
|
| 780 |
+
var square = COLUMNS[i] + j
|
| 781 |
+
squareElsIds[square] = square + '-' + uuid()
|
| 782 |
+
}
|
| 783 |
+
}
|
| 784 |
+
|
| 785 |
+
// spare pieces
|
| 786 |
+
var pieces = 'KQRNBP'.split('')
|
| 787 |
+
for (i = 0; i < pieces.length; i++) {
|
| 788 |
+
var whitePiece = 'w' + pieces[i]
|
| 789 |
+
var blackPiece = 'b' + pieces[i]
|
| 790 |
+
sparePiecesElsIds[whitePiece] = whitePiece + '-' + uuid()
|
| 791 |
+
sparePiecesElsIds[blackPiece] = blackPiece + '-' + uuid()
|
| 792 |
+
}
|
| 793 |
+
}
|
| 794 |
+
|
| 795 |
+
// -------------------------------------------------------------------------
|
| 796 |
+
// Markup Building
|
| 797 |
+
// -------------------------------------------------------------------------
|
| 798 |
+
|
| 799 |
+
function buildBoardHTML (orientation) {
|
| 800 |
+
if (orientation !== 'black') {
|
| 801 |
+
orientation = 'white'
|
| 802 |
+
}
|
| 803 |
+
|
| 804 |
+
var html = ''
|
| 805 |
+
|
| 806 |
+
// algebraic notation / orientation
|
| 807 |
+
var alpha = deepCopy(COLUMNS)
|
| 808 |
+
var row = 8
|
| 809 |
+
if (orientation === 'black') {
|
| 810 |
+
alpha.reverse()
|
| 811 |
+
row = 1
|
| 812 |
+
}
|
| 813 |
+
|
| 814 |
+
var squareColor = 'white'
|
| 815 |
+
for (var i = 0; i < 8; i++) {
|
| 816 |
+
html += '<div class="{row}">'
|
| 817 |
+
for (var j = 0; j < 8; j++) {
|
| 818 |
+
var square = alpha[j] + row
|
| 819 |
+
|
| 820 |
+
html += '<div class="{square} ' + CSS[squareColor] + ' ' +
|
| 821 |
+
'square-' + square + '" ' +
|
| 822 |
+
'style="width:' + squareSize + 'px;height:' + squareSize + 'px;" ' +
|
| 823 |
+
'id="' + squareElsIds[square] + '" ' +
|
| 824 |
+
'data-square="' + square + '">'
|
| 825 |
+
|
| 826 |
+
if (config.showNotation) {
|
| 827 |
+
// alpha notation
|
| 828 |
+
if ((orientation === 'white' && row === 1) ||
|
| 829 |
+
(orientation === 'black' && row === 8)) {
|
| 830 |
+
html += '<div class="{notation} {alpha}">' + alpha[j] + '</div>'
|
| 831 |
+
}
|
| 832 |
+
|
| 833 |
+
// numeric notation
|
| 834 |
+
if (j === 0) {
|
| 835 |
+
html += '<div class="{notation} {numeric}">' + row + '</div>'
|
| 836 |
+
}
|
| 837 |
+
}
|
| 838 |
+
|
| 839 |
+
html += '</div>' // end .square
|
| 840 |
+
|
| 841 |
+
squareColor = (squareColor === 'white') ? 'black' : 'white'
|
| 842 |
+
}
|
| 843 |
+
html += '<div class="{clearfix}"></div></div>'
|
| 844 |
+
|
| 845 |
+
squareColor = (squareColor === 'white') ? 'black' : 'white'
|
| 846 |
+
|
| 847 |
+
if (orientation === 'white') {
|
| 848 |
+
row = row - 1
|
| 849 |
+
} else {
|
| 850 |
+
row = row + 1
|
| 851 |
+
}
|
| 852 |
+
}
|
| 853 |
+
|
| 854 |
+
return interpolateTemplate(html, CSS)
|
| 855 |
+
}
|
| 856 |
+
|
| 857 |
+
function buildPieceImgSrc (piece) {
|
| 858 |
+
if (isFunction(config.pieceTheme)) {
|
| 859 |
+
return config.pieceTheme(piece)
|
| 860 |
+
}
|
| 861 |
+
|
| 862 |
+
if (isString(config.pieceTheme)) {
|
| 863 |
+
return interpolateTemplate(config.pieceTheme, {piece: piece})
|
| 864 |
+
}
|
| 865 |
+
|
| 866 |
+
// NOTE: this should never happen
|
| 867 |
+
error(8272, 'Unable to build image source for config.pieceTheme.')
|
| 868 |
+
return ''
|
| 869 |
+
}
|
| 870 |
+
|
| 871 |
+
function buildPieceHTML (piece, hidden, id) {
|
| 872 |
+
var html = '<img src="' + buildPieceImgSrc(piece) + '" '
|
| 873 |
+
if (isString(id) && id !== '') {
|
| 874 |
+
html += 'id="' + id + '" '
|
| 875 |
+
}
|
| 876 |
+
html += 'alt="" ' +
|
| 877 |
+
'class="{piece}" ' +
|
| 878 |
+
'data-piece="' + piece + '" ' +
|
| 879 |
+
'style="width:' + squareSize + 'px;' + 'height:' + squareSize + 'px;'
|
| 880 |
+
|
| 881 |
+
if (hidden) {
|
| 882 |
+
html += 'display:none;'
|
| 883 |
+
}
|
| 884 |
+
|
| 885 |
+
html += '" />'
|
| 886 |
+
|
| 887 |
+
return interpolateTemplate(html, CSS)
|
| 888 |
+
}
|
| 889 |
+
|
| 890 |
+
function buildSparePiecesHTML (color) {
|
| 891 |
+
var pieces = ['wK', 'wQ', 'wR', 'wB', 'wN', 'wP']
|
| 892 |
+
if (color === 'black') {
|
| 893 |
+
pieces = ['bK', 'bQ', 'bR', 'bB', 'bN', 'bP']
|
| 894 |
+
}
|
| 895 |
+
|
| 896 |
+
var html = ''
|
| 897 |
+
for (var i = 0; i < pieces.length; i++) {
|
| 898 |
+
html += buildPieceHTML(pieces[i], false, sparePiecesElsIds[pieces[i]])
|
| 899 |
+
}
|
| 900 |
+
|
| 901 |
+
return html
|
| 902 |
+
}
|
| 903 |
+
|
| 904 |
+
// -------------------------------------------------------------------------
|
| 905 |
+
// Animations
|
| 906 |
+
// -------------------------------------------------------------------------
|
| 907 |
+
|
| 908 |
+
function animateSquareToSquare (src, dest, piece, completeFn) {
|
| 909 |
+
// get information about the source and destination squares
|
| 910 |
+
var $srcSquare = $('#' + squareElsIds[src])
|
| 911 |
+
var srcSquarePosition = $srcSquare.offset()
|
| 912 |
+
var $destSquare = $('#' + squareElsIds[dest])
|
| 913 |
+
var destSquarePosition = $destSquare.offset()
|
| 914 |
+
|
| 915 |
+
// create the animated piece and absolutely position it
|
| 916 |
+
// over the source square
|
| 917 |
+
var animatedPieceId = uuid()
|
| 918 |
+
$('body').append(buildPieceHTML(piece, true, animatedPieceId))
|
| 919 |
+
var $animatedPiece = $('#' + animatedPieceId)
|
| 920 |
+
$animatedPiece.css({
|
| 921 |
+
display: '',
|
| 922 |
+
position: 'absolute',
|
| 923 |
+
top: srcSquarePosition.top,
|
| 924 |
+
left: srcSquarePosition.left
|
| 925 |
+
})
|
| 926 |
+
|
| 927 |
+
// remove original piece from source square
|
| 928 |
+
$srcSquare.find('.' + CSS.piece).remove()
|
| 929 |
+
|
| 930 |
+
function onFinishAnimation1 () {
|
| 931 |
+
// add the "real" piece to the destination square
|
| 932 |
+
$destSquare.append(buildPieceHTML(piece))
|
| 933 |
+
|
| 934 |
+
// remove the animated piece
|
| 935 |
+
$animatedPiece.remove()
|
| 936 |
+
|
| 937 |
+
// run complete function
|
| 938 |
+
if (isFunction(completeFn)) {
|
| 939 |
+
completeFn()
|
| 940 |
+
}
|
| 941 |
+
}
|
| 942 |
+
|
| 943 |
+
// animate the piece to the destination square
|
| 944 |
+
var opts = {
|
| 945 |
+
duration: config.moveSpeed,
|
| 946 |
+
complete: onFinishAnimation1
|
| 947 |
+
}
|
| 948 |
+
$animatedPiece.animate(destSquarePosition, opts)
|
| 949 |
+
}
|
| 950 |
+
|
| 951 |
+
function animateSparePieceToSquare (piece, dest, completeFn) {
|
| 952 |
+
var srcOffset = $('#' + sparePiecesElsIds[piece]).offset()
|
| 953 |
+
var $destSquare = $('#' + squareElsIds[dest])
|
| 954 |
+
var destOffset = $destSquare.offset()
|
| 955 |
+
|
| 956 |
+
// create the animate piece
|
| 957 |
+
var pieceId = uuid()
|
| 958 |
+
$('body').append(buildPieceHTML(piece, true, pieceId))
|
| 959 |
+
var $animatedPiece = $('#' + pieceId)
|
| 960 |
+
$animatedPiece.css({
|
| 961 |
+
display: '',
|
| 962 |
+
position: 'absolute',
|
| 963 |
+
left: srcOffset.left,
|
| 964 |
+
top: srcOffset.top
|
| 965 |
+
})
|
| 966 |
+
|
| 967 |
+
// on complete
|
| 968 |
+
function onFinishAnimation2 () {
|
| 969 |
+
// add the "real" piece to the destination square
|
| 970 |
+
$destSquare.find('.' + CSS.piece).remove()
|
| 971 |
+
$destSquare.append(buildPieceHTML(piece))
|
| 972 |
+
|
| 973 |
+
// remove the animated piece
|
| 974 |
+
$animatedPiece.remove()
|
| 975 |
+
|
| 976 |
+
// run complete function
|
| 977 |
+
if (isFunction(completeFn)) {
|
| 978 |
+
completeFn()
|
| 979 |
+
}
|
| 980 |
+
}
|
| 981 |
+
|
| 982 |
+
// animate the piece to the destination square
|
| 983 |
+
var opts = {
|
| 984 |
+
duration: config.moveSpeed,
|
| 985 |
+
complete: onFinishAnimation2
|
| 986 |
+
}
|
| 987 |
+
$animatedPiece.animate(destOffset, opts)
|
| 988 |
+
}
|
| 989 |
+
|
| 990 |
+
// execute an array of animations
|
| 991 |
+
function doAnimations (animations, oldPos, newPos) {
|
| 992 |
+
if (animations.length === 0) return
|
| 993 |
+
|
| 994 |
+
var numFinished = 0
|
| 995 |
+
function onFinishAnimation3 () {
|
| 996 |
+
// exit if all the animations aren't finished
|
| 997 |
+
numFinished = numFinished + 1
|
| 998 |
+
if (numFinished !== animations.length) return
|
| 999 |
+
|
| 1000 |
+
drawPositionInstant()
|
| 1001 |
+
|
| 1002 |
+
// run their onMoveEnd function
|
| 1003 |
+
if (isFunction(config.onMoveEnd)) {
|
| 1004 |
+
config.onMoveEnd(deepCopy(oldPos), deepCopy(newPos))
|
| 1005 |
+
}
|
| 1006 |
+
}
|
| 1007 |
+
|
| 1008 |
+
for (var i = 0; i < animations.length; i++) {
|
| 1009 |
+
var animation = animations[i]
|
| 1010 |
+
|
| 1011 |
+
// clear a piece
|
| 1012 |
+
if (animation.type === 'clear') {
|
| 1013 |
+
$('#' + squareElsIds[animation.square] + ' .' + CSS.piece)
|
| 1014 |
+
.fadeOut(config.trashSpeed, onFinishAnimation3)
|
| 1015 |
+
|
| 1016 |
+
// add a piece with no spare pieces - fade the piece onto the square
|
| 1017 |
+
} else if (animation.type === 'add' && !config.sparePieces) {
|
| 1018 |
+
$('#' + squareElsIds[animation.square])
|
| 1019 |
+
.append(buildPieceHTML(animation.piece, true))
|
| 1020 |
+
.find('.' + CSS.piece)
|
| 1021 |
+
.fadeIn(config.appearSpeed, onFinishAnimation3)
|
| 1022 |
+
|
| 1023 |
+
// add a piece with spare pieces - animate from the spares
|
| 1024 |
+
} else if (animation.type === 'add' && config.sparePieces) {
|
| 1025 |
+
animateSparePieceToSquare(animation.piece, animation.square, onFinishAnimation3)
|
| 1026 |
+
|
| 1027 |
+
// move a piece from squareA to squareB
|
| 1028 |
+
} else if (animation.type === 'move') {
|
| 1029 |
+
animateSquareToSquare(animation.source, animation.destination, animation.piece, onFinishAnimation3)
|
| 1030 |
+
}
|
| 1031 |
+
}
|
| 1032 |
+
}
|
| 1033 |
+
|
| 1034 |
+
// calculate an array of animations that need to happen in order to get
|
| 1035 |
+
// from pos1 to pos2
|
| 1036 |
+
function calculateAnimations (pos1, pos2) {
|
| 1037 |
+
// make copies of both
|
| 1038 |
+
pos1 = deepCopy(pos1)
|
| 1039 |
+
pos2 = deepCopy(pos2)
|
| 1040 |
+
|
| 1041 |
+
var animations = []
|
| 1042 |
+
var squaresMovedTo = {}
|
| 1043 |
+
|
| 1044 |
+
// remove pieces that are the same in both positions
|
| 1045 |
+
for (var i in pos2) {
|
| 1046 |
+
if (!pos2.hasOwnProperty(i)) continue
|
| 1047 |
+
|
| 1048 |
+
if (pos1.hasOwnProperty(i) && pos1[i] === pos2[i]) {
|
| 1049 |
+
delete pos1[i]
|
| 1050 |
+
delete pos2[i]
|
| 1051 |
+
}
|
| 1052 |
+
}
|
| 1053 |
+
|
| 1054 |
+
// find all the "move" animations
|
| 1055 |
+
for (i in pos2) {
|
| 1056 |
+
if (!pos2.hasOwnProperty(i)) continue
|
| 1057 |
+
|
| 1058 |
+
var closestPiece = findClosestPiece(pos1, pos2[i], i)
|
| 1059 |
+
if (closestPiece) {
|
| 1060 |
+
animations.push({
|
| 1061 |
+
type: 'move',
|
| 1062 |
+
source: closestPiece,
|
| 1063 |
+
destination: i,
|
| 1064 |
+
piece: pos2[i]
|
| 1065 |
+
})
|
| 1066 |
+
|
| 1067 |
+
delete pos1[closestPiece]
|
| 1068 |
+
delete pos2[i]
|
| 1069 |
+
squaresMovedTo[i] = true
|
| 1070 |
+
}
|
| 1071 |
+
}
|
| 1072 |
+
|
| 1073 |
+
// "add" animations
|
| 1074 |
+
for (i in pos2) {
|
| 1075 |
+
if (!pos2.hasOwnProperty(i)) continue
|
| 1076 |
+
|
| 1077 |
+
animations.push({
|
| 1078 |
+
type: 'add',
|
| 1079 |
+
square: i,
|
| 1080 |
+
piece: pos2[i]
|
| 1081 |
+
})
|
| 1082 |
+
|
| 1083 |
+
delete pos2[i]
|
| 1084 |
+
}
|
| 1085 |
+
|
| 1086 |
+
// "clear" animations
|
| 1087 |
+
for (i in pos1) {
|
| 1088 |
+
if (!pos1.hasOwnProperty(i)) continue
|
| 1089 |
+
|
| 1090 |
+
// do not clear a piece if it is on a square that is the result
|
| 1091 |
+
// of a "move", ie: a piece capture
|
| 1092 |
+
if (squaresMovedTo.hasOwnProperty(i)) continue
|
| 1093 |
+
|
| 1094 |
+
animations.push({
|
| 1095 |
+
type: 'clear',
|
| 1096 |
+
square: i,
|
| 1097 |
+
piece: pos1[i]
|
| 1098 |
+
})
|
| 1099 |
+
|
| 1100 |
+
delete pos1[i]
|
| 1101 |
+
}
|
| 1102 |
+
|
| 1103 |
+
return animations
|
| 1104 |
+
}
|
| 1105 |
+
|
| 1106 |
+
// -------------------------------------------------------------------------
|
| 1107 |
+
// Control Flow
|
| 1108 |
+
// -------------------------------------------------------------------------
|
| 1109 |
+
|
| 1110 |
+
function drawPositionInstant () {
|
| 1111 |
+
// clear the board
|
| 1112 |
+
$board.find('.' + CSS.piece).remove()
|
| 1113 |
+
|
| 1114 |
+
// add the pieces
|
| 1115 |
+
for (var i in currentPosition) {
|
| 1116 |
+
if (!currentPosition.hasOwnProperty(i)) continue
|
| 1117 |
+
|
| 1118 |
+
$('#' + squareElsIds[i]).append(buildPieceHTML(currentPosition[i]))
|
| 1119 |
+
}
|
| 1120 |
+
}
|
| 1121 |
+
|
| 1122 |
+
function drawBoard () {
|
| 1123 |
+
$board.html(buildBoardHTML(currentOrientation, squareSize, config.showNotation))
|
| 1124 |
+
drawPositionInstant()
|
| 1125 |
+
|
| 1126 |
+
if (config.sparePieces) {
|
| 1127 |
+
if (currentOrientation === 'white') {
|
| 1128 |
+
$sparePiecesTop.html(buildSparePiecesHTML('black'))
|
| 1129 |
+
$sparePiecesBottom.html(buildSparePiecesHTML('white'))
|
| 1130 |
+
} else {
|
| 1131 |
+
$sparePiecesTop.html(buildSparePiecesHTML('white'))
|
| 1132 |
+
$sparePiecesBottom.html(buildSparePiecesHTML('black'))
|
| 1133 |
+
}
|
| 1134 |
+
}
|
| 1135 |
+
}
|
| 1136 |
+
|
| 1137 |
+
function setCurrentPosition (position) {
|
| 1138 |
+
var oldPos = deepCopy(currentPosition)
|
| 1139 |
+
var newPos = deepCopy(position)
|
| 1140 |
+
var oldFen = objToFen(oldPos)
|
| 1141 |
+
var newFen = objToFen(newPos)
|
| 1142 |
+
|
| 1143 |
+
// do nothing if no change in position
|
| 1144 |
+
if (oldFen === newFen) return
|
| 1145 |
+
|
| 1146 |
+
// run their onChange function
|
| 1147 |
+
if (isFunction(config.onChange)) {
|
| 1148 |
+
config.onChange(oldPos, newPos)
|
| 1149 |
+
}
|
| 1150 |
+
|
| 1151 |
+
// update state
|
| 1152 |
+
currentPosition = position
|
| 1153 |
+
}
|
| 1154 |
+
|
| 1155 |
+
function isXYOnSquare (x, y) {
|
| 1156 |
+
for (var i in squareElsOffsets) {
|
| 1157 |
+
if (!squareElsOffsets.hasOwnProperty(i)) continue
|
| 1158 |
+
|
| 1159 |
+
var s = squareElsOffsets[i]
|
| 1160 |
+
if (x >= s.left &&
|
| 1161 |
+
x < s.left + squareSize &&
|
| 1162 |
+
y >= s.top &&
|
| 1163 |
+
y < s.top + squareSize) {
|
| 1164 |
+
return i
|
| 1165 |
+
}
|
| 1166 |
+
}
|
| 1167 |
+
|
| 1168 |
+
return 'offboard'
|
| 1169 |
+
}
|
| 1170 |
+
|
| 1171 |
+
// records the XY coords of every square into memory
|
| 1172 |
+
function captureSquareOffsets () {
|
| 1173 |
+
squareElsOffsets = {}
|
| 1174 |
+
|
| 1175 |
+
for (var i in squareElsIds) {
|
| 1176 |
+
if (!squareElsIds.hasOwnProperty(i)) continue
|
| 1177 |
+
|
| 1178 |
+
squareElsOffsets[i] = $('#' + squareElsIds[i]).offset()
|
| 1179 |
+
}
|
| 1180 |
+
}
|
| 1181 |
+
|
| 1182 |
+
function removeSquareHighlights () {
|
| 1183 |
+
$board
|
| 1184 |
+
.find('.' + CSS.square)
|
| 1185 |
+
.removeClass(CSS.highlight1 + ' ' + CSS.highlight2)
|
| 1186 |
+
}
|
| 1187 |
+
|
| 1188 |
+
function snapbackDraggedPiece () {
|
| 1189 |
+
// there is no "snapback" for spare pieces
|
| 1190 |
+
if (draggedPieceSource === 'spare') {
|
| 1191 |
+
trashDraggedPiece()
|
| 1192 |
+
return
|
| 1193 |
+
}
|
| 1194 |
+
|
| 1195 |
+
removeSquareHighlights()
|
| 1196 |
+
|
| 1197 |
+
// animation complete
|
| 1198 |
+
function complete () {
|
| 1199 |
+
drawPositionInstant()
|
| 1200 |
+
$draggedPiece.css('display', 'none')
|
| 1201 |
+
|
| 1202 |
+
// run their onSnapbackEnd function
|
| 1203 |
+
if (isFunction(config.onSnapbackEnd)) {
|
| 1204 |
+
config.onSnapbackEnd(
|
| 1205 |
+
draggedPiece,
|
| 1206 |
+
draggedPieceSource,
|
| 1207 |
+
deepCopy(currentPosition),
|
| 1208 |
+
currentOrientation
|
| 1209 |
+
)
|
| 1210 |
+
}
|
| 1211 |
+
}
|
| 1212 |
+
|
| 1213 |
+
// get source square position
|
| 1214 |
+
var sourceSquarePosition = $('#' + squareElsIds[draggedPieceSource]).offset()
|
| 1215 |
+
|
| 1216 |
+
// animate the piece to the target square
|
| 1217 |
+
var opts = {
|
| 1218 |
+
duration: config.snapbackSpeed,
|
| 1219 |
+
complete: complete
|
| 1220 |
+
}
|
| 1221 |
+
$draggedPiece.animate(sourceSquarePosition, opts)
|
| 1222 |
+
|
| 1223 |
+
// set state
|
| 1224 |
+
isDragging = false
|
| 1225 |
+
}
|
| 1226 |
+
|
| 1227 |
+
function trashDraggedPiece () {
|
| 1228 |
+
removeSquareHighlights()
|
| 1229 |
+
|
| 1230 |
+
// remove the source piece
|
| 1231 |
+
var newPosition = deepCopy(currentPosition)
|
| 1232 |
+
delete newPosition[draggedPieceSource]
|
| 1233 |
+
setCurrentPosition(newPosition)
|
| 1234 |
+
|
| 1235 |
+
// redraw the position
|
| 1236 |
+
drawPositionInstant()
|
| 1237 |
+
|
| 1238 |
+
// hide the dragged piece
|
| 1239 |
+
$draggedPiece.fadeOut(config.trashSpeed)
|
| 1240 |
+
|
| 1241 |
+
// set state
|
| 1242 |
+
isDragging = false
|
| 1243 |
+
}
|
| 1244 |
+
|
| 1245 |
+
function dropDraggedPieceOnSquare (square) {
|
| 1246 |
+
removeSquareHighlights()
|
| 1247 |
+
|
| 1248 |
+
// update position
|
| 1249 |
+
var newPosition = deepCopy(currentPosition)
|
| 1250 |
+
delete newPosition[draggedPieceSource]
|
| 1251 |
+
newPosition[square] = draggedPiece
|
| 1252 |
+
setCurrentPosition(newPosition)
|
| 1253 |
+
|
| 1254 |
+
// get target square information
|
| 1255 |
+
var targetSquarePosition = $('#' + squareElsIds[square]).offset()
|
| 1256 |
+
|
| 1257 |
+
// animation complete
|
| 1258 |
+
function onAnimationComplete () {
|
| 1259 |
+
drawPositionInstant()
|
| 1260 |
+
$draggedPiece.css('display', 'none')
|
| 1261 |
+
|
| 1262 |
+
// execute their onSnapEnd function
|
| 1263 |
+
if (isFunction(config.onSnapEnd)) {
|
| 1264 |
+
config.onSnapEnd(draggedPieceSource, square, draggedPiece)
|
| 1265 |
+
}
|
| 1266 |
+
}
|
| 1267 |
+
|
| 1268 |
+
// snap the piece to the target square
|
| 1269 |
+
var opts = {
|
| 1270 |
+
duration: config.snapSpeed,
|
| 1271 |
+
complete: onAnimationComplete
|
| 1272 |
+
}
|
| 1273 |
+
$draggedPiece.animate(targetSquarePosition, opts)
|
| 1274 |
+
|
| 1275 |
+
// set state
|
| 1276 |
+
isDragging = false
|
| 1277 |
+
}
|
| 1278 |
+
|
| 1279 |
+
function beginDraggingPiece (source, piece, x, y) {
|
| 1280 |
+
// run their custom onDragStart function
|
| 1281 |
+
// their custom onDragStart function can cancel drag start
|
| 1282 |
+
if (isFunction(config.onDragStart) &&
|
| 1283 |
+
config.onDragStart(source, piece, deepCopy(currentPosition), currentOrientation) === false) {
|
| 1284 |
+
return
|
| 1285 |
+
}
|
| 1286 |
+
|
| 1287 |
+
// set state
|
| 1288 |
+
isDragging = true
|
| 1289 |
+
draggedPiece = piece
|
| 1290 |
+
draggedPieceSource = source
|
| 1291 |
+
|
| 1292 |
+
// if the piece came from spare pieces, location is offboard
|
| 1293 |
+
if (source === 'spare') {
|
| 1294 |
+
draggedPieceLocation = 'offboard'
|
| 1295 |
+
} else {
|
| 1296 |
+
draggedPieceLocation = source
|
| 1297 |
+
}
|
| 1298 |
+
|
| 1299 |
+
// capture the x, y coords of all squares in memory
|
| 1300 |
+
captureSquareOffsets()
|
| 1301 |
+
|
| 1302 |
+
// create the dragged piece
|
| 1303 |
+
$draggedPiece.attr('src', buildPieceImgSrc(piece)).css({
|
| 1304 |
+
display: '',
|
| 1305 |
+
position: 'absolute',
|
| 1306 |
+
left: x - squareSize / 2,
|
| 1307 |
+
top: y - squareSize / 2
|
| 1308 |
+
})
|
| 1309 |
+
|
| 1310 |
+
if (source !== 'spare') {
|
| 1311 |
+
// highlight the source square and hide the piece
|
| 1312 |
+
$('#' + squareElsIds[source])
|
| 1313 |
+
.addClass(CSS.highlight1)
|
| 1314 |
+
.find('.' + CSS.piece)
|
| 1315 |
+
.css('display', 'none')
|
| 1316 |
+
}
|
| 1317 |
+
}
|
| 1318 |
+
|
| 1319 |
+
function updateDraggedPiece (x, y) {
|
| 1320 |
+
// put the dragged piece over the mouse cursor
|
| 1321 |
+
$draggedPiece.css({
|
| 1322 |
+
left: x - squareSize / 2,
|
| 1323 |
+
top: y - squareSize / 2
|
| 1324 |
+
})
|
| 1325 |
+
|
| 1326 |
+
// get location
|
| 1327 |
+
var location = isXYOnSquare(x, y)
|
| 1328 |
+
|
| 1329 |
+
// do nothing if the location has not changed
|
| 1330 |
+
if (location === draggedPieceLocation) return
|
| 1331 |
+
|
| 1332 |
+
// remove highlight from previous square
|
| 1333 |
+
if (validSquare(draggedPieceLocation)) {
|
| 1334 |
+
$('#' + squareElsIds[draggedPieceLocation]).removeClass(CSS.highlight2)
|
| 1335 |
+
}
|
| 1336 |
+
|
| 1337 |
+
// add highlight to new square
|
| 1338 |
+
if (validSquare(location)) {
|
| 1339 |
+
$('#' + squareElsIds[location]).addClass(CSS.highlight2)
|
| 1340 |
+
}
|
| 1341 |
+
|
| 1342 |
+
// run onDragMove
|
| 1343 |
+
if (isFunction(config.onDragMove)) {
|
| 1344 |
+
config.onDragMove(
|
| 1345 |
+
location,
|
| 1346 |
+
draggedPieceLocation,
|
| 1347 |
+
draggedPieceSource,
|
| 1348 |
+
draggedPiece,
|
| 1349 |
+
deepCopy(currentPosition),
|
| 1350 |
+
currentOrientation
|
| 1351 |
+
)
|
| 1352 |
+
}
|
| 1353 |
+
|
| 1354 |
+
// update state
|
| 1355 |
+
draggedPieceLocation = location
|
| 1356 |
+
}
|
| 1357 |
+
|
| 1358 |
+
function stopDraggedPiece (location) {
|
| 1359 |
+
// determine what the action should be
|
| 1360 |
+
var action = 'drop'
|
| 1361 |
+
if (location === 'offboard' && config.dropOffBoard === 'snapback') {
|
| 1362 |
+
action = 'snapback'
|
| 1363 |
+
}
|
| 1364 |
+
if (location === 'offboard' && config.dropOffBoard === 'trash') {
|
| 1365 |
+
action = 'trash'
|
| 1366 |
+
}
|
| 1367 |
+
|
| 1368 |
+
// run their onDrop function, which can potentially change the drop action
|
| 1369 |
+
if (isFunction(config.onDrop)) {
|
| 1370 |
+
var newPosition = deepCopy(currentPosition)
|
| 1371 |
+
|
| 1372 |
+
// source piece is a spare piece and position is off the board
|
| 1373 |
+
// if (draggedPieceSource === 'spare' && location === 'offboard') {...}
|
| 1374 |
+
// position has not changed; do nothing
|
| 1375 |
+
|
| 1376 |
+
// source piece is a spare piece and position is on the board
|
| 1377 |
+
if (draggedPieceSource === 'spare' && validSquare(location)) {
|
| 1378 |
+
// add the piece to the board
|
| 1379 |
+
newPosition[location] = draggedPiece
|
| 1380 |
+
}
|
| 1381 |
+
|
| 1382 |
+
// source piece was on the board and position is off the board
|
| 1383 |
+
if (validSquare(draggedPieceSource) && location === 'offboard') {
|
| 1384 |
+
// remove the piece from the board
|
| 1385 |
+
delete newPosition[draggedPieceSource]
|
| 1386 |
+
}
|
| 1387 |
+
|
| 1388 |
+
// source piece was on the board and position is on the board
|
| 1389 |
+
if (validSquare(draggedPieceSource) && validSquare(location)) {
|
| 1390 |
+
// move the piece
|
| 1391 |
+
delete newPosition[draggedPieceSource]
|
| 1392 |
+
newPosition[location] = draggedPiece
|
| 1393 |
+
}
|
| 1394 |
+
|
| 1395 |
+
var oldPosition = deepCopy(currentPosition)
|
| 1396 |
+
|
| 1397 |
+
var result = config.onDrop(
|
| 1398 |
+
draggedPieceSource,
|
| 1399 |
+
location,
|
| 1400 |
+
draggedPiece,
|
| 1401 |
+
newPosition,
|
| 1402 |
+
oldPosition,
|
| 1403 |
+
currentOrientation
|
| 1404 |
+
)
|
| 1405 |
+
if (result === 'snapback' || result === 'trash') {
|
| 1406 |
+
action = result
|
| 1407 |
+
}
|
| 1408 |
+
}
|
| 1409 |
+
|
| 1410 |
+
// do it!
|
| 1411 |
+
if (action === 'snapback') {
|
| 1412 |
+
snapbackDraggedPiece()
|
| 1413 |
+
} else if (action === 'trash') {
|
| 1414 |
+
trashDraggedPiece()
|
| 1415 |
+
} else if (action === 'drop') {
|
| 1416 |
+
dropDraggedPieceOnSquare(location)
|
| 1417 |
+
}
|
| 1418 |
+
}
|
| 1419 |
+
|
| 1420 |
+
// -------------------------------------------------------------------------
|
| 1421 |
+
// Public Methods
|
| 1422 |
+
// -------------------------------------------------------------------------
|
| 1423 |
+
|
| 1424 |
+
// clear the board
|
| 1425 |
+
widget.clear = function (useAnimation) {
|
| 1426 |
+
widget.position({}, useAnimation)
|
| 1427 |
+
}
|
| 1428 |
+
|
| 1429 |
+
// remove the widget from the page
|
| 1430 |
+
widget.destroy = function () {
|
| 1431 |
+
// remove markup
|
| 1432 |
+
$container.html('')
|
| 1433 |
+
$draggedPiece.remove()
|
| 1434 |
+
|
| 1435 |
+
// remove event handlers
|
| 1436 |
+
$container.unbind()
|
| 1437 |
+
}
|
| 1438 |
+
|
| 1439 |
+
// shorthand method to get the current FEN
|
| 1440 |
+
widget.fen = function () {
|
| 1441 |
+
return widget.position('fen')
|
| 1442 |
+
}
|
| 1443 |
+
|
| 1444 |
+
// flip orientation
|
| 1445 |
+
widget.flip = function () {
|
| 1446 |
+
return widget.orientation('flip')
|
| 1447 |
+
}
|
| 1448 |
+
|
| 1449 |
+
// move pieces
|
| 1450 |
+
// TODO: this method should be variadic as well as accept an array of moves
|
| 1451 |
+
widget.move = function () {
|
| 1452 |
+
// no need to throw an error here; just do nothing
|
| 1453 |
+
// TODO: this should return the current position
|
| 1454 |
+
if (arguments.length === 0) return
|
| 1455 |
+
|
| 1456 |
+
var useAnimation = true
|
| 1457 |
+
|
| 1458 |
+
// collect the moves into an object
|
| 1459 |
+
var moves = {}
|
| 1460 |
+
for (var i = 0; i < arguments.length; i++) {
|
| 1461 |
+
// any "false" to this function means no animations
|
| 1462 |
+
if (arguments[i] === false) {
|
| 1463 |
+
useAnimation = false
|
| 1464 |
+
continue
|
| 1465 |
+
}
|
| 1466 |
+
|
| 1467 |
+
// skip invalid arguments
|
| 1468 |
+
if (!validMove(arguments[i])) {
|
| 1469 |
+
error(2826, 'Invalid move passed to the move method.', arguments[i])
|
| 1470 |
+
continue
|
| 1471 |
+
}
|
| 1472 |
+
|
| 1473 |
+
var tmp = arguments[i].split('-')
|
| 1474 |
+
moves[tmp[0]] = tmp[1]
|
| 1475 |
+
}
|
| 1476 |
+
|
| 1477 |
+
// calculate position from moves
|
| 1478 |
+
var newPos = calculatePositionFromMoves(currentPosition, moves)
|
| 1479 |
+
|
| 1480 |
+
// update the board
|
| 1481 |
+
widget.position(newPos, useAnimation)
|
| 1482 |
+
|
| 1483 |
+
// return the new position object
|
| 1484 |
+
return newPos
|
| 1485 |
+
}
|
| 1486 |
+
|
| 1487 |
+
widget.orientation = function (arg) {
|
| 1488 |
+
// no arguments, return the current orientation
|
| 1489 |
+
if (arguments.length === 0) {
|
| 1490 |
+
return currentOrientation
|
| 1491 |
+
}
|
| 1492 |
+
|
| 1493 |
+
// set to white or black
|
| 1494 |
+
if (arg === 'white' || arg === 'black') {
|
| 1495 |
+
currentOrientation = arg
|
| 1496 |
+
drawBoard()
|
| 1497 |
+
return currentOrientation
|
| 1498 |
+
}
|
| 1499 |
+
|
| 1500 |
+
// flip orientation
|
| 1501 |
+
if (arg === 'flip') {
|
| 1502 |
+
currentOrientation = currentOrientation === 'white' ? 'black' : 'white'
|
| 1503 |
+
drawBoard()
|
| 1504 |
+
return currentOrientation
|
| 1505 |
+
}
|
| 1506 |
+
|
| 1507 |
+
error(5482, 'Invalid value passed to the orientation method.', arg)
|
| 1508 |
+
}
|
| 1509 |
+
|
| 1510 |
+
widget.position = function (position, useAnimation) {
|
| 1511 |
+
// no arguments, return the current position
|
| 1512 |
+
if (arguments.length === 0) {
|
| 1513 |
+
return deepCopy(currentPosition)
|
| 1514 |
+
}
|
| 1515 |
+
|
| 1516 |
+
// get position as FEN
|
| 1517 |
+
if (isString(position) && position.toLowerCase() === 'fen') {
|
| 1518 |
+
return objToFen(currentPosition)
|
| 1519 |
+
}
|
| 1520 |
+
|
| 1521 |
+
// start position
|
| 1522 |
+
if (isString(position) && position.toLowerCase() === 'start') {
|
| 1523 |
+
position = deepCopy(START_POSITION)
|
| 1524 |
+
}
|
| 1525 |
+
|
| 1526 |
+
// convert FEN to position object
|
| 1527 |
+
if (validFen(position)) {
|
| 1528 |
+
position = fenToObj(position)
|
| 1529 |
+
}
|
| 1530 |
+
|
| 1531 |
+
// validate position object
|
| 1532 |
+
if (!validPositionObject(position)) {
|
| 1533 |
+
error(6482, 'Invalid value passed to the position method.', position)
|
| 1534 |
+
return
|
| 1535 |
+
}
|
| 1536 |
+
|
| 1537 |
+
// default for useAnimations is true
|
| 1538 |
+
if (useAnimation !== false) useAnimation = true
|
| 1539 |
+
|
| 1540 |
+
if (useAnimation) {
|
| 1541 |
+
// start the animations
|
| 1542 |
+
var animations = calculateAnimations(currentPosition, position)
|
| 1543 |
+
doAnimations(animations, currentPosition, position)
|
| 1544 |
+
|
| 1545 |
+
// set the new position
|
| 1546 |
+
setCurrentPosition(position)
|
| 1547 |
+
} else {
|
| 1548 |
+
// instant update
|
| 1549 |
+
setCurrentPosition(position)
|
| 1550 |
+
drawPositionInstant()
|
| 1551 |
+
}
|
| 1552 |
+
}
|
| 1553 |
+
|
| 1554 |
+
widget.resize = function () {
|
| 1555 |
+
// calulate the new square size
|
| 1556 |
+
squareSize = calculateSquareSize()
|
| 1557 |
+
|
| 1558 |
+
// set board width
|
| 1559 |
+
$board.css('width', squareSize * 8 + 'px')
|
| 1560 |
+
|
| 1561 |
+
// set drag piece size
|
| 1562 |
+
$draggedPiece.css({
|
| 1563 |
+
height: squareSize,
|
| 1564 |
+
width: squareSize
|
| 1565 |
+
})
|
| 1566 |
+
|
| 1567 |
+
// spare pieces
|
| 1568 |
+
if (config.sparePieces) {
|
| 1569 |
+
$container
|
| 1570 |
+
.find('.' + CSS.sparePieces)
|
| 1571 |
+
.css('paddingLeft', squareSize + boardBorderSize + 'px')
|
| 1572 |
+
}
|
| 1573 |
+
|
| 1574 |
+
// redraw the board
|
| 1575 |
+
drawBoard()
|
| 1576 |
+
}
|
| 1577 |
+
|
| 1578 |
+
// set the starting position
|
| 1579 |
+
widget.start = function (useAnimation) {
|
| 1580 |
+
widget.position('start', useAnimation)
|
| 1581 |
+
}
|
| 1582 |
+
|
| 1583 |
+
// -------------------------------------------------------------------------
|
| 1584 |
+
// Browser Events
|
| 1585 |
+
// -------------------------------------------------------------------------
|
| 1586 |
+
|
| 1587 |
+
function stopDefault (evt) {
|
| 1588 |
+
evt.preventDefault()
|
| 1589 |
+
}
|
| 1590 |
+
|
| 1591 |
+
function mousedownSquare (evt) {
|
| 1592 |
+
// do nothing if we're not draggable
|
| 1593 |
+
if (!config.draggable) return
|
| 1594 |
+
|
| 1595 |
+
// do nothing if there is no piece on this square
|
| 1596 |
+
var square = $(this).attr('data-square')
|
| 1597 |
+
if (!validSquare(square)) return
|
| 1598 |
+
if (!currentPosition.hasOwnProperty(square)) return
|
| 1599 |
+
|
| 1600 |
+
beginDraggingPiece(square, currentPosition[square], evt.pageX, evt.pageY)
|
| 1601 |
+
}
|
| 1602 |
+
|
| 1603 |
+
function touchstartSquare (e) {
|
| 1604 |
+
// do nothing if we're not draggable
|
| 1605 |
+
if (!config.draggable) return
|
| 1606 |
+
|
| 1607 |
+
// do nothing if there is no piece on this square
|
| 1608 |
+
var square = $(this).attr('data-square')
|
| 1609 |
+
if (!validSquare(square)) return
|
| 1610 |
+
if (!currentPosition.hasOwnProperty(square)) return
|
| 1611 |
+
|
| 1612 |
+
e = e.originalEvent
|
| 1613 |
+
beginDraggingPiece(
|
| 1614 |
+
square,
|
| 1615 |
+
currentPosition[square],
|
| 1616 |
+
e.changedTouches[0].pageX,
|
| 1617 |
+
e.changedTouches[0].pageY
|
| 1618 |
+
)
|
| 1619 |
+
}
|
| 1620 |
+
|
| 1621 |
+
function mousedownSparePiece (evt) {
|
| 1622 |
+
// do nothing if sparePieces is not enabled
|
| 1623 |
+
if (!config.sparePieces) return
|
| 1624 |
+
|
| 1625 |
+
var piece = $(this).attr('data-piece')
|
| 1626 |
+
|
| 1627 |
+
beginDraggingPiece('spare', piece, evt.pageX, evt.pageY)
|
| 1628 |
+
}
|
| 1629 |
+
|
| 1630 |
+
function touchstartSparePiece (e) {
|
| 1631 |
+
// do nothing if sparePieces is not enabled
|
| 1632 |
+
if (!config.sparePieces) return
|
| 1633 |
+
|
| 1634 |
+
var piece = $(this).attr('data-piece')
|
| 1635 |
+
|
| 1636 |
+
e = e.originalEvent
|
| 1637 |
+
beginDraggingPiece(
|
| 1638 |
+
'spare',
|
| 1639 |
+
piece,
|
| 1640 |
+
e.changedTouches[0].pageX,
|
| 1641 |
+
e.changedTouches[0].pageY
|
| 1642 |
+
)
|
| 1643 |
+
}
|
| 1644 |
+
|
| 1645 |
+
function mousemoveWindow (evt) {
|
| 1646 |
+
if (isDragging) {
|
| 1647 |
+
updateDraggedPiece(evt.pageX, evt.pageY)
|
| 1648 |
+
}
|
| 1649 |
+
}
|
| 1650 |
+
|
| 1651 |
+
var throttledMousemoveWindow = throttle(mousemoveWindow, config.dragThrottleRate)
|
| 1652 |
+
|
| 1653 |
+
function touchmoveWindow (evt) {
|
| 1654 |
+
// do nothing if we are not dragging a piece
|
| 1655 |
+
if (!isDragging) return
|
| 1656 |
+
|
| 1657 |
+
// prevent screen from scrolling
|
| 1658 |
+
evt.preventDefault()
|
| 1659 |
+
|
| 1660 |
+
updateDraggedPiece(evt.originalEvent.changedTouches[0].pageX,
|
| 1661 |
+
evt.originalEvent.changedTouches[0].pageY)
|
| 1662 |
+
}
|
| 1663 |
+
|
| 1664 |
+
var throttledTouchmoveWindow = throttle(touchmoveWindow, config.dragThrottleRate)
|
| 1665 |
+
|
| 1666 |
+
function mouseupWindow (evt) {
|
| 1667 |
+
// do nothing if we are not dragging a piece
|
| 1668 |
+
if (!isDragging) return
|
| 1669 |
+
|
| 1670 |
+
// get the location
|
| 1671 |
+
var location = isXYOnSquare(evt.pageX, evt.pageY)
|
| 1672 |
+
|
| 1673 |
+
stopDraggedPiece(location)
|
| 1674 |
+
}
|
| 1675 |
+
|
| 1676 |
+
function touchendWindow (evt) {
|
| 1677 |
+
// do nothing if we are not dragging a piece
|
| 1678 |
+
if (!isDragging) return
|
| 1679 |
+
|
| 1680 |
+
// get the location
|
| 1681 |
+
var location = isXYOnSquare(evt.originalEvent.changedTouches[0].pageX,
|
| 1682 |
+
evt.originalEvent.changedTouches[0].pageY)
|
| 1683 |
+
|
| 1684 |
+
stopDraggedPiece(location)
|
| 1685 |
+
}
|
| 1686 |
+
|
| 1687 |
+
function mouseenterSquare (evt) {
|
| 1688 |
+
// do not fire this event if we are dragging a piece
|
| 1689 |
+
// NOTE: this should never happen, but it's a safeguard
|
| 1690 |
+
if (isDragging) return
|
| 1691 |
+
|
| 1692 |
+
// exit if they did not provide a onMouseoverSquare function
|
| 1693 |
+
if (!isFunction(config.onMouseoverSquare)) return
|
| 1694 |
+
|
| 1695 |
+
// get the square
|
| 1696 |
+
var square = $(evt.currentTarget).attr('data-square')
|
| 1697 |
+
|
| 1698 |
+
// NOTE: this should never happen; defensive
|
| 1699 |
+
if (!validSquare(square)) return
|
| 1700 |
+
|
| 1701 |
+
// get the piece on this square
|
| 1702 |
+
var piece = false
|
| 1703 |
+
if (currentPosition.hasOwnProperty(square)) {
|
| 1704 |
+
piece = currentPosition[square]
|
| 1705 |
+
}
|
| 1706 |
+
|
| 1707 |
+
// execute their function
|
| 1708 |
+
config.onMouseoverSquare(square, piece, deepCopy(currentPosition), currentOrientation)
|
| 1709 |
+
}
|
| 1710 |
+
|
| 1711 |
+
function mouseleaveSquare (evt) {
|
| 1712 |
+
// do not fire this event if we are dragging a piece
|
| 1713 |
+
// NOTE: this should never happen, but it's a safeguard
|
| 1714 |
+
if (isDragging) return
|
| 1715 |
+
|
| 1716 |
+
// exit if they did not provide an onMouseoutSquare function
|
| 1717 |
+
if (!isFunction(config.onMouseoutSquare)) return
|
| 1718 |
+
|
| 1719 |
+
// get the square
|
| 1720 |
+
var square = $(evt.currentTarget).attr('data-square')
|
| 1721 |
+
|
| 1722 |
+
// NOTE: this should never happen; defensive
|
| 1723 |
+
if (!validSquare(square)) return
|
| 1724 |
+
|
| 1725 |
+
// get the piece on this square
|
| 1726 |
+
var piece = false
|
| 1727 |
+
if (currentPosition.hasOwnProperty(square)) {
|
| 1728 |
+
piece = currentPosition[square]
|
| 1729 |
+
}
|
| 1730 |
+
|
| 1731 |
+
// execute their function
|
| 1732 |
+
config.onMouseoutSquare(square, piece, deepCopy(currentPosition), currentOrientation)
|
| 1733 |
+
}
|
| 1734 |
+
|
| 1735 |
+
// -------------------------------------------------------------------------
|
| 1736 |
+
// Initialization
|
| 1737 |
+
// -------------------------------------------------------------------------
|
| 1738 |
+
|
| 1739 |
+
function addEvents () {
|
| 1740 |
+
// prevent "image drag"
|
| 1741 |
+
$('body').on('mousedown mousemove', '.' + CSS.piece, stopDefault)
|
| 1742 |
+
|
| 1743 |
+
// mouse drag pieces
|
| 1744 |
+
$board.on('mousedown', '.' + CSS.square, mousedownSquare)
|
| 1745 |
+
$container.on('mousedown', '.' + CSS.sparePieces + ' .' + CSS.piece, mousedownSparePiece)
|
| 1746 |
+
|
| 1747 |
+
// mouse enter / leave square
|
| 1748 |
+
$board
|
| 1749 |
+
.on('mouseenter', '.' + CSS.square, mouseenterSquare)
|
| 1750 |
+
.on('mouseleave', '.' + CSS.square, mouseleaveSquare)
|
| 1751 |
+
|
| 1752 |
+
// piece drag
|
| 1753 |
+
var $window = $(window)
|
| 1754 |
+
$window
|
| 1755 |
+
.on('mousemove', throttledMousemoveWindow)
|
| 1756 |
+
.on('mouseup', mouseupWindow)
|
| 1757 |
+
|
| 1758 |
+
// touch drag pieces
|
| 1759 |
+
if (isTouchDevice()) {
|
| 1760 |
+
$board.on('touchstart', '.' + CSS.square, touchstartSquare)
|
| 1761 |
+
$container.on('touchstart', '.' + CSS.sparePieces + ' .' + CSS.piece, touchstartSparePiece)
|
| 1762 |
+
$window
|
| 1763 |
+
.on('touchmove', throttledTouchmoveWindow)
|
| 1764 |
+
.on('touchend', touchendWindow)
|
| 1765 |
+
}
|
| 1766 |
+
}
|
| 1767 |
+
|
| 1768 |
+
function initDOM () {
|
| 1769 |
+
// create unique IDs for all the elements we will create
|
| 1770 |
+
createElIds()
|
| 1771 |
+
|
| 1772 |
+
// build board and save it in memory
|
| 1773 |
+
$container.html(buildContainerHTML(config.sparePieces))
|
| 1774 |
+
$board = $container.find('.' + CSS.board)
|
| 1775 |
+
|
| 1776 |
+
if (config.sparePieces) {
|
| 1777 |
+
$sparePiecesTop = $container.find('.' + CSS.sparePiecesTop)
|
| 1778 |
+
$sparePiecesBottom = $container.find('.' + CSS.sparePiecesBottom)
|
| 1779 |
+
}
|
| 1780 |
+
|
| 1781 |
+
// create the drag piece
|
| 1782 |
+
var draggedPieceId = uuid()
|
| 1783 |
+
$('body').append(buildPieceHTML('wP', true, draggedPieceId))
|
| 1784 |
+
$draggedPiece = $('#' + draggedPieceId)
|
| 1785 |
+
|
| 1786 |
+
// TODO: need to remove this dragged piece element if the board is no
|
| 1787 |
+
// longer in the DOM
|
| 1788 |
+
|
| 1789 |
+
// get the border size
|
| 1790 |
+
boardBorderSize = parseInt($board.css('borderLeftWidth'), 10)
|
| 1791 |
+
|
| 1792 |
+
// set the size and draw the board
|
| 1793 |
+
widget.resize()
|
| 1794 |
+
}
|
| 1795 |
+
|
| 1796 |
+
// -------------------------------------------------------------------------
|
| 1797 |
+
// Initialization
|
| 1798 |
+
// -------------------------------------------------------------------------
|
| 1799 |
+
|
| 1800 |
+
setInitialState()
|
| 1801 |
+
initDOM()
|
| 1802 |
+
addEvents()
|
| 1803 |
+
|
| 1804 |
+
// return the widget object
|
| 1805 |
+
return widget
|
| 1806 |
+
} // end constructor
|
| 1807 |
+
|
| 1808 |
+
// TODO: do module exports here
|
| 1809 |
+
window['Chessboard'] = constructor
|
| 1810 |
+
|
| 1811 |
+
// support legacy ChessBoard name
|
| 1812 |
+
window['ChessBoard'] = window['Chessboard']
|
| 1813 |
+
|
| 1814 |
+
// expose util functions
|
| 1815 |
+
window['Chessboard']['fenToObj'] = fenToObj
|
| 1816 |
+
window['Chessboard']['objToFen'] = objToFen
|
| 1817 |
+
})() // end anonymous wrapper
|
js/chessboard-1.0.0.min.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*! chessboard.js v1.0.0 | (c) 2019 Chris Oakman | MIT License chessboardjs.com/license */
|
| 2 |
+
!function(){"use strict";var z=window.jQuery,F="abcdefgh".split(""),r=20,A="…",W="1.8.3",e="rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",G=pe(e),n=200,t=200,o=60,a=30,i=100,H={};function V(e,r,n){function t(){o=0,a&&(a=!1,s())}var o=0,a=!1,i=[],s=function(){o=window.setTimeout(t,r),e.apply(n,i)};return function(e){i=arguments,o?a=!0:s()}}function Z(){return"xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx".replace(/x/g,function(e){return(16*Math.random()|0).toString(16)})}function _(e){return JSON.parse(JSON.stringify(e))}function s(e){var r=e.split(".");return{major:parseInt(r[0],10),minor:parseInt(r[1],10),patch:parseInt(r[2],10)}}function ee(e,r){for(var n in r)if(r.hasOwnProperty(n))for(var t="{"+n+"}",o=r[n];-1!==e.indexOf(t);)e=e.replace(t,o);return e}function re(e){return"string"==typeof e}function ne(e){return"function"==typeof e}function p(e){return"number"==typeof e&&isFinite(e)&&Math.floor(e)===e}function c(e){return"fast"===e||"slow"===e||!!p(e)&&0<=e}function te(e){if(!re(e))return!1;var r=e.split("-");return 2===r.length&&(oe(r[0])&&oe(r[1]))}function oe(e){return re(e)&&-1!==e.search(/^[a-h][1-8]$/)}function u(e){return re(e)&&-1!==e.search(/^[bw][KQRNBP]$/)}function ae(e){if(!re(e))return!1;var r=(e=function(e){return e.replace(/8/g,"11111111").replace(/7/g,"1111111").replace(/6/g,"111111").replace(/5/g,"11111").replace(/4/g,"1111").replace(/3/g,"111").replace(/2/g,"11")}(e=e.replace(/ .+$/,""))).split("/");if(8!==r.length)return!1;for(var n=0;n<8;n++)if(8!==r[n].length||-1!==r[n].search(/[^kqrnbpKQRNBP1]/))return!1;return!0}function ie(e){if(!z.isPlainObject(e))return!1;for(var r in e)if(e.hasOwnProperty(r)&&(!oe(r)||!u(e[r])))return!1;return!0}function se(){return typeof window.$&&z.fn&&z.fn.jquery&&function(e,r){e=s(e),r=s(r);var n=1e5*e.major*1e5+1e5*e.minor+e.patch;return 1e5*r.major*1e5+1e5*r.minor+r.patch<=n}(z.fn.jquery,W)}function pe(e){if(!ae(e))return!1;for(var r,n=(e=e.replace(/ .+$/,"")).split("/"),t={},o=8,a=0;a<8;a++){for(var i=n[a].split(""),s=0,p=0;p<i.length;p++){if(-1!==i[p].search(/[1-8]/))s+=parseInt(i[p],10);else t[F[s]+o]=(r=i[p]).toLowerCase()===r?"b"+r.toUpperCase():"w"+r.toUpperCase(),s+=1}o-=1}return t}function ce(e){if(!ie(e))return!1;for(var r,n,t="",o=8,a=0;a<8;a++){for(var i=0;i<8;i++){var s=F[i]+o;e.hasOwnProperty(s)?t+=(r=e[s],n=void 0,"w"===(n=r.split(""))[0]?n[1].toUpperCase():n[1].toLowerCase()):t+="1"}7!==a&&(t+="/"),o-=1}return t=function(e){return e.replace(/11111111/g,"8").replace(/1111111/g,"7").replace(/111111/g,"6").replace(/11111/g,"5").replace(/1111/g,"4").replace(/111/g,"3").replace(/11/g,"2")}(t)}function ue(e,r,n){for(var t=function(e){for(var r=[],n=0;n<8;n++)for(var t=0;t<8;t++){var o=F[n]+(t+1);e!==o&&r.push({square:o,distance:(a=e,i=o,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,s=a.split(""),p=F.indexOf(s[0])+1,c=parseInt(s[1],10),u=i.split(""),f=F.indexOf(u[0])+1,d=parseInt(u[1],10),h=Math.abs(p-f),l=Math.abs(c-d),l<=h?h:l)})}var a,i,s,p,c,u,f,d,h,l;r.sort(function(e,r){return e.distance-r.distance});var v=[];for(n=0;n<r.length;n++)v.push(r[n].square);return v}(n),o=0;o<t.length;o++){var a=t[o];if(e.hasOwnProperty(a)&&e[a]===r)return a}return!1}function fe(e){return"black"!==e.orientation&&(e.orientation="white"),!1!==e.showNotation&&(e.showNotation=!0),!0!==e.draggable&&(e.draggable=!1),"trash"!==e.dropOffBoard&&(e.dropOffBoard="snapback"),!0!==e.sparePieces&&(e.sparePieces=!1),e.sparePieces&&(e.draggable=!0),e.hasOwnProperty("pieceTheme")&&(re(e.pieceTheme)||ne(e.pieceTheme))||(e.pieceTheme="img/chesspieces/wikipedia/{piece}.png"),c(e.appearSpeed)||(e.appearSpeed=n),c(e.moveSpeed)||(e.moveSpeed=t),c(e.snapbackSpeed)||(e.snapbackSpeed=o),c(e.snapSpeed)||(e.snapSpeed=a),c(e.trashSpeed)||(e.trashSpeed=i),function(e){return p(e)&&1<=e}(e.dragThrottleRate)||(e.dragThrottleRate=r),e}H.alpha="alpha-d2270",H.black="black-3c85d",H.board="board-b72b1",H.chessboard="chessboard-63f37",H.clearfix="clearfix-7da63",H.highlight1="highlight1-32417",H.highlight2="highlight2-9c5d2",H.notation="notation-322f9",H.numeric="numeric-fc462",H.piece="piece-417db",H.row="row-5277c",H.sparePieces="spare-pieces-7492f",H.sparePiecesBottom="spare-pieces-bottom-ae20f",H.sparePiecesTop="spare-pieces-top-4028b",H.square="square-55d63",H.white="white-1e1d7",window.Chessboard=function(e,f){if(!function(){if(se())return!0;var e="Chessboard Error 1005: Unable to find a valid version of jQuery. Please include jQuery "+W+" or higher on the page\n\nExiting"+A;return window.alert(e),!1}())return null;var n=function(e){if(""===e){var r="Chessboard Error 1001: The first argument to Chessboard() cannot be an empty string.\n\nExiting"+A;return window.alert(r),!1}re(e)&&"#"!==e.charAt(0)&&(e="#"+e);var n=z(e);if(1===n.length)return n;var t="Chessboard Error 1003: The first argument to Chessboard() must be the ID of a DOM node, an ID query selector, or a single DOM node.\n\nExiting"+A;return window.alert(t),!1}(e);if(!n)return null;f=fe(f=function(e){return"start"===e?e={position:_(G)}:ae(e)?e={position:pe(e)}:ie(e)&&(e={position:_(e)}),z.isPlainObject(e)||(e={}),e}(f));var r=null,a=null,t=null,o=null,i={},s=2,p="white",c={},u=null,d=null,h=null,l=!1,v={},g={},w={},b=16;function m(e,r,n){if(!0===f.hasOwnProperty("showErrors")&&!1!==f.showErrors){var t="Chessboard Error "+e+": "+r;return"console"===f.showErrors&&"object"==typeof console&&"function"==typeof console.log?(console.log(t),void(2<=arguments.length&&console.log(n))):"alert"===f.showErrors?(n&&(t+="\n\n"+JSON.stringify(n)),void window.alert(t)):void(ne(f.showErrors)&&f.showErrors(e,r,n))}}function P(e){return ne(f.pieceTheme)?f.pieceTheme(e):re(f.pieceTheme)?ee(f.pieceTheme,{piece:e}):(m(8272,"Unable to build image source for config.pieceTheme."),"")}function y(e,r,n){var t='<img src="'+P(e)+'" ';return re(n)&&""!==n&&(t+='id="'+n+'" '),t+='alt="" class="{piece}" data-piece="'+e+'" style="width:'+b+"px;height:"+b+"px;",r&&(t+="display:none;"),ee(t+='" />',H)}function x(e){var r=["wK","wQ","wR","wB","wN","wP"];"black"===e&&(r=["bK","bQ","bR","bB","bN","bP"]);for(var n="",t=0;t<r.length;t++)n+=y(r[t],!1,v[r[t]]);return n}function O(e,r,n,t){var o=z("#"+g[e]),a=o.offset(),i=z("#"+g[r]),s=i.offset(),p=Z();z("body").append(y(n,!0,p));var c=z("#"+p);c.css({display:"",position:"absolute",top:a.top,left:a.left}),o.find("."+H.piece).remove();var u={duration:f.moveSpeed,complete:function(){i.append(y(n)),c.remove(),ne(t)&&t()}};c.animate(s,u)}function S(e,r,n){var t=z("#"+v[e]).offset(),o=z("#"+g[r]),a=o.offset(),i=Z();z("body").append(y(e,!0,i));var s=z("#"+i);s.css({display:"",position:"absolute",left:t.left,top:t.top});var p={duration:f.moveSpeed,complete:function(){o.find("."+H.piece).remove(),o.append(y(e)),s.remove(),ne(n)&&n()}};s.animate(a,p)}function T(){for(var e in r.find("."+H.piece).remove(),c)c.hasOwnProperty(e)&&z("#"+g[e]).append(y(c[e]))}function q(){r.html(function(e){"black"!==e&&(e="white");var r="",n=_(F),t=8;"black"===e&&(n.reverse(),t=1);for(var o="white",a=0;a<8;a++){r+='<div class="{row}">';for(var i=0;i<8;i++){var s=n[i]+t;r+='<div class="{square} '+H[o]+" square-"+s+'" style="width:'+b+"px;height:"+b+'px;" id="'+g[s]+'" data-square="'+s+'">',f.showNotation&&(("white"===e&&1===t||"black"===e&&8===t)&&(r+='<div class="{notation} {alpha}">'+n[i]+"</div>"),0===i&&(r+='<div class="{notation} {numeric}">'+t+"</div>")),r+="</div>",o="white"===o?"black":"white"}r+='<div class="{clearfix}"></div></div>',o="white"===o?"black":"white","white"===e?t-=1:t+=1}return ee(r,H)}(p,f.showNotation)),T(),f.sparePieces&&("white"===p?(t.html(x("black")),o.html(x("white"))):(t.html(x("white")),o.html(x("black"))))}function k(e){var r=_(c),n=_(e);ce(r)!==ce(n)&&(ne(f.onChange)&&f.onChange(r,n),c=e)}function E(e,r){for(var n in w)if(w.hasOwnProperty(n)){var t=w[n];if(e>=t.left&&e<t.left+b&&r>=t.top&&r<t.top+b)return n}return"offboard"}function C(){r.find("."+H.square).removeClass(H.highlight1+" "+H.highlight2)}function B(){C();var e=_(c);delete e[h],k(e),T(),a.fadeOut(f.trashSpeed),l=!1}function I(e,r,n,t){ne(f.onDragStart)&&!1===f.onDragStart(e,r,_(c),p)||(l=!0,u=r,d="spare"===(h=e)?"offboard":e,function(){for(var e in w={},g)g.hasOwnProperty(e)&&(w[e]=z("#"+g[e]).offset())}(),a.attr("src",P(r)).css({display:"",position:"absolute",left:n-b/2,top:t-b/2}),"spare"!==e&&z("#"+g[e]).addClass(H.highlight1).find("."+H.piece).css("display","none"))}function M(e,r){a.css({left:e-b/2,top:r-b/2});var n=E(e,r);n!==d&&(oe(d)&&z("#"+g[d]).removeClass(H.highlight2),oe(n)&&z("#"+g[n]).addClass(H.highlight2),ne(f.onDragMove)&&f.onDragMove(n,d,h,u,_(c),p),d=n)}function N(e){var r="drop";if("offboard"===e&&"snapback"===f.dropOffBoard&&(r="snapback"),"offboard"===e&&"trash"===f.dropOffBoard&&(r="trash"),ne(f.onDrop)){var n=_(c);"spare"===h&&oe(e)&&(n[e]=u),oe(h)&&"offboard"===e&&delete n[h],oe(h)&&oe(e)&&(delete n[h],n[e]=u);var t=_(c),o=f.onDrop(h,e,u,n,t,p);"snapback"!==o&&"trash"!==o||(r=o)}"snapback"===r?function(){if("spare"!==h){C();var e=z("#"+g[h]).offset(),r={duration:f.snapbackSpeed,complete:function(){T(),a.css("display","none"),ne(f.onSnapbackEnd)&&f.onSnapbackEnd(u,h,_(c),p)}};a.animate(e,r),l=!1}else B()}():"trash"===r?B():"drop"===r&&function(e){C();var r=_(c);delete r[h],r[e]=u,k(r);var n=z("#"+g[e]).offset(),t={duration:f.snapSpeed,complete:function(){T(),a.css("display","none"),ne(f.onSnapEnd)&&f.onSnapEnd(h,e,u)}};a.animate(n,t),l=!1}(e)}function j(e){e.preventDefault()}function D(e){if(f.draggable){var r=z(this).attr("data-square");oe(r)&&c.hasOwnProperty(r)&&I(r,c[r],e.pageX,e.pageY)}}function R(e){if(f.draggable){var r=z(this).attr("data-square");oe(r)&&c.hasOwnProperty(r)&&(e=e.originalEvent,I(r,c[r],e.changedTouches[0].pageX,e.changedTouches[0].pageY))}}function Q(e){f.sparePieces&&I("spare",z(this).attr("data-piece"),e.pageX,e.pageY)}function X(e){f.sparePieces&&I("spare",z(this).attr("data-piece"),(e=e.originalEvent).changedTouches[0].pageX,e.changedTouches[0].pageY)}i.clear=function(e){i.position({},e)},i.destroy=function(){n.html(""),a.remove(),n.unbind()},i.fen=function(){return i.position("fen")},i.flip=function(){return i.orientation("flip")},i.move=function(){if(0!==arguments.length){for(var e=!0,r={},n=0;n<arguments.length;n++)if(!1!==arguments[n])if(te(arguments[n])){var t=arguments[n].split("-");r[t[0]]=t[1]}else m(2826,"Invalid move passed to the move method.",arguments[n]);else e=!1;var o=function(e,r){var n=_(e);for(var t in r)if(r.hasOwnProperty(t)&&n.hasOwnProperty(t)){var o=n[t];delete n[t],n[r[t]]=o}return n}(c,r);return i.position(o,e),o}},i.orientation=function(e){return 0===arguments.length?p:"white"===e||"black"===e?(p=e,q(),p):"flip"===e?(p="white"===p?"black":"white",q(),p):void m(5482,"Invalid value passed to the orientation method.",e)},i.position=function(e,r){if(0===arguments.length)return _(c);if(re(e)&&"fen"===e.toLowerCase())return ce(c);(re(e)&&"start"===e.toLowerCase()&&(e=_(G)),ae(e)&&(e=pe(e)),ie(e))?(!1!==r&&(r=!0),r?(function(e,r,n){if(0!==e.length)for(var t=0,o=0;o<e.length;o++){var a=e[o];"clear"===a.type?z("#"+g[a.square]+" ."+H.piece).fadeOut(f.trashSpeed,i):"add"!==a.type||f.sparePieces?"add"===a.type&&f.sparePieces?S(a.piece,a.square,i):"move"===a.type&&O(a.source,a.destination,a.piece,i):z("#"+g[a.square]).append(y(a.piece,!0)).find("."+H.piece).fadeIn(f.appearSpeed,i)}function i(){(t+=1)===e.length&&(T(),ne(f.onMoveEnd)&&f.onMoveEnd(_(r),_(n)))}}(function(e,r){e=_(e),r=_(r);var n=[],t={};for(var o in r)r.hasOwnProperty(o)&&e.hasOwnProperty(o)&&e[o]===r[o]&&(delete e[o],delete r[o]);for(o in r)if(r.hasOwnProperty(o)){var a=ue(e,r[o],o);a&&(n.push({type:"move",source:a,destination:o,piece:r[o]}),delete e[a],delete r[o],t[o]=!0)}for(o in r)r.hasOwnProperty(o)&&(n.push({type:"add",square:o,piece:r[o]}),delete r[o]);for(o in e)e.hasOwnProperty(o)&&(t.hasOwnProperty(o)||(n.push({type:"clear",square:o,piece:e[o]}),delete e[o]));return n}(c,e),c,e),k(e)):(k(e),T())):m(6482,"Invalid value passed to the position method.",e)},i.resize=function(){b=function(){var e=parseInt(n.width(),10);if(!e||e<=0)return 0;for(var r=e-1;r%8!=0&&0<r;)r-=1;return r/8}(),r.css("width",8*b+"px"),a.css({height:b,width:b}),f.sparePieces&&n.find("."+H.sparePieces).css("paddingLeft",b+s+"px"),q()},i.start=function(e){i.position("start",e)};var Y=V(function(e){l&&M(e.pageX,e.pageY)},f.dragThrottleRate),K=V(function(e){l&&(e.preventDefault(),M(e.originalEvent.changedTouches[0].pageX,e.originalEvent.changedTouches[0].pageY))},f.dragThrottleRate);function L(e){l&&N(E(e.pageX,e.pageY))}function U(e){l&&N(E(e.originalEvent.changedTouches[0].pageX,e.originalEvent.changedTouches[0].pageY))}function $(e){if(!l&&ne(f.onMouseoverSquare)){var r=z(e.currentTarget).attr("data-square");if(oe(r)){var n=!1;c.hasOwnProperty(r)&&(n=c[r]),f.onMouseoverSquare(r,n,_(c),p)}}}function J(e){if(!l&&ne(f.onMouseoutSquare)){var r=z(e.currentTarget).attr("data-square");if(oe(r)){var n=!1;c.hasOwnProperty(r)&&(n=c[r]),f.onMouseoutSquare(r,n,_(c),p)}}}return p=f.orientation,f.hasOwnProperty("position")&&("start"===f.position?c=_(G):ae(f.position)?c=pe(f.position):ie(f.position)?c=_(f.position):m(7263,"Invalid value passed to config.position.",f.position)),function(){!function(){for(var e=0;e<F.length;e++)for(var r=1;r<=8;r++){var n=F[e]+r;g[n]=n+"-"+Z()}var t="KQRNBP".split("");for(e=0;e<t.length;e++){var o="w"+t[e],a="b"+t[e];v[o]=o+"-"+Z(),v[a]=a+"-"+Z()}}(),n.html(function(e){var r='<div class="{chessboard}">';return e&&(r+='<div class="{sparePieces} {sparePiecesTop}"></div>'),r+='<div class="{board}"></div>',e&&(r+='<div class="{sparePieces} {sparePiecesBottom}"></div>'),ee(r+="</div>",H)}(f.sparePieces)),r=n.find("."+H.board),f.sparePieces&&(t=n.find("."+H.sparePiecesTop),o=n.find("."+H.sparePiecesBottom));var e=Z();z("body").append(y("wP",!0,e)),a=z("#"+e),s=parseInt(r.css("borderLeftWidth"),10),i.resize()}(),function(){z("body").on("mousedown mousemove","."+H.piece,j),r.on("mousedown","."+H.square,D),n.on("mousedown","."+H.sparePieces+" ."+H.piece,Q),r.on("mouseenter","."+H.square,$).on("mouseleave","."+H.square,J);var e=z(window);e.on("mousemove",Y).on("mouseup",L),"ontouchstart"in document.documentElement&&(r.on("touchstart","."+H.square,R),n.on("touchstart","."+H.sparePieces+" ."+H.piece,X),e.on("touchmove",K).on("touchend",U))}(),i},window.ChessBoard=window.Chessboard,window.Chessboard.fenToObj=pe,window.Chessboard.objToFen=ce}();
|
helpers.js → js/helpers.js
RENAMED
|
@@ -8,7 +8,7 @@ function convertTypedArray(src, type) {
|
|
| 8 |
|
| 9 |
var printTextarea = (function() {
|
| 10 |
var element = document.getElementById('output');
|
| 11 |
-
if (element) element.
|
| 12 |
return function(text) {
|
| 13 |
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
| 14 |
console.log(text);
|
|
@@ -22,6 +22,7 @@ var printTextarea = (function() {
|
|
| 22 |
async function clearCache() {
|
| 23 |
if (confirm('Are you sure you want to clear the cache?\nAll the models will be downloaded again.')) {
|
| 24 |
indexedDB.deleteDatabase(dbName);
|
|
|
|
| 25 |
}
|
| 26 |
}
|
| 27 |
|
|
@@ -88,11 +89,15 @@ async function fetchRemote(url, cbProgress, cbPrint) {
|
|
| 88 |
// - check if the data is already in the IndexedDB
|
| 89 |
// - if not, fetch it from the remote URL and store it in the IndexedDB
|
| 90 |
function loadRemote(url, dst, size_mb, cbProgress, cbReady, cbCancel, cbPrint) {
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
|
| 97 |
// check if the data is already in the IndexedDB
|
| 98 |
var rq = indexedDB.open(dbName, dbVersion);
|
|
@@ -141,7 +146,15 @@ function loadRemote(url, dst, size_mb, cbProgress, cbReady, cbCancel, cbPrint) {
|
|
| 141 |
var db = event.target.result;
|
| 142 |
var tx = db.transaction(['models'], 'readwrite');
|
| 143 |
var os = tx.objectStore('models');
|
| 144 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
|
| 146 |
rq.onsuccess = function (event) {
|
| 147 |
cbPrint('loadRemote: "' + url + '" stored in the IndexedDB');
|
|
@@ -176,7 +189,6 @@ function loadRemote(url, dst, size_mb, cbProgress, cbReady, cbCancel, cbPrint) {
|
|
| 176 |
|
| 177 |
rq.onabort = function (event) {
|
| 178 |
cbPrint('loadRemote: failed to open IndexedDB: abort');
|
| 179 |
-
|
| 180 |
};
|
| 181 |
}
|
| 182 |
-
|
|
|
|
| 8 |
|
| 9 |
var printTextarea = (function() {
|
| 10 |
var element = document.getElementById('output');
|
| 11 |
+
if (element) element.value = ''; // clear browser cache
|
| 12 |
return function(text) {
|
| 13 |
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
| 14 |
console.log(text);
|
|
|
|
| 22 |
async function clearCache() {
|
| 23 |
if (confirm('Are you sure you want to clear the cache?\nAll the models will be downloaded again.')) {
|
| 24 |
indexedDB.deleteDatabase(dbName);
|
| 25 |
+
location.reload();
|
| 26 |
}
|
| 27 |
}
|
| 28 |
|
|
|
|
| 89 |
// - check if the data is already in the IndexedDB
|
| 90 |
// - if not, fetch it from the remote URL and store it in the IndexedDB
|
| 91 |
function loadRemote(url, dst, size_mb, cbProgress, cbReady, cbCancel, cbPrint) {
|
| 92 |
+
if (!navigator.storage || !navigator.storage.estimate) {
|
| 93 |
+
cbPrint('loadRemote: navigator.storage.estimate() is not supported');
|
| 94 |
+
} else {
|
| 95 |
+
// query the storage quota and print it
|
| 96 |
+
navigator.storage.estimate().then(function (estimate) {
|
| 97 |
+
cbPrint('loadRemote: storage quota: ' + estimate.quota + ' bytes');
|
| 98 |
+
cbPrint('loadRemote: storage usage: ' + estimate.usage + ' bytes');
|
| 99 |
+
});
|
| 100 |
+
}
|
| 101 |
|
| 102 |
// check if the data is already in the IndexedDB
|
| 103 |
var rq = indexedDB.open(dbName, dbVersion);
|
|
|
|
| 146 |
var db = event.target.result;
|
| 147 |
var tx = db.transaction(['models'], 'readwrite');
|
| 148 |
var os = tx.objectStore('models');
|
| 149 |
+
|
| 150 |
+
var rq = null;
|
| 151 |
+
try {
|
| 152 |
+
var rq = os.put(data, url);
|
| 153 |
+
} catch (e) {
|
| 154 |
+
cbPrint('loadRemote: failed to store "' + url + '" in the IndexedDB: \n' + e);
|
| 155 |
+
cbCancel();
|
| 156 |
+
return;
|
| 157 |
+
}
|
| 158 |
|
| 159 |
rq.onsuccess = function (event) {
|
| 160 |
cbPrint('loadRemote: "' + url + '" stored in the IndexedDB');
|
|
|
|
| 189 |
|
| 190 |
rq.onabort = function (event) {
|
| 191 |
cbPrint('loadRemote: failed to open IndexedDB: abort');
|
| 192 |
+
cbCancel();
|
| 193 |
};
|
| 194 |
}
|
|
|
js/jquery-3.7.1.min.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */
|
| 2 |
+
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}function fe(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}ce.fn=ce.prototype={jquery:t,constructor:ce,length:0,toArray:function(){return ae.call(this)},get:function(e){return null==e?ae.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=ce.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return ce.each(this,e)},map:function(n){return this.pushStack(ce.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(ae.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(ce.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(ce.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:oe.sort,splice:oe.splice},ce.extend=ce.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||v(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(ce.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||ce.isPlainObject(n)?n:{},i=!1,a[t]=ce.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},ce.extend({expando:"jQuery"+(t+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==i.call(e))&&(!(t=r(e))||"function"==typeof(n=ue.call(t,"constructor")&&t.constructor)&&o.call(n)===a)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){m(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(c(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},text:function(e){var t,n="",r=0,i=e.nodeType;if(!i)while(t=e[r++])n+=ce.text(t);return 1===i||11===i?e.textContent:9===i?e.documentElement.textContent:3===i||4===i?e.nodeValue:n},makeArray:function(e,t){var n=t||[];return null!=e&&(c(Object(e))?ce.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:se.call(t,e,n)},isXMLDoc:function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!l.test(t||n&&n.nodeName||"HTML")},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(c(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:le}),"function"==typeof Symbol&&(ce.fn[Symbol.iterator]=oe[Symbol.iterator]),ce.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var pe=oe.pop,de=oe.sort,he=oe.splice,ge="[\\x20\\t\\r\\n\\f]",ve=new RegExp("^"+ge+"+|((?:^|[^\\\\])(?:\\\\.)*)"+ge+"+$","g");ce.contains=function(e,t){var n=t&&t.parentNode;return e===n||!(!n||1!==n.nodeType||!(e.contains?e.contains(n):e.compareDocumentPosition&&16&e.compareDocumentPosition(n)))};var f=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;function p(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e}ce.escapeSelector=function(e){return(e+"").replace(f,p)};var ye=C,me=s;!function(){var e,b,w,o,a,T,r,C,d,i,k=me,S=ce.expando,E=0,n=0,s=W(),c=W(),u=W(),h=W(),l=function(e,t){return e===t&&(a=!0),0},f="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",t="(?:\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",p="\\["+ge+"*("+t+")(?:"+ge+"*([*^$|!~]?=)"+ge+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+t+"))|)"+ge+"*\\]",g=":("+t+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+p+")*)|.*)\\)|)",v=new RegExp(ge+"+","g"),y=new RegExp("^"+ge+"*,"+ge+"*"),m=new RegExp("^"+ge+"*([>+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="<a id='"+S+"' href='' disabled='disabled'></a><select id='"+S+"-\r\\' disabled='disabled'><option selected=''></option></select>",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0<I(t,T,null,[e]).length},I.contains=function(e,t){return(e.ownerDocument||e)!=T&&V(e),ce.contains(e,t)},I.attr=function(e,t){(e.ownerDocument||e)!=T&&V(e);var n=b.attrHandle[t.toLowerCase()],r=n&&ue.call(b.attrHandle,t.toLowerCase())?n(e,t,!C):void 0;return void 0!==r?r:e.getAttribute(t)},I.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},ce.uniqueSort=function(e){var t,n=[],r=0,i=0;if(a=!le.sortStable,o=!le.sortStable&&ae.call(e,0),de.call(e,l),a){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)he.call(e,n[r],1)}return o=null,e},ce.fn.uniqueSort=function(){return this.pushStack(ce.uniqueSort(ae.apply(this)))},(b=ce.expr={cacheLength:50,createPseudo:F,match:D,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(v," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(d,e,t,h,g){var v="nth"!==d.slice(0,3),y="last"!==d.slice(-4),m="of-type"===e;return 1===h&&0===g?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u=v!==y?"nextSibling":"previousSibling",l=e.parentNode,c=m&&e.nodeName.toLowerCase(),f=!n&&!m,p=!1;if(l){if(v){while(u){o=e;while(o=o[u])if(m?fe(o,c):1===o.nodeType)return!1;s=u="only"===d&&!s&&"nextSibling"}return!0}if(s=[y?l.firstChild:l.lastChild],y&&f){p=(a=(r=(i=l[S]||(l[S]={}))[d]||[])[0]===E&&r[1])&&r[2],o=a&&l.childNodes[a];while(o=++a&&o&&o[u]||(p=a=0)||s.pop())if(1===o.nodeType&&++p&&o===e){i[d]=[E,a,p];break}}else if(f&&(p=a=(r=(i=e[S]||(e[S]={}))[d]||[])[0]===E&&r[1]),!1===p)while(o=++a&&o&&o[u]||(p=a=0)||s.pop())if((m?fe(o,c):1===o.nodeType)&&++p&&(f&&((i=o[S]||(o[S]={}))[d]=[E,p]),o===e))break;return(p-=g)===h||p%h==0&&0<=p/h}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||I.error("unsupported pseudo: "+e);return a[S]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?F(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=se.call(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:F(function(e){var r=[],i=[],s=ne(e.replace(ve,"$1"));return s[S]?F(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:F(function(t){return function(e){return 0<I(t,e).length}}),contains:F(function(t){return t=t.replace(O,P),function(e){return-1<(e.textContent||ce.text(e)).indexOf(t)}}),lang:F(function(n){return A.test(n||"")||I.error("unsupported lang: "+n),n=n.replace(O,P).toLowerCase(),function(e){var t;do{if(t=C?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=ie.location&&ie.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===r},focus:function(e){return e===function(){try{return T.activeElement}catch(e){}}()&&T.hasFocus()&&!!(e.type||e.href||~e.tabIndex)},enabled:z(!1),disabled:z(!0),checked:function(e){return fe(e,"input")&&!!e.checked||fe(e,"option")&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return q.test(e.nodeName)},input:function(e){return N.test(e.nodeName)},button:function(e){return fe(e,"input")&&"button"===e.type||fe(e,"button")},text:function(e){var t;return fe(e,"input")&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:X(function(){return[0]}),last:X(function(e,t){return[t-1]}),eq:X(function(e,t,n){return[n<0?n+t:n]}),even:X(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:X(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:X(function(e,t,n){var r;for(r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:X(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=B(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=_(e);function G(){}function Y(e,t){var n,r,i,o,a,s,u,l=c[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=y.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=m.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace(ve," ")}),a=a.slice(n.length)),b.filter)!(r=D[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?I.error(e):c(e,s).slice(0)}function Q(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function J(a,e,t){var s=e.dir,u=e.next,l=u||s,c=t&&"parentNode"===l,f=n++;return e.first?function(e,t,n){while(e=e[s])if(1===e.nodeType||c)return a(e,t,n);return!1}:function(e,t,n){var r,i,o=[E,f];if(n){while(e=e[s])if((1===e.nodeType||c)&&a(e,t,n))return!0}else while(e=e[s])if(1===e.nodeType||c)if(i=e[S]||(e[S]={}),u&&fe(e,u))e=e[s]||e;else{if((r=i[l])&&r[0]===E&&r[1]===f)return o[2]=r[2];if((i[l]=o)[2]=a(e,t,n))return!0}return!1}}function K(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Z(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function ee(d,h,g,v,y,e){return v&&!v[S]&&(v=ee(v)),y&&!y[S]&&(y=ee(y,e)),F(function(e,t,n,r){var i,o,a,s,u=[],l=[],c=t.length,f=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)I(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),p=!d||!e&&h?f:Z(f,u,d,n,r);if(g?g(p,s=y||(e?d:c||v)?[]:t,n,r):s=p,v){i=Z(s,l),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(s[l[o]]=!(p[l[o]]=a))}if(e){if(y||d){if(y){i=[],o=s.length;while(o--)(a=s[o])&&i.push(p[o]=a);y(null,s=[],i,r)}o=s.length;while(o--)(a=s[o])&&-1<(i=y?se.call(e,a):u[o])&&(e[i]=!(t[i]=a))}}else s=Z(s===t?s.splice(c,s.length):s),y?y(null,t,s,r):k.apply(t,s)})}function te(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=J(function(e){return e===i},a,!0),l=J(function(e){return-1<se.call(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!=w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[J(K(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return ee(1<s&&K(c),1<s&&Q(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(ve,"$1"),t,s<n&&te(e.slice(s,n)),n<r&&te(e=e.slice(n)),n<r&&Q(e))}c.push(t)}return K(c)}function ne(e,t){var n,v,y,m,x,r,i=[],o=[],a=u[e+" "];if(!a){t||(t=Y(e)),n=t.length;while(n--)(a=te(t[n]))[S]?i.push(a):o.push(a);(a=u(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=E+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==T||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==T||(V(o),n=!C);while(s=v[a++])if(s(o,t||T,n)){k.call(r,o);break}i&&(E=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=pe.call(r));f=Z(f)}k.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&ce.uniqueSort(r)}return i&&(E=h,w=p),c},m?F(r):r))).selector=e}return a}function re(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&Y(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&C&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(O,P),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=D.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(O,P),H.test(o[0].type)&&U(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&Q(o)))return k.apply(n,r),n;break}}}return(l||ne(e,c))(r,t,!C,n,!t||H.test(e)&&U(t.parentNode)||t),n}G.prototype=b.filters=b.pseudos,b.setFilters=new G,le.sortStable=S.split("").sort(l).join("")===S,V(),le.sortDetached=$(function(e){return 1&e.compareDocumentPosition(T.createElement("fieldset"))}),ce.find=I,ce.expr[":"]=ce.expr.pseudos,ce.unique=ce.uniqueSort,I.compile=ne,I.select=re,I.setDocument=V,I.tokenize=Y,I.escape=ce.escapeSelector,I.getText=ce.text,I.isXML=ce.isXMLDoc,I.selectors=ce.expr,I.support=ce.support,I.uniqueSort=ce.uniqueSort}();var d=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&ce(e).is(n))break;r.push(e)}return r},h=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},b=ce.expr.match.needsContext,w=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1<se.call(n,e)!==r}):ce.filter(n,e,r)}ce.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?ce.find.matchesSelector(r,e)?[r]:[]:ce.find.matches(e,ce.grep(t,function(e){return 1===e.nodeType}))},ce.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(ce(e).filter(function(){for(t=0;t<r;t++)if(ce.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)ce.find(e,i[t],n);return 1<r?ce.uniqueSort(n):n},filter:function(e){return this.pushStack(T(this,e||[],!1))},not:function(e){return this.pushStack(T(this,e||[],!0))},is:function(e){return!!T(this,"string"==typeof e&&b.test(e)?ce(e):e||[],!1).length}});var k,S=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(ce.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&ce(e);if(!b.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&ce.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?ce.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?se.call(ce(e),this[0]):se.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(ce.uniqueSort(ce.merge(this.get(),ce(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),ce.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return d(e,"parentNode")},parentsUntil:function(e,t,n){return d(e,"parentNode",n)},next:function(e){return A(e,"nextSibling")},prev:function(e){return A(e,"previousSibling")},nextAll:function(e){return d(e,"nextSibling")},prevAll:function(e){return d(e,"previousSibling")},nextUntil:function(e,t,n){return d(e,"nextSibling",n)},prevUntil:function(e,t,n){return d(e,"previousSibling",n)},siblings:function(e){return h((e.parentNode||{}).firstChild,e)},children:function(e){return h(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(fe(e,"template")&&(e=e.content||e),ce.merge([],e.childNodes))}},function(r,i){ce.fn[r]=function(e,t){var n=ce.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=ce.filter(t,n)),1<this.length&&(j[r]||ce.uniqueSort(n),E.test(r)&&n.reverse()),this.pushStack(n)}});var D=/[^\x20\t\r\n\f]+/g;function N(e){return e}function q(e){throw e}function L(e,t,n,r){var i;try{e&&v(i=e.promise)?i.call(e).done(t).fail(n):e&&v(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}ce.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},ce.each(e.match(D)||[],function(e,t){n[t]=!0}),n):ce.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){ce.each(e,function(e,t){v(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==x(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return ce.each(arguments,function(e,t){var n;while(-1<(n=ce.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<ce.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},ce.extend({Deferred:function(e){var o=[["notify","progress",ce.Callbacks("memory"),ce.Callbacks("memory"),2],["resolve","done",ce.Callbacks("once memory"),ce.Callbacks("once memory"),0,"resolved"],["reject","fail",ce.Callbacks("once memory"),ce.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return ce.Deferred(function(r){ce.each(o,function(e,t){var n=v(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&v(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,v(t)?s?t.call(e,l(u,o,N,s),l(u,o,q,s)):(u++,t.call(e,l(u,o,N,s),l(u,o,q,s),l(u,o,N,o.notifyWith))):(a!==N&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){ce.Deferred.exceptionHook&&ce.Deferred.exceptionHook(e,t.error),u<=i+1&&(a!==q&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(ce.Deferred.getErrorHook?t.error=ce.Deferred.getErrorHook():ce.Deferred.getStackHook&&(t.error=ce.Deferred.getStackHook()),ie.setTimeout(t))}}return ce.Deferred(function(e){o[0][3].add(l(0,e,v(r)?r:N,e.notifyWith)),o[1][3].add(l(0,e,v(t)?t:N)),o[2][3].add(l(0,e,v(n)?n:q))}).promise()},promise:function(e){return null!=e?ce.extend(e,a):a}},s={};return ce.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=ae.call(arguments),o=ce.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?ae.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(L(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||v(i[t]&&i[t].then)))return o.then();while(t--)L(i[t],a(t),o.reject);return o.promise()}});var H=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;ce.Deferred.exceptionHook=function(e,t){ie.console&&ie.console.warn&&e&&H.test(e.name)&&ie.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},ce.readyException=function(e){ie.setTimeout(function(){throw e})};var O=ce.Deferred();function P(){C.removeEventListener("DOMContentLoaded",P),ie.removeEventListener("load",P),ce.ready()}ce.fn.ready=function(e){return O.then(e)["catch"](function(e){ce.readyException(e)}),this},ce.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--ce.readyWait:ce.isReady)||(ce.isReady=!0)!==e&&0<--ce.readyWait||O.resolveWith(C,[ce])}}),ce.ready.then=O.then,"complete"===C.readyState||"loading"!==C.readyState&&!C.documentElement.doScroll?ie.setTimeout(ce.ready):(C.addEventListener("DOMContentLoaded",P),ie.addEventListener("load",P));var M=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===x(n))for(s in i=!0,n)M(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,v(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(ce(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},R=/^-ms-/,I=/-([a-z])/g;function W(e,t){return t.toUpperCase()}function F(e){return e.replace(R,"ms-").replace(I,W)}var $=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function B(){this.expando=ce.expando+B.uid++}B.uid=1,B.prototype={cache:function(e){var t=e[this.expando];return t||(t={},$(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[F(t)]=n;else for(r in t)i[F(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][F(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(F):(t=F(t))in r?[t]:t.match(D)||[]).length;while(n--)delete r[t[n]]}(void 0===t||ce.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!ce.isEmptyObject(t)}};var _=new B,z=new B,X=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,U=/[A-Z]/g;function V(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(U,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:X.test(i)?JSON.parse(i):i)}catch(e){}z.set(e,t,n)}else n=void 0;return n}ce.extend({hasData:function(e){return z.hasData(e)||_.hasData(e)},data:function(e,t,n){return z.access(e,t,n)},removeData:function(e,t){z.remove(e,t)},_data:function(e,t,n){return _.access(e,t,n)},_removeData:function(e,t){_.remove(e,t)}}),ce.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=z.get(o),1===o.nodeType&&!_.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=F(r.slice(5)),V(o,r,i[r]));_.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){z.set(this,n)}):M(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=z.get(o,n))?t:void 0!==(t=V(o,n))?t:void 0;this.each(function(){z.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){z.remove(this,e)})}}),ce.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=_.get(e,t),n&&(!r||Array.isArray(n)?r=_.access(e,t,ce.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=ce.queue(e,t),r=n.length,i=n.shift(),o=ce._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){ce.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return _.get(e,n)||_.access(e,n,{empty:ce.Callbacks("once memory").add(function(){_.remove(e,[t+"queue",n])})})}}),ce.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?ce.queue(this[0],t):void 0===n?this:this.each(function(){var e=ce.queue(this,t,n);ce._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&ce.dequeue(this,t)})},dequeue:function(e){return this.each(function(){ce.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=ce.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=_.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var G=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,Y=new RegExp("^(?:([+-])=|)("+G+")([a-z%]*)$","i"),Q=["Top","Right","Bottom","Left"],J=C.documentElement,K=function(e){return ce.contains(e.ownerDocument,e)},Z={composed:!0};J.getRootNode&&(K=function(e){return ce.contains(e.ownerDocument,e)||e.getRootNode(Z)===e.ownerDocument});var ee=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&K(e)&&"none"===ce.css(e,"display")};function te(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return ce.css(e,t,"")},u=s(),l=n&&n[3]||(ce.cssNumber[t]?"":"px"),c=e.nodeType&&(ce.cssNumber[t]||"px"!==l&&+u)&&Y.exec(ce.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)ce.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,ce.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ne={};function re(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=_.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ee(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ne[s])||(o=a.body.appendChild(a.createElement(s)),u=ce.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ne[s]=u)))):"none"!==n&&(l[c]="none",_.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}ce.fn.extend({show:function(){return re(this,!0)},hide:function(){return re(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ee(this)?ce(this).show():ce(this).hide()})}});var xe,be,we=/^(?:checkbox|radio)$/i,Te=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="<textarea>x</textarea>",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="<option></option>",le.option=!!xe.lastChild;var ke={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n<r;n++)_.set(e[n],"globalEval",!t||_.get(t[n],"globalEval"))}ke.tbody=ke.tfoot=ke.colgroup=ke.caption=ke.thead,ke.th=ke.td,le.option||(ke.optgroup=ke.option=[1,"<select multiple='multiple'>","</select>"]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===x(o))ce.merge(p,o.nodeType?[o]:o);else if(je.test(o)){a=a||f.appendChild(t.createElement("div")),s=(Te.exec(o)||["",""])[1].toLowerCase(),u=ke[s]||ke._default,a.innerHTML=u[1]+ce.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;ce.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<ce.inArray(o,r))i&&i.push(o);else if(l=K(o),a=Se(f.appendChild(o),"script"),l&&Ee(a),n){c=0;while(o=a[c++])Ce.test(o.type||"")&&n.push(o)}return f}var De=/^([^.]*)(?:\.(.+)|)/;function Ne(){return!0}function qe(){return!1}function Le(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Le(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=qe;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return ce().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=ce.guid++)),e.each(function(){ce.event.add(this,t,i,r,n)})}function He(e,r,t){t?(_.set(e,r,!1),ce.event.add(e,r,{namespace:!1,handler:function(e){var t,n=_.get(this,r);if(1&e.isTrigger&&this[r]){if(n)(ce.event.special[r]||{}).delegateType&&e.stopPropagation();else if(n=ae.call(arguments),_.set(this,r,n),this[r](),t=_.get(this,r),_.set(this,r,!1),n!==t)return e.stopImmediatePropagation(),e.preventDefault(),t}else n&&(_.set(this,r,ce.event.trigger(n[0],n.slice(1),this)),e.stopPropagation(),e.isImmediatePropagationStopped=Ne)}})):void 0===_.get(e,r)&&ce.event.add(e,r,Ne)}ce.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=_.get(t);if($(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&ce.find.matchesSelector(J,i),n.guid||(n.guid=ce.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof ce&&ce.event.triggered!==e.type?ce.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(D)||[""]).length;while(l--)d=g=(s=De.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=ce.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=ce.event.special[d]||{},c=ce.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&ce.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),ce.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=_.hasData(e)&&_.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(D)||[""]).length;while(l--)if(d=g=(s=De.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=ce.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||ce.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)ce.event.remove(e,d+t[l],n,r,!0);ce.isEmptyObject(u)&&_.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=ce.event.fix(e),l=(_.get(this,"events")||Object.create(null))[u.type]||[],c=ce.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=ce.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((ce.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<ce(i,this).index(l):ce.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(ce.Event.prototype,t,{enumerable:!0,configurable:!0,get:v(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[ce.expando]?e:new ce.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return we.test(t.type)&&t.click&&fe(t,"input")&&He(t,"click",!0),!1},trigger:function(e){var t=this||e;return we.test(t.type)&&t.click&&fe(t,"input")&&He(t,"click"),!0},_default:function(e){var t=e.target;return we.test(t.type)&&t.click&&fe(t,"input")&&_.get(t,"click")||fe(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},ce.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},ce.Event=function(e,t){if(!(this instanceof ce.Event))return new ce.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ne:qe,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&ce.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[ce.expando]=!0},ce.Event.prototype={constructor:ce.Event,isDefaultPrevented:qe,isPropagationStopped:qe,isImmediatePropagationStopped:qe,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ne,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ne,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ne,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},ce.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:!0},ce.event.addProp),ce.each({focus:"focusin",blur:"focusout"},function(r,i){function o(e){if(C.documentMode){var t=_.get(this,"handle"),n=ce.event.fix(e);n.type="focusin"===e.type?"focus":"blur",n.isSimulated=!0,t(e),n.target===n.currentTarget&&t(n)}else ce.event.simulate(i,e.target,ce.event.fix(e))}ce.event.special[r]={setup:function(){var e;if(He(this,r,!0),!C.documentMode)return!1;(e=_.get(this,i))||this.addEventListener(i,o),_.set(this,i,(e||0)+1)},trigger:function(){return He(this,r),!0},teardown:function(){var e;if(!C.documentMode)return!1;(e=_.get(this,i)-1)?_.set(this,i,e):(this.removeEventListener(i,o),_.remove(this,i))},_default:function(e){return _.get(e.target,r)},delegateType:i},ce.event.special[i]={setup:function(){var e=this.ownerDocument||this.document||this,t=C.documentMode?this:e,n=_.get(t,i);n||(C.documentMode?this.addEventListener(i,o):e.addEventListener(r,o,!0)),_.set(t,i,(n||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=C.documentMode?this:e,n=_.get(t,i)-1;n?_.set(t,i,n):(C.documentMode?this.removeEventListener(i,o):e.removeEventListener(r,o,!0),_.remove(t,i))}}}),ce.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){ce.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||ce.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),ce.fn.extend({on:function(e,t,n,r){return Le(this,e,t,n,r)},one:function(e,t,n,r){return Le(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,ce(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=qe),this.each(function(){ce.event.remove(this,e,n,t)})}});var Oe=/<script|<style|<link/i,Pe=/checked\s*(?:[^=]|=\s*.checked.)/i,Me=/^\s*<!\[CDATA\[|\]\]>\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)ce.event.add(t,i,s[i][n]);z.hasData(e)&&(o=z.access(e),a=ce.extend({},o),z.set(t,a))}}function $e(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=v(d);if(h||1<f&&"string"==typeof d&&!le.checkClone&&Pe.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),$e(t,r,i,o)});if(f&&(t=(e=Ae(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=ce.map(Se(e,"script"),Ie)).length;c<f;c++)u=e,c!==p&&(u=ce.clone(u,!0,!0),s&&ce.merge(a,Se(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,ce.map(a,We),c=0;c<s;c++)u=a[c],Ce.test(u.type||"")&&!_.access(u,"globalEval")&&ce.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?ce._evalUrl&&!u.noModule&&ce._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):m(u.textContent.replace(Me,""),u,l))}return n}function Be(e,t,n){for(var r,i=t?ce.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||ce.cleanData(Se(r)),r.parentNode&&(n&&K(r)&&Ee(Se(r,"script")),r.parentNode.removeChild(r));return e}ce.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=K(e);if(!(le.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||ce.isXMLDoc(e)))for(a=Se(c),r=0,i=(o=Se(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&we.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||Se(e),a=a||Se(c),r=0,i=o.length;r<i;r++)Fe(o[r],a[r]);else Fe(e,c);return 0<(a=Se(c,"script")).length&&Ee(a,!f&&Se(e,"script")),c},cleanData:function(e){for(var t,n,r,i=ce.event.special,o=0;void 0!==(n=e[o]);o++)if($(n)){if(t=n[_.expando]){if(t.events)for(r in t.events)i[r]?ce.event.remove(n,r):ce.removeEvent(n,r,t.handle);n[_.expando]=void 0}n[z.expando]&&(n[z.expando]=void 0)}}}),ce.fn.extend({detach:function(e){return Be(this,e,!0)},remove:function(e){return Be(this,e)},text:function(e){return M(this,function(e){return void 0===e?ce.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return $e(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Re(this,e).appendChild(e)})},prepend:function(){return $e(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Re(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return $e(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return $e(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(ce.cleanData(Se(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return ce.clone(this,e,t)})},html:function(e){return M(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Oe.test(e)&&!ke[(Te.exec(e)||["",""])[1].toLowerCase()]){e=ce.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(ce.cleanData(Se(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return $e(this,arguments,function(e){var t=this.parentNode;ce.inArray(this,n)<0&&(ce.cleanData(Se(this)),t&&t.replaceChild(e,this))},n)}}),ce.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){ce.fn[e]=function(e){for(var t,n=[],r=ce(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),ce(r[o])[a](t),s.apply(n,t.get());return this.pushStack(n)}});var _e=new RegExp("^("+G+")(?!px)[a-z%]+$","i"),ze=/^--/,Xe=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=ie),t.getComputedStyle(e)},Ue=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Ve=new RegExp(Q.join("|"),"i");function Ge(e,t,n){var r,i,o,a,s=ze.test(t),u=e.style;return(n=n||Xe(e))&&(a=n.getPropertyValue(t)||n[t],s&&a&&(a=a.replace(ve,"$1")||void 0),""!==a||K(e)||(a=ce.style(e,t)),!le.pixelBoxStyles()&&_e.test(a)&&Ve.test(t)&&(r=u.width,i=u.minWidth,o=u.maxWidth,u.minWidth=u.maxWidth=u.width=a,a=n.width,u.width=r,u.minWidth=i,u.maxWidth=o)),void 0!==a?a+"":a}function Ye(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",J.appendChild(u).appendChild(l);var e=ie.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),J.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=C.createElement("div"),l=C.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",le.clearCloneStyle="content-box"===l.style.backgroundClip,ce.extend(le,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=C.createElement("table"),t=C.createElement("tr"),n=C.createElement("div"),e.style.cssText="position:absolute;left:-11111px;border-collapse:separate",t.style.cssText="box-sizing:content-box;border:1px solid",t.style.height="1px",n.style.height="9px",n.style.display="block",J.appendChild(e).appendChild(t).appendChild(n),r=ie.getComputedStyle(t),a=parseInt(r.height,10)+parseInt(r.borderTopWidth,10)+parseInt(r.borderBottomWidth,10)===t.offsetHeight,J.removeChild(e)),a}}))}();var Qe=["Webkit","Moz","ms"],Je=C.createElement("div").style,Ke={};function Ze(e){var t=ce.cssProps[e]||Ke[e];return t||(e in Je?e:Ke[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=Qe.length;while(n--)if((e=Qe[n]+t)in Je)return e}(e)||e)}var et=/^(none|table(?!-c[ea]).+)/,tt={position:"absolute",visibility:"hidden",display:"block"},nt={letterSpacing:"0",fontWeight:"400"};function rt(e,t,n){var r=Y.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function it(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0,l=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(l+=ce.css(e,n+Q[a],!0,i)),r?("content"===n&&(u-=ce.css(e,"padding"+Q[a],!0,i)),"margin"!==n&&(u-=ce.css(e,"border"+Q[a]+"Width",!0,i))):(u+=ce.css(e,"padding"+Q[a],!0,i),"padding"!==n?u+=ce.css(e,"border"+Q[a]+"Width",!0,i):s+=ce.css(e,"border"+Q[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u+l}function ot(e,t,n){var r=Xe(e),i=(!le.boxSizingReliable()||n)&&"border-box"===ce.css(e,"boxSizing",!1,r),o=i,a=Ge(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(_e.test(a)){if(!n)return a;a="auto"}return(!le.boxSizingReliable()&&i||!le.reliableTrDimensions()&&fe(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===ce.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===ce.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+it(e,t,n||(i?"border":"content"),o,r,a)+"px"}function at(e,t,n,r,i){return new at.prototype.init(e,t,n,r,i)}ce.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Ge(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,aspectRatio:!0,borderImageSlice:!0,columnCount:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,scale:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeMiterlimit:!0,strokeOpacity:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=F(t),u=ze.test(t),l=e.style;if(u||(t=Ze(s)),a=ce.cssHooks[t]||ce.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=Y.exec(n))&&i[1]&&(n=te(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(ce.cssNumber[s]?"":"px")),le.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=F(t);return ze.test(t)||(t=Ze(s)),(a=ce.cssHooks[t]||ce.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Ge(e,t,r)),"normal"===i&&t in nt&&(i=nt[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),ce.each(["height","width"],function(e,u){ce.cssHooks[u]={get:function(e,t,n){if(t)return!et.test(ce.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?ot(e,u,n):Ue(e,tt,function(){return ot(e,u,n)})},set:function(e,t,n){var r,i=Xe(e),o=!le.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===ce.css(e,"boxSizing",!1,i),s=n?it(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-it(e,u,"border",!1,i)-.5)),s&&(r=Y.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=ce.css(e,u)),rt(0,t,s)}}}),ce.cssHooks.marginLeft=Ye(le.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Ge(e,"marginLeft"))||e.getBoundingClientRect().left-Ue(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),ce.each({margin:"",padding:"",border:"Width"},function(i,o){ce.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+Q[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(ce.cssHooks[i+o].set=rt)}),ce.fn.extend({css:function(e,t){return M(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Xe(e),i=t.length;a<i;a++)o[t[a]]=ce.css(e,t[a],!1,r);return o}return void 0!==n?ce.style(e,t,n):ce.css(e,t)},e,t,1<arguments.length)}}),((ce.Tween=at).prototype={constructor:at,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||ce.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(ce.cssNumber[n]?"":"px")},cur:function(){var e=at.propHooks[this.prop];return e&&e.get?e.get(this):at.propHooks._default.get(this)},run:function(e){var t,n=at.propHooks[this.prop];return this.options.duration?this.pos=t=ce.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):at.propHooks._default.set(this),this}}).init.prototype=at.prototype,(at.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=ce.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){ce.fx.step[e.prop]?ce.fx.step[e.prop](e):1!==e.elem.nodeType||!ce.cssHooks[e.prop]&&null==e.elem.style[Ze(e.prop)]?e.elem[e.prop]=e.now:ce.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=at.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},ce.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},ce.fx=at.prototype.init,ce.fx.step={};var st,ut,lt,ct,ft=/^(?:toggle|show|hide)$/,pt=/queueHooks$/;function dt(){ut&&(!1===C.hidden&&ie.requestAnimationFrame?ie.requestAnimationFrame(dt):ie.setTimeout(dt,ce.fx.interval),ce.fx.tick())}function ht(){return ie.setTimeout(function(){st=void 0}),st=Date.now()}function gt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=Q[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function vt(e,t,n){for(var r,i=(yt.tweeners[t]||[]).concat(yt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function yt(o,e,t){var n,a,r=0,i=yt.prefilters.length,s=ce.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=st||ht(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:ce.extend({},e),opts:ce.extend(!0,{specialEasing:{},easing:ce.easing._default},t),originalProperties:e,originalOptions:t,startTime:st||ht(),duration:t.duration,tweens:[],createTween:function(e,t){var n=ce.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=F(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=ce.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=yt.prefilters[r].call(l,o,c,l.opts))return v(n.stop)&&(ce._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return ce.map(c,vt,l),v(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),ce.fx.timer(ce.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}ce.Animation=ce.extend(yt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return te(n.elem,e,Y.exec(t),n),n}]},tweener:function(e,t){v(e)?(t=e,e=["*"]):e=e.match(D);for(var n,r=0,i=e.length;r<i;r++)n=e[r],yt.tweeners[n]=yt.tweeners[n]||[],yt.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ee(e),v=_.get(e,"fxshow");for(r in n.queue||(null==(a=ce._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,ce.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],ft.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||ce.style(e,r)}if((u=!ce.isEmptyObject(t))||!ce.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=_.get(e,"display")),"none"===(c=ce.css(e,"display"))&&(l?c=l:(re([e],!0),l=e.style.display||l,c=ce.css(e,"display"),re([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===ce.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=_.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&re([e],!0),p.done(function(){for(r in g||re([e]),_.remove(e,"fxshow"),d)ce.style(e,r,d[r])})),u=vt(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?yt.prefilters.unshift(e):yt.prefilters.push(e)}}),ce.speed=function(e,t,n){var r=e&&"object"==typeof e?ce.extend({},e):{complete:n||!n&&t||v(e)&&e,duration:e,easing:n&&t||t&&!v(t)&&t};return ce.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in ce.fx.speeds?r.duration=ce.fx.speeds[r.duration]:r.duration=ce.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){v(r.old)&&r.old.call(this),r.queue&&ce.dequeue(this,r.queue)},r},ce.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ee).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=ce.isEmptyObject(t),o=ce.speed(e,n,r),a=function(){var e=yt(this,ce.extend({},t),o);(i||_.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=ce.timers,r=_.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&pt.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||ce.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=_.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=ce.timers,o=n?n.length:0;for(t.finish=!0,ce.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),ce.each(["toggle","show","hide"],function(e,r){var i=ce.fn[r];ce.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(gt(r,!0),e,t,n)}}),ce.each({slideDown:gt("show"),slideUp:gt("hide"),slideToggle:gt("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){ce.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),ce.timers=[],ce.fx.tick=function(){var e,t=0,n=ce.timers;for(st=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||ce.fx.stop(),st=void 0},ce.fx.timer=function(e){ce.timers.push(e),ce.fx.start()},ce.fx.interval=13,ce.fx.start=function(){ut||(ut=!0,dt())},ce.fx.stop=function(){ut=null},ce.fx.speeds={slow:600,fast:200,_default:400},ce.fn.delay=function(r,e){return r=ce.fx&&ce.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=ie.setTimeout(e,r);t.stop=function(){ie.clearTimeout(n)}})},lt=C.createElement("input"),ct=C.createElement("select").appendChild(C.createElement("option")),lt.type="checkbox",le.checkOn=""!==lt.value,le.optSelected=ct.selected,(lt=C.createElement("input")).value="t",lt.type="radio",le.radioValue="t"===lt.value;var mt,xt=ce.expr.attrHandle;ce.fn.extend({attr:function(e,t){return M(this,ce.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){ce.removeAttr(this,e)})}}),ce.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?ce.prop(e,t,n):(1===o&&ce.isXMLDoc(e)||(i=ce.attrHooks[t.toLowerCase()]||(ce.expr.match.bool.test(t)?mt:void 0)),void 0!==n?null===n?void ce.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=ce.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!le.radioValue&&"radio"===t&&fe(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(D);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),mt={set:function(e,t,n){return!1===t?ce.removeAttr(e,n):e.setAttribute(n,n),n}},ce.each(ce.expr.match.bool.source.match(/\w+/g),function(e,t){var a=xt[t]||ce.find.attr;xt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=xt[o],xt[o]=r,r=null!=a(e,t,n)?o:null,xt[o]=i),r}});var bt=/^(?:input|select|textarea|button)$/i,wt=/^(?:a|area)$/i;function Tt(e){return(e.match(D)||[]).join(" ")}function Ct(e){return e.getAttribute&&e.getAttribute("class")||""}function kt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(D)||[]}ce.fn.extend({prop:function(e,t){return M(this,ce.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[ce.propFix[e]||e]})}}),ce.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&ce.isXMLDoc(e)||(t=ce.propFix[t]||t,i=ce.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=ce.find.attr(e,"tabindex");return t?parseInt(t,10):bt.test(e.nodeName)||wt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),le.optSelected||(ce.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),ce.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){ce.propFix[this.toLowerCase()]=this}),ce.fn.extend({addClass:function(t){var e,n,r,i,o,a;return v(t)?this.each(function(e){ce(this).addClass(t.call(this,e,Ct(this)))}):(e=kt(t)).length?this.each(function(){if(r=Ct(this),n=1===this.nodeType&&" "+Tt(r)+" "){for(o=0;o<e.length;o++)i=e[o],n.indexOf(" "+i+" ")<0&&(n+=i+" ");a=Tt(n),r!==a&&this.setAttribute("class",a)}}):this},removeClass:function(t){var e,n,r,i,o,a;return v(t)?this.each(function(e){ce(this).removeClass(t.call(this,e,Ct(this)))}):arguments.length?(e=kt(t)).length?this.each(function(){if(r=Ct(this),n=1===this.nodeType&&" "+Tt(r)+" "){for(o=0;o<e.length;o++){i=e[o];while(-1<n.indexOf(" "+i+" "))n=n.replace(" "+i+" "," ")}a=Tt(n),r!==a&&this.setAttribute("class",a)}}):this:this.attr("class","")},toggleClass:function(t,n){var e,r,i,o,a=typeof t,s="string"===a||Array.isArray(t);return v(t)?this.each(function(e){ce(this).toggleClass(t.call(this,e,Ct(this),n),n)}):"boolean"==typeof n&&s?n?this.addClass(t):this.removeClass(t):(e=kt(t),this.each(function(){if(s)for(o=ce(this),i=0;i<e.length;i++)r=e[i],o.hasClass(r)?o.removeClass(r):o.addClass(r);else void 0!==t&&"boolean"!==a||((r=Ct(this))&&_.set(this,"__className__",r),this.setAttribute&&this.setAttribute("class",r||!1===t?"":_.get(this,"__className__")||""))}))},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+Tt(Ct(n))+" ").indexOf(t))return!0;return!1}});var St=/\r/g;ce.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=v(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,ce(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=ce.map(t,function(e){return null==e?"":e+""})),(r=ce.valHooks[this.type]||ce.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=ce.valHooks[t.type]||ce.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(St,""):null==e?"":e:void 0}}),ce.extend({valHooks:{option:{get:function(e){var t=ce.find.attr(e,"value");return null!=t?t:Tt(ce.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!fe(n.parentNode,"optgroup"))){if(t=ce(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=ce.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<ce.inArray(ce.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),ce.each(["radio","checkbox"],function(){ce.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<ce.inArray(ce(e).val(),t)}},le.checkOn||(ce.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Et=ie.location,jt={guid:Date.now()},At=/\?/;ce.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{t=(new ie.DOMParser).parseFromString(e,"text/xml")}catch(e){}return n=t&&t.getElementsByTagName("parsererror")[0],t&&!n||ce.error("Invalid XML: "+(n?ce.map(n.childNodes,function(e){return e.textContent}).join("\n"):e)),t};var Dt=/^(?:focusinfocus|focusoutblur)$/,Nt=function(e){e.stopPropagation()};ce.extend(ce.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||C],d=ue.call(e,"type")?e.type:e,h=ue.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||C,3!==n.nodeType&&8!==n.nodeType&&!Dt.test(d+ce.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[ce.expando]?e:new ce.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:ce.makeArray(t,[e]),c=ce.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!y(n)){for(s=c.delegateType||d,Dt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||C)&&p.push(a.defaultView||a.parentWindow||ie)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(_.get(o,"events")||Object.create(null))[e.type]&&_.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&$(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!$(n)||u&&v(n[d])&&!y(n)&&((a=n[u])&&(n[u]=null),ce.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,Nt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,Nt),ce.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=ce.extend(new ce.Event,n,{type:e,isSimulated:!0});ce.event.trigger(r,null,t)}}),ce.fn.extend({trigger:function(e,t){return this.each(function(){ce.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return ce.event.trigger(e,t,n,!0)}});var qt=/\[\]$/,Lt=/\r?\n/g,Ht=/^(?:submit|button|image|reset|file)$/i,Ot=/^(?:input|select|textarea|keygen)/i;function Pt(n,e,r,i){var t;if(Array.isArray(e))ce.each(e,function(e,t){r||qt.test(n)?i(n,t):Pt(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==x(e))i(n,e);else for(t in e)Pt(n+"["+t+"]",e[t],r,i)}ce.param=function(e,t){var n,r=[],i=function(e,t){var n=v(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!ce.isPlainObject(e))ce.each(e,function(){i(this.name,this.value)});else for(n in e)Pt(n,e[n],t,i);return r.join("&")},ce.fn.extend({serialize:function(){return ce.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=ce.prop(this,"elements");return e?ce.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!ce(this).is(":disabled")&&Ot.test(this.nodeName)&&!Ht.test(e)&&(this.checked||!we.test(e))}).map(function(e,t){var n=ce(this).val();return null==n?null:Array.isArray(n)?ce.map(n,function(e){return{name:t.name,value:e.replace(Lt,"\r\n")}}):{name:t.name,value:n.replace(Lt,"\r\n")}}).get()}});var Mt=/%20/g,Rt=/#.*$/,It=/([?&])_=[^&]*/,Wt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ft=/^(?:GET|HEAD)$/,$t=/^\/\//,Bt={},_t={},zt="*/".concat("*"),Xt=C.createElement("a");function Ut(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(D)||[];if(v(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Vt(t,i,o,a){var s={},u=t===_t;function l(e){var r;return s[e]=!0,ce.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function Gt(e,t){var n,r,i=ce.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&ce.extend(!0,e,r),e}Xt.href=Et.href,ce.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Et.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Et.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":zt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":ce.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Gt(Gt(e,ce.ajaxSettings),t):Gt(ce.ajaxSettings,e)},ajaxPrefilter:Ut(Bt),ajaxTransport:Ut(_t),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=ce.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?ce(y):ce.event,x=ce.Deferred(),b=ce.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Wt.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||Et.href)+"").replace($t,Et.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(D)||[""],null==v.crossDomain){r=C.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Xt.protocol+"//"+Xt.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=ce.param(v.data,v.traditional)),Vt(Bt,v,t,T),h)return T;for(i in(g=ce.event&&v.global)&&0==ce.active++&&ce.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!Ft.test(v.type),f=v.url.replace(Rt,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(Mt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(At.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(It,"$1"),o=(At.test(f)?"&":"?")+"_="+jt.guid+++o),v.url=f+o),v.ifModified&&(ce.lastModified[f]&&T.setRequestHeader("If-Modified-Since",ce.lastModified[f]),ce.etag[f]&&T.setRequestHeader("If-None-Match",ce.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+zt+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Vt(_t,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=ie.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&ie.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),!i&&-1<ce.inArray("script",v.dataTypes)&&ce.inArray("json",v.dataTypes)<0&&(v.converters["text script"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(ce.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(ce.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--ce.active||ce.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return ce.get(e,t,n,"json")},getScript:function(e,t){return ce.get(e,void 0,t,"script")}}),ce.each(["get","post"],function(e,i){ce[i]=function(e,t,n,r){return v(t)&&(r=r||n,n=t,t=void 0),ce.ajax(ce.extend({url:e,type:i,dataType:r,data:t,success:n},ce.isPlainObject(e)&&e))}}),ce.ajaxPrefilter(function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),ce._evalUrl=function(e,t,n){return ce.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){ce.globalEval(e,t,n)}})},ce.fn.extend({wrapAll:function(e){var t;return this[0]&&(v(e)&&(e=e.call(this[0])),t=ce(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return v(n)?this.each(function(e){ce(this).wrapInner(n.call(this,e))}):this.each(function(){var e=ce(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=v(t);return this.each(function(e){ce(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){ce(this).replaceWith(this.childNodes)}),this}}),ce.expr.pseudos.hidden=function(e){return!ce.expr.pseudos.visible(e)},ce.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},ce.ajaxSettings.xhr=function(){try{return new ie.XMLHttpRequest}catch(e){}};var Yt={0:200,1223:204},Qt=ce.ajaxSettings.xhr();le.cors=!!Qt&&"withCredentials"in Qt,le.ajax=Qt=!!Qt,ce.ajaxTransport(function(i){var o,a;if(le.cors||Qt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(Yt[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&ie.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),ce.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),ce.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return ce.globalEval(e),e}}}),ce.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),ce.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=ce("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=Tt(e.slice(s)),e=e.slice(0,s)),v(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&ce.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?ce("<div>").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var en=/^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;ce.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),v(e))return r=ae.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(ae.call(arguments)))}).guid=e.guid=e.guid||ce.guid++,i},ce.holdReady=function(e){e?ce.readyWait++:ce.ready(!0)},ce.isArray=Array.isArray,ce.parseJSON=JSON.parse,ce.nodeName=fe,ce.isFunction=v,ce.isWindow=y,ce.camelCase=F,ce.type=x,ce.now=Date.now,ce.isNumeric=function(e){var t=ce.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},ce.trim=function(e){return null==e?"":(e+"").replace(en,"$1")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return ce});var tn=ie.jQuery,nn=ie.$;return ce.noConflict=function(e){return ie.$===ce&&(ie.$=nn),e&&ie.jQuery===ce&&(ie.jQuery=tn),ce},"undefined"==typeof e&&(ie.jQuery=ie.$=ce),ce});
|
js/wchess.wasm.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
js/wchess.wasm.worker.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
"use strict";var Module={};var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";if(ENVIRONMENT_IS_NODE){var nodeWorkerThreads=require("worker_threads");var parentPort=nodeWorkerThreads.parentPort;parentPort.on("message",data=>onmessage({data:data}));var fs=require("fs");Object.assign(global,{self:global,require:require,Module:Module,location:{href:__filename},Worker:nodeWorkerThreads.Worker,importScripts:f=>(0,eval)(fs.readFileSync(f,"utf8")+"//# sourceURL="+f),postMessage:msg=>parentPort.postMessage(msg),performance:global.performance||{now:Date.now}})}var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");if(ENVIRONMENT_IS_NODE){fs.writeSync(2,text+"\n");return}console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var module=Module["wasmModule"];Module["wasmModule"]=null;var instance=new WebAssembly.Instance(module,info);return receiveInstance(instance)};self.onunhandledrejection=e=>{throw e.reason||e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=(...args)=>{postMessage({cmd:"callHandler",handler:handler,args:args})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["__emscripten_thread_mailbox_await"](e.data.pthread_ptr);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){throw ex}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="checkMailbox"){if(initializedJS){Module["checkMailbox"]()}}else if(e.data.cmd){err(`worker.js received unknown command ${e.data.cmd}`);err(e.data)}}catch(ex){if(Module["__emscripten_thread_crashed"]){Module["__emscripten_thread_crashed"]()}throw ex}}self.onmessage=handleMessage;
|
libmain.worker.js
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
"use strict";var Module={};var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";if(ENVIRONMENT_IS_NODE){var nodeWorkerThreads=require("worker_threads");var parentPort=nodeWorkerThreads.parentPort;parentPort.on("message",data=>onmessage({data:data}));var fs=require("fs");Object.assign(global,{self:global,require:require,Module:Module,location:{href:__filename},Worker:nodeWorkerThreads.Worker,importScripts:function(f){(0,eval)(fs.readFileSync(f,"utf8")+"//# sourceURL="+f)},postMessage:function(msg){parentPort.postMessage(msg)},performance:global.performance||{now:function(){return Date.now()}}})}var initializedJS=false;var pendingNotifiedProxyingQueues=[];function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");if(ENVIRONMENT_IS_NODE){fs.writeSync(2,text+"\n");return}console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var instance=new WebAssembly.Instance(Module["wasmModule"],info);receiveInstance(instance);Module["wasmModule"]=null;return instance.exports};self.onunhandledrejection=e=>{throw e.reason??e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=function(){postMessage({cmd:"callHandler",handler:handler,args:[...arguments]})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();pendingNotifiedProxyingQueues.forEach(queue=>{Module["executeNotifiedProxyingQueue"](queue)});pendingNotifiedProxyingQueues=[];initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){if(ex instanceof Module["ExitStatus"]){if(Module["keepRuntimeAlive"]()){}else{Module["__emscripten_thread_exit"](ex.status)}}else{throw ex}}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processProxyingQueue"){if(initializedJS){Module["executeNotifiedProxyingQueue"](e.data.queue)}else{pendingNotifiedProxyingQueues.push(e.data.queue)}}else if(e.data.cmd){err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){if(Module["__emscripten_thread_crashed"]){Module["__emscripten_thread_crashed"]()}throw ex}}self.onmessage=handleMessage;
|
|
|
|
|
|
libwhisper.worker.js
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
"use strict";var Module={};var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";if(ENVIRONMENT_IS_NODE){var nodeWorkerThreads=require("worker_threads");var parentPort=nodeWorkerThreads.parentPort;parentPort.on("message",data=>onmessage({data:data}));var fs=require("fs");Object.assign(global,{self:global,require:require,Module:Module,location:{href:__filename},Worker:nodeWorkerThreads.Worker,importScripts:function(f){(0,eval)(fs.readFileSync(f,"utf8")+"//# sourceURL="+f)},postMessage:function(msg){parentPort.postMessage(msg)},performance:global.performance||{now:function(){return Date.now()}}})}var initializedJS=false;var pendingNotifiedProxyingQueues=[];function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");if(ENVIRONMENT_IS_NODE){fs.writeSync(2,text+"\n");return}console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var instance=new WebAssembly.Instance(Module["wasmModule"],info);receiveInstance(instance);Module["wasmModule"]=null;return instance.exports};self.onunhandledrejection=e=>{throw e.reason??e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{Module=instance;postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=function(){postMessage({cmd:"callHandler",handler:handler,args:[...arguments]})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}whisper_factory(Module)}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();pendingNotifiedProxyingQueues.forEach(queue=>{Module["executeNotifiedProxyingQueue"](queue)});pendingNotifiedProxyingQueues=[];initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){if(ex instanceof Module["ExitStatus"]){if(Module["keepRuntimeAlive"]()){}else{Module["__emscripten_thread_exit"](ex.status)}}else{throw ex}}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processProxyingQueue"){if(initializedJS){Module["executeNotifiedProxyingQueue"](e.data.queue)}else{pendingNotifiedProxyingQueues.push(e.data.queue)}}else if(e.data.cmd){err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){if(Module["__emscripten_thread_crashed"]){Module["__emscripten_thread_crashed"]()}throw ex}}self.onmessage=handleMessage;
|
|
|
|
|
|
models/.gitattributes
DELETED
|
@@ -1,51 +0,0 @@
|
|
| 1 |
-
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
-
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
-
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
-
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
-
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 6 |
-
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
-
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 8 |
-
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 9 |
-
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 10 |
-
*.lz4 filter=lfs diff=lfs merge=lfs -text
|
| 11 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
| 12 |
-
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 13 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 14 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 15 |
-
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 16 |
-
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 17 |
-
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 18 |
-
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 19 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 20 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 21 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 22 |
-
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 23 |
-
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 24 |
-
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 25 |
-
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 26 |
-
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 27 |
-
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 28 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 29 |
-
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 30 |
-
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 31 |
-
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 32 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 33 |
-
# Audio files - uncompressed
|
| 34 |
-
*.pcm filter=lfs diff=lfs merge=lfs -text
|
| 35 |
-
*.sam filter=lfs diff=lfs merge=lfs -text
|
| 36 |
-
*.raw filter=lfs diff=lfs merge=lfs -text
|
| 37 |
-
# Audio files - compressed
|
| 38 |
-
*.aac filter=lfs diff=lfs merge=lfs -text
|
| 39 |
-
*.flac filter=lfs diff=lfs merge=lfs -text
|
| 40 |
-
*.mp3 filter=lfs diff=lfs merge=lfs -text
|
| 41 |
-
*.ogg filter=lfs diff=lfs merge=lfs -text
|
| 42 |
-
*.wav filter=lfs diff=lfs merge=lfs -text
|
| 43 |
-
# Image files - uncompressed
|
| 44 |
-
*.bmp filter=lfs diff=lfs merge=lfs -text
|
| 45 |
-
*.gif filter=lfs diff=lfs merge=lfs -text
|
| 46 |
-
*.png filter=lfs diff=lfs merge=lfs -text
|
| 47 |
-
*.tiff filter=lfs diff=lfs merge=lfs -text
|
| 48 |
-
# Image files - compressed
|
| 49 |
-
*.jpg filter=lfs diff=lfs merge=lfs -text
|
| 50 |
-
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
| 51 |
-
*.webp filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
models/README.md
DELETED
|
@@ -1,24 +0,0 @@
|
|
| 1 |
-
---
|
| 2 |
-
license: mit
|
| 3 |
-
---
|
| 4 |
-
|
| 5 |
-
# OpenAI's Whisper models converted to ggml format
|
| 6 |
-
|
| 7 |
-
[Available models](https://huggingface.co/datasets/ggerganov/whisper.cpp/tree/main)
|
| 8 |
-
|
| 9 |
-
| Model | Disk | Mem | SHA |
|
| 10 |
-
| --- | --- | --- | --- |
|
| 11 |
-
| tiny | 75 MB | ~390 MB | `bd577a113a864445d4c299885e0cb97d4ba92b5f` |
|
| 12 |
-
| tiny.en | 75 MB | ~390 MB | `c78c86eb1a8faa21b369bcd33207cc90d64ae9df` |
|
| 13 |
-
| base | 142 MB | ~500 MB | `465707469ff3a37a2b9b8d8f89f2f99de7299dac` |
|
| 14 |
-
| base.en | 142 MB | ~500 MB | `137c40403d78fd54d454da0f9bd998f78703390c` |
|
| 15 |
-
| small | 466 MB | ~1.0 GB | `55356645c2b361a969dfd0ef2c5a50d530afd8d5` |
|
| 16 |
-
| small.en | 466 MB | ~1.0 GB | `db8a495a91d927739e50b3fc1cc4c6b8f6c2d022` |
|
| 17 |
-
| medium | 1.5 GB | ~2.6 GB | `fd9727b6e1217c2f614f9b698455c4ffd82463b4` |
|
| 18 |
-
| medium.en | 1.5 GB | ~2.6 GB | `8c30f0e44ce9560643ebd10bbe50cd20eafd3723` |
|
| 19 |
-
| large-v1 | 2.9 GB | ~4.7 GB | `b1caaf735c4cc1429223d5a74f0f4d0b9b59a299` |
|
| 20 |
-
| large | 2.9 GB | ~4.7 GB | `0f4c8e34f21cf1a914c59d8b3ce882345ad349d6` |
|
| 21 |
-
|
| 22 |
-
For more information, visit:
|
| 23 |
-
|
| 24 |
-
https://github.com/ggerganov/whisper.cpp/tree/master/models
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
models/ggml-base.bin
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:60ed5bc3dd14eea856493d334349b405782ddcaf0028d4b5df4088345fba2efe
|
| 3 |
-
size 147951465
|
|
|
|
|
|
|
|
|
|
|
|
models/ggml-base.en.bin
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:a03779c86df3323075f5e796cb2ce5029f00ec8869eee3fdfb897afe36c6d002
|
| 3 |
-
size 147964211
|
|
|
|
|
|
|
|
|
|
|
|
models/ggml-tiny.bin
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:be07e048e1e599ad46341c8d2a135645097a538221678b7acdd1b1919c6e1b21
|
| 3 |
-
size 77691713
|
|
|
|
|
|
|
|
|
|
|
|
models/ggml-tiny.en.bin
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:921e4cf8686fdd993dcd081a5da5b6c365bfde1162e72b08d75ac75289920b1f
|
| 3 |
-
size 77704715
|
|
|
|
|
|
|
|
|
|
|
|