
var EncodeTable = new Array(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,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,48,49,50,51,
                      52,53,54,55,56,57,43,47);
var DecodeTable = new Array(62,128,128,128,63,52,53,54,55,56,
                       57,58,59,60,61,128,128,128,0,128,
 					  128,128,0,1,2,3,4,5,6,7,
 					  8,9,10,11,12,13,14,15,16,17,
 					  18,19,20,21,22,23,24,25,128,128,
 					  128,128,128,128,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);

function e64(triplet) {
	var quad = new Array();
	
	quad[0] = EncodeTable[(triplet[0] >> 2) & 63];
	quad[1] = EncodeTable[((triplet[0] & 3) << 4) + ((triplet[1] & 240) >> 4)];
	quad[2] = EncodeTable[((triplet[1] & 15) << 2) + ((triplet[2] & 192) >> 6)];
	quad[3] = EncodeTable[triplet[2] & 63];
	
	return quad;
}
 
function d64(quad) {
	var triplet = new Array();
	
	triplet[0] = (DecodeTable[quad[0] - 43] << 2) + (DecodeTable[quad[1] - 43] >> 4);
	triplet[1] = (DecodeTable[quad[1] - 43] << 4) + (DecodeTable[quad[2] - 43] >> 2);
	triplet[2] = (DecodeTable[quad[2] - 43] << 6) + DecodeTable[quad[3] - 43];
	
	return triplet;
}

function decode64(theString) {
	var numequalsigns = 0;
	var i = 0; var j = 0;
	var quad = new Array(4);
	var octets = new Array();
	while(i < theString.length) {
		if(theString.charAt(i) == "=")
			numequalsigns++;
		if(theString.charCodeAt(i) < 43 ||
				theString.charCodeAt(i) > 122 ||
				DecodeTable[theString.charCodeAt(i) - 43] == 128)
			i++;
		quad[j++] = theString.charCodeAt(i++);
		if(j == 4) {
			j = 0;
			var t = d64(quad);
			for(var k = 0; k < t.length; k++)
				octets[octets.length] = String.fromCharCode(t[k] & 255);
		}
	}
	octets.length -= numequalsigns;
	return octets.join("")
}

function encode64(theString) {
	var i = 0; var j = 0;
	var triad = new Array(3);
	var bases = new Array();
	while(i < theString.length) {
		triad[j++] = theString.charCodeAt(i++);
		if(j == 3) {
			j = 0;
			var q = e64(triad);
			for(var k = 0; k < q.length; k++)
				bases[bases.length] = String.fromCharCode(q[k]);
		}
	}
	if(j != 0) {
		switch(j) {
			case 1:
				triad[1] = 0;
			case 2:
				triad[2] = 0;
		}
		var q = e64(triad);
		for(var k = 0; k < q.length; k++)
			if(k > j)
				bases[bases.length] = "=";
			else
				bases[bases.length] = String.fromCharCode(q[k]);
	}
	return bases.join("");
}
