diff --git a/ByteBuffer.min.js b/ByteBuffer.min.js new file mode 100644 index 00000000..4bc46b7e --- /dev/null +++ b/ByteBuffer.min.js @@ -0,0 +1,55 @@ +/* + ByteBuffer.js (c) 2013 Daniel Wirtz + Released under the Apache License, Version 2.0 + see: https://github.com/dcodeIO/ByteBuffer.js for details +*/ +(function(n){function q(l){function c(a,b,d){a="undefined"!==typeof a?parseInt(a,10):c.DEFAULT_CAPACITY;1>a&&(a=c.DEFAULT_CAPACITY);this.array=d?null:new ArrayBuffer(a);this.view=d?null:new DataView(this.array);this.offset=0;this.markedOffset=-1;this.length=0;this.littleEndian="undefined"!=typeof b?!!b:!1}var p=null;if("function"===typeof require)try{var n=require("buffer"),p=n&&"function"===typeof n.Buffer&&"function"===typeof n.Buffer.isBuffer?n.Buffer:null}catch(q){}c.VERSION="2.3.1";c.DEFAULT_CAPACITY= +16;c.LITTLE_ENDIAN=!0;c.BIG_ENDIAN=!1;c.Long=l||null;c.isByteBuffer=function(a){return a&&(a instanceof c||"object"===typeof a&&(null===a.array||a.array instanceof ArrayBuffer)&&(null===a.view||a.view instanceof DataView)&&"number"===typeof a.offset&&"number"===typeof a.markedOffset&&"number"===typeof a.length&&"boolean"===typeof a.littleEndian)};c.allocate=function(a,b){return new c(a,b)};c.wrap=function(a,b,d){"boolean"===typeof b&&(d=b,b="utf8");if("string"===typeof a)switch(b){case "base64":return c.decode64(a, +d);case "hex":return c.decodeHex(a,d);case "binary":return c.decodeBinary(a,d);default:return(new c(c.DEFAULT_CAPACITY,d)).writeUTF8String(a).flip()}if(p&&p.isBuffer(a)){b=(new Uint8Array(a)).buffer;if(b===a){b=new ArrayBuffer(a.length);for(var e=new Uint8Array(b),f=0,g=a.length;fa)return!1;null===this.array&&(this.array=new ArrayBuffer(a),this.view=new DataView(this.array));if(this.array.byteLengtha||a>this.array.byteLength||1>b||b>this.array.byteLength)throw Error(this+" cannot be sliced: Index out of bounds (0-"+this.array.byteLength+" -> "+a+"-"+b+")");d=this.clone();d.offset= +a;d.length=b;return d};c.prototype.ensureCapacity=function(a){return null===this.array?this.resize(a):this.array.byteLength=a?2*this.array.byteLength:a):this};c.prototype.flip=function(){this.length=null==this.array?0:this.offset;this.offset=0;return this};c.prototype.mark=function(a){if(null==this.array)throw Error(this+" cannot be marked: Already destroyed");a="undefined"!==typeof a?parseInt(a,10):this.offset;if(0>a||a>this.array.byteLength)throw Error(this+ +" cannot be marked: Offset to mark is less than 0 or bigger than the capacity ("+this.array.byteLength+"): "+a);this.markedOffset=a;return this};c.prototype.reset=function(){if(null===this.array)throw Error(this+" cannot be reset: Already destroyed");0<=this.markedOffset?(this.offset=this.markedOffset,this.markedOffset=-1):this.length=this.offset=0;return this};c.prototype.clone=function(){var a=new c(-1,this.littleEndian,!0);a.array=this.array;a.view=this.view;a.offset=this.offset;a.markedOffset= +this.markedOffset;a.length=this.length;return a};c.prototype.copy=function(){if(null==this.array)return this.clone();var a=new c(this.array.byteLength,this.littleEndian),b=new Uint8Array(this.array);(new Uint8Array(a.array)).set(b);a.offset=this.offset;a.markedOffset=this.markedOffset;a.length=this.length;return a};c.prototype.remaining=function(){return null===this.array?0:this.length-this.offset};c.prototype.capacity=function(){return null!=this.array?this.array.byteLength:0};c.prototype.compact= +function(){if(null==this.array)throw Error(this+" cannot be compacted: Already destroyed");this.offset>this.length&&this.flip();if(this.offset===this.length)return this.array=new ArrayBuffer(0),this.view=null,this;if(0===this.offset&&this.length===this.array.byteLength)return this;var a=new Uint8Array(this.array),b=new ArrayBuffer(this.length-this.offset);(new Uint8Array(b)).set(a.subarray(this.offset,this.length));this.array=b;this.markedOffset=this.markedOffset>=this.offset?this.markedOffset-this.offset: +-1;this.offset=0;this.length=this.array.byteLength;return this};c.prototype.destroy=function(){null!==this.array&&(this.view=this.array=null,this.offset=0,this.markedOffset=-1,this.length=0);return this};c.prototype.reverse=function(){if(null===this.array)throw Error(this+" cannot be reversed: Already destroyed");Array.prototype.reverse.call(new Uint8Array(this.array));var a=this.offset;this.offset=this.array.byteLength-this.length;this.markedOffset=-1;this.length=this.array.byteLength-a;this.view= +new DataView(this.array);return this};c.prototype.append=function(a,b){a instanceof c||(a=c.wrap(a));if(null===a.array)throw Error(a+" cannot be appended to "+this+": Already destroyed");var d=a.length-a.offset;if(0==d)return this;0>d&&(a=a.clone().flip(),d=a.length-a.offset);b="undefined"!==typeof b?b:(this.offset+=d)-d;this.ensureCapacity(b+d);d=new Uint8Array(a.array);(new Uint8Array(this.array)).set(d.subarray(a.offset,a.length),b);return this};c.prototype.prepend=function(a,b){a instanceof c|| +(a=c.wrap(a));if(null===a.array)throw a+" cannot be prepended to "+this+": Already destroyed";var d=a.length-a.offset;if(0==d)return this;0>d&&(a=a.clone().flip(),d=a.length-a.offset);var e="undefined"===typeof b;b="undefined"!==typeof b?b:this.offset;var f=d-b;0=this.array.byteLength)throw Error("Cannot read int8 from "+this+" at "+a+": Capacity overflow");return this.view.getInt8(a)};c.prototype.writeByte=c.prototype.writeInt8;c.prototype.readByte=c.prototype.readInt8;c.prototype.writeUint8=function(a,b){b="undefined"!==typeof b?b:(this.offset+=1)-1;this.ensureCapacity(b+1);this.view.setUint8(b,a);return this}; +c.prototype.readUint8=function(a){a="undefined"!==typeof a?a:(this.offset+=1)-1;if(a+1>this.array.byteLength)throw Error("Cannot read uint8 from "+this+" at "+a+": Capacity overflow");return this.view.getUint8(a)};c.prototype.writeInt16=function(a,b){b="undefined"!==typeof b?b:(this.offset+=2)-2;this.ensureCapacity(b+2);this.view.setInt16(b,a,this.littleEndian);return this};c.prototype.readInt16=function(a){a="undefined"!==typeof a?a:(this.offset+=2)-2;if(a+2>this.array.byteLength)throw Error("Cannot read int16 from "+ +this+" at "+a+": Capacity overflow");return this.view.getInt16(a,this.littleEndian)};c.prototype.writeShort=c.prototype.writeInt16;c.prototype.readShort=c.prototype.readInt16;c.prototype.writeUint16=function(a,b){b="undefined"!==typeof b?b:(this.offset+=2)-2;this.ensureCapacity(b+2);this.view.setUint16(b,a,this.littleEndian);return this};c.prototype.readUint16=function(a){a="undefined"!==typeof a?a:(this.offset+=2)-2;if(a+2>this.array.byteLength)throw Error("Cannot read int16 from "+this+" at "+a+ +": Capacity overflow");return this.view.getUint16(a,this.littleEndian)};c.prototype.writeInt32=function(a,b){b="undefined"!==typeof b?b:(this.offset+=4)-4;this.ensureCapacity(b+4);this.view.setInt32(b,a,this.littleEndian);return this};c.prototype.readInt32=function(a){a="undefined"!==typeof a?a:(this.offset+=4)-4;if(a+4>this.array.byteLength)throw Error("Cannot read int32 from "+this+" at "+a+": Capacity overflow");return this.view.getInt32(a,this.littleEndian)};c.prototype.writeInt=c.prototype.writeInt32; +c.prototype.readInt=c.prototype.readInt32;c.prototype.writeUint32=function(a,b){b="undefined"!=typeof b?b:(this.offset+=4)-4;this.ensureCapacity(b+4);this.view.setUint32(b,a,this.littleEndian);return this};c.prototype.readUint32=function(a){a="undefined"!==typeof a?a:(this.offset+=4)-4;if(a+4>this.array.byteLength)throw Error("Cannot read uint32 from "+this+" at "+a+": Capacity overflow");return this.view.getUint32(a,this.littleEndian)};c.prototype.writeFloat32=function(a,b){b="undefined"!==typeof b? +b:(this.offset+=4)-4;this.ensureCapacity(b+4);this.view.setFloat32(b,a,this.littleEndian);return this};c.prototype.readFloat32=function(a){a="undefined"!==typeof a?a:(this.offset+=4)-4;if(null===this.array||a+4>this.array.byteLength)throw Error("Cannot read float32 from "+this+" at "+a+": Capacity overflow");return this.view.getFloat32(a,this.littleEndian)};c.prototype.writeFloat=c.prototype.writeFloat32;c.prototype.readFloat=c.prototype.readFloat32;c.prototype.writeFloat64=function(a,b){b="undefined"!== +typeof b?b:(this.offset+=8)-8;this.ensureCapacity(b+8);this.view.setFloat64(b,a,this.littleEndian);return this};c.prototype.readFloat64=function(a){a="undefined"!==typeof a?a:(this.offset+=8)-8;if(null===this.array||a+8>this.array.byteLength)throw Error("Cannot read float64 from "+this+" at "+a+": Capacity overflow");return this.view.getFloat64(a,this.littleEndian)};c.prototype.writeDouble=c.prototype.writeFloat64;c.prototype.readDouble=c.prototype.readFloat64;l&&(c.prototype.writeInt64=function(a, +b){b="undefined"!==typeof b?b:(this.offset+=8)-8;"object"===typeof a&&a instanceof l||(a=l.fromNumber(a,!1));this.ensureCapacity(b+8);this.littleEndian?(this.view.setInt32(b,a.getLowBits(),!0),this.view.setInt32(b+4,a.getHighBits(),!0)):(this.view.setInt32(b,a.getHighBits(),!1),this.view.setInt32(b+4,a.getLowBits(),!1));return this},c.prototype.readInt64=function(a){a="undefined"!==typeof a?a:(this.offset+=8)-8;if(null===this.array||a+8>this.array.byteLength)throw this.offset-=8,Error("Cannot read int64 from "+ +this+" at "+a+": Capacity overflow");return this.littleEndian?l.fromBits(this.view.getInt32(a,!0),this.view.getInt32(a+4,!0),!1):l.fromBits(this.view.getInt32(a+4,!1),this.view.getInt32(a,!1),!1)},c.prototype.writeUint64=function(a,b){b="undefined"!==typeof b?b:(this.offset+=8)-8;"object"===typeof a&&a instanceof l||(a=l.fromNumber(a,!0));this.ensureCapacity(b+8);this.littleEndian?(this.view.setUint32(b,a.getLowBitsUnsigned(),!0),this.view.setUint32(b+4,a.getHighBitsUnsigned(),!0)):(this.view.setUint32(b, +a.getHighBitsUnsigned(),!1),this.view.setUint32(b+4,a.getLowBitsUnsigned(),!1));return this},c.prototype.readUint64=function(a){a="undefined"!==typeof a?a:(this.offset+=8)-8;if(null===this.array||a+8>this.array.byteLength)throw this.offset-=8,Error("Cannot read int64 from "+this+" at "+a+": Capacity overflow");return this.littleEndian?l.fromBits(this.view.getUint32(a,!0),this.view.getUint32(a+4,!0),!0):l.fromBits(this.view.getUint32(a+4,!1),this.view.getUint32(a,!1),!0)},c.prototype.writeLong=c.prototype.writeInt64, +c.prototype.readLong=c.prototype.readInt64);c.MAX_VARINT32_BYTES=5;c.prototype.writeVarint32=function(a,b){var d="undefined"===typeof b;b="undefined"!==typeof b?b:this.offset;a>>>=0;this.ensureCapacity(b+c.calculateVarint32(a));var e=this.view,f=0;e.setUint8(b,a|128);128<=a?(e.setUint8(b+1,a>>7|128),16384<=a?(e.setUint8(b+2,a>>14|128),2097152<=a?(e.setUint8(b+3,a>>21|128),268435456<=a?(e.setUint8(b+4,a>>28&127),f=5):(e.setUint8(b+3,e.getUint8(b+3)&127),f=4)):(e.setUint8(b+2,e.getUint8(b+2)&127),f= +3)):(e.setUint8(b+1,e.getUint8(b+1)&127),f=2)):(e.setUint8(b,e.getUint8(b)&127),f=1);return d?(this.offset+=f,this):f};c.prototype.readVarint32=function(a){var b="undefined"===typeof a;a="undefined"!==typeof a?a:this.offset;var d=0,e,f=this.view,g=0;do e=f.getUint8(a+d),d>>0),++d;while(e&128);g|=0;return b?(this.offset+=d,g):{value:g,length:d}};c.prototype.writeZigZagVarint32=function(a,b){return this.writeVarint32(c.zigZagEncode32(a),b)};c.prototype.readZigZagVarint32= +function(a){a=this.readVarint32(a);return"object"===typeof a?(a.value=c.zigZagDecode32(a.value),a):c.zigZagDecode32(a)};c.MAX_VARINT64_BYTES=10;l&&(c.prototype.writeVarint64=function(a,b){var d="undefined"===typeof b;b="undefined"!==typeof b?b:this.offset;"object"===typeof a&&a instanceof l||(a=l.fromNumber(a,!1));var e=a.toInt()>>>0,f=a.shiftRightUnsigned(28).toInt()>>>0,g=a.shiftRightUnsigned(56).toInt()>>>0,k=c.calculateVarint64(a);this.ensureCapacity(b+k);var h=this.view;switch(k){case 10:h.setUint8(b+ +9,g>>>7|128);case 9:h.setUint8(b+8,g|128);case 8:h.setUint8(b+7,f>>>21|128);case 7:h.setUint8(b+6,f>>>14|128);case 6:h.setUint8(b+5,f>>>7|128);case 5:h.setUint8(b+4,f|128);case 4:h.setUint8(b+3,e>>>21|128);case 3:h.setUint8(b+2,e>>>14|128);case 2:h.setUint8(b+1,e>>>7|128);case 1:h.setUint8(b+0,e|128)}h.setUint8(b+k-1,h.getUint8(b+k-1)&127);return d?(this.offset+=k,this):k},c.prototype.readVarint64=function(a){var b="undefined"===typeof a,d=a="undefined"!==typeof a?a:this.offset,c=this.view,f,g=0, +k=0,h;h=c.getUint8(a++);f=h&127;if(h&128&&(h=c.getUint8(a++),f|=(h&127)<<7,h&128&&(h=c.getUint8(a++),f|=(h&127)<<14,h&128&&(h=c.getUint8(a++),f|=(h&127)<<21,h&128&&(h=c.getUint8(a++),g=h&127,h&128&&(h=c.getUint8(a++),g|=(h&127)<<7,h&128&&(h=c.getUint8(a++),g|=(h&127)<<14,h&128&&(h=c.getUint8(a++),g|=(h&127)<<21,h&128&&(h=c.getUint8(a++),k=h&127,h&128&&(h=c.getUint8(a++),k|=(h&127)<<7,h&128))))))))))throw Error("Data must be corrupt: Buffer overrun");c=l.from28Bits(f,g,k,!1);return b?(this.offset= +a,c):{value:c,length:a-d}},c.prototype.writeZigZagVarint64=function(a,b){return this.writeVarint64(c.zigZagEncode64(a),b)},c.prototype.readZigZagVarint64=function(a){a=this.readVarint64(a);return"object"!==typeof a||a instanceof l?c.zigZagDecode64(a):(a.value=c.zigZagDecode64(a.value),a)});c.prototype.writeVarint=c.prototype.writeVarint32;c.prototype.readVarint=c.prototype.readVarint32;c.prototype.writeZigZagVarint=c.prototype.writeZigZagVarint32;c.prototype.readZigZagVarint=c.prototype.readZigZagVarint32; +c.calculateVarint32=function(a){a>>>=0;return 128>a?1:16384>a?2:2097152>a?3:268435456>a?4:5};l&&(c.calculateVarint64=function(a){"object"===typeof a&&a instanceof l||(a=l.fromNumber(a,!1));var b=a.toInt()>>>0,d=a.shiftRightUnsigned(28).toInt()>>>0;a=a.shiftRightUnsigned(56).toInt()>>>0;return 0==a?0==d?16384>b?128>b?1:2:2097152>b?3:4:16384>d?128>d?5:6:2097152>d?7:8:128>a?9:10});c.zigZagEncode32=function(a){return((a|=0)<<1^a>>31)>>>0};c.zigZagDecode32=function(a){return a>>>1^-(a&1)|0};l&&(c.zigZagEncode64= +function(a){"object"===typeof a&&a instanceof l?a.unsigned&&(a=a.toSigned()):a=l.fromNumber(a,!1);return a.shiftLeft(1).xor(a.shiftRight(63)).toUnsigned()},c.zigZagDecode64=function(a){"object"===typeof a&&a instanceof l?a.unsigned||(a=a.toUnsigned()):a=l.fromNumber(a,!0);return a.shiftRightUnsigned(1).xor(a.and(l.ONE).toSigned().negate()).toSigned()});c.decodeUTF8Char=function(a,b){var d=a.readUint8(b),c,f,g,k,h,l=b;if(0==(d&128))b+=1;else if(192==(d&224))c=a.readUint8(b+1),d=(d&31)<<6|c&63,b+=2; +else if(224==(d&240))c=a.readUint8(b+1),f=a.readUint8(b+2),d=(d&15)<<12|(c&63)<<6|f&63,b+=3;else if(240==(d&248))c=a.readUint8(b+1),f=a.readUint8(b+2),g=a.readUint8(b+3),d=(d&7)<<18|(c&63)<<12|(f&63)<<6|g&63,b+=4;else if(248==(d&252))c=a.readUint8(b+1),f=a.readUint8(b+2),g=a.readUint8(b+3),k=a.readUint8(b+4),d=(d&3)<<24|(c&63)<<18|(f&63)<<12|(g&63)<<6|k&63,b+=5;else if(252==(d&254))c=a.readUint8(b+1),f=a.readUint8(b+2),g=a.readUint8(b+3),k=a.readUint8(b+4),h=a.readUint8(b+5),d=(d&1)<<30|(c&63)<<24| +(f&63)<<18|(g&63)<<12|(k&63)<<6|h&63,b+=6;else throw Error("Cannot decode UTF8 character at offset "+b+": charCode (0x"+d.toString(16)+") is invalid");return{"char":d,length:b-l}};c.encodeUTF8Char=function(a,b,c){var e=c;if(0>a)throw Error("Cannot encode UTF8 character: charCode ("+a+") is negative");if(128>a)b.writeUint8(a&127,c),c+=1;else if(2048>a)b.writeUint8(a>>6&31|192,c).writeUint8(a&63|128,c+1),c+=2;else if(65536>a)b.writeUint8(a>>12&15|224,c).writeUint8(a>>6&63|128,c+1).writeUint8(a&63|128, +c+2),c+=3;else if(2097152>a)b.writeUint8(a>>18&7|240,c).writeUint8(a>>12&63|128,c+1).writeUint8(a>>6&63|128,c+2).writeUint8(a&63|128,c+3),c+=4;else if(67108864>a)b.writeUint8(a>>24&3|248,c).writeUint8(a>>18&63|128,c+1).writeUint8(a>>12&63|128,c+2).writeUint8(a>>6&63|128,c+3).writeUint8(a&63|128,c+4),c+=5;else if(2147483648>a)b.writeUint8(a>>30&1|252,c).writeUint8(a>>24&63|128,c+1).writeUint8(a>>18&63|128,c+2).writeUint8(a>>12&63|128,c+3).writeUint8(a>>6&63|128,c+4).writeUint8(a&63|128,c+5),c+=6;else throw Error("Cannot encode UTF8 character: charCode (0x"+ +a.toString(16)+") is too large (>= 0x80000000)");return c-e};c.calculateUTF8Char=function(a){if(0>a)throw Error("Cannot calculate length of UTF8 character: charCode ("+a+") is negative");if(128>a)return 1;if(2048>a)return 2;if(65536>a)return 3;if(2097152>a)return 4;if(67108864>a)return 5;if(2147483648>a)return 6;throw Error("Cannot calculate length of UTF8 character: charCode (0x"+a.toString(16)+") is too large (>= 0x80000000)");};c.a=function(a){a=""+a;for(var b=0,d=0,e=a.length;dg?a.readUint8(g++):0,e=a.length>g?a.readUint8(g++):0,f=b<<16|d<<8|e,b=f>>18&63,d=f>>12&63,e=f>>6&63,f&=63,h[k++]=m.charAt(b)+m.charAt(d)+m.charAt(e)+m.charAt(f);while(gd||0>e||0>g||0>k)throw Error("Illegal argument: Not a valid base64 encoded string");f=d<<18|e<<12|g<<6|k;d=f>>16&255;e=f>>8&255;f&=255;64==g?l.writeUint8(d):64==k?l.writeUint8(d).writeUint8(e):l.writeUint8(d).writeUint8(e).writeUint8(f)}while(h< +a.length);return l.flip()};c.encodeHex=function(a){a instanceof c?a.lengthb.length&&(b="0"+b),d.push(b);return d.join("")};c.decodeHex=function(a,b){if("string"!==typeof a)throw Error("Illegal argument: Not a string");if(0!==a.length%2)throw Error("Illegal argument: Not a hex encoded string");for(var d=new c(a.length/2,b),e=0,f=a.length;e< +f;e+=2)d.writeUint8(parseInt(a.substring(e,e+2),16));return d.flip()};c.encodeBinary=function(a){a instanceof c?a.lengtha?"+":"")+b-a)+" bytes");return d?(this.offset=b,f):{string:f,length:b-g}};c.prototype.writeLString=function(a,b){a= +""+a;var d="undefined"===typeof b;b="undefined"!==typeof b?b:this.offset;var e=c.encodeUTF8Char(a.length,this,b),e=e+this.writeUTF8String(a,b+e);return d?(this.offset+=e,this):e};c.prototype.readLString=function(a){var b="undefined"===typeof a;a="undefined"!==typeof a?a:this.offset;var d=c.decodeUTF8Char(this,a);a=this.readUTF8String(d["char"],a+d.length);return b?(this.offset+=d.length+a.length,a.string):{string:a.string,length:d.length+a.length}};c.prototype.writeVString=function(a,b){a=""+a;var d= +"undefined"===typeof b;b="undefined"!==typeof b?b:this.offset;var e=this.writeVarint32(c.a(a),b),e=e+this.writeUTF8String(a,b+e);return d?(this.offset+=e,this):e};c.prototype.readVString=function(a){var b="undefined"===typeof a;a="undefined"!==typeof a?a:this.offset;var c=this.readVarint32(a);a=this.readUTF8StringBytes(c.value,a+c.length);return b?(this.offset+=c.length+a.length,a.string):{string:a.string,length:c.length+a.length}};c.prototype.writeCString=function(a,b){var c="undefined"===typeof b; +b="undefined"!==typeof b?b:this.offset;var e=this.writeUTF8String(""+a,b);this.writeUint8(0,b+e);return c?(this.offset+=e+1,this):e+1};c.prototype.readCString=function(a){var b="undefined"===typeof a;a="undefined"!==typeof a?a:this.offset;var d,e="",f=a;do d=c.decodeUTF8Char(this,a),a+=d.length,0!=d["char"]&&(e+=String.fromCharCode(d["char"]));while(0!=d["char"]);return b?(this.offset=a,e):{string:e,length:a-f}};c.prototype.writeJSON=function(a,b,c){c="function"===typeof c?c:JSON.stringify;return this.writeLString(c(a), +b)};c.prototype.readJSON=function(a,b){b="function"===typeof b?b:JSON.parse;var c=this.readLString(a);return"string"===typeof c?b(c):{data:b(c.string),length:c.length}};c.prototype.toColumns=function(a){if(null===this.array)return"DESTROYED";a="undefined"!==typeof a?parseInt(a,10):16;1>a&&(a=16);for(var b="",c=[],e,f=this.view,b=0==this.offset&&0==this.length?b+"|":0==this.length?b+">":0==this.offset?b+"<":b+" ",g=0,k=this.array.byteLength;ge.length&&(e="0"+e);b+=e;b=g+1==this.offset&&g+1==this.length?b+"|":g+1==this.offset?b+"<":g+1==this.length?b+">":b+" "}" "!=b&&c.push(b);g=0;for(k=c.length;ge?String.fromCharCode(e):".";""!=b&&(c[h]+=" "+b);return c.join("\n")};c.prototype.printDebug=function(a){"function"!==typeof a&&(a= +console.log.bind(console));a((null!=this.array?"ByteBuffer(offset="+this.offset+",markedOffset="+this.markedOffset+",length="+this.length+",capacity="+this.array.byteLength+")":"ByteBuffer(DESTROYED)")+"\n-------------------------------------------------------------------\n"+this.toColumns()+"\n")};c.prototype.toHex=function(a){var b="",d=this.view,e,f;if(a){if(null===this.array)return"DESTROYED";b=0==this.offset&&0==this.length?b+"|":0==this.length?b+">":0==this.offset?b+"<":b+" ";e=0;for(f=this.array.byteLength;e< +f;++e)a=d.getUint8(e).toString(16).toUpperCase(),2>a.length&&(a="0"+a),b+=a,b=e+1===this.offset&&e+1===this.length?b+"|":e+1==this.offset?b+"<":e+1==this.length?b+">":b+" ";return b}return c.encodeHex(this)};c.prototype.toBinary=function(){return c.encodeBinary(this)};c.prototype.toBase64=function(){return null===this.array||this.offset>=this.length?"":c.encode64(this)};c.prototype.toUTF8=function(){return null===this.array||this.offset>=this.length?"":this.readUTF8StringBytes(this.length-this.offset, +this.offset).string};c.prototype.toString=function(a){switch(a||""){case "utf8":return this.toUTF8();case "base64":return this.toBase64();case "hex":return this.toHex();case "binary":return this.toBinary();case "debug":return this.toHex(!0);default:return null===this.array?"ByteBuffer(DESTROYED)":"ByteBuffer(offset="+this.offset+",markedOffset="+this.markedOffset+",length="+this.length+",capacity="+this.array.byteLength+")"}};c.prototype.toArrayBuffer=function(a){if(null===this.array)return null; +var b=this.clone();b.offset>b.length&&b.flip();var c=!1;if(0b)var c=a,a=b,b=c;return new p((new Uint8Array(this.array)).subarray(a,b))});return c}"undefined"!==typeof module&&module.exports?module.exports=q(require("long")):"undefined"!==typeof define&&define.amd?define("ByteBuffer",["Math/Long"],function(l){return q(l)}): +(n.dcodeIO||(n.dcodeIO={}),n.dcodeIO.ByteBuffer=q(n.dcodeIO.Long))})(this); diff --git a/Long.min.js b/Long.min.js new file mode 100644 index 00000000..a1be1ab8 --- /dev/null +++ b/Long.min.js @@ -0,0 +1,26 @@ +/* + Long.js (c) 2013 Daniel Wirtz + Released under the Apache License, Version 2.0 + see: https://github.com/dcodeIO/Long.js for details + + Long.js is based on goog.math.Long from the Closure Library. + Copyright 2009 The Closure Library Authors. All Rights Reserved. + Released under the Apache License, Version 2.0 + see: https://code.google.com/p/closure-library/ for details +*/ +var p=!1; +(function(r){function b(a,b,d){this.low=a|0;this.high=b|0;this.unsigned=!!d}var s={},t={};b.fromInt=function(a,c){var d;if(c){a>>>=0;if(0<=a&&256>a&&(d=t[a]))return d;d=new b(a,0>(a|0)?-1:0,!0);0<=a&&256>a&&(t[a]=d)}else{a|=0;if(-128<=a&&128>a&&(d=s[a]))return d;d=new b(a,0>a?-1:0,p);-128<=a&&128>a&&(s[a]=d)}return d};b.fromNumber=function(a,c){c=!!c;return isNaN(a)||!isFinite(a)?b.ZERO:!c&&a<=-u?b.MIN_SIGNED_VALUE:c&&0>=a?b.MIN_UNSIGNED_VALUE:!c&&a+1>=u?b.MAX_SIGNED_VALUE:c&&a>=v?b.MAX_UNSIGNED_VALUE:0> +a?b.fromNumber(-a,p).negate():new b(a%l|0,a/l|0,c)};b.fromBits=function(a,c,d){return new b(a,c,d)};b.from28Bits=function(a,c,d,e){return b.fromBits(a|c<<28,c>>>4|d<<24,e)};b.fromString=function(a,c,d){if(0==a.length)throw Error("number format error: empty string");if("NaN"===a||"Infinity"===a||"+Infinity"===a||"-Infinity"===a)return b.ZERO;"number"===typeof c&&(d=c,c=p);d=d||10;if(2>d||36f?(f=b.fromNumber(Math.pow(d,f)),e=e.multiply(f).add(b.fromNumber(k))):(e=e.multiply(c),e=e.add(b.fromNumber(k)))}return e};var l=4294967296,v=l*l,u=v/2,w=b.fromInt(16777216);b.ZERO=b.fromInt(0);b.ONE=b.fromInt(1);b.NEG_ONE=b.fromInt(-1);b.MAX_SIGNED_VALUE=b.fromBits(-1,2147483647,p); +b.MAX_UNSIGNED_VALUE=b.fromBits(-1,-1,!0);b.MAX_VALUE=b.MAX_SIGNED_VALUE;b.MIN_SIGNED_VALUE=b.fromBits(0,-2147483648,p);b.MIN_UNSIGNED_VALUE=b.fromBits(0,0,!0);b.MIN_VALUE=b.MIN_SIGNED_VALUE;b.prototype.toInt=function(){return this.unsigned?this.low>>>0:this.low};b.prototype.toNumber=function(){return this.unsigned?(this.high>>>0)*l+(this.low>>>0):this.high*l+(this.low>>>0)};b.prototype.toString=function(a){a=a||10;if(2>a||36f.length;)f="0"+f;e=""+f+e}};b.prototype.getHighBits=function(){return this.high};b.prototype.getHighBitsUnsigned=function(){return this.high>>>0}; +b.prototype.getLowBits=function(){return this.low};b.prototype.getLowBitsUnsigned=function(){return this.low>>>0};b.prototype.getNumBitsAbs=function(){if(this.isNegative())return this.equals(b.MIN_SIGNED_VALUE)?64:this.negate().getNumBitsAbs();for(var a=0!=this.high?this.high:this.low,c=31;0this.high};b.prototype.isOdd=function(){return 1== +(this.low&1)};b.prototype.equals=function(a){return this.unsigned!=a.unsigned&&this.high>>>31!=a.high>>>31?p:this.high==a.high&&this.low==a.low};b.prototype.notEquals=function(a){return!this.equals(a)};b.prototype.lessThan=function(a){return 0>this.compare(a)};b.prototype.lessThanOrEqual=function(a){return 0>=this.compare(a)};b.prototype.greaterThan=function(a){return 0>>0>this.high>>>0||a.high==this.high&&a.low>>>0>this.low>>>0?-1:1:this.subtract(a).isNegative()?-1:1};b.prototype.negate=function(){return!this.unsigned&&this.equals(b.MIN_SIGNED_VALUE)?b.MIN_SIGNED_VALUE:this.not().add(b.ONE)};b.prototype.add=function(a){var c=this.high>>>16,d=this.high&65535,e=this.low>>>16,g=a.high>>>16,f=a.high&65535,k=a.low>>>16,q;q=0+((this.low&65535)+(a.low&65535));a=0+(q>>>16);a+=e+k;e=0+ +(a>>>16);e+=d+f;d=0+(e>>>16);d=d+(c+g)&65535;return b.fromBits((a&65535)<<16|q&65535,d<<16|e&65535,this.unsigned)};b.prototype.subtract=function(a){return this.add(a.negate())};b.prototype.multiply=function(a){if(this.isZero()||a.isZero())return b.ZERO;if(this.equals(b.MIN_VALUE))return a.isOdd()?b.MIN_VALUE:b.ZERO;if(a.equals(b.MIN_VALUE))return this.isOdd()?b.MIN_VALUE:b.ZERO;if(this.isNegative())return a.isNegative()?this.negate().multiply(a.negate()):this.negate().multiply(a).negate();if(a.isNegative())return this.multiply(a.negate()).negate(); +if(this.lessThan(w)&&a.lessThan(w))return b.fromNumber(this.toNumber()*a.toNumber(),this.unsigned);var c=this.high>>>16,d=this.high&65535,e=this.low>>>16,g=this.low&65535,f=a.high>>>16,k=a.high&65535,q=a.low>>>16;a=a.low&65535;var n,h,m,l;l=0+g*a;m=0+(l>>>16);m+=e*a;h=0+(m>>>16);m=(m&65535)+g*q;h+=m>>>16;m&=65535;h+=d*a;n=0+(h>>>16);h=(h&65535)+e*q;n+=h>>>16;h&=65535;h+=g*k;n+=h>>>16;h&=65535;n=n+(c*a+d*q+e*k+g*f)&65535;return b.fromBits(m<<16|l&65535,n<<16|h,this.unsigned)};b.prototype.div=function(a){if(a.isZero())throw Error("division by zero"); +if(this.isZero())return b.ZERO;if(this.equals(b.MIN_SIGNED_VALUE)){if(a.equals(b.ONE)||a.equals(b.NEG_ONE))return min;if(a.equals(b.MIN_VALUE))return b.ONE;var c=this.shiftRight(1).div(a).shiftLeft(1);if(c.equals(b.ZERO))return a.isNegative()?b.ONE:b.NEG_ONE;var d=this.subtract(a.multiply(c));return c.add(d.div(a))}if(a.equals(b.MIN_VALUE))return b.ZERO;if(this.isNegative())return a.isNegative()?this.negate().div(a.negate()):this.negate().div(a).negate();if(a.isNegative())return this.div(a.negate()).negate(); +for(var e=b.ZERO,d=this;d.greaterThanOrEqual(a);){for(var c=Math.max(1,Math.floor(d.toNumber()/a.toNumber())),g=Math.ceil(Math.log(c)/Math.LN2),g=48>=g?1:Math.pow(2,g-48),f=b.fromNumber(c,this.unsigned),k=f.multiply(a);k.isNegative()||k.greaterThan(d);)c-=g,f=b.fromNumber(c,this.unsigned),k=f.multiply(a);f.isZero()&&(f=b.ONE);e=e.add(f);d=d.subtract(k)}return e};b.prototype.modulo=function(a){return this.subtract(this.div(a).multiply(a))};b.prototype.not=function(){return b.fromBits(~this.low,~this.high, +this.unsigned)};b.prototype.and=function(a){return b.fromBits(this.low&a.low,this.high&a.high,this.unsigned)};b.prototype.or=function(a){return b.fromBits(this.low|a.low,this.high|a.high,this.unsigned)};b.prototype.xor=function(a){return b.fromBits(this.low^a.low,this.high^a.high,this.unsigned)};b.prototype.shiftLeft=function(a){a&=63;if(0==a)return this;var c=this.low;return 32>a?b.fromBits(c<>>32-a,this.unsigned):b.fromBits(0,c<a?b.fromBits(this.low>>>a|c<<32-a,c>>a,this.unsigned):b.fromBits(c>>a-32,0<=c?0:-1,this.unsigned)};b.prototype.shiftRightUnsigned=function(a){a&=63;if(0==a)return this;var c=this.high;return 32>a?b.fromBits(this.low>>>a|c<<32-a,c>>>a,this.unsigned):32==a?b.fromBits(c,0,this.unsigned):b.fromBits(c>>>a-32,0,this.unsigned)};b.prototype.toSigned=function(){var a=this.clone();a.unsigned=p;return a};b.prototype.toUnsigned=function(){var a=this.clone();a.unsigned= +!0;return a};b.prototype.clone=function(){return new b(this.low,this.high,this.unsigned)};"undefined"!=typeof module&&module.exports?module.exports=b:"undefined"!=typeof define&&define.amd?define("Math/Long",[],function(){return b}):(r.dcodeIO||(r.dcodeIO={}),r.dcodeIO.Long=b)})(this); diff --git a/OutgoingMessageSignal.proto b/OutgoingMessageSignal.proto new file mode 100644 index 00000000..06cf1460 --- /dev/null +++ b/OutgoingMessageSignal.proto @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2013 Open WhisperSystems + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package textsecure; + +option java_package = "org.whispersystems.textsecuregcm.entities"; +option java_outer_classname = "MessageProtos"; + +message OutgoingMessageSignal { + optional uint32 type = 1; + optional string source = 2; + optional string relay = 3; + repeated string destinations = 4; + optional uint64 timestamp = 5; + optional bytes message = 6; +} \ No newline at end of file diff --git a/ProtoBuf.min.js b/ProtoBuf.min.js new file mode 100644 index 00000000..cf479d8f --- /dev/null +++ b/ProtoBuf.min.js @@ -0,0 +1,93 @@ +/* + ProtoBuf.js (c) 2013 Daniel Wirtz + Released under the Apache License, Version 2.0 + see: https://github.com/dcodeIO/ProtoBuf.js for details +*/ +(function(r){function s(p){var g={VERSION:"2.0.3",WIRE_TYPES:{}};g.WIRE_TYPES.VARINT=0;g.WIRE_TYPES.BITS64=1;g.WIRE_TYPES.LDELIM=2;g.WIRE_TYPES.STARTGROUP=3;g.WIRE_TYPES.ENDGROUP=4;g.WIRE_TYPES.BITS32=5;g.TYPES={int32:{name:"int32",wireType:g.WIRE_TYPES.VARINT},uint32:{name:"uint32",wireType:g.WIRE_TYPES.VARINT},sint32:{name:"sint32",wireType:g.WIRE_TYPES.VARINT},int64:{name:"int64",wireType:g.WIRE_TYPES.VARINT},uint64:{name:"uint64",wireType:g.WIRE_TYPES.VARINT},sint64:{name:"sint64",wireType:g.WIRE_TYPES.VARINT}, +bool:{name:"bool",wireType:g.WIRE_TYPES.VARINT},"double":{name:"double",wireType:g.WIRE_TYPES.BITS64},string:{name:"string",wireType:g.WIRE_TYPES.LDELIM},bytes:{name:"bytes",wireType:g.WIRE_TYPES.LDELIM},fixed32:{name:"fixed32",wireType:g.WIRE_TYPES.BITS32},sfixed32:{name:"sfixed32",wireType:g.WIRE_TYPES.BITS32},fixed64:{name:"fixed64",wireType:g.WIRE_TYPES.BITS64},sfixed64:{name:"sfixed64",wireType:g.WIRE_TYPES.BITS64},"float":{name:"float",wireType:g.WIRE_TYPES.BITS32},"enum":{name:"enum",wireType:g.WIRE_TYPES.VARINT}, +message:{name:"message",wireType:g.WIRE_TYPES.LDELIM}};g.Long=p.Long;g.convertFieldsToCamelCase=!1;g.Util=function(){Object.create||(Object.create=function(b){function c(){}if(1=this.source.length)return null;if(this.readingString)return this.readingString=!1,this._readString();var b,k;do{for(b=!1;c.WHITESPACE.test(k=this.source.charAt(this.index));)if(this.index++,"\n"===k&&this.line++,this.index===this.source.length)return null;if("/"===this.source.charAt(this.index))if("/"===this.source.charAt(++this.index)){for(;"\n"!==this.source.charAt(this.index);)if(this.index++,this.index==this.source.length)return null;this.index++;this.line++;b=!0}else if("*"=== +this.source.charAt(this.index)){for(k="";"*/"!==k+(k=this.source.charAt(this.index));)if(this.index++,"\n"===k&&this.line++,this.index===this.source.length)return null;this.index++;b=!0}else throw Error("Invalid comment at line "+this.line+": /"+this.source.charAt(this.index)+" ('/' or '*' expected)");}while(b);if(this.index===this.source.length)return null;b=this.index;c.DELIM.lastIndex=0;if(c.DELIM.test(this.source.charAt(b)))b++;else for(b++;ba?"-":"")+c);};c.prototype._parseId=function(c,a){var d=-1,e=1;"-"==c.charAt(0)&& +(e=-1,c=c.substring(1));if(b.NUMBER_DEC.test(c))d=parseInt(c);else if(b.NUMBER_HEX.test(c))d=parseInt(c.substring(2),16);else if(b.NUMBER_OCT.test(c))d=parseInt(c.substring(1),8);else throw Error("Illegal ID value at line "+this.tn.line+": "+(0>e?"-":"")+c);d=e*d|0;if(!a&&0>d)throw Error("Illegal ID range at line "+this.tn.line+": "+(0>e?"-":"")+c);return d};c.prototype._parsePackage=function(c){c=this.tn.next();if(!b.TYPEREF.test(c))throw Error("Illegal package name at line "+this.tn.line+": "+c); +var a=c;c=this.tn.next();if(c!=b.END)throw Error("Illegal end of package definition at line "+this.tn.line+": "+c+" ('"+b.END+"' expected)");return a};c.prototype._parseImport=function(c){c=this.tn.next();"public"===c&&(c=this.tn.next());if(c!==b.STRINGOPEN)throw Error("Illegal begin of import value at line "+this.tn.line+": "+c+" ('"+b.STRINGOPEN+"' expected)");var a=this.tn.next();c=this.tn.next();if(c!==b.STRINGCLOSE)throw Error("Illegal end of import value at line "+this.tn.line+": "+c+" ('"+ +b.STRINGCLOSE+"' expected)");c=this.tn.next();if(c!==b.END)throw Error("Illegal end of import definition at line "+this.tn.line+": "+c+" ('"+b.END+"' expected)");return a};c.prototype._parseOption=function(c,a){a=this.tn.next();var d=!1;a==b.COPTOPEN&&(d=!0,a=this.tn.next());if(!b.NAME.test(a))throw Error("Illegal option name in message "+c.name+" at line "+this.tn.line+": "+a);var e=a;a=this.tn.next();if(d){if(a!==b.COPTCLOSE)throw Error("Illegal custom option name delimiter in message "+c.name+ +", option "+e+" at line "+this.tn.line+": "+a+" ('"+b.COPTCLOSE+"' expected)");e="("+e+")";a=this.tn.next();b.FQTYPEREF.test(a)&&(e+=a,a=this.tn.next())}if(a!==b.EQUAL)throw Error("Illegal option operator in message "+c.name+", option "+e+" at line "+this.tn.line+": "+a+" ('"+b.EQUAL+"' expected)");a=this.tn.next();if(a===b.STRINGOPEN){if(d=this.tn.next(),a=this.tn.next(),a!==b.STRINGCLOSE)throw Error("Illegal end of option value in message "+c.name+", option "+e+" at line "+this.tn.line+": "+a+" ('"+ +b.STRINGCLOSE+"' expected)");}else if(b.NUMBER.test(a))d=this._parseNumber(a,!0);else if(b.TYPEREF.test(a))d=a;else throw Error("Illegal option value in message "+c.name+", option "+e+" at line "+this.tn.line+": "+a);a=this.tn.next();if(a!==b.END)throw Error("Illegal end of option in message "+c.name+", option "+e+" at line "+this.tn.line+": "+a+" ('"+b.END+"' expected)");c.options[e]=d};c.prototype._parseIgnoredBlock=function(c,a){var d=this.tn.next();if(!b.TYPEREF.test(d))throw Error("Illegal "+ +a+" type in "+c.name+": "+d);var e=d,d=this.tn.next();if(d!==b.OPEN)throw Error("Illegal OPEN in "+c.name+" after "+a+" "+e+" at line "+this.tn.line+": "+d);var h=1;do{d=this.tn.next();if(null===d)throw Error("Unexpected EOF in "+c.name+", "+a+" (ignored) at line "+this.tn.line+": "+e);if(d===b.OPEN)h++;else if(d===b.CLOSE&&(d=this.tn.peek(),d===b.END&&this.tn.next(),h--,0===h))break}while(1)};c.prototype._parseIgnoredStatement=function(c,a){var d;do{d=this.tn.next();if(null===d)throw Error("Unexpected EOF in "+ +c.name+", "+a+" (ignored) at line "+this.tn.line);if(d===b.END)break}while(1)};c.prototype._parseService=function(c,a){var d=this.tn.next();if(!b.NAME.test(d))throw Error("Illegal service name at line "+this.tn.line+": "+d);var e=d,h={name:e,rpc:{},options:{}},d=this.tn.next();if(d!==b.OPEN)throw Error("Illegal OPEN after service "+e+" at line "+this.tn.line+": "+d+" ('"+b.OPEN+"' expected)");do if(d=this.tn.next(),"option"===d)this._parseOption(h,d);else if("rpc"===d)this._parseServiceRPC(h,d);else if(d!== +b.CLOSE)throw Error("Illegal type for service "+e+" at line "+this.tn.line+": "+d);while(d!==b.CLOSE);c.services.push(h)};c.prototype._parseServiceRPC=function(c,a){var d=a;a=this.tn.next();if(!b.NAME.test(a))throw Error("Illegal RPC method name in service "+c.name+" at line "+this.tn.line+": "+a);var e=a,h={request:null,response:null,options:{}};a=this.tn.next();if(a!==b.COPTOPEN)throw Error("Illegal start of request type in RPC service "+c.name+"#"+e+" at line "+this.tn.line+": "+a+" ('"+b.COPTOPEN+ +"' expected)");a=this.tn.next();if(!b.TYPEREF.test(a))throw Error("Illegal request type in RPC service "+c.name+"#"+e+" at line "+this.tn.line+": "+a);h.request=a;a=this.tn.next();if(a!=b.COPTCLOSE)throw Error("Illegal end of request type in RPC service "+c.name+"#"+e+" at line "+this.tn.line+": "+a+" ('"+b.COPTCLOSE+"' expected)");a=this.tn.next();if("returns"!==a.toLowerCase())throw Error("Illegal request/response delimiter in RPC service "+c.name+"#"+e+" at line "+this.tn.line+": "+a+" ('returns' expected)"); +a=this.tn.next();if(a!=b.COPTOPEN)throw Error("Illegal start of response type in RPC service "+c.name+"#"+e+" at line "+this.tn.line+": "+a+" ('"+b.COPTOPEN+"' expected)");a=this.tn.next();h.response=a;a=this.tn.next();if(a!==b.COPTCLOSE)throw Error("Illegal end of response type in RPC service "+c.name+"#"+e+" at line "+this.tn.line+": "+a+" ('"+b.COPTCLOSE+"' expected)");a=this.tn.next();if(a===b.OPEN){do if(a=this.tn.next(),"option"===a)this._parseOption(h,a);else if(a!==b.CLOSE)throw Error("Illegal start of option in RPC service "+ +c.name+"#"+e+" at line "+this.tn.line+": "+a+" ('option' expected)");while(a!==b.CLOSE)}else if(a!==b.END)throw Error("Illegal method delimiter in RPC service "+c.name+"#"+e+" at line "+this.tn.line+": "+a+" ('"+b.END+"' or '"+b.OPEN+"' expected)");"undefined"===typeof c[d]&&(c[d]={});c[d][e]=h};c.prototype._parseMessage=function(c,a){var d={};a=this.tn.next();if(!b.NAME.test(a))throw Error("Illegal message name"+(c?" in message "+c.name:"")+" at line "+this.tn.line+": "+a);d.name=a;a=this.tn.next(); +if(a!=b.OPEN)throw Error("Illegal OPEN after message "+d.name+" at line "+this.tn.line+": "+a+" ('"+b.OPEN+"' expected)");d.fields=[];d.enums=[];d.messages=[];d.options={};do if(a=this.tn.next(),a===b.CLOSE){a=this.tn.peek();a===b.END&&this.tn.next();break}else if(b.RULE.test(a))this._parseMessageField(d,a);else if("enum"===a)this._parseEnum(d,a);else if("message"===a)this._parseMessage(d,a);else if("option"===a)this._parseOption(d,a);else if("extensions"===a)d.extensions=this._parseExtensions(d, +a);else if("extend"===a)this._parseExtend(d,a);else throw Error("Illegal token in message "+d.name+" at line "+this.tn.line+": "+a+" (type or '"+b.CLOSE+"' expected)");while(1);c.messages.push(d);return d};c.prototype._parseMessageField=function(c,a){var d={};d.rule=a;a=this.tn.next();if(!b.TYPE.test(a)&&!b.TYPEREF.test(a))throw Error("Illegal field type in message "+c.name+" at line "+this.tn.line+": "+a);d.type=a;a=this.tn.next();if(!b.NAME.test(a))throw Error("Illegal field name in message "+c.name+ +" at line "+this.tn.line+": "+a);d.name=a;a=this.tn.next();if(a!==b.EQUAL)throw Error("Illegal field number operator in message "+c.name+"#"+d.name+" at line "+this.tn.line+": "+a+" ('"+b.EQUAL+"' expected)");a=this.tn.next();try{d.id=this._parseId(a)}catch(e){throw Error("Illegal field id in message "+c.name+"#"+d.name+" at line "+this.tn.line+": "+a);}d.options={};a=this.tn.next();a===b.OPTOPEN&&(this._parseFieldOptions(c,d,a),a=this.tn.next());if(a!==b.END)throw Error("Illegal field delimiter in message "+ +c.name+"#"+d.name+" at line "+this.tn.line+": "+a+" ('"+b.END+"' expected)");c.fields.push(d)};c.prototype._parseFieldOptions=function(c,a,d){var e=!0;do{d=this.tn.next();if(d===b.OPTCLOSE)break;else if(d===b.OPTEND){if(e)throw Error("Illegal start of message field options in message "+c.name+"#"+a.name+" at line "+this.tn.line+": "+d);d=this.tn.next()}this._parseFieldOption(c,a,d);e=!1}while(1)};c.prototype._parseFieldOption=function(c,a,d){var e=!1;d===b.COPTOPEN&&(d=this.tn.next(),e=!0);if(!b.NAME.test(d))throw Error("Illegal field option in message "+ +c.name+"#"+a.name+" at line "+this.tn.line+": "+d);var h=d;d=this.tn.next();if(e){if(d!==b.COPTCLOSE)throw Error("Illegal custom field option name delimiter in message "+c.name+"#"+a.name+" at line "+this.tn.line+": "+d+" (')' expected)");h="("+h+")";d=this.tn.next();b.FQTYPEREF.test(d)&&(h+=d,d=this.tn.next())}if(d!==b.EQUAL)throw Error("Illegal field option operation in message "+c.name+"#"+a.name+" at line "+this.tn.line+": "+d+" ('=' expected)");d=this.tn.next();if(d===b.STRINGOPEN){if(e=this.tn.next(), +d=this.tn.next(),d!=b.STRINGCLOSE)throw Error("Illegal end of field value in message "+c.name+"#"+a.name+", option "+h+" at line "+this.tn.line+": "+d+" ('"+b.STRINGCLOSE+"' expected)");}else if(b.NUMBER.test(d,!0))e=this._parseNumber(d,!0);else if(b.BOOL.test(d))e="true"===d.toLowerCase();else if(b.TYPEREF.test(d))e=d;else throw Error("Illegal field option value in message "+c.name+"#"+a.name+", option "+h+" at line "+this.tn.line+": "+d);a.options[h]=e};c.prototype._parseEnum=function(c,a){var d= +{};a=this.tn.next();if(!b.NAME.test(a))throw Error("Illegal enum name in message "+c.name+" at line "+this.tn.line+": "+a);d.name=a;a=this.tn.next();if(a!==b.OPEN)throw Error("Illegal OPEN after enum "+d.name+" at line "+this.tn.line+": "+a);d.values=[];d.options={};do{a=this.tn.next();if(a===b.CLOSE){a=this.tn.peek();a===b.END&&this.tn.next();break}if("option"==a)this._parseOption(d,a);else{if(!b.NAME.test(a))throw Error("Illegal enum value name in enum "+d.name+" at line "+this.tn.line+": "+a); +this._parseEnumValue(d,a)}}while(1);c.enums.push(d)};c.prototype._parseEnumValue=function(c,a){var d={};d.name=a;a=this.tn.next();if(a!==b.EQUAL)throw Error("Illegal enum value operator in enum "+c.name+" at line "+this.tn.line+": "+a+" ('"+b.EQUAL+"' expected)");a=this.tn.next();try{d.id=this._parseId(a,!0)}catch(e){throw Error("Illegal enum value id in enum "+c.name+" at line "+this.tn.line+": "+a);}c.values.push(d);a=this.tn.next();a===b.OPTOPEN&&(this._parseFieldOptions(c,{options:{}},a),a=this.tn.next()); +if(a!==b.END)throw Error("Illegal enum value delimiter in enum "+c.name+" at line "+this.tn.line+": "+a+" ('"+b.END+"' expected)");};c.prototype._parseExtensions=function(c,a){var d=[];a=this.tn.next();"min"===a?d.push(b.ID_MIN):"max"===a?d.push(b.ID_MAX):d.push(this._parseNumber(a));a=this.tn.next();if("to"!==a)throw"Illegal extensions delimiter in message "+c.name+" at line "+this.tn.line+" ('to' expected)";a=this.tn.next();"min"===a?d.push(b.ID_MIN):"max"===a?d.push(b.ID_MAX):d.push(this._parseNumber(a)); +a=this.tn.next();if(a!==b.END)throw Error("Illegal extension delimiter in message "+c.name+" at line "+this.tn.line+": "+a+" ('"+b.END+"' expected)");return d};c.prototype._parseExtend=function(c,a){a=this.tn.next();if(!b.TYPEREF.test(a))throw Error("Illegal extended message name at line "+this.tn.line+": "+a);var d={};d.ref=a;d.fields=[];a=this.tn.next();if(a!==b.OPEN)throw Error("Illegal OPEN in extend "+d.name+" at line "+this.tn.line+": "+a+" ('"+b.OPEN+"' expected)");do if(a=this.tn.next(),a=== +b.CLOSE){a=this.tn.peek();a==b.END&&this.tn.next();break}else if(b.RULE.test(a))this._parseMessageField(d,a);else throw Error("Illegal token in extend "+d.name+" at line "+this.tn.line+": "+a+" (rule or '"+b.CLOSE+"' expected)");while(1);c.messages.push(d);return d};c.prototype.toString=function(){return"Parser"};return c}(g,g.Lang,g.DotProto.Tokenizer);g.Reflect=function(c){var b={},g=function(a,c){this.parent=a;this.name=c};g.prototype.fqn=function(){var a=this.name,c=this;do{c=c.parent;if(null== +c)break;a=c.name+"."+a}while(1);return a};g.prototype.toString=function(c){var b=this.fqn();c&&(this instanceof a?b="Message "+b:this instanceof a.Field?b="Message.Field "+b:this instanceof e?b="Enum "+b:this instanceof e.Value?b="Enum.Value "+b:this instanceof h?b="Service "+b:this instanceof h.Method?b=this instanceof h.RPCMethod?"Service.RPCMethod "+b:"Service.Method "+b:this instanceof k&&(b="Namespace "+b));return b};g.prototype.build=function(){throw Error(this.toString(!0)+" cannot be built directly"); +};b.T=g;var k=function(a,c,b){g.call(this,a,c);this.children=[];this.options=b||{}};k.prototype=Object.create(g.prototype);k.prototype.getChildren=function(a){a=a||null;if(null==a)return this.children.slice();for(var c=[],b=0;b>3,k=this.getChild(h);if(k)k.repeated&&!k.options.packed? +e.add(k.name,k.decode(g,a)):e.set(k.name,k.decode(g,a));else switch(g){case c.WIRE_TYPES.VARINT:a.readVarint32();break;case c.WIRE_TYPES.BITS32:a.offset+=4;break;case c.WIRE_TYPES.BITS64:a.offset+=8;break;case c.WIRE_TYPES.LDELIM:g=a.readVarint32();a.offset+=g;break;default:throw Error("Illegal wire type of unknown field "+h+" in "+this.toString(!0)+"#decode: "+g);}}d=this.getChildren(c.Reflect.Field);for(g=0;g>>0;if(c.Long){if(this.type==c.TYPES.int64||this.type==c.TYPES.sint64||this.type==c.TYPES.sfixed64)return"object"==typeof a&&a instanceof c.Long?a.unsigned?a.toSigned():a:c.Long.fromNumber(a,!1);if(this.type==c.TYPES.uint64||this.type==c.TYPES.fixed64)return"object"==typeof a&&a instanceof c.Long?a.unsigned?a:a.toUnsigned():c.Long.fromNumber(a,!0)}if(this.type==c.TYPES.bool)return"string"===typeof a?"true"===a:!!a;if(this.type==c.TYPES["float"]||this.type==c.TYPES["double"])return parseFloat(a); +if(this.type==c.TYPES.string)return""+a;if(this.type==c.TYPES.bytes)return a&&a instanceof p?a:p.wrap(a);if(this.type==c.TYPES["enum"]){h=this.resolvedType.getChildren(e.Value);for(d=0;da.length&&(b=b.clone().flip()),b.writeVarint32(a.remaining()),b.append(a);else if(this.type==c.TYPES.message){var d=(new p).LE();this.resolvedType.encode(a, +d);b.writeVarint32(d.offset);b.append(d.flip())}else throw Error("[INTERNAL] Illegal value to encode in "+this.toString(!0)+": "+a+" (unknown type)");return b}};d.prototype.decode=function(a,b,d){if(a!=this.type.wireType&&(d||a!=c.WIRE_TYPES.LDELIM||!this.repeated))throw Error("Illegal wire type for field "+this.toString(!0)+": "+a+" ("+this.type.wireType+" expected)");if(a==c.WIRE_TYPES.LDELIM&&this.repeated&&this.options.packed&&!d){a=b.readVarint32();a=b.offset+a;for(d=[];b.offset>>0;if(this.type==c.TYPES.sint32)return b.readZigZagVarint32()|0;if(this.type==c.TYPES.fixed32)return b.readUint32()>>>0;if(this.type==c.TYPES.sfixed32)return b.readInt32()|0;if(this.type==c.TYPES.int64)return b.readVarint64();if(this.type==c.TYPES.uint64)return b.readVarint64().toUnsigned();if(this.type==c.TYPES.sint64)return b.readZigZagVarint64();if(this.type==c.TYPES.fixed64)return b.readUint64(); +if(this.type==c.TYPES.sfixed64)return b.readInt64();if(this.type==c.TYPES.bool)return!!b.readVarint32();if(this.type==c.TYPES["enum"])return b.readVarint32();if(this.type==c.TYPES["float"])return b.readFloat();if(this.type==c.TYPES["double"])return b.readDouble();if(this.type==c.TYPES.string)return b.readVString();if(this.type==c.TYPES.bytes){a=b.readVarint32();if(b.remaining()c.Lang.ID_MAX&&(h.extensions[1]=c.Lang.ID_MAX));this.ptr.addChild(h);0h.extensions[1])throw Error("Illegal extended field id in message "+h.name+": "+e.fields[f].id+" ("+h.extensions.join(" to ")+" expected)");h.addChild(new g.Message.Field(h,e.fields[f].rule, +e.fields[f].type,e.fields[f].name,e.fields[f].id,e.fields[f].options))}else{if(!/\.?google\.protobuf\./.test(e.ref))throw Error("Extended message "+e.ref+" is not defined");}else throw Error("Not a valid message, enum, service or extend definition: "+JSON.stringify(e));else throw Error("Not a valid namespace definition: "+JSON.stringify(a));this.ptr=this.ptr.parent}this.resolved=!1;this.result=null;return this}};k.isValidImport=function(a){return!/google\/protobuf\//.test(a)};k.prototype["import"]= +function(a,b){if("string"===typeof b){c.Util.IS_NODE&&(b=require("path").resolve(b));if(this.files[b])return this.reset(),this;this.files[b]=!0}if(a.imports&&0>>2]|=(e[k>>>2]>>>24-8*(k%4)&255)<<24-8*((j+k)%4);else if(65535>>2]=e[k>>>2];else c.push.apply(c,e);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< +32-8*(c%4);a.length=u.ceil(c/4)},clone:function(){var a=t.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],e=0;e>>2]>>>24-8*(j%4)&255;e.push((k>>>4).toString(16));e.push((k&15).toString(16))}return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j>>3]|=parseInt(a.substr(j, +2),16)<<24-4*(j%8);return new r.init(e,c/2)}},b=w.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j>>2]>>>24-8*(j%4)&255));return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j>>2]|=(a.charCodeAt(j)&255)<<24-8*(j%4);return new r.init(e,c)}},x=w.Utf8={stringify:function(a){try{return decodeURIComponent(escape(b.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return b.parse(unescape(encodeURIComponent(a)))}}, +q=l.BufferedBlockAlgorithm=t.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=x.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,e=c.words,j=c.sigBytes,k=this.blockSize,b=j/(4*k),b=a?u.ceil(b):u.max((b|0)-this._minBufferSize,0);a=b*k;j=u.min(4*a,j);if(a){for(var q=0;q>>2]>>>24-8*(r%4)&255)<<16|(l[r+1>>>2]>>>24-8*((r+1)%4)&255)<<8|l[r+2>>>2]>>>24-8*((r+2)%4)&255,v=0;4>v&&r+0.75*v>>6*(3-v)&63));if(l=t.charAt(64))for(;d.length%4;)d.push(l);return d.join("")},parse:function(d){var l=d.length,s=this._map,t=s.charAt(64);t&&(t=d.indexOf(t),-1!=t&&(l=t));for(var t=[],r=0,w=0;w< +l;w++)if(w%4){var v=s.indexOf(d.charAt(w-1))<<2*(w%4),b=s.indexOf(d.charAt(w))>>>6-2*(w%4);t[r>>>2]|=(v|b)<<24-8*(r%4);r++}return p.create(t,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})(); +(function(u){function p(b,n,a,c,e,j,k){b=b+(n&a|~n&c)+e+k;return(b<>>32-j)+n}function d(b,n,a,c,e,j,k){b=b+(n&c|a&~c)+e+k;return(b<>>32-j)+n}function l(b,n,a,c,e,j,k){b=b+(n^a^c)+e+k;return(b<>>32-j)+n}function s(b,n,a,c,e,j,k){b=b+(a^(n|~c))+e+k;return(b<>>32-j)+n}for(var t=CryptoJS,r=t.lib,w=r.WordArray,v=r.Hasher,r=t.algo,b=[],x=0;64>x;x++)b[x]=4294967296*u.abs(u.sin(x+1))|0;r=r.MD5=v.extend({_doReset:function(){this._hash=new w.init([1732584193,4023233417,2562383102,271733878])}, +_doProcessBlock:function(q,n){for(var a=0;16>a;a++){var c=n+a,e=q[c];q[c]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360}var a=this._hash.words,c=q[n+0],e=q[n+1],j=q[n+2],k=q[n+3],z=q[n+4],r=q[n+5],t=q[n+6],w=q[n+7],v=q[n+8],A=q[n+9],B=q[n+10],C=q[n+11],u=q[n+12],D=q[n+13],E=q[n+14],x=q[n+15],f=a[0],m=a[1],g=a[2],h=a[3],f=p(f,m,g,h,c,7,b[0]),h=p(h,f,m,g,e,12,b[1]),g=p(g,h,f,m,j,17,b[2]),m=p(m,g,h,f,k,22,b[3]),f=p(f,m,g,h,z,7,b[4]),h=p(h,f,m,g,r,12,b[5]),g=p(g,h,f,m,t,17,b[6]),m=p(m,g,h,f,w,22,b[7]), +f=p(f,m,g,h,v,7,b[8]),h=p(h,f,m,g,A,12,b[9]),g=p(g,h,f,m,B,17,b[10]),m=p(m,g,h,f,C,22,b[11]),f=p(f,m,g,h,u,7,b[12]),h=p(h,f,m,g,D,12,b[13]),g=p(g,h,f,m,E,17,b[14]),m=p(m,g,h,f,x,22,b[15]),f=d(f,m,g,h,e,5,b[16]),h=d(h,f,m,g,t,9,b[17]),g=d(g,h,f,m,C,14,b[18]),m=d(m,g,h,f,c,20,b[19]),f=d(f,m,g,h,r,5,b[20]),h=d(h,f,m,g,B,9,b[21]),g=d(g,h,f,m,x,14,b[22]),m=d(m,g,h,f,z,20,b[23]),f=d(f,m,g,h,A,5,b[24]),h=d(h,f,m,g,E,9,b[25]),g=d(g,h,f,m,k,14,b[26]),m=d(m,g,h,f,v,20,b[27]),f=d(f,m,g,h,D,5,b[28]),h=d(h,f, +m,g,j,9,b[29]),g=d(g,h,f,m,w,14,b[30]),m=d(m,g,h,f,u,20,b[31]),f=l(f,m,g,h,r,4,b[32]),h=l(h,f,m,g,v,11,b[33]),g=l(g,h,f,m,C,16,b[34]),m=l(m,g,h,f,E,23,b[35]),f=l(f,m,g,h,e,4,b[36]),h=l(h,f,m,g,z,11,b[37]),g=l(g,h,f,m,w,16,b[38]),m=l(m,g,h,f,B,23,b[39]),f=l(f,m,g,h,D,4,b[40]),h=l(h,f,m,g,c,11,b[41]),g=l(g,h,f,m,k,16,b[42]),m=l(m,g,h,f,t,23,b[43]),f=l(f,m,g,h,A,4,b[44]),h=l(h,f,m,g,u,11,b[45]),g=l(g,h,f,m,x,16,b[46]),m=l(m,g,h,f,j,23,b[47]),f=s(f,m,g,h,c,6,b[48]),h=s(h,f,m,g,w,10,b[49]),g=s(g,h,f,m, +E,15,b[50]),m=s(m,g,h,f,r,21,b[51]),f=s(f,m,g,h,u,6,b[52]),h=s(h,f,m,g,k,10,b[53]),g=s(g,h,f,m,B,15,b[54]),m=s(m,g,h,f,e,21,b[55]),f=s(f,m,g,h,v,6,b[56]),h=s(h,f,m,g,x,10,b[57]),g=s(g,h,f,m,t,15,b[58]),m=s(m,g,h,f,D,21,b[59]),f=s(f,m,g,h,z,6,b[60]),h=s(h,f,m,g,C,10,b[61]),g=s(g,h,f,m,j,15,b[62]),m=s(m,g,h,f,A,21,b[63]);a[0]=a[0]+f|0;a[1]=a[1]+m|0;a[2]=a[2]+g|0;a[3]=a[3]+h|0},_doFinalize:function(){var b=this._data,n=b.words,a=8*this._nDataBytes,c=8*b.sigBytes;n[c>>>5]|=128<<24-c%32;var e=u.floor(a/ +4294967296);n[(c+64>>>9<<4)+15]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360;n[(c+64>>>9<<4)+14]=(a<<8|a>>>24)&16711935|(a<<24|a>>>8)&4278255360;b.sigBytes=4*(n.length+1);this._process();b=this._hash;n=b.words;for(a=0;4>a;a++)c=n[a],n[a]=(c<<8|c>>>24)&16711935|(c<<24|c>>>8)&4278255360;return b},clone:function(){var b=v.clone.call(this);b._hash=this._hash.clone();return b}});t.MD5=v._createHelper(r);t.HmacMD5=v._createHmacHelper(r)})(Math); +(function(){var u=CryptoJS,p=u.lib,d=p.Base,l=p.WordArray,p=u.algo,s=p.EvpKDF=d.extend({cfg:d.extend({keySize:4,hasher:p.MD5,iterations:1}),init:function(d){this.cfg=this.cfg.extend(d)},compute:function(d,r){for(var p=this.cfg,s=p.hasher.create(),b=l.create(),u=b.words,q=p.keySize,p=p.iterations;u.length>>2]&255}};d.BlockCipher=v.extend({cfg:v.cfg.extend({mode:b,padding:q}),reset:function(){v.reset.call(this);var a=this.cfg,b=a.iv,a=a.mode;if(this._xformMode==this._ENC_XFORM_MODE)var c=a.createEncryptor;else c=a.createDecryptor,this._minBufferSize=1;this._mode=c.call(a, +this,b&&b.words)},_doProcessBlock:function(a,b){this._mode.processBlock(a,b)},_doFinalize:function(){var a=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){a.pad(this._data,this.blockSize);var b=this._process(!0)}else b=this._process(!0),a.unpad(b);return b},blockSize:4});var n=d.CipherParams=l.extend({init:function(a){this.mixIn(a)},toString:function(a){return(a||this.formatter).stringify(this)}}),b=(p.format={}).OpenSSL={stringify:function(a){var b=a.ciphertext;a=a.salt;return(a?s.create([1398893684, +1701076831]).concat(a).concat(b):b).toString(r)},parse:function(a){a=r.parse(a);var b=a.words;if(1398893684==b[0]&&1701076831==b[1]){var c=s.create(b.slice(2,4));b.splice(0,4);a.sigBytes-=16}return n.create({ciphertext:a,salt:c})}},a=d.SerializableCipher=l.extend({cfg:l.extend({format:b}),encrypt:function(a,b,c,d){d=this.cfg.extend(d);var l=a.createEncryptor(c,d);b=l.finalize(b);l=l.cfg;return n.create({ciphertext:b,key:c,iv:l.iv,algorithm:a,mode:l.mode,padding:l.padding,blockSize:a.blockSize,formatter:d.format})}, +decrypt:function(a,b,c,d){d=this.cfg.extend(d);b=this._parse(b,d.format);return a.createDecryptor(c,d).finalize(b.ciphertext)},_parse:function(a,b){return"string"==typeof a?b.parse(a,this):a}}),p=(p.kdf={}).OpenSSL={execute:function(a,b,c,d){d||(d=s.random(8));a=w.create({keySize:b+c}).compute(a,d);c=s.create(a.words.slice(b),4*c);a.sigBytes=4*b;return n.create({key:a,iv:c,salt:d})}},c=d.PasswordBasedCipher=a.extend({cfg:a.cfg.extend({kdf:p}),encrypt:function(b,c,d,l){l=this.cfg.extend(l);d=l.kdf.execute(d, +b.keySize,b.ivSize);l.iv=d.iv;b=a.encrypt.call(this,b,c,d.key,l);b.mixIn(d);return b},decrypt:function(b,c,d,l){l=this.cfg.extend(l);c=this._parse(c,l.format);d=l.kdf.execute(d,b.keySize,b.ivSize,c.salt);l.iv=d.iv;return a.decrypt.call(this,b,c,d.key,l)}})}(); +(function(){for(var u=CryptoJS,p=u.lib.BlockCipher,d=u.algo,l=[],s=[],t=[],r=[],w=[],v=[],b=[],x=[],q=[],n=[],a=[],c=0;256>c;c++)a[c]=128>c?c<<1:c<<1^283;for(var e=0,j=0,c=0;256>c;c++){var k=j^j<<1^j<<2^j<<3^j<<4,k=k>>>8^k&255^99;l[e]=k;s[k]=e;var z=a[e],F=a[z],G=a[F],y=257*a[k]^16843008*k;t[e]=y<<24|y>>>8;r[e]=y<<16|y>>>16;w[e]=y<<8|y>>>24;v[e]=y;y=16843009*G^65537*F^257*z^16843008*e;b[k]=y<<24|y>>>8;x[k]=y<<16|y>>>16;q[k]=y<<8|y>>>24;n[k]=y;e?(e=z^a[a[a[G^z]]],j^=a[a[j]]):e=j=1}var H=[0,1,2,4,8, +16,32,64,128,27,54],d=d.AES=p.extend({_doReset:function(){for(var a=this._key,c=a.words,d=a.sigBytes/4,a=4*((this._nRounds=d+6)+1),e=this._keySchedule=[],j=0;j>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255]):(k=k<<8|k>>>24,k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255],k^=H[j/d|0]<<24);e[j]=e[j-d]^k}c=this._invKeySchedule=[];for(d=0;dd||4>=j?k:b[l[k>>>24]]^x[l[k>>>16&255]]^q[l[k>>> +8&255]]^n[l[k&255]]},encryptBlock:function(a,b){this._doCryptBlock(a,b,this._keySchedule,t,r,w,v,l)},decryptBlock:function(a,c){var d=a[c+1];a[c+1]=a[c+3];a[c+3]=d;this._doCryptBlock(a,c,this._invKeySchedule,b,x,q,n,s);d=a[c+1];a[c+1]=a[c+3];a[c+3]=d},_doCryptBlock:function(a,b,c,d,e,j,l,f){for(var m=this._nRounds,g=a[b]^c[0],h=a[b+1]^c[1],k=a[b+2]^c[2],n=a[b+3]^c[3],p=4,r=1;r>>24]^e[h>>>16&255]^j[k>>>8&255]^l[n&255]^c[p++],s=d[h>>>24]^e[k>>>16&255]^j[n>>>8&255]^l[g&255]^c[p++],t= +d[k>>>24]^e[n>>>16&255]^j[g>>>8&255]^l[h&255]^c[p++],n=d[n>>>24]^e[g>>>16&255]^j[h>>>8&255]^l[k&255]^c[p++],g=q,h=s,k=t;q=(f[g>>>24]<<24|f[h>>>16&255]<<16|f[k>>>8&255]<<8|f[n&255])^c[p++];s=(f[h>>>24]<<24|f[k>>>16&255]<<16|f[n>>>8&255]<<8|f[g&255])^c[p++];t=(f[k>>>24]<<24|f[n>>>16&255]<<16|f[g>>>8&255]<<8|f[h&255])^c[p++];n=(f[n>>>24]<<24|f[g>>>16&255]<<16|f[h>>>8&255]<<8|f[k&255])^c[p++];a[b]=q;a[b+1]=s;a[b+2]=t;a[b+3]=n},keySize:8});u.AES=p._createHelper(d)})(); diff --git a/helpers.js b/helpers.js index b00db44b..f655a899 100644 --- a/helpers.js +++ b/helpers.js @@ -1,3 +1,83 @@ +//TODO: Stolen from MDN (copyright...) +function b64ToUint6 (nChr) { + + return nChr > 64 && nChr < 91 ? + nChr - 65 + : nChr > 96 && nChr < 123 ? + nChr - 71 + : nChr > 47 && nChr < 58 ? + nChr + 4 + : nChr === 43 ? + 62 + : nChr === 47 ? + 63 + : + 0; + +} + +function base64DecToArr (sBase64, nBlocksSize) { + var + sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length, + nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen); + + for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) { + nMod4 = nInIdx & 3; + nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4; + if (nMod4 === 3 || nInLen - nInIdx === 1) { + for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { + taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255; + } + nUint24 = 0; + } + } + return taBytes; +} + +/********************************* + *** Type conversion utilities *** + *********************************/ +function getString(thing) { + if (thing == "[object Uint8Array]") + return String.fromCharCode.apply(null, thing); + return thing; +} + +function getUint8Array(string) { + return base64DecToArr(btoa(string)); +} + +function base64ToUint8Array(string) { + return base64DecToArr(string); +} + +var OutgoingMessageProtobuf = dcodeIO.ProtoBuf.loadProtoFile("OutgoingMessageSignal.proto").build("textsecure.OutgoingMessageSignal"); +function decodeProtobuf(string) { + return OutgoingMessageProtobuf.decode(string); +} + +function getNumberFromString(string) { + return string.split(".")[0]; +} + +function getEncodedNumber(number) { + var split = number.split("."); + if (split.length > 1) { + if (split[1] == 1) + return split[0]; + else + return number; + } else + return number; +} + +function getDeviceId(encodedNumber) { + var split = encodedNumber.split("."); + if (split.length > 1) + return split[1]; + return 1; +} + /************************************************ *** Utilities to store data in local storage *** ************************************************/ @@ -5,7 +85,7 @@ var storage = {}; storage.putEncrypted = function(key, value) { //TODO - localStorage.setItem("e" + key, value); + localStorage.setItem("e" + key, getString(value)); } storage.getEncrypted = function(key, defaultValue) { @@ -17,7 +97,7 @@ storage.getEncrypted = function(key, defaultValue) { } storage.putUnencrypted = function(key, value) { - localStorage.setItem("u" + key, value); + localStorage.setItem("u" + key, getString(value)); } storage.getUnencrypted = function(key, defaultValue) { @@ -27,77 +107,6 @@ storage.getUnencrypted = function(key, defaultValue) { return value; } -/************************************************ - *** Utilities to communicate with the server *** - ************************************************/ -var URL_BASE = "http://textsecure-test.herokuapp.com"; -var URL_CALLS = {}; -URL_CALLS['devices'] = "/v1/devices"; -URL_CALLS['keys'] = "/v1/keys"; -URL_CALLS['push'] = "/v1/messagesocket"; - -/** - * REQUIRED PARAMS: - * call: URL_CALLS entry - * httpType: POST/GET/PUT/etc - * success_callback: function(response object) called on success - * error_callback: function(http status code = -1 or != 200) called on failure - * OPTIONAL PARAMS: - * urlParameters: crap appended to the url (probably including a leading /) - * user: user name to be sent in a basic auth header - * password: password to be sent in a basic auth header - * jsonData: JSON data sent in the request body - */ -function doAjax(param) { - if (param.urlParameters === undefined) - param.urlParameters = ""; - $.ajax(URL_BASE + URL_CALLS[param.call] + param.urlParameters, { - type: param.httpType, - data: param.jsonData, - beforeSend: function(xhr) { - if (param.user !== undefined && param.password !== undefined) - xhr.setRequestHeader("Authorization", "Basic " + btoa(param.user + ":" + param.password)); - }, - success: function(response, textStatus, jqXHR) { - param.success_callback(response); - }, - error: function(jqXHR, textStatus, errorThrown) { - var code = jqXHR.status; - if (code > 999 || code < 100) - code = -1; - param.error_callback(code); - }, - cache: false - }); -} - -function subscribeToPush(user, password, message_callback) { - var request = { url: URL_BASE + URL_CALLS['push'], - contentType: 'application/json', - transport: 'websocket', - fallbackTransport: 'long-polling', - logLevel: 'debug', //TODO - headers: {'Authorization: Basic ' + btoa(user + ":" + password)}, - onOpen = function(response) { - console.log('Connected to server using ' + response.transport); - }, - onMessage = function(response) { - try { - var message = JSON.parse(response.responseBody); - } catch (e) { - console.log('Error parsing server JSON message: ' + response.responseBody); - return; - } - console.log('Received server message' + message); //TODO - message_callback(message); - }, - onError = function(response) { - console.log('Server is down :('); - //TODO: GUI - }}; - $.atmosphere.subscribe(request); -} - /******************************************* *** Utilities to manage keys/randomness *** *******************************************/ @@ -141,3 +150,274 @@ function generateKeys() { keys.lastResortKey = {keyId: 16777215, publicKey: getNewPubKey("lastResortKey" + keyGroupId), identityKey: identityKey}; return keys; } + +// Keep track of other's keys too +function getDeviceObject(encodedNumber) { + var deviceObject = storage.getEncrypted("deviceObject" + encodedNumber); + if (deviceObject === undefined) + return deviceObject; + return JSON.parseJSON(deviceObject); +} + +function getDeviceIdListFromNumber(number) { + return storage.getEncrypted("deviceIdList" + getNumberFromString(number), []); +} + +function addDeviceIdForNumber(number, deviceId) { + var deviceIdList = JSON.parseJSON(getDeviceIdListFromNumber(getNumberFromString(number))); + for (var i = 0; i < deviceIdList.length; i++) { + if (deviceIdList[i] == deviceId) + return; + } + deviceIdList[deviceIdList.length] = deviceId; + storage.putEncrypted("deviceIdList" + getNumberFromString(number), deviceIdList); +} + +// throws "Identity key mismatch" +function saveDeviceObject(deviceObject) { + var existing = getDeviceObject(deviceObject.encodedNumber); + for (key in deviceObject) { + if (key == "encodedNumber") + continue; + + if (key == "identityKey" && deviceObject.identityKey != deviceObject.identityKey) + throw "Identity key mismatch"; + + existing[key] = deviceObject[key]; + } + storage.putEncrypted("deviceObject", JSON.encode(existing)); + addDeviceIdForNumber(deviceObject.encodedNumber, getDeviceId(deviceObject.encodedNumber)); +} + +function getDeviceObjectListFromNumber(number) { + var deviceObjectList = []; + var deviceIdList = getDeviceIdForNumber(number); + for (var i = 0; i < deviceIdList.length; i++) + deviceObjectList[deviceObjectList.length] = getDeviceObject(getNumberFromString(number) + "." + deviceIdList[i]); + return deviceObjectList; +} + +/******************** + *** Crypto stuff *** + ********************/ + +// Decrypts message into a BASE64 string +function decryptWebsocketMessage(message) { + //TODO: Use a native AES impl (so I dont feel so bad about side-channels) + var signaling_key = storage.getEncrypted("signaling_key"); + var aes_key = CryptoJS.enc.Latin1.parse(signaling_key.substring(0, 32)); + var mac_key = CryptoJS.enc.Latin1.parse(signaling_key.substring(32, 32 + 20)); + + var decodedMessage = base64ToUint8Array(message); + if (decodedMessage[0] != 1) { + console.log("Got bad version number: " + decodedMessage[0]); + return; + } + var iv = CryptoJS.lib.WordArray.create(decodedMessage.subarray(1, 1 + 16)); + var ciphertext = btoa(getString(decodedMessage.subarray(1 + 16, decodedMessage.length - 10))); + var mac = CryptoJS.lib.WordArray.create(decodedMessage.subarray(decodedMessage.length - 10, decodedMessage.length)); + + var calculated_mac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, mac_key); + calculated_mac.update(CryptoJS.enc.Latin1.parse(String.fromCharCode(1))); + calculated_mac.update(iv); + calculated_mac.update(ciphertext); + calculated_mac = calculated_mac.finalize(); + + var plaintext = CryptoJS.AES.decrypt(ciphertext, aes_key, {iv: iv});//TODO: Does this throw on invalid padding? + + if (calculated_mac.toString(CryptoJS.enc.Hex).substring(0, 20) != mac.toString(CryptoJS.enc.Hex)) { + console.log("Got message with bad MAC"); + throw "Bad MAC"; + } + + return plaintext.toString(CryptoJS.enc.Base64); +} + +function encryptMessageFor(deviceObject, message) { + return message + " encrypted to " + deviceObject.encodedNumber + " with relay " + deviceObject.relay + + " with identityKey " + deviceObject.identityKey + " and public key " + deviceObject.publicKey; //TODO +} + +/************************************************ + *** Utilities to communicate with the server *** + ************************************************/ +var URL_BASE = "http://textsecure-test.herokuapp.com"; +var URL_CALLS = {}; +URL_CALLS['devices'] = "/v1/devices"; +URL_CALLS['keys'] = "/v1/keys"; +URL_CALLS['push'] = "/v1/messagesocket"; +URL_CALLS['messages'] = "/v1/messages"; + +/** + * REQUIRED PARAMS: + * call: URL_CALLS entry + * httpType: POST/GET/PUT/etc + * OPTIONAL PARAMS: + * success_callback: function(response object) called on success + * error_callback: function(http status code = -1 or != 200) called on failure + * urlParameters: crap appended to the url (probably including a leading /) + * user: user name to be sent in a basic auth header + * password: password to be sent in a basic auth headerA + * do_auth: alternative to user/password where user/password are figured out automagically + * jsonData: JSON data sent in the request body + */ +function doAjax(param) { + if (param.urlParameters === undefined) + param.urlParameters = ""; + if (param.do_auth) { + param.user = storage.getUnencrypted("number_id"); + param.password = storage.getEncrypted("password"); + } + $.ajax(URL_BASE + URL_CALLS[param.call] + param.urlParameters, { + type: param.httpType, + data: JSON.stringify(param.jsonData), + contentType: 'application/json; charset=utf-8', + dataType: 'json', + beforeSend: function(xhr) { + if (param.user !== undefined && param.password !== undefined) + xhr.setRequestHeader("Authorization", "Basic " + btoa(getString(param.user) + ":" + getString(param.password))); + }, + success: function(response, textStatus, jqXHR) { + if (param.success_callback !== undefined) + param.success_callback(response); + }, + error: function(jqXHR, textStatus, errorThrown) { + var code = jqXHR.status; + if (code > 999 || code < 100) + code = -1; + if (param.error_callback !== undefined) + param.error_callback(code); + }, + cache: false + }); +} + +function subscribeToPush(message_callback) { + var user = storage.getUnencrypted("number_id"); + var password = storage.getEncrypted("password"); + var request = { url: URL_BASE + URL_CALLS['push'] + "/?user=%2B" + getString(user).substring(1) + "&password=" + getString(password), + method: 'GET', + fallbackMethod: 'GET', + transport: 'websocket', + fallbackTransport: 'websocket', + logLevel: 'debug', //TODO + trackMessageLength: false, + //data: "user=" + getString(user) + "&password=" + getString(password), + onOpen: function(response) { + console.log('Connected to server using ' + response.transport); + }, + onMessage: function(response) { + try { + // Some bug in Atmosphere.js is forcing trackMessageLength to true + var message = JSON.parse(response.responseBody.split("|")[1]); + } catch (e) { + console.log('Error parsing server JSON message: ' + response.responseBody.split("|")[1]); + return; + } + + try { + var plaintext = decryptWebsocketMessage(message.message); + var proto = decodeProtobuf(plaintext); + } catch (e) { + console.log("Error decoding message: " + e); + return; + } + + doAjax({call: 'push', httpType: 'PUT', urlParameters: '/' + message.id, do_auth: true}); + + message_callback(proto); + }, + onError: function(response) { + console.log('Server is down :('); + //TODO: GUI + }}; + $.atmosphere.subscribe(request); +} + +// success_callback(identity_key), error_callback(error_msg) +function getKeysForNumber(number, success_callback, error_callback) { + doAjax({call: 'keys', httpType: 'GET', do_auth: true, urlParameters: "/" + getNumberFromString(number) + "?multikeys", + success_callback: function(response) { + for (var i = 0; i < response.length; i++) { + try { + saveDeviceObject({ + encodedNumber: number + "." + response[i].deviceId, + identityKey: response[i].identityKey, + publicKey: response[i].publicKey + }); + } catch (e) { + error_callback(e); + return; + } + } + success_callback(response[0].identityKey); + }, error_callback: function(code) { + error_callback("Error making HTTP request: " + code); + } + }); +} + +// success_callback(server success/failure map), error_callback(error_msg) +function sendMessageToDevices(deviceObjectList, message, success_callback, error_callback) { + if (message.type === undefined) + message.type = 0; //TODO: Change to 1 for ciphertext instead of plaintext + + var jsonData = []; + for (var i = 0; i < deviceObjectList.legnth; i++) { + jsonData[jsonData.length] = { + type: message.type, + destination: deviceObjectList[i].encodedNumber, + body: encryptMessageFor(deviceObjectList[i], message.message), + relay: deviceObjectList[i].relay, + timestamp: new Date().getTime() + }; + } + doAjax({call: 'messages', httpType: 'POST', do_auth: true, jsonData: jsonData, + success_callback: function(result) { + success_callback(result); + }, error_callback: function(code) { + error_callback("Failed to conect to data channel: " + code); + } + }); +} + +// success_callback(success/failure map, see second-to-last line), error_callback(error_msg) +function sendMessageToNumbers(numbers, message, success_callback, error_callback) { + var deviceObjectList = []; + for (var i = 0; i < numbers.length; i++) { + var devicesForNumber = getDeviceObjectListFromNumber(numbers[i]); + for (var j = 0; j < devicesForNumber.length; j++) + deviceObjectList[deviceObjectList.length] = devicesForNumber[j]; + } + return sendMessageToDevices(deviceObjectList, message, function(result) { + if (result.missingDeviceIds.length > 0) { + var responsesLeft = result.missingDeviceIds.length; + var errorThrown = 0; + for (var i = 0; i < result.missingDeviceIds.length; i++) { + getKeysForNumber(result.missingDeviceIds[i], function(identity_key) { + responsesLeft--; + if (responsesLeft == 0) + sendMessageToNumbers(numbers, message, success_callback, error_callback); + }, function(error_msg) { + errorThrown++; + if (errorThrown == 1) + error_callback("Failed to retreive new device keys for number " + result.missingDeviceIds[i]); + }); + } + } + + var successNumbers = {}; + var failureNumbers = {}; + for (var i = 0; i < result.success; i++) + successNumbers[getNumberFromString(result.success[i])] = 1; + for (var i = 0; i < result.failure; i++) + failureNumbers[getNumberFromString(result.success[i])] = 1; + + success_callback({success: successNumbers, failure: failureNumbers}); + }, error_callback); +} + + +function requestIdentityPrivKeyFromMasterDevice(number, identityKey) { + sendMessage(number, {message: "Identity Key request"}, function() {}, function() {});//TODO +} diff --git a/hmac-sha1.js b/hmac-sha1.js new file mode 100644 index 00000000..0d50d81a --- /dev/null +++ b/hmac-sha1.js @@ -0,0 +1,17 @@ +/* +CryptoJS v3.1.2 +code.google.com/p/crypto-js +(c) 2009-2013 by Jeff Mott. All rights reserved. +code.google.com/p/crypto-js/wiki/License +*/ +var CryptoJS=CryptoJS||function(g,l){var e={},d=e.lib={},m=function(){},k=d.Base={extend:function(a){m.prototype=this;var c=new m;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}}, +p=d.WordArray=k.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=l?c:4*a.length},toString:function(a){return(a||n).stringify(this)},concat:function(a){var c=this.words,q=a.words,f=this.sigBytes;a=a.sigBytes;this.clamp();if(f%4)for(var b=0;b>>2]|=(q[b>>>2]>>>24-8*(b%4)&255)<<24-8*((f+b)%4);else if(65535>>2]=q[b>>>2];else c.push.apply(c,q);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< +32-8*(c%4);a.length=g.ceil(c/4)},clone:function(){var a=k.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],b=0;b>>2]>>>24-8*(f%4)&255;b.push((d>>>4).toString(16));b.push((d&15).toString(16))}return b.join("")},parse:function(a){for(var c=a.length,b=[],f=0;f>>3]|=parseInt(a.substr(f, +2),16)<<24-4*(f%8);return new p.init(b,c/2)}},j=b.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var b=[],f=0;f>>2]>>>24-8*(f%4)&255));return b.join("")},parse:function(a){for(var c=a.length,b=[],f=0;f>>2]|=(a.charCodeAt(f)&255)<<24-8*(f%4);return new p.init(b,c)}},h=b.Utf8={stringify:function(a){try{return decodeURIComponent(escape(j.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return j.parse(unescape(encodeURIComponent(a)))}}, +r=d.BufferedBlockAlgorithm=k.extend({reset:function(){this._data=new p.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=h.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,b=c.words,f=c.sigBytes,d=this.blockSize,e=f/(4*d),e=a?g.ceil(e):g.max((e|0)-this._minBufferSize,0);a=e*d;f=g.min(4*a,f);if(a){for(var k=0;ka;a++){if(16>a)m[a]=d[e+a]|0;else{var c=m[a-3]^m[a-8]^m[a-14]^m[a-16];m[a]=c<<1|c>>>31}c=(n<<5|n>>>27)+l+m[a];c=20>a?c+((j&h|~j&g)+1518500249):40>a?c+((j^h^g)+1859775393):60>a?c+((j&h|j&g|h&g)-1894007588):c+((j^h^ +g)-899497514);l=g;g=h;h=j<<30|j>>>2;j=n;n=c}b[0]=b[0]+n|0;b[1]=b[1]+j|0;b[2]=b[2]+h|0;b[3]=b[3]+g|0;b[4]=b[4]+l|0},_doFinalize:function(){var d=this._data,e=d.words,b=8*this._nDataBytes,g=8*d.sigBytes;e[g>>>5]|=128<<24-g%32;e[(g+64>>>9<<4)+14]=Math.floor(b/4294967296);e[(g+64>>>9<<4)+15]=b;d.sigBytes=4*e.length;this._process();return this._hash},clone:function(){var e=d.clone.call(this);e._hash=this._hash.clone();return e}});g.SHA1=d._createHelper(l);g.HmacSHA1=d._createHmacHelper(l)})(); +(function(){var g=CryptoJS,l=g.enc.Utf8;g.algo.HMAC=g.lib.Base.extend({init:function(e,d){e=this._hasher=new e.init;"string"==typeof d&&(d=l.parse(d));var g=e.blockSize,k=4*g;d.sigBytes>k&&(d=e.finalize(d));d.clamp();for(var p=this._oKey=d.clone(),b=this._iKey=d.clone(),n=p.words,j=b.words,h=0;h>>2]|=(d[e>>>2]>>>24-8*(e%4)&255)<<24-8*((b+e)%4);else if(65535>>2]=d[e>>>2];else c.push.apply(c,d);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< +32-8*(c%4);a.length=h.ceil(c/4)},clone:function(){var a=m.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],d=0;d>>2]>>>24-8*(b%4)&255;d.push((e>>>4).toString(16));d.push((e&15).toString(16))}return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b>>3]|=parseInt(a.substr(b, +2),16)<<24-4*(b%8);return new r.init(d,c/2)}},n=l.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b>>2]>>>24-8*(b%4)&255));return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b>>2]|=(a.charCodeAt(b)&255)<<24-8*(b%4);return new r.init(d,c)}},j=l.Utf8={stringify:function(a){try{return decodeURIComponent(escape(n.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return n.parse(unescape(encodeURIComponent(a)))}}, +u=g.BufferedBlockAlgorithm=m.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=j.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,d=c.words,b=c.sigBytes,e=this.blockSize,f=b/(4*e),f=a?h.ceil(f):h.max((f|0)-this._minBufferSize,0);a=f*e;b=h.min(4*a,b);if(a){for(var g=0;gn;){var j;a:{j=k;for(var u=h.sqrt(j),t=2;t<=u;t++)if(!(j%t)){j=!1;break a}j=!0}j&&(8>n&&(m[n]=l(h.pow(k,0.5))),r[n]=l(h.pow(k,1/3)),n++);k++}var a=[],f=f.SHA256=q.extend({_doReset:function(){this._hash=new g.init(m.slice(0))},_doProcessBlock:function(c,d){for(var b=this._hash.words,e=b[0],f=b[1],g=b[2],j=b[3],h=b[4],m=b[5],n=b[6],q=b[7],p=0;64>p;p++){if(16>p)a[p]= +c[d+p]|0;else{var k=a[p-15],l=a[p-2];a[p]=((k<<25|k>>>7)^(k<<14|k>>>18)^k>>>3)+a[p-7]+((l<<15|l>>>17)^(l<<13|l>>>19)^l>>>10)+a[p-16]}k=q+((h<<26|h>>>6)^(h<<21|h>>>11)^(h<<7|h>>>25))+(h&m^~h&n)+r[p]+a[p];l=((e<<30|e>>>2)^(e<<19|e>>>13)^(e<<10|e>>>22))+(e&f^e&g^f&g);q=n;n=m;m=h;h=j+k|0;j=g;g=f;f=e;e=k+l|0}b[0]=b[0]+e|0;b[1]=b[1]+f|0;b[2]=b[2]+g|0;b[3]=b[3]+j|0;b[4]=b[4]+h|0;b[5]=b[5]+m|0;b[6]=b[6]+n|0;b[7]=b[7]+q|0},_doFinalize:function(){var a=this._data,d=a.words,b=8*this._nDataBytes,e=8*a.sigBytes; +d[e>>>5]|=128<<24-e%32;d[(e+64>>>9<<4)+14]=h.floor(b/4294967296);d[(e+64>>>9<<4)+15]=b;a.sigBytes=4*d.length;this._process();return this._hash},clone:function(){var a=q.clone.call(this);a._hash=this._hash.clone();return a}});s.SHA256=q._createHelper(f);s.HmacSHA256=q._createHmacHelper(f)})(Math); +(function(){var h=CryptoJS,s=h.enc.Utf8;h.algo.HMAC=h.lib.Base.extend({init:function(f,g){f=this._hasher=new f.init;"string"==typeof g&&(g=s.parse(g));var h=f.blockSize,m=4*h;g.sigBytes>m&&(g=f.finalize(g));g.clamp();for(var r=this._oKey=g.clone(),l=this._iKey=g.clone(),k=r.words,n=l.words,j=0;j + * If request is currently opened, this one will be closed. + * + * @param {Object} Request parameters. + * @private + */ + function _subscribe(options) { + _reinit(); + + _request = jQuery.extend(_request, options); + // Allow at least 1 request + _request.mrequest = _request.reconnect; + if (!_request.reconnect) { + _request.reconnect = true; + } + } + + /** + * Check if web socket is supported (check for custom implementation provided by request object or browser implementation). + * + * @returns {boolean} True if web socket is supported, false otherwise. + * @private + */ + function _supportWebsocket() { + return _request.webSocketImpl != null || window.WebSocket || window.MozWebSocket; + } + + /** + * Check if server side events (SSE) is supported (check for custom implementation provided by request object or browser implementation). + * + * @returns {boolean} True if web socket is supported, false otherwise. + * @private + */ + function _supportSSE() { + return window.EventSource; + } + + /** + * Open request using request transport.
+ * If request transport is 'websocket' but websocket can't be opened, request will automatically reconnect using fallback transport. + * + * @private + */ + function _execute() { + // Shared across multiple tabs/windows. + if (_request.shared) { + _localStorageService = _local(_request); + if (_localStorageService != null) { + if (_request.logLevel === 'debug') { + jQuery.atmosphere.debug("Storage service available. All communication will be local"); + } + + if (_localStorageService.open(_request)) { + // Local connection. + return; + } + } + + if (_request.logLevel === 'debug') { + jQuery.atmosphere.debug("No Storage service available."); + } + // Wasn't local or an error occurred + _localStorageService = null; + } + + // Protocol + _request.firstMessage = jQuery.atmosphere.uuid == 0 ? true : false; + _request.isOpen = false; + _request.ctime = jQuery.now(); + _request.uuid = jQuery.atmosphere.uuid; + _request.closedByClientTimeout = false; + + if (_request.transport !== 'websocket' && _request.transport !== 'sse') { + _executeRequest(_request); + + } else if (_request.transport === 'websocket') { + if (!_supportWebsocket()) { + _reconnectWithFallbackTransport("Websocket is not supported, using request.fallbackTransport (" + _request.fallbackTransport + + ")"); + } else { + _executeWebSocket(false); + } + } else if (_request.transport === 'sse') { + if (!_supportSSE()) { + _reconnectWithFallbackTransport("Server Side Events(SSE) is not supported, using request.fallbackTransport (" + + _request.fallbackTransport + ")"); + } else { + _executeSSE(false); + } + } + } + + function _local(request) { + var trace, connector, orphan, name = "atmosphere-" + request.url, connectors = { + storage: function () { + if (!jQuery.atmosphere.supportStorage()) { + return; + } + + var storage = window.localStorage, get = function (key) { + return jQuery.parseJSON(storage.getItem(name + "-" + key)); + }, set = function (key, value) { + storage.setItem(name + "-" + key, jQuery.stringifyJSON(value)); + }; + + return { + init: function () { + set("children", get("children").concat([guid])); + jQuery(window).on("storage.socket", function (event) { + event = event.originalEvent; + if (event.key === name && event.newValue) { + listener(event.newValue); + } + }); + return get("opened"); + }, + signal: function (type, data) { + storage.setItem(name, jQuery.stringifyJSON({ + target: "p", + type: type, + data: data + })); + }, + close: function () { + var index, children = get("children"); + + jQuery(window).off("storage.socket"); + if (children) { + index = jQuery.inArray(request.id, children); + if (index > -1) { + children.splice(index, 1); + set("children", children); + } + } + } + }; + }, + windowref: function () { + var win = window.open("", name.replace(/\W/g, "")); + + if (!win || win.closed || !win.callbacks) { + return; + } + + return { + init: function () { + win.callbacks.push(listener); + win.children.push(guid); + return win.opened; + }, + signal: function (type, data) { + if (!win.closed && win.fire) { + win.fire(jQuery.stringifyJSON({ + target: "p", + type: type, + data: data + })); + } + }, + close: function () { + function remove(array, e) { + var index = jQuery.inArray(e, array); + if (index > -1) { + array.splice(index, 1); + } + } + + // Removes traces only if the parent is alive + if (!orphan) { + remove(win.callbacks, listener); + remove(win.children, guid); + } + } + + }; + } + }; + + // Receives open, close and message command from the parent + function listener(string) { + var command = jQuery.parseJSON(string), data = command.data; + + if (command.target === "c") { + switch (command.type) { + case "open": + _open("opening", 'local', _request); + break; + case "close": + if (!orphan) { + orphan = true; + if (data.reason === "aborted") { + _close(); + } else { + // Gives the heir some time to reconnect + if (data.heir === guid) { + _execute(); + } else { + setTimeout(function () { + _execute(); + }, 100); + } + } + } + break; + case "message": + _prepareCallback(data, "messageReceived", 200, request.transport); + break; + case "localMessage": + _localMessage(data); + break; + } + } + } + + function findTrace() { + var matcher = new RegExp("(?:^|; )(" + encodeURIComponent(name) + ")=([^;]*)").exec(document.cookie); + if (matcher) { + return jQuery.parseJSON(decodeURIComponent(matcher[2])); + } + } + + // Finds and validates the parent socket's trace from the cookie + trace = findTrace(); + if (!trace || jQuery.now() - trace.ts > 1000) { + return; + } + + // Chooses a connector + connector = connectors.storage() || connectors.windowref(); + if (!connector) { + return; + } + + return { + open: function () { + var parentOpened; + + // Checks the shared one is alive + _traceTimer = setInterval(function () { + var oldTrace = trace; + trace = findTrace(); + if (!trace || oldTrace.ts === trace.ts) { + // Simulates a close signal + listener(jQuery.stringifyJSON({ + target: "c", + type: "close", + data: { + reason: "error", + heir: oldTrace.heir + } + })); + } + }, 1000); + + parentOpened = connector.init(); + if (parentOpened) { + // Firing the open event without delay robs the user of the opportunity to bind connecting event handlers + setTimeout(function () { + _open("opening", 'local', request); + }, 50); + } + return parentOpened; + }, + send: function (event) { + connector.signal("send", event); + }, + localSend: function (event) { + connector.signal("localSend", jQuery.stringifyJSON({ + id: guid, + event: event + })); + }, + close: function () { + // Do not signal the parent if this method is executed by the unload event handler + if (!_abordingConnection) { + clearInterval(_traceTimer); + connector.signal("close"); + connector.close(); + } + } + }; + } + + function share() { + var storageService, name = "atmosphere-" + _request.url, servers = { + // Powered by the storage event and the localStorage + // http://www.w3.org/TR/webstorage/#event-storage + storage: function () { + if (!jQuery.atmosphere.supportStorage()) { + return; + } + + var storage = window.localStorage; + + return { + init: function () { + // Handles the storage event + jQuery(window).on("storage.socket", function (event) { + event = event.originalEvent; + // When a deletion, newValue initialized to null + if (event.key === name && event.newValue) { + listener(event.newValue); + } + }); + }, + signal: function (type, data) { + storage.setItem(name, jQuery.stringifyJSON({ + target: "c", + type: type, + data: data + })); + }, + get: function (key) { + return jQuery.parseJSON(storage.getItem(name + "-" + key)); + }, + set: function (key, value) { + storage.setItem(name + "-" + key, jQuery.stringifyJSON(value)); + }, + close: function () { + jQuery(window).off("storage.socket"); + storage.removeItem(name); + storage.removeItem(name + "-opened"); + storage.removeItem(name + "-children"); + } + + }; + }, + // Powered by the window.open method + // https://developer.mozilla.org/en/DOM/window.open + windowref: function () { + // Internet Explorer raises an invalid argument error + // when calling the window.open method with the name containing non-word characters + var neim = name.replace(/\W/g, ""), win = (jQuery('iframe[name="' + neim + '"]')[0] || jQuery( + '