1
lorchess.ru/assets/vendor/pgn4web/encoder-decoder-test.html

1479 lines
38 KiB
HTML
Raw Normal View History

2014-02-13 01:44:20 +04:00
<!DOCTYPE HTML>
<html>
<!--
pgn4web javascript chessboard
copyright (C) 2009-2013 Paolo Casaschi
see README file and http://pgn4web.casaschi.net
for credits, license and more details
Huffman encoding/decoding derived from code at http://rumkin.com/tools/compression/compress_huff.php
PLEASE NOTE THIS FILE IS USED ONLY TO FINE TUNE HUFFMANN ENCODING:
actual functions for PGN encoding/decoding are contained in pgn-decoder.js and pgn-encoder.js
-->
<head>
<title>pgn4web PGN encoder/decoder test</title>
<link rel="shortcut icon" href="pawn.ico" />
<script type="text/javascript">
"use strict";
// fix this to use customized letter distribution
var USE_PRESET_LETTER_DISTRIBUTION = true;
// fix this once you have the letter codes corresponding to the letter distribution above
var USE_PRESET_LETTER_CODES = true;
// fix this once you have the decoding values l[] corresponding to the letter codes above
var USE_PRESET_DECODING_SET = true;
var encodingCharSet = "$0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
var encodingVersion = 1;
// version 1 of PGN encoding:
// encodedPGN = nnn$xxx0
// nnn = number representing bytes length of the decoded message
// $ = dollar char (delimiter for length info)
// xxx = encoded text (using LetterCodes below)
// 0 = zero char (version marker)
function BitsToBytes(i) {
var o = 0;
if (i.charAt(0) == '1') { o += 32; }
if (i.charAt(1) == '1') { o += 16; }
if (i.charAt(2) == '1') { o += 8; }
if (i.charAt(3) == '1') { o += 4; }
if (i.charAt(4) == '1') { o += 2; }
if (i.charAt(5) == '1') { o += 1; }
return encodingCharSet.charAt(o);
}
function EncodePGN(ov) {
var i, idx, c;
var Letters = new Array(256);
var LetterCodes = new Array(256);
for (i = 0; i < 256; i ++) { Letters[i] = 0; }
for (i = 0; i < ov.length; i ++) { Letters[ov.charCodeAt(i)]++; }
if (USE_PRESET_LETTER_DISTRIBUTION) {
Letters[0] = 1;
Letters[1] = 1;
Letters[2] = 1;
Letters[3] = 1;
Letters[4] = 1;
Letters[5] = 1;
Letters[6] = 1;
Letters[7] = 1;
Letters[8] = 1;
Letters[9] = 1;
Letters[10] = 25000;
Letters[11] = 1;
Letters[12] = 1;
Letters[13] = 25000;
Letters[14] = 1;
Letters[15] = 1;
Letters[16] = 1;
Letters[17] = 1;
Letters[18] = 1;
Letters[19] = 1;
Letters[20] = 1;
Letters[21] = 1;
Letters[22] = 1;
Letters[23] = 1;
Letters[24] = 1;
Letters[25] = 1;
Letters[26] = 1;
Letters[27] = 1;
Letters[28] = 1;
Letters[29] = 1;
Letters[30] = 1;
Letters[31] = 1;
Letters[32] = 273240;
Letters[33] = 200; // !
Letters[34] = 64928; // "
Letters[35] = 326; // #
Letters[36] = 163; // $
Letters[37] = 25; // %
Letters[38] = 25; // &
Letters[39] = 500; // '
Letters[40] = 1607; // (
Letters[41] = 1592; // )
Letters[42] = 10; // *
Letters[43] = 9086; // +
Letters[44] = 4231; // ,
Letters[45] = 11848; // -
Letters[46] = 91283; // .
Letters[47] = 9685; // /
Letters[48] = 27308; // 0
Letters[49] = 57229; // 1
Letters[50] = 57065; // 2
Letters[51] = 49049; // 3
Letters[52] = 46441; // 4
Letters[53] = 42430; // 5
Letters[54] = 38872; // 6
Letters[55] = 27853; // 7
Letters[56] = 21292; // 8
Letters[57] = 14627; // 9
Letters[58] = 270; // :
Letters[59] = 136; // ;
Letters[60] = 290; // <
Letters[61] = 1015; // =
Letters[62] = 290; // >
Letters[63] = 7511; // ?
Letters[64] = 100; // @
Letters[65] = 3580; // A
Letters[66] = 31461; // B
Letters[67] = 4369; // C
Letters[68] = 6993; // D
Letters[69] = 13777; // E
Letters[70] = 1719; // F
Letters[71] = 1902; // G
Letters[72] = 639; // H
Letters[73] = 1054; // I
Letters[74] = 420; // J
Letters[75] = 16962; // K
Letters[76] = 961; // L
Letters[77] = 1378; // M
Letters[78] = 29494; // N
Letters[79] = 10671; // O
Letters[80] = 7817; // P
Letters[81] = 19645; // Q
Letters[82] = 34436; // R
Letters[83] = 5795; // S
Letters[84] = 2037; // T
Letters[85] = 1364; // U
Letters[86] = 621; // V
Letters[87] = 5270; // W
Letters[88] = 249; // X
Letters[89] = 185; // Y
Letters[90] = 620; // Z
Letters[91] = 31633; // [
Letters[92] = 15; // \
Letters[93] = 31628; // ]
Letters[94] = 10; // ^
Letters[95] = 15; // _
Letters[96] = 10; // `
Letters[97] = 35573; // a
Letters[98] = 19456; // b
Letters[99] = 33228; // c
Letters[100] = 36380; // d
Letters[101] = 64738; // e
Letters[102] = 25736; // f
Letters[103] = 19801; // g
Letters[104] = 20415; // h
Letters[105] = 16706; // i
Letters[106] = 530; // j
Letters[107] = 7806; // k
Letters[108] = 18510; // l
Letters[109] = 3044; // m
Letters[110] = 20680; // n
Letters[111] = 17771; // o
Letters[112] = 9101; // p
Letters[113] = 903; // q
Letters[114] = 10153; // r
Letters[115] = 9963; // s
Letters[116] = 32763; // t
Letters[117] = 10268; // u
Letters[118] = 7508; // v
Letters[119] = 2173; // w
Letters[120] = 32913; // x
Letters[121] = 2135; // y
Letters[122] = 722; // z
Letters[123] = 1000; // {
Letters[124] = 10; // |
Letters[125] = 1000; // }
Letters[126] = 10; // ~
Letters[127] = 1;
Letters[128] = 1;
Letters[129] = 1;
Letters[130] = 1;
Letters[131] = 1;
Letters[132] = 1;
Letters[133] = 1;
Letters[134] = 1;
Letters[135] = 1;
Letters[136] = 1;
Letters[137] = 1;
Letters[138] = 1;
Letters[139] = 1;
Letters[140] = 1;
Letters[141] = 1;
Letters[142] = 1;
Letters[143] = 1;
Letters[144] = 1;
Letters[145] = 1;
Letters[146] = 1;
Letters[147] = 1;
Letters[148] = 1;
Letters[149] = 1;
Letters[150] = 1;
Letters[151] = 1;
Letters[152] = 1;
Letters[153] = 1;
Letters[154] = 1;
Letters[155] = 1;
Letters[156] = 1;
Letters[157] = 1;
Letters[158] = 1;
Letters[159] = 1;
Letters[160] = 1;
Letters[161] = 1;
Letters[162] = 1;
Letters[163] = 1;
Letters[164] = 1;
Letters[165] = 1;
Letters[166] = 1;
Letters[167] = 1;
Letters[168] = 1;
Letters[169] = 1;
Letters[170] = 1;
Letters[171] = 1;
Letters[172] = 1;
Letters[173] = 1;
Letters[174] = 1;
Letters[175] = 1;
Letters[176] = 1;
Letters[177] = 1;
Letters[178] = 1;
Letters[179] = 1;
Letters[180] = 1;
Letters[181] = 1;
Letters[182] = 1;
Letters[183] = 1;
Letters[184] = 1;
Letters[185] = 1;
Letters[186] = 1;
Letters[187] = 1;
Letters[188] = 1;
Letters[189] = 1;
Letters[190] = 1;
Letters[191] = 1;
Letters[192] = 1;
Letters[193] = 1;
Letters[194] = 1;
Letters[195] = 1;
Letters[196] = 1;
Letters[197] = 1;
Letters[198] = 1;
Letters[199] = 1;
Letters[200] = 1;
Letters[201] = 1;
Letters[202] = 1;
Letters[203] = 1;
Letters[204] = 1;
Letters[205] = 1;
Letters[206] = 1;
Letters[207] = 1;
Letters[208] = 1;
Letters[209] = 1;
Letters[210] = 1;
Letters[211] = 1;
Letters[212] = 1;
Letters[213] = 1;
Letters[214] = 1;
Letters[215] = 1;
Letters[216] = 1;
Letters[217] = 1;
Letters[218] = 1;
Letters[219] = 1;
Letters[220] = 1;
Letters[221] = 1;
Letters[222] = 1;
Letters[223] = 1;
Letters[224] = 1;
Letters[225] = 1;
Letters[226] = 1;
Letters[227] = 1;
Letters[228] = 1;
Letters[229] = 1;
Letters[230] = 1;
Letters[231] = 1;
Letters[232] = 1;
Letters[233] = 1;
Letters[234] = 1;
Letters[235] = 1;
Letters[236] = 1;
Letters[237] = 1;
Letters[238] = 1;
Letters[239] = 1;
Letters[240] = 1;
Letters[241] = 1;
Letters[242] = 1;
Letters[243] = 1;
Letters[244] = 1;
Letters[245] = 1;
Letters[246] = 1;
Letters[247] = 1;
Letters[248] = 1;
Letters[249] = 1;
Letters[250] = 1;
Letters[251] = 1;
Letters[252] = 1;
Letters[253] = 1;
Letters[254] = 1;
Letters[255] = 1;
}
// Build a Huffman tree from the letter count frequencies
var NodeLetter = new Array(512);
var NodeCount = new Array(512);
var NodeChild1 = new Array(512);
var NodeChild2 = new Array(512);
var NextParent = 0;
for (i = 0; i < 256; i ++) {
if (Letters[i] > 0) {
NodeLetter[NextParent] = i;
NodeCount[NextParent] = Letters[i];
NodeChild1[NextParent] = -1;
NodeChild2[NextParent] = -1;
NextParent ++;
}
}
// Built node list. Now combine nodes to make a tree
var SmallestNode1;
var SmallestNode2 = 1;
while (SmallestNode2 != -1) {
SmallestNode1 = -1;
SmallestNode2 = -1;
for (i = 0; i < NextParent; i ++) {
if (NodeCount[i] > 0) {
if (SmallestNode1 == -1) {
SmallestNode1 = i;
} else if (SmallestNode2 == -1) {
if (NodeCount[i] < NodeCount[SmallestNode1]) {
SmallestNode2 = SmallestNode1;
SmallestNode1 = i;
} else {
SmallestNode2 = i;
}
} else if (NodeCount[i] <= NodeCount[SmallestNode1]) {
SmallestNode2 = SmallestNode1;
SmallestNode1 = i;
}
}
}
if (SmallestNode2 != -1) {
NodeCount[NextParent] = NodeCount[SmallestNode1] + NodeCount[SmallestNode2];
NodeCount[SmallestNode1] = 0;
NodeCount[SmallestNode2] = 0;
// Reversed SmallestNode numbers here for ordering in the tree
NodeChild1[NextParent] = SmallestNode2;
NodeChild2[NextParent] = SmallestNode1;
NextParent ++;
}
}
// We have constructed the nodes. Now rewrite the list into a single array.
// The value of an array element will be positive if it is the character
// code we want. Otherwise, it branches. The left branch will be the next
// array element. The value of the array will be (offset * -1), which is
// the right branch.
var FinalNodes = Array(NextParent);
var DepthIndex = Array(256);
var Depth = 0;
var NextFinal = 0;
DepthIndex[Depth] = SmallestNode1;
while (Depth >= 0) {
if (NodeChild1[DepthIndex[Depth]] > -1 && NodeChild2[DepthIndex[Depth]] > -1) {
// If there is a left and right, push them on the stack
idx = NodeChild1[DepthIndex[Depth]];
NodeChild1[DepthIndex[Depth]] = -2 - NextFinal;
Depth ++;
DepthIndex[Depth] = idx;
NextFinal ++;
} else if (NodeChild1[DepthIndex[Depth]] < 0 && NodeChild2[DepthIndex[Depth]] > -1) {
// If there is a left and a right, but the left was taken,
// push the right on the stack.
// Update the FinalNodes[] with the location for the right branch.
idx = NodeChild1[DepthIndex[Depth]];
idx = 0 - idx;
idx -= 2;
FinalNodes[idx] = - NextFinal;
// Traverse right branch
idx = NodeChild2[DepthIndex[Depth]];
NodeChild2[DepthIndex[Depth]] = -2;
Depth ++;
DepthIndex[Depth] = idx;
} else if (NodeChild1[DepthIndex[Depth]] < -1 && NodeChild2[DepthIndex[Depth]] < -1) {
// If there was a left and a right, but they were both taken, pop up a level
Depth --;
} else if (NodeChild1[DepthIndex[Depth]] == -1 && NodeChild2[DepthIndex[Depth]] == -1) {
// If we have a child here, add it to the final nodes, pop up
FinalNodes[NextFinal] = NodeLetter[DepthIndex[Depth]];
NextFinal ++;
Depth --;
} else {
// This shouldn't ever happen
alert('Bad algorithm!');
return new Array ("", "", "");
}
}
// We have the tree. Associate codes with the letters.
var CodeIndex = new Array(256);
DepthIndex[0] = 0;
CodeIndex[0] = "";
Depth = 0;
while (Depth >= 0) {
if (FinalNodes[DepthIndex[Depth]] < 0) {
c = CodeIndex[Depth];
idx = DepthIndex[Depth];
DepthIndex[Depth + 1] = DepthIndex[Depth] + 1;
CodeIndex[Depth + 1] = c + '0';
DepthIndex[Depth] = 0 - FinalNodes[idx];
CodeIndex[Depth] = c + '1';
Depth ++;
} else {
LetterCodes[FinalNodes[DepthIndex[Depth]]] = CodeIndex[Depth];
Depth --;
}
}
if (USE_PRESET_LETTER_CODES) {
LetterCodes[0] = '00111111111111110';
LetterCodes[1] = '0101101';
LetterCodes[2] = '00111111111111111';
LetterCodes[3] = '00111111111111100';
LetterCodes[4] = '00111111111111101';
LetterCodes[5] = '000011111111111010';
LetterCodes[6] = '000011111111111011';
LetterCodes[7] = '000011111111111000';
LetterCodes[8] = '000011111111111001';
LetterCodes[9] = '000011111111111110';
LetterCodes[10] = '0101100';
LetterCodes[11] = '000011111111111111';
LetterCodes[12] = '000011111111111100';
LetterCodes[13] = '0011100';
LetterCodes[14] = '000011111111111101';
LetterCodes[15] = '000011111111110010';
LetterCodes[16] = '000011111111110011';
LetterCodes[17] = '000011111111110000';
LetterCodes[18] = '000011111111110001';
LetterCodes[19] = '000011111111110110';
LetterCodes[20] = '000011111111110111';
LetterCodes[21] = '000011111111110100';
LetterCodes[22] = '000011111111110101';
LetterCodes[23] = '1111111111110101010';
LetterCodes[24] = '1111111111110101011';
LetterCodes[25] = '1111111111110101000';
LetterCodes[26] = '1111111111110101001';
LetterCodes[27] = '1111111111110101110';
LetterCodes[28] = '1111111111110101111';
LetterCodes[29] = '1111111111110101100';
LetterCodes[30] = '1111111111110101101';
LetterCodes[31] = '1111111111110100010';
LetterCodes[32] = '1000';
LetterCodes[33] = '101111111110';
LetterCodes[34] = '00010';
LetterCodes[35] = '11111111110';
LetterCodes[36] = '0011111111110';
LetterCodes[37] = '1011111111110';
LetterCodes[38] = '00001111111110';
LetterCodes[39] = '00111111110';
LetterCodes[40] = '0011101';
LetterCodes[41] = '111111110';
LetterCodes[42] = '11001111111110';
LetterCodes[43] = '1111110';
LetterCodes[44] = '000011110';
LetterCodes[45] = '0011110';
LetterCodes[46] = '00000';
LetterCodes[47] = '0110110';
LetterCodes[48] = '010100';
LetterCodes[49] = '00110';
LetterCodes[50] = '01000';
LetterCodes[51] = '01100';
LetterCodes[52] = '11000';
LetterCodes[53] = '11010';
LetterCodes[54] = '11100';
LetterCodes[55] = '001010';
LetterCodes[56] = '011100';
LetterCodes[57] = '0001110';
LetterCodes[58] = '001111111110';
LetterCodes[59] = '1111111111100';
LetterCodes[60] = '10111111110';
LetterCodes[61] = '1100110100';
LetterCodes[62] = '000011111110';
LetterCodes[63] = '00011110';
LetterCodes[64] = '1100111111110';
LetterCodes[65] = '110011100';
LetterCodes[66] = '000010';
LetterCodes[67] = '10111110';
LetterCodes[68] = '00111110';
LetterCodes[69] = '0010110';
LetterCodes[70] = '110011101';
LetterCodes[71] = '110011110';
LetterCodes[72] = '1100110101';
LetterCodes[73] = '0010111110';
LetterCodes[74] = '11001111110';
LetterCodes[75] = '101110';
LetterCodes[76] = '1100111110';
LetterCodes[77] = '101111110';
LetterCodes[78] = '000110';
LetterCodes[79] = '0101110';
LetterCodes[80] = '1011110';
LetterCodes[81] = '011101';
LetterCodes[82] = '11101';
LetterCodes[83] = '11001100';
LetterCodes[84] = '001111110';
LetterCodes[85] = '0000111110';
LetterCodes[86] = '1111111110';
LetterCodes[87] = '11111110';
LetterCodes[88] = '110011111110';
LetterCodes[89] = '0000111111110';
LetterCodes[90] = '1011111110';
LetterCodes[91] = '10010';
LetterCodes[92] = '00111111111110';
LetterCodes[93] = '10011';
LetterCodes[94] = '11001111111111';
LetterCodes[95] = '11111111111010';
LetterCodes[96] = '10111111111110';
LetterCodes[97] = '11110';
LetterCodes[98] = '011010';
LetterCodes[99] = '10100';
LetterCodes[100] = '11011';
LetterCodes[101] = '00100';
LetterCodes[102] = '010010';
LetterCodes[103] = '010011';
LetterCodes[104] = '011110';
LetterCodes[105] = '0000110';
LetterCodes[106] = '00001111110';
LetterCodes[107] = '00001110';
LetterCodes[108] = '110010';
LetterCodes[109] = '000111110';
LetterCodes[110] = '010101';
LetterCodes[111] = '111110';
LetterCodes[112] = '0110111';
LetterCodes[113] = '1100110110';
LetterCodes[114] = '0111110';
LetterCodes[115] = '0111111';
LetterCodes[116] = '10110';
LetterCodes[117] = '0101111';
LetterCodes[118] = '00101110';
LetterCodes[119] = '000111111';
LetterCodes[120] = '10101';
LetterCodes[121] = '001011110';
LetterCodes[122] = '1100110111';
LetterCodes[123] = '0010111111';
LetterCodes[124] = '001111111111110';
LetterCodes[125] = '0011111110';
LetterCodes[126] = '111111111110110';
LetterCodes[127] = '1111111111110100011';
LetterCodes[128] = '1111111111110100000';
LetterCodes[129] = '1111111111110100001';
LetterCodes[130] = '1111111111110100110';
LetterCodes[131] = '1111111111110100111';
LetterCodes[132] = '1111111111110100100';
LetterCodes[133] = '1111111111110100101';
LetterCodes[134] = '1111111111110111010';
LetterCodes[135] = '1111111111110111011';
LetterCodes[136] = '1111111111110111000';
LetterCodes[137] = '1111111111110111001';
LetterCodes[138] = '1111111111110111110';
LetterCodes[139] = '1111111111110111111';
LetterCodes[140] = '1111111111110111100';
LetterCodes[141] = '1111111111110111101';
LetterCodes[142] = '1111111111110110010';
LetterCodes[143] = '1111111111110110011';
LetterCodes[144] = '1111111111110110000';
LetterCodes[145] = '1111111111110110001';
LetterCodes[146] = '1111111111110110110';
LetterCodes[147] = '1111111111110110111';
LetterCodes[148] = '1111111111110110100';
LetterCodes[149] = '1111111111110110101';
LetterCodes[150] = '1111111111110001010';
LetterCodes[151] = '1111111111110001011';
LetterCodes[152] = '1111111111110001000';
LetterCodes[153] = '1111111111110001001';
LetterCodes[154] = '1111111111110001110';
LetterCodes[155] = '1111111111110001111';
LetterCodes[156] = '1111111111110001100';
LetterCodes[157] = '1111111111110001101';
LetterCodes[158] = '1111111111110000010';
LetterCodes[159] = '1111111111110000011';
LetterCodes[160] = '1111111111110000000';
LetterCodes[161] = '1111111111110000001';
LetterCodes[162] = '1111111111110000110';
LetterCodes[163] = '1111111111110000111';
LetterCodes[164] = '1111111111110000100';
LetterCodes[165] = '1111111111110000101';
LetterCodes[166] = '1111111111110011010';
LetterCodes[167] = '1111111111110011011';
LetterCodes[168] = '1111111111110011000';
LetterCodes[169] = '1111111111110011001';
LetterCodes[170] = '1111111111110011110';
LetterCodes[171] = '1111111111110011111';
LetterCodes[172] = '1111111111110011100';
LetterCodes[173] = '1111111111110011101';
LetterCodes[174] = '1111111111110010010';
LetterCodes[175] = '1111111111110010011';
LetterCodes[176] = '1111111111110010000';
LetterCodes[177] = '1111111111110010001';
LetterCodes[178] = '1111111111110010110';
LetterCodes[179] = '1111111111110010111';
LetterCodes[180] = '1111111111110010100';
LetterCodes[181] = '1111111111110010101';
LetterCodes[182] = '1111111111111101010';
LetterCodes[183] = '1111111111111101011';
LetterCodes[184] = '1111111111111101000';
LetterCodes[185] = '1111111111111101001';
LetterCodes[186] = '1111111111111101110';
LetterCodes[187] = '1111111111111101111';
LetterCodes[188] = '1111111111111101100';
LetterCodes[189] = '1111111111111101101';
LetterCodes[190] = '1111111111111100010';
LetterCodes[191] = '1111111111111100011';
LetterCodes[192] = '1111111111111100000';
LetterCodes[193] = '1111111111111100001';
LetterCodes[194] = '1111111111111100110';
LetterCodes[195] = '1111111111111100111';
LetterCodes[196] = '1111111111111100100';
LetterCodes[197] = '1111111111111100101';
LetterCodes[198] = '1111111111111111010';
LetterCodes[199] = '1111111111111111011';
LetterCodes[200] = '1111111111111111000';
LetterCodes[201] = '1111111111111111001';
LetterCodes[202] = '1111111111111111110';
LetterCodes[203] = '1111111111111111111';
LetterCodes[204] = '1111111111111111100';
LetterCodes[205] = '1111111111111111101';
LetterCodes[206] = '1111111111111110010';
LetterCodes[207] = '1111111111111110011';
LetterCodes[208] = '1111111111111110000';
LetterCodes[209] = '1111111111111110001';
LetterCodes[210] = '1111111111111110110';
LetterCodes[211] = '1111111111111110111';
LetterCodes[212] = '1111111111111110100';
LetterCodes[213] = '1111111111111110101';
LetterCodes[214] = '1111111111111001010';
LetterCodes[215] = '1111111111111001011';
LetterCodes[216] = '1111111111111001000';
LetterCodes[217] = '1111111111111001001';
LetterCodes[218] = '1111111111111001110';
LetterCodes[219] = '1111111111111001111';
LetterCodes[220] = '1111111111111001100';
LetterCodes[221] = '1111111111111001101';
LetterCodes[222] = '1111111111111000010';
LetterCodes[223] = '1111111111111000011';
LetterCodes[224] = '1111111111111000000';
LetterCodes[225] = '1111111111111000001';
LetterCodes[226] = '1111111111111000110';
LetterCodes[227] = '1111111111111000111';
LetterCodes[228] = '1111111111111000100';
LetterCodes[229] = '1111111111111000101';
LetterCodes[230] = '1111111111111011010';
LetterCodes[231] = '1111111111111011011';
LetterCodes[232] = '1111111111111011000';
LetterCodes[233] = '1111111111111011001';
LetterCodes[234] = '1111111111111011110';
LetterCodes[235] = '1111111111111011111';
LetterCodes[236] = '1111111111111011100';
LetterCodes[237] = '1111111111111011101';
LetterCodes[238] = '1111111111111010010';
LetterCodes[239] = '1111111111111010011';
LetterCodes[240] = '1111111111111010000';
LetterCodes[241] = '1111111111111010001';
LetterCodes[242] = '1111111111111010110';
LetterCodes[243] = '1111111111111010111';
LetterCodes[244] = '1111111111111010100';
LetterCodes[245] = '1111111111111010101';
LetterCodes[246] = '10111111111111010';
LetterCodes[247] = '10111111111111011';
LetterCodes[248] = '10111111111111000';
LetterCodes[249] = '10111111111111001';
LetterCodes[250] = '10111111111111110';
LetterCodes[251] = '10111111111111111';
LetterCodes[252] = '10111111111111100';
LetterCodes[253] = '10111111111111101';
LetterCodes[254] = '1111111111101110';
LetterCodes[255] = '1111111111101111';
}
// Build resulting data stream
// The bits string could get very large
var bits = "";
var bytes = ov.length + "$";
for (i = 0; i < ov.length; i ++) {
// converts ASCII chars above 255 to a star (code 42) avoiding decoding failure
if (ov.charCodeAt(i) > 255) { bits += LetterCodes[42]; }
else { bits += LetterCodes[ov.charCodeAt(i)]; }
while (bits.length > 5) {
bytes += BitsToBytes(bits);
bits = bits.slice(6, bits.length);
}
}
bytes += BitsToBytes(bits);
var encodedNodes = "";
for (i = 0; i < FinalNodes.length; i ++) {
var x, y;
x = FinalNodes[i] + 512;
y = x & 0x3F;
x >>= 6;
x &= 0x3F;
encodedNodes += encodingCharSet.charAt(x) + encodingCharSet.charAt(y);
}
bytes += encodingCharSet.charAt(encodingVersion);
return new Array (bytes, encodedNodes, LetterCodes);
}
function DecodePGN(bytes, encodedNodes) {
if (bytes.charAt(bytes.length - 1) != encodingCharSet.charAt(encodingVersion)) {
alert("ERROR: PGN encoding version mismatch (e:" +
bytes.charAt(bytes.length - 1) + " d:" + encodingCharSet.charAt(encodingVersion) + ")");
}
var originalLength = parseInt(bytes.match(/^[0-9]*/), 10);
bytes = bytes.replace(/^[0-9]*\$/,"");
var l = new Array();
while(encodedNodes.length) {
l.push((encodingCharSet.indexOf(encodedNodes.charAt(0))<<6)+encodingCharSet.indexOf(encodedNodes.charAt(1))-512);
encodedNodes = encodedNodes.slice(2,encodedNodes.length);
}
if (USE_PRESET_DECODING_SET) {
l[0] = -146;
l[1] = -111;
l[2] = -66;
l[3] = -55;
l[4] = -6;
l[5] = 46;
l[6] = -8;
l[7] = 66;
l[8] = -10;
l[9] = 105;
l[10] = -12;
l[11] = 107;
l[12] = -14;
l[13] = 44;
l[14] = -16;
l[15] = 85;
l[16] = -18;
l[17] = 106;
l[18] = -20;
l[19] = 62;
l[20] = -22;
l[21] = 89;
l[22] = -24;
l[23] = 38;
l[24] = -40;
l[25] = -33;
l[26] = -30;
l[27] = -29;
l[28] = 17;
l[29] = 18;
l[30] = -32;
l[31] = 15;
l[32] = 16;
l[33] = -37;
l[34] = -36;
l[35] = 21;
l[36] = 22;
l[37] = -39;
l[38] = 19;
l[39] = 20;
l[40] = -48;
l[41] = -45;
l[42] = -44;
l[43] = 7;
l[44] = 8;
l[45] = -47;
l[46] = 5;
l[47] = 6;
l[48] = -52;
l[49] = -51;
l[50] = 12;
l[51] = 14;
l[52] = -54;
l[53] = 9;
l[54] = 11;
l[55] = -57;
l[56] = 34;
l[57] = -59;
l[58] = 78;
l[59] = -61;
l[60] = 57;
l[61] = -63;
l[62] = 63;
l[63] = -65;
l[64] = 109;
l[65] = 119;
l[66] = -80;
l[67] = -69;
l[68] = 101;
l[69] = -71;
l[70] = 55;
l[71] = -73;
l[72] = 69;
l[73] = -75;
l[74] = 118;
l[75] = -77;
l[76] = 121;
l[77] = -79;
l[78] = 73;
l[79] = 123;
l[80] = -82;
l[81] = 49;
l[82] = -86;
l[83] = -85;
l[84] = 13;
l[85] = 40;
l[86] = -88;
l[87] = 45;
l[88] = -90;
l[89] = 68;
l[90] = -92;
l[91] = 84;
l[92] = -94;
l[93] = 125;
l[94] = -96;
l[95] = 39;
l[96] = -98;
l[97] = 58;
l[98] = -100;
l[99] = 36;
l[100] = -102;
l[101] = 92;
l[102] = -104;
l[103] = 124;
l[104] = -108;
l[105] = -107;
l[106] = 3;
l[107] = 4;
l[108] = -110;
l[109] = 0;
l[110] = 2;
l[111] = -129;
l[112] = -118;
l[113] = -115;
l[114] = 50;
l[115] = -117;
l[116] = 102;
l[117] = 103;
l[118] = -122;
l[119] = -121;
l[120] = 48;
l[121] = 110;
l[122] = -126;
l[123] = -125;
l[124] = 10;
l[125] = 1;
l[126] = -128;
l[127] = 79;
l[128] = 117;
l[129] = -137;
l[130] = -132;
l[131] = 51;
l[132] = -134;
l[133] = 98;
l[134] = -136;
l[135] = 47;
l[136] = 112;
l[137] = -141;
l[138] = -140;
l[139] = 56;
l[140] = 81;
l[141] = -143;
l[142] = 104;
l[143] = -145;
l[144] = 114;
l[145] = 115;
l[146] = -192;
l[147] = -153;
l[148] = -150;
l[149] = 32;
l[150] = -152;
l[151] = 91;
l[152] = 93;
l[153] = -157;
l[154] = -156;
l[155] = 99;
l[156] = 120;
l[157] = -159;
l[158] = 116;
l[159] = -161;
l[160] = 75;
l[161] = -163;
l[162] = 80;
l[163] = -165;
l[164] = 67;
l[165] = -167;
l[166] = 77;
l[167] = -169;
l[168] = 90;
l[169] = -171;
l[170] = 60;
l[171] = -173;
l[172] = 33;
l[173] = -175;
l[174] = 37;
l[175] = -177;
l[176] = 96;
l[177] = -185;
l[178] = -182;
l[179] = -181;
l[180] = 248;
l[181] = 249;
l[182] = -184;
l[183] = 246;
l[184] = 247;
l[185] = -189;
l[186] = -188;
l[187] = 252;
l[188] = 253;
l[189] = -191;
l[190] = 250;
l[191] = 251;
l[192] = -228;
l[193] = -225;
l[194] = -196;
l[195] = 52;
l[196] = -198;
l[197] = 108;
l[198] = -208;
l[199] = -201;
l[200] = 83;
l[201] = -205;
l[202] = -204;
l[203] = 61;
l[204] = 72;
l[205] = -207;
l[206] = 113;
l[207] = 122;
l[208] = -212;
l[209] = -211;
l[210] = 65;
l[211] = 70;
l[212] = -214;
l[213] = 71;
l[214] = -216;
l[215] = 76;
l[216] = -218;
l[217] = 74;
l[218] = -220;
l[219] = 88;
l[220] = -222;
l[221] = 64;
l[222] = -224;
l[223] = 42;
l[224] = 94;
l[225] = -227;
l[226] = 53;
l[227] = 100;
l[228] = -232;
l[229] = -231;
l[230] = 54;
l[231] = 82;
l[232] = -234;
l[233] = 97;
l[234] = -236;
l[235] = 111;
l[236] = -238;
l[237] = 43;
l[238] = -240;
l[239] = 87;
l[240] = -242;
l[241] = 41;
l[242] = -244;
l[243] = 86;
l[244] = -246;
l[245] = 35;
l[246] = -256;
l[247] = -249;
l[248] = 59;
l[249] = -251;
l[250] = 95;
l[251] = -253;
l[252] = 126;
l[253] = -255;
l[254] = 254;
l[255] = 255;
l[256] = -384;
l[257] = -321;
l[258] = -290;
l[259] = -275;
l[260] = -268;
l[261] = -265;
l[262] = -264;
l[263] = 160;
l[264] = 161;
l[265] = -267;
l[266] = 158;
l[267] = 159;
l[268] = -272;
l[269] = -271;
l[270] = 164;
l[271] = 165;
l[272] = -274;
l[273] = 162;
l[274] = 163;
l[275] = -283;
l[276] = -280;
l[277] = -279;
l[278] = 152;
l[279] = 153;
l[280] = -282;
l[281] = 150;
l[282] = 151;
l[283] = -287;
l[284] = -286;
l[285] = 156;
l[286] = 157;
l[287] = -289;
l[288] = 154;
l[289] = 155;
l[290] = -306;
l[291] = -299;
l[292] = -296;
l[293] = -295;
l[294] = 176;
l[295] = 177;
l[296] = -298;
l[297] = 174;
l[298] = 175;
l[299] = -303;
l[300] = -302;
l[301] = 180;
l[302] = 181;
l[303] = -305;
l[304] = 178;
l[305] = 179;
l[306] = -314;
l[307] = -311;
l[308] = -310;
l[309] = 168;
l[310] = 169;
l[311] = -313;
l[312] = 166;
l[313] = 167;
l[314] = -318;
l[315] = -317;
l[316] = 172;
l[317] = 173;
l[318] = -320;
l[319] = 170;
l[320] = 171;
l[321] = -353;
l[322] = -338;
l[323] = -331;
l[324] = -328;
l[325] = -327;
l[326] = 128;
l[327] = 129;
l[328] = -330;
l[329] = 31;
l[330] = 127;
l[331] = -335;
l[332] = -334;
l[333] = 132;
l[334] = 133;
l[335] = -337;
l[336] = 130;
l[337] = 131;
l[338] = -346;
l[339] = -343;
l[340] = -342;
l[341] = 25;
l[342] = 26;
l[343] = -345;
l[344] = 23;
l[345] = 24;
l[346] = -350;
l[347] = -349;
l[348] = 29;
l[349] = 30;
l[350] = -352;
l[351] = 27;
l[352] = 28;
l[353] = -369;
l[354] = -362;
l[355] = -359;
l[356] = -358;
l[357] = 144;
l[358] = 145;
l[359] = -361;
l[360] = 142;
l[361] = 143;
l[362] = -366;
l[363] = -365;
l[364] = 148;
l[365] = 149;
l[366] = -368;
l[367] = 146;
l[368] = 147;
l[369] = -377;
l[370] = -374;
l[371] = -373;
l[372] = 136;
l[373] = 137;
l[374] = -376;
l[375] = 134;
l[376] = 135;
l[377] = -381;
l[378] = -380;
l[379] = 140;
l[380] = 141;
l[381] = -383;
l[382] = 138;
l[383] = 139;
l[384] = -448;
l[385] = -417;
l[386] = -402;
l[387] = -395;
l[388] = -392;
l[389] = -391;
l[390] = 224;
l[391] = 225;
l[392] = -394;
l[393] = 222;
l[394] = 223;
l[395] = -399;
l[396] = -398;
l[397] = 228;
l[398] = 229;
l[399] = -401;
l[400] = 226;
l[401] = 227;
l[402] = -410;
l[403] = -407;
l[404] = -406;
l[405] = 216;
l[406] = 217;
l[407] = -409;
l[408] = 214;
l[409] = 215;
l[410] = -414;
l[411] = -413;
l[412] = 220;
l[413] = 221;
l[414] = -416;
l[415] = 218;
l[416] = 219;
l[417] = -433;
l[418] = -426;
l[419] = -423;
l[420] = -422;
l[421] = 240;
l[422] = 241;
l[423] = -425;
l[424] = 238;
l[425] = 239;
l[426] = -430;
l[427] = -429;
l[428] = 244;
l[429] = 245;
l[430] = -432;
l[431] = 242;
l[432] = 243;
l[433] = -441;
l[434] = -438;
l[435] = -437;
l[436] = 232;
l[437] = 233;
l[438] = -440;
l[439] = 230;
l[440] = 231;
l[441] = -445;
l[442] = -444;
l[443] = 236;
l[444] = 237;
l[445] = -447;
l[446] = 234;
l[447] = 235;
l[448] = -480;
l[449] = -465;
l[450] = -458;
l[451] = -455;
l[452] = -454;
l[453] = 192;
l[454] = 193;
l[455] = -457;
l[456] = 190;
l[457] = 191;
l[458] = -462;
l[459] = -461;
l[460] = 196;
l[461] = 197;
l[462] = -464;
l[463] = 194;
l[464] = 195;
l[465] = -473;
l[466] = -470;
l[467] = -469;
l[468] = 184;
l[469] = 185;
l[470] = -472;
l[471] = 182;
l[472] = 183;
l[473] = -477;
l[474] = -476;
l[475] = 188;
l[476] = 189;
l[477] = -479;
l[478] = 186;
l[479] = 187;
l[480] = -496;
l[481] = -489;
l[482] = -486;
l[483] = -485;
l[484] = 208;
l[485] = 209;
l[486] = -488;
l[487] = 206;
l[488] = 207;
l[489] = -493;
l[490] = -492;
l[491] = 212;
l[492] = 213;
l[493] = -495;
l[494] = 210;
l[495] = 211;
l[496] = -504;
l[497] = -501;
l[498] = -500;
l[499] = 200;
l[500] = 201;
l[501] = -503;
l[502] = 198;
l[503] = 199;
l[504] = -508;
l[505] = -507;
l[506] = 204;
l[507] = 205;
l[508] = -510;
l[509] = 202;
l[510] = 203;
}
var a=0, b=0, e=0, i, o="";
function B() { if (a===0) { b=encodingCharSet.indexOf(bytes.charAt(e++)); a=6; } return ((b>>--a)&0x01); }
while(originalLength>0) { i=0;
while(l[i]<0) {
if (B()) { i=-l[i]; }
else { i++; }
}
o+=String.fromCharCode(l[i]);
originalLength--;
}
return o;
}
</script>
</head>
<body style="margin: 0px; padding: 1.75em; font-family: sans-serif;">
<h1 style="margin-top:0px; padding-top:0px;">pgn4web PGN encoder/decoder test</h1>
<center>
<textarea id="textArea" style="height:300px; width:900px;"></textarea>
<form>
<input type="button" style="width:700px;" onClick="javascript: testPGNencode();" value="pgn4web PGN encoder/decoder test">
<input type="button" style="width:200px;" onClick="javascript: document.getElementById('textArea').value = '';" value="clear form">
</form>
<div style="width: 900px; text-align: left"><b>status: </b><span id="status">enter PGN data and press the test button</span></div>
<br>
<table cellspacing=2 cellpadding=0 border=1>
<tr style="font-weight: bold; text-align: center;">
<td>original</td>
<td>decoded</td>
</tr>
<tr>
<td>
<textarea id="original" readonly style="height:300px; width:447px;">
</textarea>
</td>
<td>
<textarea id="decoded" readonly style="height:300px; width:447px;">
</textarea>
</td>
</tr>
</table>
<br>
<table cellspacing=2 cellpadding=0 border=1>
<tr style="font-weight: bold; text-align: center;">
<td>encoded</td>
</tr>
<tr>
<td>
<textarea id="encoded" readonly style="height:80px; width:896px;">
</textarea>
</td>
</tr>
<tr style="font-weight: bold; text-align: center;">
<td>decoding key</td>
</tr>
<tr>
<td>
<textarea id="decodingKey" readonly style="height:80px; width:896px;">
</textarea>
</td>
</tr>
</table>
<br>
<table cellspacing=2 cellpadding=0 border=1>
<tr style="font-weight: bold; text-align: center;">
<td>original letters</td>
<td>letter codes</td>
<td>decoding values</td>
<td>encoded letters</td>
</tr>
<tr>
<td>
<textarea id="originalLetters" readonly style="height:300px; width:195px;">
</textarea>
</td>
<td>
<textarea id="LetterCodes" readonly style="height:300px; width:335px;">
</textarea>
</td>
<td>
<textarea id="decodingValues" readonly style="height:300px; width:165px;">
</textarea>
</td>
<td>
<textarea id="encodedLetters" readonly style="height:300px; width:195px;">
</textarea>
</td>
</tr>
</table>
<br>
</center>
<script type="text/javascript">
function testPGNencode() {
document.getElementById("status").innerHTML = "encoding data, please wait...";
if (document.getElementById("textArea").value === "") {
document.getElementById("original").value = document.getElementById("originalInput").innerHTML;
} else {
document.getElementById("original").value = document.getElementById("textArea").value;
}
original_var = document.getElementById("original").value;
ret = new Array(3);
ret = EncodePGN(original_var);
test_bytes = ret[0];
test_encodedNodes = ret[1];
test_LetterCodes = ret[2];
document.getElementById("status").innerHTML = "decoding data, please wait...";
document.getElementById("encoded").value = test_bytes;
document.getElementById("decoded").value = DecodePGN(test_bytes, test_encodedNodes);
compressPerc = Math.floor(100 * (document.getElementById("original").value.length - document.getElementById("encoded").value.length) / document.getElementById("original").value.length);
document.getElementById("status").innerHTML = "encoding/decoding test completed;" +
" original: " + document.getElementById("original").value.length + ";" +
" encoded: " + document.getElementById("encoded").value.length + ";" +
" compression rate: " + compressPerc + "%";
if (document.getElementById("decoded").value != document.getElementById("original").value) {
document.getElementById("status").innerHTML += "<br><span style='font-weight: bold; color: red;'>error: decoded different from original, please check for ASCII chars greater than 255 in the original input</span>";
}
document.getElementById("originalLetters").value = letter_frequency(document.getElementById("original").value);
document.getElementById("encodedLetters").value = letter_frequency(document.getElementById("encoded").value);
document.getElementById("decodingKey").value = test_encodedNodes;
l = new Array();
while(test_encodedNodes.length) {
l.push((encodingCharSet.indexOf(test_encodedNodes.charAt(0))<<6)+encodingCharSet.indexOf(test_encodedNodes.charAt(1))-512);
test_encodedNodes = test_encodedNodes.slice(2,test_encodedNodes.length);
}
o = "";
for (i=0; i<l.length; i++) {
o += "l[" + i + "]";
if (i < 10) { o += " "; }
else { if (i < 100) { o += " "; } }
o += " = " + l[i] + ";\n";
}
document.getElementById("decodingValues").value = o;
o = "";
for (i=0; i<test_LetterCodes.length; i++) {
o += "LetterCodes[" + i + "]";
if (i < 10) { o += " "; }
else { if (i < 100) { o += " "; } }
o += " = '" + test_LetterCodes[i] + "';\n";
}
document.getElementById("LetterCodes").innerHTML = o;
}
function letter_frequency(s) {
var thisLetters = new Array(256);
for (i = 0; i < thisLetters.length; i ++) { thisLetters[i]=0; }
var o = "";
for (i = 0; i < s.length; i ++) { thisLetters[s.charCodeAt(i)]++; }
for (i = 0; i < thisLetters.length; i ++) {
o += "Letters[" + i + "]";
if (i < 10) { o += " "; }
else { if (i < 100) { o += " "; } }
o += " = " + thisLetters[i] + ";";
if (i > 32) { o += " // " + String.fromCharCode(i); }
o += "\n";
}
return o;
}
</script>
<textarea id="originalInput" style="display:none;">
[White "Spassky, Boris"]
[Black "Fischer, Robert"]
[Result "0-1"]
[Date "1972"]
[Event "World Championship"]
[Site "Reykjavik"]
[Round "13"]
1. e4 Nf6 2. e5 Nd5 3. d4 d6 4. Nf3 g6
5. Bc4 Nb6 6. Bb3 Bg7 7. Nbd2 O-O 8. h3 a5
9. a4 dxe5 10. dxe5 Na6 11. O-O Nc5 12. Qe2 Qe8
13. Ne4 Nbxa4 14. Bxa4 Nxa4 15. Re1 Nb6 16. Bd2 a4
17. Bg5 h6 18. Bh4 Bf5 19. g4 Be6 20. Nd4 Bc4
21. Qd2 Qd7 22. Rad1 Rfe8 23. f4 Bd5 24. Nc5 Qc8
25. Qc3 e6 26. Kh2 Nd7 27. Nd3 c5 28. Nb5 Qc6
29. Nd6 Qxd6 30. exd6 Bxc3 31. bxc3 f6 32. g5 hxg5
33. fxg5 f5 34. Bg3 Kf7 35. Ne5 Nxe5 36. Bxe5 b5
37. Rf1 Rh8 38. Bf6 a3 39. Rf4 a2 40. c4 Bxc4
41. d7 Bd5 42. Kg3 Ra3 43. c3 Rha8 44. Rh4 e5
45. Rh7 Ke6 46. Re7 Kd6 47. Rxe5 Rxc3 48. Kf2 Rc2
49. Ke1 Kxd7 50. Rexd5 Kc6 51. Rd6 Kb7 52. Rd7 Ka6
53. R7d2 Rxd2 54. Kxd2 b4 55. h4 Kb5 56. h5 c4
57. Ra1 gxh5 58. g6 h4 59. g7 h3 60. Be7 Rg8
61. Bf8 h2 62. Kc2 Kc6 63. Rd1 b3 64. Kc3 h1Q
65. Rxh1 Kd5 66. Kb2 f4 67. Rd1 Ke4 68. Rc1 Kd3
69. Rd1 Ke2 70. Rc1 f3 71. Bc5 Rxg7 72. Rxc4 Rd7
73. Re4 Kf1 74. Bd4 f2 0-1
</textarea>
</body>
</html>