refactoring files and directory structure
This commit is contained in:
128
js/base64.js
Normal file
128
js/base64.js
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* $Id: base64.js,v 1.2 2011/12/27 14:34:49 dankogai Exp dankogai $
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
*/
|
||||
|
||||
(function(global){
|
||||
|
||||
if (global.Base64) return;
|
||||
|
||||
var b64chars
|
||||
= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
var b64tab = function(bin){
|
||||
var t = {};
|
||||
for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;
|
||||
return t;
|
||||
}(b64chars);
|
||||
|
||||
var sub_toBase64 = function(m){
|
||||
var n = (m.charCodeAt(0) << 16)
|
||||
| (m.charCodeAt(1) << 8)
|
||||
| (m.charCodeAt(2) );
|
||||
return b64chars.charAt( n >>> 18)
|
||||
+ b64chars.charAt((n >>> 12) & 63)
|
||||
+ b64chars.charAt((n >>> 6) & 63)
|
||||
+ b64chars.charAt( n & 63);
|
||||
};
|
||||
|
||||
var toBase64 = function(bin){
|
||||
if (bin.match(/[^\x00-\xFF]/)) throw 'unsupported character found' ;
|
||||
var padlen = 0;
|
||||
while(bin.length % 3) {
|
||||
bin += '\0';
|
||||
padlen++;
|
||||
};
|
||||
var b64 = bin.replace(/[\x00-\xFF]{3}/g, sub_toBase64);
|
||||
if (!padlen) return b64;
|
||||
b64 = b64.substr(0, b64.length - padlen);
|
||||
while(padlen--) b64 += '=';
|
||||
return b64;
|
||||
};
|
||||
|
||||
var btoa = global.btoa || toBase64;
|
||||
|
||||
var sub_fromBase64 = function(m){
|
||||
var n = (b64tab[ m.charAt(0) ] << 18)
|
||||
| (b64tab[ m.charAt(1) ] << 12)
|
||||
| (b64tab[ m.charAt(2) ] << 6)
|
||||
| (b64tab[ m.charAt(3) ]);
|
||||
return String.fromCharCode( n >> 16 )
|
||||
+ String.fromCharCode( (n >> 8) & 0xff )
|
||||
+ String.fromCharCode( n & 0xff );
|
||||
};
|
||||
|
||||
var fromBase64 = function(b64){
|
||||
b64 = b64.replace(/[^A-Za-z0-9\+\/]/g, '');
|
||||
var padlen = 0;
|
||||
while(b64.length % 4){
|
||||
b64 += 'A';
|
||||
padlen++;
|
||||
}
|
||||
var bin = b64.replace(/[A-Za-z0-9\+\/]{4}/g, sub_fromBase64);
|
||||
if (padlen >= 2)
|
||||
bin = bin.substring(0, bin.length - [0,0,2,1][padlen]);
|
||||
return bin;
|
||||
};
|
||||
|
||||
var atob = global.atob || fromBase64;
|
||||
|
||||
var re_char_nonascii = /[^\x00-\x7F]/g;
|
||||
|
||||
var sub_char_nonascii = function(m){
|
||||
var n = m.charCodeAt(0);
|
||||
return n < 0x800 ? String.fromCharCode(0xc0 | (n >>> 6))
|
||||
+ String.fromCharCode(0x80 | (n & 0x3f))
|
||||
: String.fromCharCode(0xe0 | ((n >>> 12) & 0x0f))
|
||||
+ String.fromCharCode(0x80 | ((n >>> 6) & 0x3f))
|
||||
+ String.fromCharCode(0x80 | (n & 0x3f))
|
||||
;
|
||||
};
|
||||
|
||||
var utob = function(uni){
|
||||
return uni.replace(re_char_nonascii, sub_char_nonascii);
|
||||
};
|
||||
|
||||
var re_bytes_nonascii
|
||||
= /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g;
|
||||
|
||||
var sub_bytes_nonascii = function(m){
|
||||
var c0 = m.charCodeAt(0);
|
||||
var c1 = m.charCodeAt(1);
|
||||
if(c0 < 0xe0){
|
||||
return String.fromCharCode(((c0 & 0x1f) << 6) | (c1 & 0x3f));
|
||||
}else{
|
||||
var c2 = m.charCodeAt(2);
|
||||
return String.fromCharCode(
|
||||
((c0 & 0x0f) << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
var btou = function(bin){
|
||||
return bin.replace(re_bytes_nonascii, sub_bytes_nonascii);
|
||||
};
|
||||
|
||||
global.Base64 = {
|
||||
fromBase64:fromBase64,
|
||||
toBase64:toBase64,
|
||||
atob:atob,
|
||||
btoa:btoa,
|
||||
utob:utob,
|
||||
btou:btou,
|
||||
encode:function(u){ return btoa(utob(u)) },
|
||||
encodeURI:function(u){
|
||||
return btoa(utob(u)).replace(/[+\/]/g, function(m0){
|
||||
return m0 == '+' ? '-' : '_';
|
||||
}).replace(/=+$/, '');
|
||||
},
|
||||
decode:function(a){
|
||||
return btou(atob(a.replace(/[-_]/g, function(m0){
|
||||
return m0 == '-' ? '+' : '/';
|
||||
})));
|
||||
}
|
||||
};
|
||||
|
||||
})(this);
|
||||
4
js/jquery.js
vendored
Normal file
4
js/jquery.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1671
js/rawdeflate.js
Normal file
1671
js/rawdeflate.js
Normal file
File diff suppressed because it is too large
Load Diff
753
js/rawinflate.js
Normal file
753
js/rawinflate.js
Normal file
@@ -0,0 +1,753 @@
|
||||
/*
|
||||
* $Id: rawinflate.js,v 0.2 2009/03/01 18:32:24 dankogai Exp $
|
||||
*
|
||||
* original:
|
||||
* http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt
|
||||
*/
|
||||
|
||||
(function(){
|
||||
|
||||
/* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
|
||||
* Version: 1.0.0.1
|
||||
* LastModified: Dec 25 1999
|
||||
*/
|
||||
|
||||
/* Interface:
|
||||
* data = zip_inflate(src);
|
||||
*/
|
||||
|
||||
/* constant parameters */
|
||||
var zip_WSIZE = 32768; // Sliding Window size
|
||||
var zip_STORED_BLOCK = 0;
|
||||
var zip_STATIC_TREES = 1;
|
||||
var zip_DYN_TREES = 2;
|
||||
|
||||
/* for inflate */
|
||||
var zip_lbits = 9; // bits in base literal/length lookup table
|
||||
var zip_dbits = 6; // bits in base distance lookup table
|
||||
var zip_INBUFSIZ = 32768; // Input buffer size
|
||||
var zip_INBUF_EXTRA = 64; // Extra buffer
|
||||
|
||||
/* variables (inflate) */
|
||||
var zip_slide;
|
||||
var zip_wp; // current position in slide
|
||||
var zip_fixed_tl = null; // inflate static
|
||||
var zip_fixed_td; // inflate static
|
||||
var zip_fixed_bl, fixed_bd; // inflate static
|
||||
var zip_bit_buf; // bit buffer
|
||||
var zip_bit_len; // bits in bit buffer
|
||||
var zip_method;
|
||||
var zip_eof;
|
||||
var zip_copy_leng;
|
||||
var zip_copy_dist;
|
||||
var zip_tl, zip_td; // literal/length and distance decoder tables
|
||||
var zip_bl, zip_bd; // number of bits decoded by tl and td
|
||||
|
||||
var zip_inflate_data;
|
||||
var zip_inflate_pos;
|
||||
|
||||
|
||||
/* constant tables (inflate) */
|
||||
var zip_MASK_BITS = new Array(
|
||||
0x0000,
|
||||
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
|
||||
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff);
|
||||
// Tables for deflate from PKZIP's appnote.txt.
|
||||
var zip_cplens = new Array( // Copy lengths for literal codes 257..285
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0);
|
||||
/* note: see note #13 above about the 258 in this list. */
|
||||
var zip_cplext = new Array( // Extra bits for literal codes 257..285
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99); // 99==invalid
|
||||
var zip_cpdist = new Array( // Copy offsets for distance codes 0..29
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||
8193, 12289, 16385, 24577);
|
||||
var zip_cpdext = new Array( // Extra bits for distance codes
|
||||
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
|
||||
7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
|
||||
12, 12, 13, 13);
|
||||
var zip_border = new Array( // Order of the bit length code lengths
|
||||
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15);
|
||||
/* objects (inflate) */
|
||||
|
||||
var zip_HuftList = function() {
|
||||
this.next = null;
|
||||
this.list = null;
|
||||
}
|
||||
|
||||
var zip_HuftNode = function() {
|
||||
this.e = 0; // number of extra bits or operation
|
||||
this.b = 0; // number of bits in this code or subcode
|
||||
|
||||
// union
|
||||
this.n = 0; // literal, length base, or distance base
|
||||
this.t = null; // (zip_HuftNode) pointer to next level of table
|
||||
}
|
||||
|
||||
var zip_HuftBuild = function(b, // code lengths in bits (all assumed <= BMAX)
|
||||
n, // number of codes (assumed <= N_MAX)
|
||||
s, // number of simple-valued codes (0..s-1)
|
||||
d, // list of base values for non-simple codes
|
||||
e, // list of extra bits for non-simple codes
|
||||
mm // maximum lookup bits
|
||||
) {
|
||||
this.BMAX = 16; // maximum bit length of any code
|
||||
this.N_MAX = 288; // maximum number of codes in any set
|
||||
this.status = 0; // 0: success, 1: incomplete table, 2: bad input
|
||||
this.root = null; // (zip_HuftList) starting table
|
||||
this.m = 0; // maximum lookup bits, returns actual
|
||||
|
||||
/* Given a list of code lengths and a maximum table size, make a set of
|
||||
tables to decode that set of codes. Return zero on success, one if
|
||||
the given code set is incomplete (the tables are still built in this
|
||||
case), two if the input is invalid (all zero length codes or an
|
||||
oversubscribed set of lengths), and three if not enough memory.
|
||||
The code with value 256 is special, and the tables are constructed
|
||||
so that no bits beyond that code are fetched when that code is
|
||||
decoded. */
|
||||
{
|
||||
var a; // counter for codes of length k
|
||||
var c = new Array(this.BMAX+1); // bit length count table
|
||||
var el; // length of EOB code (value 256)
|
||||
var f; // i repeats in table every f entries
|
||||
var g; // maximum code length
|
||||
var h; // table level
|
||||
var i; // counter, current code
|
||||
var j; // counter
|
||||
var k; // number of bits in current code
|
||||
var lx = new Array(this.BMAX+1); // stack of bits per table
|
||||
var p; // pointer into c[], b[], or v[]
|
||||
var pidx; // index of p
|
||||
var q; // (zip_HuftNode) points to current table
|
||||
var r = new zip_HuftNode(); // table entry for structure assignment
|
||||
var u = new Array(this.BMAX); // zip_HuftNode[BMAX][] table stack
|
||||
var v = new Array(this.N_MAX); // values in order of bit length
|
||||
var w;
|
||||
var x = new Array(this.BMAX+1);// bit offsets, then code stack
|
||||
var xp; // pointer into x or c
|
||||
var y; // number of dummy codes added
|
||||
var z; // number of entries in current table
|
||||
var o;
|
||||
var tail; // (zip_HuftList)
|
||||
|
||||
tail = this.root = null;
|
||||
for(i = 0; i < c.length; i++)
|
||||
c[i] = 0;
|
||||
for(i = 0; i < lx.length; i++)
|
||||
lx[i] = 0;
|
||||
for(i = 0; i < u.length; i++)
|
||||
u[i] = null;
|
||||
for(i = 0; i < v.length; i++)
|
||||
v[i] = 0;
|
||||
for(i = 0; i < x.length; i++)
|
||||
x[i] = 0;
|
||||
|
||||
// Generate counts for each bit length
|
||||
el = n > 256 ? b[256] : this.BMAX; // set length of EOB code, if any
|
||||
p = b; pidx = 0;
|
||||
i = n;
|
||||
do {
|
||||
c[p[pidx]]++; // assume all entries <= BMAX
|
||||
pidx++;
|
||||
} while(--i > 0);
|
||||
if(c[0] == n) { // null input--all zero length codes
|
||||
this.root = null;
|
||||
this.m = 0;
|
||||
this.status = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Find minimum and maximum length, bound *m by those
|
||||
for(j = 1; j <= this.BMAX; j++)
|
||||
if(c[j] != 0)
|
||||
break;
|
||||
k = j; // minimum code length
|
||||
if(mm < j)
|
||||
mm = j;
|
||||
for(i = this.BMAX; i != 0; i--)
|
||||
if(c[i] != 0)
|
||||
break;
|
||||
g = i; // maximum code length
|
||||
if(mm > i)
|
||||
mm = i;
|
||||
|
||||
// Adjust last length count to fill out codes, if needed
|
||||
for(y = 1 << j; j < i; j++, y <<= 1)
|
||||
if((y -= c[j]) < 0) {
|
||||
this.status = 2; // bad input: more codes than bits
|
||||
this.m = mm;
|
||||
return;
|
||||
}
|
||||
if((y -= c[i]) < 0) {
|
||||
this.status = 2;
|
||||
this.m = mm;
|
||||
return;
|
||||
}
|
||||
c[i] += y;
|
||||
|
||||
// Generate starting offsets into the value table for each length
|
||||
x[1] = j = 0;
|
||||
p = c;
|
||||
pidx = 1;
|
||||
xp = 2;
|
||||
while(--i > 0) // note that i == g from above
|
||||
x[xp++] = (j += p[pidx++]);
|
||||
|
||||
// Make a table of values in order of bit lengths
|
||||
p = b; pidx = 0;
|
||||
i = 0;
|
||||
do {
|
||||
if((j = p[pidx++]) != 0)
|
||||
v[x[j]++] = i;
|
||||
} while(++i < n);
|
||||
n = x[g]; // set n to length of v
|
||||
|
||||
// Generate the Huffman codes and for each, make the table entries
|
||||
x[0] = i = 0; // first Huffman code is zero
|
||||
p = v; pidx = 0; // grab values in bit order
|
||||
h = -1; // no tables yet--level -1
|
||||
w = lx[0] = 0; // no bits decoded yet
|
||||
q = null; // ditto
|
||||
z = 0; // ditto
|
||||
|
||||
// go through the bit lengths (k already is bits in shortest code)
|
||||
for(; k <= g; k++) {
|
||||
a = c[k];
|
||||
while(a-- > 0) {
|
||||
// here i is the Huffman code of length k bits for value p[pidx]
|
||||
// make tables up to required level
|
||||
while(k > w + lx[1 + h]) {
|
||||
w += lx[1 + h]; // add bits already decoded
|
||||
h++;
|
||||
|
||||
// compute minimum size table less than or equal to *m bits
|
||||
z = (z = g - w) > mm ? mm : z; // upper limit
|
||||
if((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table
|
||||
// too few codes for k-w bit table
|
||||
f -= a + 1; // deduct codes from patterns left
|
||||
xp = k;
|
||||
while(++j < z) { // try smaller tables up to z bits
|
||||
if((f <<= 1) <= c[++xp])
|
||||
break; // enough codes to use up j bits
|
||||
f -= c[xp]; // else deduct codes from patterns
|
||||
}
|
||||
}
|
||||
if(w + j > el && w < el)
|
||||
j = el - w; // make EOB code end at table
|
||||
z = 1 << j; // table entries for j-bit table
|
||||
lx[1 + h] = j; // set table size in stack
|
||||
|
||||
// allocate and link in new table
|
||||
q = new Array(z);
|
||||
for(o = 0; o < z; o++) {
|
||||
q[o] = new zip_HuftNode();
|
||||
}
|
||||
|
||||
if(tail == null)
|
||||
tail = this.root = new zip_HuftList();
|
||||
else
|
||||
tail = tail.next = new zip_HuftList();
|
||||
tail.next = null;
|
||||
tail.list = q;
|
||||
u[h] = q; // table starts after link
|
||||
|
||||
/* connect to last table, if there is one */
|
||||
if(h > 0) {
|
||||
x[h] = i; // save pattern for backing up
|
||||
r.b = lx[h]; // bits to dump before this table
|
||||
r.e = 16 + j; // bits in this table
|
||||
r.t = q; // pointer to this table
|
||||
j = (i & ((1 << w) - 1)) >> (w - lx[h]);
|
||||
u[h-1][j].e = r.e;
|
||||
u[h-1][j].b = r.b;
|
||||
u[h-1][j].n = r.n;
|
||||
u[h-1][j].t = r.t;
|
||||
}
|
||||
}
|
||||
|
||||
// set up table entry in r
|
||||
r.b = k - w;
|
||||
if(pidx >= n)
|
||||
r.e = 99; // out of values--invalid code
|
||||
else if(p[pidx] < s) {
|
||||
r.e = (p[pidx] < 256 ? 16 : 15); // 256 is end-of-block code
|
||||
r.n = p[pidx++]; // simple code is just the value
|
||||
} else {
|
||||
r.e = e[p[pidx] - s]; // non-simple--look up in lists
|
||||
r.n = d[p[pidx++] - s];
|
||||
}
|
||||
|
||||
// fill code-like entries with r //
|
||||
f = 1 << (k - w);
|
||||
for(j = i >> w; j < z; j += f) {
|
||||
q[j].e = r.e;
|
||||
q[j].b = r.b;
|
||||
q[j].n = r.n;
|
||||
q[j].t = r.t;
|
||||
}
|
||||
|
||||
// backwards increment the k-bit code i
|
||||
for(j = 1 << (k - 1); (i & j) != 0; j >>= 1)
|
||||
i ^= j;
|
||||
i ^= j;
|
||||
|
||||
// backup over finished tables
|
||||
while((i & ((1 << w) - 1)) != x[h]) {
|
||||
w -= lx[h]; // don't need to update q
|
||||
h--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* return actual size of base table */
|
||||
this.m = lx[1];
|
||||
|
||||
/* Return true (1) if we were given an incomplete table */
|
||||
this.status = ((y != 0 && g != 1) ? 1 : 0);
|
||||
} /* end of constructor */
|
||||
}
|
||||
|
||||
|
||||
/* routines (inflate) */
|
||||
|
||||
var zip_GET_BYTE = function() {
|
||||
if(zip_inflate_data.length == zip_inflate_pos)
|
||||
return -1;
|
||||
return zip_inflate_data.charCodeAt(zip_inflate_pos++) & 0xff;
|
||||
}
|
||||
|
||||
var zip_NEEDBITS = function(n) {
|
||||
while(zip_bit_len < n) {
|
||||
zip_bit_buf |= zip_GET_BYTE() << zip_bit_len;
|
||||
zip_bit_len += 8;
|
||||
}
|
||||
}
|
||||
|
||||
var zip_GETBITS = function(n) {
|
||||
return zip_bit_buf & zip_MASK_BITS[n];
|
||||
}
|
||||
|
||||
var zip_DUMPBITS = function(n) {
|
||||
zip_bit_buf >>= n;
|
||||
zip_bit_len -= n;
|
||||
}
|
||||
|
||||
var zip_inflate_codes = function(buff, off, size) {
|
||||
/* inflate (decompress) the codes in a deflated (compressed) block.
|
||||
Return an error code or zero if it all goes ok. */
|
||||
var e; // table entry flag/number of extra bits
|
||||
var t; // (zip_HuftNode) pointer to table entry
|
||||
var n;
|
||||
|
||||
if(size == 0)
|
||||
return 0;
|
||||
|
||||
// inflate the coded data
|
||||
n = 0;
|
||||
for(;;) { // do until end of block
|
||||
zip_NEEDBITS(zip_bl);
|
||||
t = zip_tl.list[zip_GETBITS(zip_bl)];
|
||||
e = t.e;
|
||||
while(e > 16) {
|
||||
if(e == 99)
|
||||
return -1;
|
||||
zip_DUMPBITS(t.b);
|
||||
e -= 16;
|
||||
zip_NEEDBITS(e);
|
||||
t = t.t[zip_GETBITS(e)];
|
||||
e = t.e;
|
||||
}
|
||||
zip_DUMPBITS(t.b);
|
||||
|
||||
if(e == 16) { // then it's a literal
|
||||
zip_wp &= zip_WSIZE - 1;
|
||||
buff[off + n++] = zip_slide[zip_wp++] = t.n;
|
||||
if(n == size)
|
||||
return size;
|
||||
continue;
|
||||
}
|
||||
|
||||
// exit if end of block
|
||||
if(e == 15)
|
||||
break;
|
||||
|
||||
// it's an EOB or a length
|
||||
|
||||
// get length of block to copy
|
||||
zip_NEEDBITS(e);
|
||||
zip_copy_leng = t.n + zip_GETBITS(e);
|
||||
zip_DUMPBITS(e);
|
||||
|
||||
// decode distance of block to copy
|
||||
zip_NEEDBITS(zip_bd);
|
||||
t = zip_td.list[zip_GETBITS(zip_bd)];
|
||||
e = t.e;
|
||||
|
||||
while(e > 16) {
|
||||
if(e == 99)
|
||||
return -1;
|
||||
zip_DUMPBITS(t.b);
|
||||
e -= 16;
|
||||
zip_NEEDBITS(e);
|
||||
t = t.t[zip_GETBITS(e)];
|
||||
e = t.e;
|
||||
}
|
||||
zip_DUMPBITS(t.b);
|
||||
zip_NEEDBITS(e);
|
||||
zip_copy_dist = zip_wp - t.n - zip_GETBITS(e);
|
||||
zip_DUMPBITS(e);
|
||||
|
||||
// do the copy
|
||||
while(zip_copy_leng > 0 && n < size) {
|
||||
zip_copy_leng--;
|
||||
zip_copy_dist &= zip_WSIZE - 1;
|
||||
zip_wp &= zip_WSIZE - 1;
|
||||
buff[off + n++] = zip_slide[zip_wp++]
|
||||
= zip_slide[zip_copy_dist++];
|
||||
}
|
||||
|
||||
if(n == size)
|
||||
return size;
|
||||
}
|
||||
|
||||
zip_method = -1; // done
|
||||
return n;
|
||||
}
|
||||
|
||||
var zip_inflate_stored = function(buff, off, size) {
|
||||
/* "decompress" an inflated type 0 (stored) block. */
|
||||
var n;
|
||||
|
||||
// go to byte boundary
|
||||
n = zip_bit_len & 7;
|
||||
zip_DUMPBITS(n);
|
||||
|
||||
// get the length and its complement
|
||||
zip_NEEDBITS(16);
|
||||
n = zip_GETBITS(16);
|
||||
zip_DUMPBITS(16);
|
||||
zip_NEEDBITS(16);
|
||||
if(n != ((~zip_bit_buf) & 0xffff))
|
||||
return -1; // error in compressed data
|
||||
zip_DUMPBITS(16);
|
||||
|
||||
// read and output the compressed data
|
||||
zip_copy_leng = n;
|
||||
|
||||
n = 0;
|
||||
while(zip_copy_leng > 0 && n < size) {
|
||||
zip_copy_leng--;
|
||||
zip_wp &= zip_WSIZE - 1;
|
||||
zip_NEEDBITS(8);
|
||||
buff[off + n++] = zip_slide[zip_wp++] =
|
||||
zip_GETBITS(8);
|
||||
zip_DUMPBITS(8);
|
||||
}
|
||||
|
||||
if(zip_copy_leng == 0)
|
||||
zip_method = -1; // done
|
||||
return n;
|
||||
}
|
||||
|
||||
var zip_inflate_fixed = function(buff, off, size) {
|
||||
/* decompress an inflated type 1 (fixed Huffman codes) block. We should
|
||||
either replace this with a custom decoder, or at least precompute the
|
||||
Huffman tables. */
|
||||
|
||||
// if first time, set up tables for fixed blocks
|
||||
if(zip_fixed_tl == null) {
|
||||
var i; // temporary variable
|
||||
var l = new Array(288); // length list for huft_build
|
||||
var h; // zip_HuftBuild
|
||||
|
||||
// literal table
|
||||
for(i = 0; i < 144; i++)
|
||||
l[i] = 8;
|
||||
for(; i < 256; i++)
|
||||
l[i] = 9;
|
||||
for(; i < 280; i++)
|
||||
l[i] = 7;
|
||||
for(; i < 288; i++) // make a complete, but wrong code set
|
||||
l[i] = 8;
|
||||
zip_fixed_bl = 7;
|
||||
|
||||
h = new zip_HuftBuild(l, 288, 257, zip_cplens, zip_cplext,
|
||||
zip_fixed_bl);
|
||||
if(h.status != 0) {
|
||||
alert("HufBuild error: "+h.status);
|
||||
return -1;
|
||||
}
|
||||
zip_fixed_tl = h.root;
|
||||
zip_fixed_bl = h.m;
|
||||
|
||||
// distance table
|
||||
for(i = 0; i < 30; i++) // make an incomplete code set
|
||||
l[i] = 5;
|
||||
zip_fixed_bd = 5;
|
||||
|
||||
h = new zip_HuftBuild(l, 30, 0, zip_cpdist, zip_cpdext, zip_fixed_bd);
|
||||
if(h.status > 1) {
|
||||
zip_fixed_tl = null;
|
||||
alert("HufBuild error: "+h.status);
|
||||
return -1;
|
||||
}
|
||||
zip_fixed_td = h.root;
|
||||
zip_fixed_bd = h.m;
|
||||
}
|
||||
|
||||
zip_tl = zip_fixed_tl;
|
||||
zip_td = zip_fixed_td;
|
||||
zip_bl = zip_fixed_bl;
|
||||
zip_bd = zip_fixed_bd;
|
||||
return zip_inflate_codes(buff, off, size);
|
||||
}
|
||||
|
||||
var zip_inflate_dynamic = function(buff, off, size) {
|
||||
// decompress an inflated type 2 (dynamic Huffman codes) block.
|
||||
var i; // temporary variables
|
||||
var j;
|
||||
var l; // last length
|
||||
var n; // number of lengths to get
|
||||
var t; // (zip_HuftNode) literal/length code table
|
||||
var nb; // number of bit length codes
|
||||
var nl; // number of literal/length codes
|
||||
var nd; // number of distance codes
|
||||
var ll = new Array(286+30); // literal/length and distance code lengths
|
||||
var h; // (zip_HuftBuild)
|
||||
|
||||
for(i = 0; i < ll.length; i++)
|
||||
ll[i] = 0;
|
||||
|
||||
// read in table lengths
|
||||
zip_NEEDBITS(5);
|
||||
nl = 257 + zip_GETBITS(5); // number of literal/length codes
|
||||
zip_DUMPBITS(5);
|
||||
zip_NEEDBITS(5);
|
||||
nd = 1 + zip_GETBITS(5); // number of distance codes
|
||||
zip_DUMPBITS(5);
|
||||
zip_NEEDBITS(4);
|
||||
nb = 4 + zip_GETBITS(4); // number of bit length codes
|
||||
zip_DUMPBITS(4);
|
||||
if(nl > 286 || nd > 30)
|
||||
return -1; // bad lengths
|
||||
|
||||
// read in bit-length-code lengths
|
||||
for(j = 0; j < nb; j++)
|
||||
{
|
||||
zip_NEEDBITS(3);
|
||||
ll[zip_border[j]] = zip_GETBITS(3);
|
||||
zip_DUMPBITS(3);
|
||||
}
|
||||
for(; j < 19; j++)
|
||||
ll[zip_border[j]] = 0;
|
||||
|
||||
// build decoding table for trees--single level, 7 bit lookup
|
||||
zip_bl = 7;
|
||||
h = new zip_HuftBuild(ll, 19, 19, null, null, zip_bl);
|
||||
if(h.status != 0)
|
||||
return -1; // incomplete code set
|
||||
|
||||
zip_tl = h.root;
|
||||
zip_bl = h.m;
|
||||
|
||||
// read in literal and distance code lengths
|
||||
n = nl + nd;
|
||||
i = l = 0;
|
||||
while(i < n) {
|
||||
zip_NEEDBITS(zip_bl);
|
||||
t = zip_tl.list[zip_GETBITS(zip_bl)];
|
||||
j = t.b;
|
||||
zip_DUMPBITS(j);
|
||||
j = t.n;
|
||||
if(j < 16) // length of code in bits (0..15)
|
||||
ll[i++] = l = j; // save last length in l
|
||||
else if(j == 16) { // repeat last length 3 to 6 times
|
||||
zip_NEEDBITS(2);
|
||||
j = 3 + zip_GETBITS(2);
|
||||
zip_DUMPBITS(2);
|
||||
if(i + j > n)
|
||||
return -1;
|
||||
while(j-- > 0)
|
||||
ll[i++] = l;
|
||||
} else if(j == 17) { // 3 to 10 zero length codes
|
||||
zip_NEEDBITS(3);
|
||||
j = 3 + zip_GETBITS(3);
|
||||
zip_DUMPBITS(3);
|
||||
if(i + j > n)
|
||||
return -1;
|
||||
while(j-- > 0)
|
||||
ll[i++] = 0;
|
||||
l = 0;
|
||||
} else { // j == 18: 11 to 138 zero length codes
|
||||
zip_NEEDBITS(7);
|
||||
j = 11 + zip_GETBITS(7);
|
||||
zip_DUMPBITS(7);
|
||||
if(i + j > n)
|
||||
return -1;
|
||||
while(j-- > 0)
|
||||
ll[i++] = 0;
|
||||
l = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// build the decoding tables for literal/length and distance codes
|
||||
zip_bl = zip_lbits;
|
||||
h = new zip_HuftBuild(ll, nl, 257, zip_cplens, zip_cplext, zip_bl);
|
||||
if(zip_bl == 0) // no literals or lengths
|
||||
h.status = 1;
|
||||
if(h.status != 0) {
|
||||
if(h.status == 1)
|
||||
;// **incomplete literal tree**
|
||||
return -1; // incomplete code set
|
||||
}
|
||||
zip_tl = h.root;
|
||||
zip_bl = h.m;
|
||||
|
||||
for(i = 0; i < nd; i++)
|
||||
ll[i] = ll[i + nl];
|
||||
zip_bd = zip_dbits;
|
||||
h = new zip_HuftBuild(ll, nd, 0, zip_cpdist, zip_cpdext, zip_bd);
|
||||
zip_td = h.root;
|
||||
zip_bd = h.m;
|
||||
|
||||
if(zip_bd == 0 && nl > 257) { // lengths but no distances
|
||||
// **incomplete distance tree**
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(h.status == 1) {
|
||||
;// **incomplete distance tree**
|
||||
}
|
||||
if(h.status != 0)
|
||||
return -1;
|
||||
|
||||
// decompress until an end-of-block code
|
||||
return zip_inflate_codes(buff, off, size);
|
||||
}
|
||||
|
||||
var zip_inflate_start = function() {
|
||||
var i;
|
||||
|
||||
if(zip_slide == null)
|
||||
zip_slide = new Array(2 * zip_WSIZE);
|
||||
zip_wp = 0;
|
||||
zip_bit_buf = 0;
|
||||
zip_bit_len = 0;
|
||||
zip_method = -1;
|
||||
zip_eof = false;
|
||||
zip_copy_leng = zip_copy_dist = 0;
|
||||
zip_tl = null;
|
||||
}
|
||||
|
||||
var zip_inflate_internal = function(buff, off, size) {
|
||||
// decompress an inflated entry
|
||||
var n, i;
|
||||
|
||||
n = 0;
|
||||
while(n < size) {
|
||||
if(zip_eof && zip_method == -1)
|
||||
return n;
|
||||
|
||||
if(zip_copy_leng > 0) {
|
||||
if(zip_method != zip_STORED_BLOCK) {
|
||||
// STATIC_TREES or DYN_TREES
|
||||
while(zip_copy_leng > 0 && n < size) {
|
||||
zip_copy_leng--;
|
||||
zip_copy_dist &= zip_WSIZE - 1;
|
||||
zip_wp &= zip_WSIZE - 1;
|
||||
buff[off + n++] = zip_slide[zip_wp++] =
|
||||
zip_slide[zip_copy_dist++];
|
||||
}
|
||||
} else {
|
||||
while(zip_copy_leng > 0 && n < size) {
|
||||
zip_copy_leng--;
|
||||
zip_wp &= zip_WSIZE - 1;
|
||||
zip_NEEDBITS(8);
|
||||
buff[off + n++] = zip_slide[zip_wp++] = zip_GETBITS(8);
|
||||
zip_DUMPBITS(8);
|
||||
}
|
||||
if(zip_copy_leng == 0)
|
||||
zip_method = -1; // done
|
||||
}
|
||||
if(n == size)
|
||||
return n;
|
||||
}
|
||||
|
||||
if(zip_method == -1) {
|
||||
if(zip_eof)
|
||||
break;
|
||||
|
||||
// read in last block bit
|
||||
zip_NEEDBITS(1);
|
||||
if(zip_GETBITS(1) != 0)
|
||||
zip_eof = true;
|
||||
zip_DUMPBITS(1);
|
||||
|
||||
// read in block type
|
||||
zip_NEEDBITS(2);
|
||||
zip_method = zip_GETBITS(2);
|
||||
zip_DUMPBITS(2);
|
||||
zip_tl = null;
|
||||
zip_copy_leng = 0;
|
||||
}
|
||||
|
||||
switch(zip_method) {
|
||||
case 0: // zip_STORED_BLOCK
|
||||
i = zip_inflate_stored(buff, off + n, size - n);
|
||||
break;
|
||||
|
||||
case 1: // zip_STATIC_TREES
|
||||
if(zip_tl != null)
|
||||
i = zip_inflate_codes(buff, off + n, size - n);
|
||||
else
|
||||
i = zip_inflate_fixed(buff, off + n, size - n);
|
||||
break;
|
||||
|
||||
case 2: // zip_DYN_TREES
|
||||
if(zip_tl != null)
|
||||
i = zip_inflate_codes(buff, off + n, size - n);
|
||||
else
|
||||
i = zip_inflate_dynamic(buff, off + n, size - n);
|
||||
break;
|
||||
|
||||
default: // error
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(i == -1) {
|
||||
if(zip_eof)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
n += i;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
var zip_inflate = function(str) {
|
||||
var i, j;
|
||||
|
||||
zip_inflate_start();
|
||||
zip_inflate_data = str;
|
||||
zip_inflate_pos = 0;
|
||||
|
||||
var buff = new Array(1024);
|
||||
var aout = [];
|
||||
while((i = zip_inflate_internal(buff, 0, buff.length)) > 0) {
|
||||
var cbuf = new Array(i);
|
||||
for(j = 0; j < i; j++){
|
||||
cbuf[j] = String.fromCharCode(buff[j]);
|
||||
}
|
||||
aout[aout.length] = cbuf.join("");
|
||||
}
|
||||
zip_inflate_data = null; // G.C.
|
||||
return aout.join("");
|
||||
}
|
||||
|
||||
if (! window.RawDeflate) RawDeflate = {};
|
||||
RawDeflate.inflate = zip_inflate;
|
||||
|
||||
})();
|
||||
41
js/sjcl.js
Normal file
41
js/sjcl.js
Normal file
@@ -0,0 +1,41 @@
|
||||
"use strict";var sjcl={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a},notReady:function(a){this.toString=function(){return"NOT READY: "+this.message};this.message=a}}};
|
||||
if(typeof module!="undefined"&&module.exports)module.exports=sjcl;
|
||||
sjcl.cipher.aes=function(a){this.h[0][0][0]||this.w();var b,c,d,e,f=this.h[0][4],g=this.h[1];b=a.length;var h=1;if(b!==4&&b!==6&&b!==8)throw new sjcl.exception.invalid("invalid aes key size");this.a=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(a%b===0||b===8&&a%b===4){c=f[c>>>24]<<24^f[c>>16&255]<<16^f[c>>8&255]<<8^f[c&255];if(a%b===0){c=c<<8^c>>>24^h<<24;h=h<<1^(h>>7)*283}}d[a]=d[a-b]^c}for(b=0;a;b++,a--){c=d[b&3?a:a-4];e[b]=a<=4||b<4?c:g[0][f[c>>>24]]^g[1][f[c>>16&255]]^g[2][f[c>>8&255]]^
|
||||
g[3][f[c&255]]}};
|
||||
sjcl.cipher.aes.prototype={encrypt:function(a){return this.H(a,0)},decrypt:function(a){return this.H(a,1)},h:[[[],[],[],[],[]],[[],[],[],[],[]]],w:function(){var a=this.h[0],b=this.h[1],c=a[4],d=b[4],e,f,g,h=[],i=[],k,j,l,m;for(e=0;e<0x100;e++)i[(h[e]=e<<1^(e>>7)*283)^e]=e;for(f=g=0;!c[f];f^=k||1,g=i[g]||1){l=g^g<<1^g<<2^g<<3^g<<4;l=l>>8^l&255^99;c[f]=l;d[l]=f;j=h[e=h[k=h[f]]];m=j*0x1010101^e*0x10001^k*0x101^f*0x1010100;j=h[l]*0x101^l*0x1010100;for(e=0;e<4;e++){a[e][f]=j=j<<24^j>>>8;b[e][l]=m=m<<24^m>>>8}}for(e=
|
||||
0;e<5;e++){a[e]=a[e].slice(0);b[e]=b[e].slice(0)}},H:function(a,b){if(a.length!==4)throw new sjcl.exception.invalid("invalid aes block size");var c=this.a[b],d=a[0]^c[0],e=a[b?3:1]^c[1],f=a[2]^c[2];a=a[b?1:3]^c[3];var g,h,i,k=c.length/4-2,j,l=4,m=[0,0,0,0];g=this.h[b];var n=g[0],o=g[1],p=g[2],q=g[3],r=g[4];for(j=0;j<k;j++){g=n[d>>>24]^o[e>>16&255]^p[f>>8&255]^q[a&255]^c[l];h=n[e>>>24]^o[f>>16&255]^p[a>>8&255]^q[d&255]^c[l+1];i=n[f>>>24]^o[a>>16&255]^p[d>>8&255]^q[e&255]^c[l+2];a=n[a>>>24]^o[d>>16&
|
||||
255]^p[e>>8&255]^q[f&255]^c[l+3];l+=4;d=g;e=h;f=i}for(j=0;j<4;j++){m[b?3&-j:j]=r[d>>>24]<<24^r[e>>16&255]<<16^r[f>>8&255]<<8^r[a&255]^c[l++];g=d;d=e;e=f;f=a;a=g}return m}};
|
||||
sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.P(a.slice(b/32),32-(b&31)).slice(1);return c===undefined?a:sjcl.bitArray.clamp(a,c-b)},extract:function(a,b,c){var d=Math.floor(-b-c&31);return((b+c-1^b)&-32?a[b/32|0]<<32-d^a[b/32+1|0]>>>d:a[b/32|0]>>>d)&(1<<c)-1},concat:function(a,b){if(a.length===0||b.length===0)return a.concat(b);var c=a[a.length-1],d=sjcl.bitArray.getPartial(c);return d===32?a.concat(b):sjcl.bitArray.P(b,d,c|0,a.slice(0,a.length-1))},bitLength:function(a){var b=a.length;
|
||||
if(b===0)return 0;return(b-1)*32+sjcl.bitArray.getPartial(a[b-1])},clamp:function(a,b){if(a.length*32<b)return a;a=a.slice(0,Math.ceil(b/32));var c=a.length;b&=31;if(c>0&&b)a[c-1]=sjcl.bitArray.partial(b,a[c-1]&2147483648>>b-1,1);return a},partial:function(a,b,c){if(a===32)return b;return(c?b|0:b<<32-a)+a*0x10000000000},getPartial:function(a){return Math.round(a/0x10000000000)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return false;var c=0,d;for(d=0;d<a.length;d++)c|=
|
||||
a[d]^b[d];return c===0},P:function(a,b,c,d){var e;e=0;if(d===undefined)d=[];for(;b>=32;b-=32){d.push(c);c=0}if(b===0)return d.concat(a);for(e=0;e<a.length;e++){d.push(c|a[e]>>>b);c=a[e]<<32-b}e=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(e);d.push(sjcl.bitArray.partial(b+a&31,b+a>32?c:d.pop(),1));return d},k:function(a,b){return[a[0]^b[0],a[1]^b[1],a[2]^b[2],a[3]^b[3]]}};
|
||||
sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),d,e;for(d=0;d<c/8;d++){if((d&3)===0)e=a[d/4];b+=String.fromCharCode(e>>>24);e<<=8}return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c<a.length;c++){d=d<<8|a.charCodeAt(c);if((c&3)===3){b.push(d);d=0}}c&3&&b.push(sjcl.bitArray.partial(8*(c&3),d));return b}};
|
||||
sjcl.codec.hex={fromBits:function(a){var b="",c;for(c=0;c<a.length;c++)b+=((a[c]|0)+0xf00000000000).toString(16).substr(4);return b.substr(0,sjcl.bitArray.bitLength(a)/4)},toBits:function(a){var b,c=[],d;a=a.replace(/\s|0x/g,"");d=a.length;a+="00000000";for(b=0;b<a.length;b+=8)c.push(parseInt(a.substr(b,8),16)^0);return sjcl.bitArray.clamp(c,d*4)}};
|
||||
sjcl.codec.base64={D:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",fromBits:function(a,b,c){var d="",e=0,f=sjcl.codec.base64.D,g=0,h=sjcl.bitArray.bitLength(a);if(c)f=f.substr(0,62)+"-_";for(c=0;d.length*6<h;){d+=f.charAt((g^a[c]>>>e)>>>26);if(e<6){g=a[c]<<6-e;e+=26;c++}else{g<<=6;e-=6}}for(;d.length&3&&!b;)d+="=";return d},toBits:function(a,b){a=a.replace(/\s|=/g,"");var c=[],d=0,e=sjcl.codec.base64.D,f=0,g;if(b)e=e.substr(0,62)+"-_";for(b=0;b<a.length;b++){g=e.indexOf(a.charAt(b));
|
||||
if(g<0)throw new sjcl.exception.invalid("this isn't base64!");if(d>26){d-=26;c.push(f^g>>>d);f=g<<32-d}else{d+=6;f^=g<<32-d}}d&56&&c.push(sjcl.bitArray.partial(d&56,f,1));return c}};sjcl.codec.base64url={fromBits:function(a){return sjcl.codec.base64.fromBits(a,1,1)},toBits:function(a){return sjcl.codec.base64.toBits(a,1)}};sjcl.hash.sha256=function(a){this.a[0]||this.w();if(a){this.n=a.n.slice(0);this.i=a.i.slice(0);this.e=a.e}else this.reset()};sjcl.hash.sha256.hash=function(a){return(new sjcl.hash.sha256).update(a).finalize()};
|
||||
sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.n=this.N.slice(0);this.i=[];this.e=0;return this},update:function(a){if(typeof a==="string")a=sjcl.codec.utf8String.toBits(a);var b,c=this.i=sjcl.bitArray.concat(this.i,a);b=this.e;a=this.e=b+sjcl.bitArray.bitLength(a);for(b=512+b&-512;b<=a;b+=512)this.C(c.splice(0,16));return this},finalize:function(){var a,b=this.i,c=this.n;b=sjcl.bitArray.concat(b,[sjcl.bitArray.partial(1,1)]);for(a=b.length+2;a&15;a++)b.push(0);b.push(Math.floor(this.e/
|
||||
4294967296));for(b.push(this.e|0);b.length;)this.C(b.splice(0,16));this.reset();return c},N:[],a:[],w:function(){function a(e){return(e-Math.floor(e))*0x100000000|0}var b=0,c=2,d;a:for(;b<64;c++){for(d=2;d*d<=c;d++)if(c%d===0)continue a;if(b<8)this.N[b]=a(Math.pow(c,0.5));this.a[b]=a(Math.pow(c,1/3));b++}},C:function(a){var b,c,d=a.slice(0),e=this.n,f=this.a,g=e[0],h=e[1],i=e[2],k=e[3],j=e[4],l=e[5],m=e[6],n=e[7];for(a=0;a<64;a++){if(a<16)b=d[a];else{b=d[a+1&15];c=d[a+14&15];b=d[a&15]=(b>>>7^b>>>18^
|
||||
b>>>3^b<<25^b<<14)+(c>>>17^c>>>19^c>>>10^c<<15^c<<13)+d[a&15]+d[a+9&15]|0}b=b+n+(j>>>6^j>>>11^j>>>25^j<<26^j<<21^j<<7)+(m^j&(l^m))+f[a];n=m;m=l;l=j;j=k+b|0;k=i;i=h;h=g;g=b+(h&i^k&(h^i))+(h>>>2^h>>>13^h>>>22^h<<30^h<<19^h<<10)|0}e[0]=e[0]+g|0;e[1]=e[1]+h|0;e[2]=e[2]+i|0;e[3]=e[3]+k|0;e[4]=e[4]+j|0;e[5]=e[5]+l|0;e[6]=e[6]+m|0;e[7]=e[7]+n|0}};
|
||||
sjcl.mode.ccm={name:"ccm",encrypt:function(a,b,c,d,e){var f,g=b.slice(0),h=sjcl.bitArray,i=h.bitLength(c)/8,k=h.bitLength(g)/8;e=e||64;d=d||[];if(i<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(f=2;f<4&&k>>>8*f;f++);if(f<15-i)f=15-i;c=h.clamp(c,8*(15-f));b=sjcl.mode.ccm.G(a,b,c,d,e,f);g=sjcl.mode.ccm.I(a,g,c,b,e,f);return h.concat(g.data,g.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var f=sjcl.bitArray,g=f.bitLength(c)/8,h=f.bitLength(b),i=f.clamp(b,h-e),k=f.bitSlice(b,
|
||||
h-e);h=(h-e)/8;if(g<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(b=2;b<4&&h>>>8*b;b++);if(b<15-g)b=15-g;c=f.clamp(c,8*(15-b));i=sjcl.mode.ccm.I(a,i,c,k,e,b);a=sjcl.mode.ccm.G(a,i.data,c,d,e,b);if(!f.equal(i.tag,a))throw new sjcl.exception.corrupt("ccm: tag doesn't match");return i.data},G:function(a,b,c,d,e,f){var g=[],h=sjcl.bitArray,i=h.k;e/=8;if(e%2||e<4||e>16)throw new sjcl.exception.invalid("ccm: invalid tag length");if(d.length>0xffffffff||b.length>0xffffffff)throw new sjcl.exception.bug("ccm: can't deal with 4GiB or more data");
|
||||
f=[h.partial(8,(d.length?64:0)|e-2<<2|f-1)];f=h.concat(f,c);f[3]|=h.bitLength(b)/8;f=a.encrypt(f);if(d.length){c=h.bitLength(d)/8;if(c<=65279)g=[h.partial(16,c)];else if(c<=0xffffffff)g=h.concat([h.partial(16,65534)],[c]);g=h.concat(g,d);for(d=0;d<g.length;d+=4)f=a.encrypt(i(f,g.slice(d,d+4).concat([0,0,0])))}for(d=0;d<b.length;d+=4)f=a.encrypt(i(f,b.slice(d,d+4).concat([0,0,0])));return h.clamp(f,e*8)},I:function(a,b,c,d,e,f){var g,h=sjcl.bitArray;g=h.k;var i=b.length,k=h.bitLength(b);c=h.concat([h.partial(8,
|
||||
f-1)],c).concat([0,0,0]).slice(0,4);d=h.bitSlice(g(d,a.encrypt(c)),0,e);if(!i)return{tag:d,data:[]};for(g=0;g<i;g+=4){c[3]++;e=a.encrypt(c);b[g]^=e[0];b[g+1]^=e[1];b[g+2]^=e[2];b[g+3]^=e[3]}return{tag:d,data:h.clamp(b,k)}}};
|
||||
sjcl.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,f){if(sjcl.bitArray.bitLength(c)!==128)throw new sjcl.exception.invalid("ocb iv must be 128 bits");var g,h=sjcl.mode.ocb2.A,i=sjcl.bitArray,k=i.k,j=[0,0,0,0];c=h(a.encrypt(c));var l,m=[];d=d||[];e=e||64;for(g=0;g+4<b.length;g+=4){l=b.slice(g,g+4);j=k(j,l);m=m.concat(k(c,a.encrypt(k(c,l))));c=h(c)}l=b.slice(g);b=i.bitLength(l);g=a.encrypt(k(c,[0,0,0,b]));l=i.clamp(k(l.concat([0,0,0]),g),b);j=k(j,k(l.concat([0,0,0]),g));j=a.encrypt(k(j,k(c,h(c))));
|
||||
if(d.length)j=k(j,f?d:sjcl.mode.ocb2.pmac(a,d));return m.concat(i.concat(l,i.clamp(j,e)))},decrypt:function(a,b,c,d,e,f){if(sjcl.bitArray.bitLength(c)!==128)throw new sjcl.exception.invalid("ocb iv must be 128 bits");e=e||64;var g=sjcl.mode.ocb2.A,h=sjcl.bitArray,i=h.k,k=[0,0,0,0],j=g(a.encrypt(c)),l,m,n=sjcl.bitArray.bitLength(b)-e,o=[];d=d||[];for(c=0;c+4<n/32;c+=4){l=i(j,a.decrypt(i(j,b.slice(c,c+4))));k=i(k,l);o=o.concat(l);j=g(j)}m=n-c*32;l=a.encrypt(i(j,[0,0,0,m]));l=i(l,h.clamp(b.slice(c),
|
||||
m).concat([0,0,0]));k=i(k,l);k=a.encrypt(i(k,i(j,g(j))));if(d.length)k=i(k,f?d:sjcl.mode.ocb2.pmac(a,d));if(!h.equal(h.clamp(k,e),h.bitSlice(b,n)))throw new sjcl.exception.corrupt("ocb: tag doesn't match");return o.concat(h.clamp(l,m))},pmac:function(a,b){var c,d=sjcl.mode.ocb2.A,e=sjcl.bitArray,f=e.k,g=[0,0,0,0],h=a.encrypt([0,0,0,0]);h=f(h,d(d(h)));for(c=0;c+4<b.length;c+=4){h=d(h);g=f(g,a.encrypt(f(h,b.slice(c,c+4))))}b=b.slice(c);if(e.bitLength(b)<128){h=f(h,d(h));b=e.concat(b,[2147483648|0,0,
|
||||
0,0])}g=f(g,b);return a.encrypt(f(d(f(h,d(h))),g))},A:function(a){return[a[0]<<1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^(a[0]>>>31)*135]}};sjcl.misc.hmac=function(a,b){this.M=b=b||sjcl.hash.sha256;var c=[[],[]],d=b.prototype.blockSize/32;this.l=[new b,new b];if(a.length>d)a=b.hash(a);for(b=0;b<d;b++){c[0][b]=a[b]^909522486;c[1][b]=a[b]^1549556828}this.l[0].update(c[0]);this.l[1].update(c[1])};
|
||||
sjcl.misc.hmac.prototype.encrypt=sjcl.misc.hmac.prototype.mac=function(a,b){a=(new this.M(this.l[0])).update(a,b).finalize();return(new this.M(this.l[1])).update(a).finalize()};
|
||||
sjcl.misc.pbkdf2=function(a,b,c,d,e){c=c||1E3;if(d<0||c<0)throw sjcl.exception.invalid("invalid params to pbkdf2");if(typeof a==="string")a=sjcl.codec.utf8String.toBits(a);e=e||sjcl.misc.hmac;a=new e(a);var f,g,h,i,k=[],j=sjcl.bitArray;for(i=1;32*k.length<(d||1);i++){e=f=a.encrypt(j.concat(b,[i]));for(g=1;g<c;g++){f=a.encrypt(f);for(h=0;h<f.length;h++)e[h]^=f[h]}k=k.concat(e)}if(d)k=j.clamp(k,d);return k};
|
||||
sjcl.random={randomWords:function(a,b){var c=[];b=this.isReady(b);var d;if(b===0)throw new sjcl.exception.notReady("generator isn't seeded");else b&2&&this.U(!(b&1));for(b=0;b<a;b+=4){(b+1)%0x10000===0&&this.L();d=this.u();c.push(d[0],d[1],d[2],d[3])}this.L();return c.slice(0,a)},setDefaultParanoia:function(a){this.t=a},addEntropy:function(a,b,c){c=c||"user";var d,e,f=(new Date).valueOf(),g=this.q[c],h=this.isReady();d=this.F[c];if(d===undefined)d=this.F[c]=this.R++;if(g===undefined)g=this.q[c]=0;this.q[c]=
|
||||
(this.q[c]+1)%this.b.length;switch(typeof a){case "number":break;case "object":if(b===undefined)for(c=b=0;c<a.length;c++)for(e=a[c];e>0;){b++;e>>>=1}this.b[g].update([d,this.J++,2,b,f,a.length].concat(a));break;case "string":if(b===undefined)b=a.length;this.b[g].update([d,this.J++,3,b,f,a.length]);this.b[g].update(a);break;default:throw new sjcl.exception.bug("random: addEntropy only supports number, array or string");}this.j[g]+=b;this.f+=b;if(h===0){this.isReady()!==0&&this.K("seeded",Math.max(this.g,
|
||||
this.f));this.K("progress",this.getProgress())}},isReady:function(a){a=this.B[a!==undefined?a:this.t];return this.g&&this.g>=a?this.j[0]>80&&(new Date).valueOf()>this.O?3:1:this.f>=a?2:0},getProgress:function(a){a=this.B[a?a:this.t];return this.g>=a?1["0"]:this.f>a?1["0"]:this.f/a},startCollectors:function(){if(!this.m){if(window.addEventListener){window.addEventListener("load",this.o,false);window.addEventListener("mousemove",this.p,false)}else if(document.attachEvent){document.attachEvent("onload",
|
||||
this.o);document.attachEvent("onmousemove",this.p)}else throw new sjcl.exception.bug("can't attach event");this.m=true}},stopCollectors:function(){if(this.m){if(window.removeEventListener){window.removeEventListener("load",this.o,false);window.removeEventListener("mousemove",this.p,false)}else if(window.detachEvent){window.detachEvent("onload",this.o);window.detachEvent("onmousemove",this.p)}this.m=false}},addEventListener:function(a,b){this.r[a][this.Q++]=b},removeEventListener:function(a,b){var c;
|
||||
a=this.r[a];var d=[];for(c in a)a.hasOwnProperty(c)&&a[c]===b&&d.push(c);for(b=0;b<d.length;b++){c=d[b];delete a[c]}},b:[new sjcl.hash.sha256],j:[0],z:0,q:{},J:0,F:{},R:0,g:0,f:0,O:0,a:[0,0,0,0,0,0,0,0],d:[0,0,0,0],s:undefined,t:6,m:false,r:{progress:{},seeded:{}},Q:0,B:[0,48,64,96,128,192,0x100,384,512,768,1024],u:function(){for(var a=0;a<4;a++){this.d[a]=this.d[a]+1|0;if(this.d[a])break}return this.s.encrypt(this.d)},L:function(){this.a=this.u().concat(this.u());this.s=new sjcl.cipher.aes(this.a)},
|
||||
T:function(a){this.a=sjcl.hash.sha256.hash(this.a.concat(a));this.s=new sjcl.cipher.aes(this.a);for(a=0;a<4;a++){this.d[a]=this.d[a]+1|0;if(this.d[a])break}},U:function(a){var b=[],c=0,d;this.O=b[0]=(new Date).valueOf()+3E4;for(d=0;d<16;d++)b.push(Math.random()*0x100000000|0);for(d=0;d<this.b.length;d++){b=b.concat(this.b[d].finalize());c+=this.j[d];this.j[d]=0;if(!a&&this.z&1<<d)break}if(this.z>=1<<this.b.length){this.b.push(new sjcl.hash.sha256);this.j.push(0)}this.f-=c;if(c>this.g)this.g=c;this.z++;
|
||||
this.T(b)},p:function(a){sjcl.random.addEntropy([a.x||a.clientX||a.offsetX,a.y||a.clientY||a.offsetY],2,"mouse")},o:function(){sjcl.random.addEntropy(new Date,2,"loadtime")},K:function(a,b){var c;a=sjcl.random.r[a];var d=[];for(c in a)a.hasOwnProperty(c)&&d.push(a[c]);for(c=0;c<d.length;c++)d[c](b)}};try{var s=new Uint32Array(32);crypto.getRandomValues(s);sjcl.random.addEntropy(s,1024,"crypto['getRandomValues']")}catch(t){}
|
||||
sjcl.json={defaults:{v:1,iter:1E3,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},encrypt:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json,f=e.c({iv:sjcl.random.randomWords(4,0)},e.defaults),g;e.c(f,c);c=f.adata;if(typeof f.salt==="string")f.salt=sjcl.codec.base64.toBits(f.salt);if(typeof f.iv==="string")f.iv=sjcl.codec.base64.toBits(f.iv);if(!sjcl.mode[f.mode]||!sjcl.cipher[f.cipher]||typeof a==="string"&&f.iter<=100||f.ts!==64&&f.ts!==96&&f.ts!==128||f.ks!==128&&f.ks!==192&&f.ks!==0x100||f.iv.length<
|
||||
2||f.iv.length>4)throw new sjcl.exception.invalid("json encrypt: invalid parameters");if(typeof a==="string"){g=sjcl.misc.cachedPbkdf2(a,f);a=g.key.slice(0,f.ks/32);f.salt=g.salt}if(typeof b==="string")b=sjcl.codec.utf8String.toBits(b);if(typeof c==="string")c=sjcl.codec.utf8String.toBits(c);g=new sjcl.cipher[f.cipher](a);e.c(d,f);d.key=a;f.ct=sjcl.mode[f.mode].encrypt(g,b,f.iv,c,f.ts);return e.encode(e.V(f,e.defaults))},decrypt:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json;b=e.c(e.c(e.c({},e.defaults),
|
||||
e.decode(b)),c,true);var f;c=b.adata;if(typeof b.salt==="string")b.salt=sjcl.codec.base64.toBits(b.salt);if(typeof b.iv==="string")b.iv=sjcl.codec.base64.toBits(b.iv);if(!sjcl.mode[b.mode]||!sjcl.cipher[b.cipher]||typeof a==="string"&&b.iter<=100||b.ts!==64&&b.ts!==96&&b.ts!==128||b.ks!==128&&b.ks!==192&&b.ks!==0x100||!b.iv||b.iv.length<2||b.iv.length>4)throw new sjcl.exception.invalid("json decrypt: invalid parameters");if(typeof a==="string"){f=sjcl.misc.cachedPbkdf2(a,b);a=f.key.slice(0,b.ks/32);
|
||||
b.salt=f.salt}if(typeof c==="string")c=sjcl.codec.utf8String.toBits(c);f=new sjcl.cipher[b.cipher](a);c=sjcl.mode[b.mode].decrypt(f,b.ct,b.iv,c,b.ts);e.c(d,b);d.key=a;return sjcl.codec.utf8String.fromBits(c)},encode:function(a){var b,c="{",d="";for(b in a)if(a.hasOwnProperty(b)){if(!b.match(/^[a-z0-9]+$/i))throw new sjcl.exception.invalid("json encode: invalid property name");c+=d+'"'+b+'":';d=",";switch(typeof a[b]){case "number":case "boolean":c+=a[b];break;case "string":c+='"'+escape(a[b])+'"';
|
||||
break;case "object":c+='"'+sjcl.codec.base64.fromBits(a[b],1)+'"';break;default:throw new sjcl.exception.bug("json encode: unsupported type");}}return c+"}"},decode:function(a){a=a.replace(/\s/g,"");if(!a.match(/^\{.*\}$/))throw new sjcl.exception.invalid("json decode: this isn't json!");a=a.replace(/^\{|\}$/g,"").split(/,/);var b={},c,d;for(c=0;c<a.length;c++){if(!(d=a[c].match(/^(?:(["']?)([a-z][a-z0-9]*)\1):(?:(\d+)|"([a-z0-9+\/%*_.@=\-]*)")$/i)))throw new sjcl.exception.invalid("json decode: this isn't json!");
|
||||
b[d[2]]=d[3]?parseInt(d[3],10):d[2].match(/^(ct|salt|iv)$/)?sjcl.codec.base64.toBits(d[4]):unescape(d[4])}return b},c:function(a,b,c){if(a===undefined)a={};if(b===undefined)return a;var d;for(d in b)if(b.hasOwnProperty(d)){if(c&&a[d]!==undefined&&a[d]!==b[d])throw new sjcl.exception.invalid("required parameter overridden");a[d]=b[d]}return a},V:function(a,b){var c={},d;for(d in a)if(a.hasOwnProperty(d)&&a[d]!==b[d])c[d]=a[d];return c},W:function(a,b){var c={},d;for(d=0;d<b.length;d++)if(a[b[d]]!==
|
||||
undefined)c[b[d]]=a[b[d]];return c}};sjcl.encrypt=sjcl.json.encrypt;sjcl.decrypt=sjcl.json.decrypt;sjcl.misc.S={};sjcl.misc.cachedPbkdf2=function(a,b){var c=sjcl.misc.S,d;b=b||{};d=b.iter||1E3;c=c[a]=c[a]||{};d=c[d]=c[d]||{firstSalt:b.salt&&b.salt.length?b.salt.slice(0):sjcl.random.randomWords(2,0)};c=b.salt===undefined?d.firstSalt:b.salt;d[c]=d[c]||sjcl.misc.pbkdf2(a,c,b.iter);return{key:d[c].slice(0),salt:c.slice(0)}};
|
||||
462
js/zerobin.js
Normal file
462
js/zerobin.js
Normal file
@@ -0,0 +1,462 @@
|
||||
/**
|
||||
* ZeroBin 0.15
|
||||
*
|
||||
* @link http://sebsauvage.net/wiki/doku.php?id=php:zerobin
|
||||
* @author sebsauvage
|
||||
*/
|
||||
|
||||
// Immediately start random number generator collector.
|
||||
sjcl.random.startCollectors();
|
||||
|
||||
/**
|
||||
* Converts a duration (in seconds) into human readable format.
|
||||
*
|
||||
* @param int seconds
|
||||
* @return string
|
||||
*/
|
||||
function secondsToHuman(seconds)
|
||||
{
|
||||
if (seconds<60) { var v=Math.floor(seconds); return v+' second'+((v>1)?'s':''); }
|
||||
if (seconds<60*60) { var v=Math.floor(seconds/60); return v+' minute'+((v>1)?'s':''); }
|
||||
if (seconds<60*60*24) { var v=Math.floor(seconds/(60*60)); return v+' hour'+((v>1)?'s':''); }
|
||||
// If less than 2 months, display in days:
|
||||
if (seconds<60*60*24*60) { var v=Math.floor(seconds/(60*60*24)); return v+' day'+((v>1)?'s':''); }
|
||||
var v=Math.floor(seconds/(60*60*24*30)); return v+' month'+((v>1)?'s':'');
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress a message (deflate compression). Returns base64 encoded data.
|
||||
*
|
||||
* @param string message
|
||||
* @return base64 string data
|
||||
*/
|
||||
function compress(message) {
|
||||
return Base64.toBase64( RawDeflate.deflate( Base64.utob(message) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress a message compressed with compress().
|
||||
*/
|
||||
function decompress(data) {
|
||||
return Base64.btou( RawDeflate.inflate( Base64.fromBase64(data) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress, then encrypt message with key.
|
||||
*
|
||||
* @param string key
|
||||
* @param string message
|
||||
* @return encrypted string data
|
||||
*/
|
||||
function zeroCipher(key, message) {
|
||||
return sjcl.encrypt(key,compress(message));
|
||||
}
|
||||
/**
|
||||
* Decrypt message with key, then decompress.
|
||||
*
|
||||
* @param key
|
||||
* @param encrypted string data
|
||||
* @return string readable message
|
||||
*/
|
||||
function zeroDecipher(key, data) {
|
||||
return decompress(sjcl.decrypt(key,data));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current script location (without search or hash part of the URL).
|
||||
* eg. http://server.com/zero/?aaaa#bbbb --> http://server.com/zero/
|
||||
*/
|
||||
function scriptLocation() {
|
||||
return window.location.href.substring(0,window.location.href.length
|
||||
-window.location.search.length -window.location.hash.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the paste unique identifier from the URL
|
||||
* eg. 'c05354954c49a487'
|
||||
*/
|
||||
function pasteID() {
|
||||
return window.location.search.substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set text of a DOM element (required for IE)
|
||||
* This is equivalent to element.text(text)
|
||||
* @param object element : a DOM element.
|
||||
* @param string text : the text to enter.
|
||||
*/
|
||||
function setElementText(element, text) {
|
||||
// For IE<10.
|
||||
if ($('div#oldienotice').is(":visible")) {
|
||||
// IE<10 do not support white-space:pre-wrap; so we have to do this BIG UGLY STINKING THING.
|
||||
element.text(text.replace(/\n/ig,'{BIG_UGLY_STINKING_THING__OH_GOD_I_HATE_IE}'));
|
||||
element.html(element.text().replace(/{BIG_UGLY_STINKING_THING__OH_GOD_I_HATE_IE}/ig,"\r\n<br>"));
|
||||
}
|
||||
// for other (sane) browsers:
|
||||
else {
|
||||
element.text(text);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show decrypted text in the display area, including discussion (if open)
|
||||
*
|
||||
* @param string key : decryption key
|
||||
* @param array comments : Array of messages to display (items = array with keys ('data','meta')
|
||||
*/
|
||||
function displayMessages(key, comments) {
|
||||
try { // Try to decrypt the paste.
|
||||
var cleartext = zeroDecipher(key, comments[0].data);
|
||||
} catch(err) {
|
||||
$('div#cleartext').hide();
|
||||
$('button#clonebutton').hide();
|
||||
showError('Could not decrypt data (Wrong key ?)');
|
||||
return;
|
||||
}
|
||||
setElementText($('div#cleartext'), cleartext);
|
||||
urls2links($('div#cleartext')); // Convert URLs to clickable links.
|
||||
|
||||
// Display paste expiration.
|
||||
if (comments[0].meta.expire_date) $('div#remainingtime').removeClass('foryoureyesonly').text('This document will expire in '+secondsToHuman(comments[0].meta.remaining_time)+'.').show();
|
||||
if (comments[0].meta.burnafterreading) {
|
||||
$('div#remainingtime').addClass('foryoureyesonly').text('FOR YOUR EYES ONLY. Don\'t close this window, this message can\'t be displayed again.').show();
|
||||
$('button#clonebutton').hide(); // Discourage cloning (as it can't really be prevented).
|
||||
}
|
||||
|
||||
// If the discussion is opened on this paste, display it.
|
||||
if (comments[0].meta.opendiscussion) {
|
||||
$('div#comments').html('');
|
||||
// For each comment.
|
||||
for (var i = 1; i < comments.length; i++) {
|
||||
var comment=comments[i];
|
||||
var cleartext="[Could not decrypt comment ; Wrong key ?]";
|
||||
try {
|
||||
cleartext = zeroDecipher(key, comment.data);
|
||||
} catch(err) { }
|
||||
var place = $('div#comments');
|
||||
// If parent comment exists, display below (CSS will automatically shift it right.)
|
||||
var cname = 'div#comment_'+comment.meta.parentid
|
||||
|
||||
// If the element exists in page
|
||||
if ($(cname).length) {
|
||||
place = $(cname);
|
||||
}
|
||||
var divComment = $('<div class="comment" id="comment_' + comment.meta.commentid+'">'
|
||||
+ '<div class="commentmeta"><span class="nickname"></span><span class="commentdate"></span></div><div class="commentdata"></div>'
|
||||
+ '<button onclick="open_reply($(this),\'' + comment.meta.commentid + '\');return false;">Reply</button>'
|
||||
+ '</div>');
|
||||
setElementText(divComment.find('div.commentdata'), cleartext);
|
||||
// Convert URLs to clickable links in comment.
|
||||
urls2links(divComment.find('div.commentdata'));
|
||||
divComment.find('span.nickname').html('<i>(Anonymous)</i>');
|
||||
|
||||
// Try to get optional nickname:
|
||||
try {
|
||||
divComment.find('span.nickname').text(zeroDecipher(key, comment.meta.nickname));
|
||||
} catch(err) { }
|
||||
divComment.find('span.commentdate').text(' ('+(new Date(comment.meta.postdate*1000).toUTCString())+')').attr('title','CommentID: ' + comment.meta.commentid);
|
||||
|
||||
// If an avatar is available, display it.
|
||||
if (comment.meta.vizhash) {
|
||||
divComment.find('span.nickname').before('<img src="' + comment.meta.vizhash + '" class="vizhash" title="Anonymous avatar (Vizhash of the IP address)" />');
|
||||
}
|
||||
|
||||
place.append(divComment);
|
||||
}
|
||||
$('div#comments').append('<div class="comment"><button onclick="open_reply($(this),\'' + pasteID() + '\');return false;">Add comment</button></div>');
|
||||
$('div#discussion').show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the comment entry when clicking the "Reply" button of a comment.
|
||||
* @param object source : element which emitted the event.
|
||||
* @param string commentid = identifier of the comment we want to reply to.
|
||||
*/
|
||||
function open_reply(source, commentid) {
|
||||
$('div.reply').remove(); // Remove any other reply area.
|
||||
source.after('<div class="reply">'
|
||||
+ '<input type="text" id="nickname" title="Optional nickname..." value="Optional nickname..." />'
|
||||
+ '<textarea id="replymessage" class="replymessage" cols="80" rows="7"></textarea>'
|
||||
+ '<br><button id="replybutton" onclick="send_comment(\'' + commentid + '\');return false;">Post comment</button>'
|
||||
+ '<div id="replystatus"> </div>'
|
||||
+ '</div>');
|
||||
$('input#nickname').focus(function() {
|
||||
$(this).css('color', '#000');
|
||||
if ($(this).val() == $(this).attr('title')) {
|
||||
$(this).val('');
|
||||
}
|
||||
});
|
||||
$('textarea#replymessage').focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a reply in a discussion.
|
||||
* @param string parentid : the comment identifier we want to send a reply to.
|
||||
*/
|
||||
function send_comment(parentid) {
|
||||
// Do not send if no data.
|
||||
if ($('textarea#replymessage').val().length==0) {
|
||||
return;
|
||||
}
|
||||
|
||||
showStatus('Sending comment...', spin=true);
|
||||
var cipherdata = zeroCipher(pageKey(), $('textarea#replymessage').val());
|
||||
var ciphernickname = '';
|
||||
var nick=$('input#nickname').val();
|
||||
if (nick != '' && nick != 'Optional nickname...') {
|
||||
ciphernickname = ciphernickname = zeroCipher(pageKey(), nick);
|
||||
}
|
||||
var data_to_send = { data:cipherdata,
|
||||
parentid: parentid,
|
||||
pasteid: pasteID(),
|
||||
nickname: ciphernickname
|
||||
};
|
||||
|
||||
$
|
||||
.post(scriptLocation(), data_to_send, 'json')
|
||||
.error(function() {
|
||||
showError('Comment could not be sent (serveur error or not responding).');
|
||||
})
|
||||
.success(function(data) {
|
||||
if (data.status == 0) {
|
||||
showStatus('Comment posted.');
|
||||
location.reload();
|
||||
}
|
||||
else if (data.status==1) {
|
||||
showError('Could not post comment: '+data.message);
|
||||
}
|
||||
else {
|
||||
showError('Could not post comment.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a new paste to server
|
||||
*/
|
||||
function send_data() {
|
||||
// Do not send if no data.
|
||||
if ($('textarea#message').val().length == 0) {
|
||||
return;
|
||||
}
|
||||
showStatus('Sending paste...', spin=true);
|
||||
var randomkey = sjcl.codec.base64.fromBits(sjcl.random.randomWords(8, 0), 0);
|
||||
var cipherdata = zeroCipher(randomkey, $('textarea#message').val());
|
||||
var data_to_send = { data: cipherdata,
|
||||
expire: $('select#pasteExpiration').val(),
|
||||
opendiscussion: $('input#opendiscussion').is(':checked') ? 1 : 0
|
||||
};
|
||||
$
|
||||
.post(scriptLocation(), data_to_send, 'json')
|
||||
.error(function() {
|
||||
showError('Data could not be sent (serveur error or not responding).');
|
||||
})
|
||||
.success(function(data) {
|
||||
if (data.status == 0) {
|
||||
stateExistingPaste();
|
||||
var url = scriptLocation() + "?" + data.id + '#' + randomkey;
|
||||
showStatus('');
|
||||
$('div#pastelink').html('Your paste is <a href="' + url + '">' + url + '</a>');
|
||||
$('div#pastelink')
|
||||
.append(' <button id="shortenbutton" onclick="document.location=\'' + shortenUrl(url) + '\'"><img src="lib/icon_shorten.png" width="13" height="15" />Shorten URL</button>')
|
||||
.show();
|
||||
setElementText($('div#cleartext'), $('textarea#message').val());
|
||||
urls2links($('div#cleartext'));
|
||||
showStatus('');
|
||||
}
|
||||
else if (data.status==1) {
|
||||
showError('Could not create paste: '+data.message);
|
||||
}
|
||||
else {
|
||||
showError('Could not create paste.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the screen in "New paste" mode.
|
||||
*/
|
||||
function stateNewPaste() {
|
||||
$('#sendbutton').show();
|
||||
$('#clonebutton').hide();
|
||||
$('div#expiration').show();
|
||||
$('div#remainingtime').hide();
|
||||
$('div#language').hide(); // $('#language').show();
|
||||
$('input#password').hide(); //$('#password').show();
|
||||
$('div#opendisc').show();
|
||||
$('#newbutton').show();
|
||||
$('div#pastelink').hide();
|
||||
$('textarea#message').text('');
|
||||
$('textarea#message').show();
|
||||
$('div#cleartext').hide();
|
||||
$('div#message').focus();
|
||||
$('div#discussion').hide();
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the screen in "Existing paste" mode.
|
||||
*/
|
||||
function stateExistingPaste() {
|
||||
$('#sendbutton').hide();
|
||||
|
||||
// No "clone" for IE<10.
|
||||
if (!$('div#oldienotice').is(":visible")) {
|
||||
$('button#clonebutton').show();
|
||||
}
|
||||
|
||||
/**
|
||||
* @FIXME
|
||||
*/
|
||||
$('#clonebutton').show();
|
||||
|
||||
$('div#expiration').hide();
|
||||
$('div#language').hide();
|
||||
$('input#password').hide();
|
||||
$('div#opendisc').hide();
|
||||
$('#newbutton').show();
|
||||
$('div#pastelink').hide();
|
||||
$('textarea#message').hide();
|
||||
$('div#cleartext').show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone the current paste.
|
||||
*/
|
||||
function clonePaste() {
|
||||
stateNewPaste();
|
||||
showStatus('');
|
||||
$('textarea#message').text($('div#cleartext').text());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new paste.
|
||||
*/
|
||||
function newPaste() {
|
||||
stateNewPaste();
|
||||
showStatus('');
|
||||
$('textarea#message').text('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display an error message
|
||||
* (We use the same function for paste and reply to comments)
|
||||
*/
|
||||
function showError(message) {
|
||||
$('div#status').addClass('errorMessage').text(message);
|
||||
$('div#replystatus').addClass('errorMessage').text(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display status
|
||||
* (We use the same function for paste and reply to comments)
|
||||
*
|
||||
* @param string message : text to display
|
||||
* @param boolean spin (optional) : tell if the "spinning" animation should be displayed.
|
||||
*/
|
||||
function showStatus(message, spin) {
|
||||
$('div#replystatus').removeClass('errorMessage');
|
||||
$('div#replystatus').text(message);
|
||||
if (!message) {
|
||||
$('div#status').html(' ');
|
||||
return;
|
||||
}
|
||||
if (message == '') {
|
||||
$('div#status').html(' ');
|
||||
return;
|
||||
}
|
||||
$('div#status').removeClass('errorMessage');
|
||||
$('div#status').text(message);
|
||||
if (spin) {
|
||||
var img = '<img src="img/busy.gif" style="width:16px;height:9px;margin:0px 4px 0px 0px;" />';
|
||||
$('div#status').prepend(img);
|
||||
$('div#replystatus').prepend(img);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate link to URL shortener.
|
||||
*/
|
||||
function shortenUrl(url) {
|
||||
return 'http://snipurl.com/site/snip?link=' + encodeURIComponent(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert URLs to clickable links.
|
||||
* URLs to handle:
|
||||
* <code>
|
||||
* magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&xt.2=urn:sha1:TXGCZQTH26NL6OUQAJJPFALHG2LTGBC7
|
||||
* http://localhost:8800/zero/?6f09182b8ea51997#WtLEUO5Epj9UHAV9JFs+6pUQZp13TuspAUjnF+iM+dM=
|
||||
* http://user:password@localhost:8800/zero/?6f09182b8ea51997#WtLEUO5Epj9UHAV9JFs+6pUQZp13TuspAUjnF+iM+dM=
|
||||
* </code>
|
||||
*
|
||||
* @param object element : a jQuery DOM element.
|
||||
* @FIXME: add ppa & apt links.
|
||||
*/
|
||||
function urls2links(element) {
|
||||
var re = /((http|https|ftp):\/\/[\w?=&.\/-;#@~%+-]+(?![\w\s?&.\/;#~%"=-]*>))/ig;
|
||||
element.html(element.html().replace(re,'<a href="$1" rel="nofollow">$1</a>'));
|
||||
var re = /((magnet):[\w?=&.\/-;#@~%+-]+)/ig;
|
||||
element.html(element.html().replace(re,'<a href="$1">$1</a>'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the deciphering key stored in anchor part of the URL
|
||||
*/
|
||||
function pageKey() {
|
||||
var key = window.location.hash.substring(1); // Get key
|
||||
|
||||
// Some stupid web 2.0 services and redirectors add data AFTER the anchor
|
||||
// (such as &utm_source=...).
|
||||
// We will strip any additional data.
|
||||
|
||||
// First, strip everything after the equal sign (=) which signals end of base64 string.
|
||||
i = key.indexOf('='); if (i>-1) { key = key.substring(0,i+1); }
|
||||
|
||||
// If the equal sign was not present, some parameters may remain:
|
||||
i = key.indexOf('&'); if (i>-1) { key = key.substring(0,i); }
|
||||
|
||||
// Then add trailing equal sign if it's missing
|
||||
if (key.charAt(key.length-1)!=='=') key+='=';
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
$(function() {
|
||||
$('select#pasteExpiration').change(function() {
|
||||
if ($(this).val() == 'burn') {
|
||||
$('div#opendisc').addClass('buttondisabled');
|
||||
$('input#opendiscussion').attr('disabled',true);
|
||||
}
|
||||
else {
|
||||
$('div#opendisc').removeClass('buttondisabled');
|
||||
$('input#opendiscussion').removeAttr('disabled');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Display an existing paste
|
||||
if ($('div#cipherdata').text().length > 1) {
|
||||
// Missing decryption key in URL ?
|
||||
if (window.location.hash.length == 0) {
|
||||
showError('Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL ?)');
|
||||
return;
|
||||
}
|
||||
|
||||
// List of messages to display
|
||||
var messages = jQuery.parseJSON($('div#cipherdata').text());
|
||||
|
||||
// Show proper elements on screen.
|
||||
stateExistingPaste();
|
||||
|
||||
displayMessages(pageKey(), messages);
|
||||
}
|
||||
// Display error message from php code.
|
||||
else if ($('div#errormessage').text().length>1) {
|
||||
showError($('div#errormessage').text());
|
||||
}
|
||||
// Create a new paste.
|
||||
else {
|
||||
newPaste();
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user