diff --git a/lib/js/index.html b/lib/js/index.html index 02a861a00ad22efff54ab4ef26bd6a435ee49d46..0f15e96e5a20fb915b2465576944b7ef6d30fda3 100644 --- a/lib/js/index.html +++ b/lib/js/index.html @@ -3,10 +3,25 @@ <head> <meta charset="utf-8"> <title>title</title> - <link rel="stylesheet" href="style.css"> <script src="lc.js"></script> </head> <body> <!-- page content --> + <script> + var oReq = new XMLHttpRequest(); + oReq.open("GET", "http://fair-2014-4.lab1.cs.lth.se:8080/logdata/clamping/experiments/bc4b3d5e-509a-40d1-81ec-1799c2ee167b/data", true); + oReq.responseType = "arraybuffer"; + + oReq.onload = function (oEvent) { + var arrayBuffer = oReq.response; // Note: not oReq.responseText + if (arrayBuffer) { + var buff = new LabComm.Buffer(new DataView(arrayBuffer)); + console.log(buff); + new LabComm.Parser(buff); + } + }; + + oReq.send(null); + </script> </body> </html> diff --git a/lib/js/lc.js b/lib/js/lc.js index 41b3a19f6542cabc4ef196ad8763e11b922b118a..8a411a2274d32118c7f511aa1ebbbd18e8e045b6 100644 --- a/lib/js/lc.js +++ b/lib/js/lc.js @@ -1,45 +1,165 @@ 'use strict'; -function LabComm() { - var samples = {}; +var LabComm = LabComm || {}; -} -function LcSample(buffer) { - - this.varint = function() { - var nextByte, result = 0, bytesRead = 0; - do { - nextByte = this._data.getUint8(offset+bytesRead); - result += (nextByte & 0x7F) << (7 * bytesRead); - bytesRead++; - } while (nextByte >= 0x80) - offset += bytesRead; - return result; - } - this.str = function() { - var l = this.varint(); - var ret = String.fromCharCode.apply(null, new Uint8Array(this._buffer, offset, l)); - offset += l; - return ret; +/** + * Constants used during parsing + * @enum {number} + */ +LabComm.Constants = { + VERSION: 0x01, + SAMPLE_DEF: 0x02, + SAMPLE_REF: 0x03, + TYPE_DEF: 0x04, + TYPE_BINDING: 0x05, + PRAGMA: 0x3f, + ARRAY: 0x10, + STRUCT: 0x11, + BOOLEAN: 0x20, + BYTE: 0x21, + SHORT: 0x22, + INT: 0x23, + LONG: 0x24, + FLOAT: 0x25, + DOUBLE: 0x26, + STRING: 0x27 +}; + +/** + * A buffer objects that supports all labcomm types + * @constructor + * @param {DataView} dataView An underlying dataview to work on + * @param {number=} offset An initial offset, defaults to 0 + */ +LabComm.Buffer = function (dataView, offset) { + this.offset = offset || 0; + this.data = dataView; +}; + +/** + * Reads a var-int from the buffer. + * @return {number} An integer + */ +LabComm.Buffer.prototype.getVarint = function() { + var nextByte, result = 0, bytesRead = 0; + do { + nextByte = this.data.getUint8(this.offset+bytesRead); + result += (nextByte & 0x7F) << (7 * bytesRead); + bytesRead++; + } while (nextByte >= 0x80) + this.offset += bytesRead; + return result; +}; + +/** + * Reads a string from the buffer. + * @return {string} A string + */ +LabComm.Buffer.prototype.getString = function() { + var len = this.getVarint(); + var chars = new Uint8Array(len); + for(var i = 0; i < len; i++) { + chars[i] = this.data.getUint8(this.offset + i); } - var consts = { - VERSION: 0x01, - SAMPLE_DEF: 0x02, - SAMPLE_REF: 0x03, - TYPE_DEF: 0x04, - TYPE_BINDING: 0x05, - PRAGMA: 0x3f, - ARRAY: 0x10, - STRUCT: 0x11, - BOOLEAN: 0x20, - BYTE: 0x21, - SHORT: 0x22, - INT: 0x23, - LONG: 0x24, - FLOAT: 0x25, - DOUBLE: 0x26, - STRING: 0x27 - }; + var str = String.fromCharCode.apply(null, chars); + this.offset += len; + return str; +}; + +/** + * Reads a boolean (8-bits) from the buffer. + * @return {Boolean} A boolean + */ +LabComm.Buffer.prototype.getBoolean = function() { + return new Boolean(this.data.getUint8(this.offset++)); +}; + +/** + * Reads a byte (8-bits) from the buffer. + * @return {number} A byte + */ +LabComm.Buffer.prototype.getByte = function() { + return this.data.getUint8(this.offset++); +}; + +/** + * Reads a short (16-bits) from the buffer. + * @return {number} A short + */ +LabComm.Buffer.prototype.getShort = function() { + var s = this.data.getInt16(this.offset); + this.offset += 2; + return s; +}; + +/** + * Reads an interger (32-bits) from the buffer. + * @return {number} An integer + */ +LabComm.Buffer.prototype.getInt = function() { + var s = this.data.getInt32(this.offset); + this.offset += 4; + return s; +}; + +/** + * Reads a long (64-bits) from the buffer, note that JavaScript only has + * doubles internaly so if the long requires more than 53-bits the number + * will fall over to +/- Infinity. + * @return {number} A long + */ +LabComm.Buffer.prototype.getLong = function() { + var low = this.data.getInt32(this.offset + 4); + var n = this.data.getInt32(this.offset) * 0x100000000 + low; + if (low < 0) n += 0x100000000; + this.offset += 8; + return n; +}; + +/** + * Reads a float (32-bits) from the buffer. + * @return {number} A float + */ +LabComm.Buffer.prototype.getFloat = function() { + var s = this.data.getFloat32(this.offset); + this.offset += 4; + return s; +}; + +/** + * Reads a double (64-bits) from the buffer. + * @return {number} A double + */ +LabComm.Buffer.prototype.getDouble = function() { + var s = this.data.getFloat64(this.offset); + this.offset += 8; + return s; +}; + +/** + * Skip a number of bytes + * @param {number} length The number of bytes to skip + */ +LabComm.Buffer.prototype.skip = function(length) { + this.offset += len; +}; + + + + + + + +/** + * A + * @constructor + * @param {LabComm.Buffer} A buffer to parse from + */ +LabComm.Parser = function(buffer) { + this.data = buffer; + + + var _uid = 1; function uid() {return this._uid++}; @@ -50,19 +170,19 @@ function LcSample(buffer) { return '"'+name+'":'+'"'+type+'"'; } this.sig = function(name, json, fb) { - var type = this.varint(); + var type = this.data.getVarint(); switch(type) { - case consts.ARRAY: + case LabComm.Constants.ARRAY: console.log("array"); //TODO: implement break; - case consts.STRUCT: + case LabComm.Constants.STRUCT: var func = []; func.push('"'+name+'":{'); json.push('"'+name+'":{'); - var fields = this.varint(); + var fields = this.data.getVarint(); while(fields--) { - var fn = this.str(); + var fn = this.data.getString(); func.push(this.sig(fn, json, fb)); if(fields!=0) { json.push(','); @@ -72,61 +192,49 @@ function LcSample(buffer) { func.push("}"); json.push("}"); return func.join(''); - case consts.BOOLEAN: - return buildParser(name, json, fb, "bool", "new Boolean(data.getUint8(offset++))"); - case consts.BYTE: - return buildParser(name, json, fb, "byte", "data.getUint8(offset++)"); - case consts.SHORT: - return buildParser(name, json, fb, "short", "data.getInt16(offset);offset+=2"); - case consts.INT: - return buildParser(name, json, fb, "int", "data.getInt32(offset);offset+=4"); - case consts.LONG: //TODO: 2-complement? - return buildParser(name, json, fb, "long", "data.getInt32(offset)<<32 + data.getInt32(offset+4);offset+=8"); - case consts.FLOAT: - return buildParser(name, json, fb, "float", "data.getFloat32(offset);offset+=4"); - case consts.DOUBLE: - return buildParser(name, json, fb, "double", "data.getFloat64(offset);offset+=8"); - case consts.STRING: //TODO: read varint - var nextByte, result = 0, bytesRead = 0 - do { - nextByte = data.getUint8(offset+bytesRead); - result += (nextByte & 0x7F) << (7 * bytesRead); - bytesRead++; - } while (nextByte >= 0x80) - offset += bytesRead; - - return '"'+name+'":'+'"string"'; + case LabComm.Constants.BOOLEAN: + return buildParser(name, json, fb, "bool", "data.getBoolean()"); + case LabComm.Constants.BYTE: + return buildParser(name, json, fb, "byte", "data.getByte()"); + case LabComm.Constants.SHORT: + return buildParser(name, json, fb, "short", "data.getShort()"); + case LabComm.Constants.INT: + return buildParser(name, json, fb, "int", "data.getInt()"); + case LabComm.Constants.LONG: + return buildParser(name, json, fb, "long", "data.getLong()"); + case LabComm.Constants.FLOAT: + return buildParser(name, json, fb, "float", "data.getFloat()"); + case LabComm.Constants.DOUBLE: + return buildParser(name, json, fb, "double", "data.getDouble()"); + case LabComm.Constants.STRING: + return buildParser(name, json, fb, "string", "data.getString()"); } } this._defs = {}; - var offset = 0; - this._buffer = buffer; - this._data = new DataView(buffer); - for(var i = 1; i < 5; i ++) { - var tag = this.varint(); - var len = this.varint(); + for(var i = 1; i < 6; i ++) { + var tag = this.data.getVarint(); + var len = this.data.getVarint(); console.log("tag: 0x" + tag.toString(16)); console.log("len: 0x" + len.toString(16)); switch(tag) { - case consts.VERSION: - var version = this.str(); + case LabComm.Constants.VERSION: + var version = this.data.getString(); console.log("LabComm version package: " + version); break; - case consts.SAMPLE_DEF: - var index = this.varint(); - var name = this.str(); - var siglen = this.varint(); + case LabComm.Constants.SAMPLE_DEF: + var index = this.data.getVarint(); + var name = this.data.getString(); + var siglen = this.data.getVarint(); console.log("sample def: 0x" + index.toString(16) + ":" + name + ", size: 0x" + siglen.toString(16)); - var pre = "\tvar offset=0;\n\t"; var json = [], fb = []; var struct = JSON.parse('{' + this.sig(name, json, fb) + "}"); - var func = pre + fb.join(';\n\t') + ';\n\treturn {' + json.join('') + '}'; + var func = fb.join(';\n\t') + ';\n\treturn {' + json.join('') + '}'; this._defs[index] = { index: index, name: name, @@ -134,24 +242,25 @@ function LcSample(buffer) { decoder: new Function('data', func) }; break; - case consts.SAMPLE_REF: - case consts.TYPE_DEF: - case consts.TYPE_BINDING: - case consts.PRAGMA: - offset += len; //TODO: standard not stable + case LabComm.Constants.SAMPLE_REF: + case LabComm.Constants.TYPE_DEF: + case LabComm.Constants.TYPE_BINDING: + case LabComm.Constants.PRAGMA: + this.data.skip(len); console.log("skipping unhandled package of size " + len); break; default: var s = this._defs[tag]; var decoder = s.decoder; - + var sample = decoder(this.data); console.log("sample name: " + s.name); - + console.log(decoder); + + console.log(sample); break; } } } -var test = (new Uint8Array([0x01, 0x0C, 0x0B, 0x4C, 0x61, 0x62, 0x43, 0x6F, 0x6D, 0x6D, 0x32, 0x30, 0x31, 0x34, 0x02, 0x64, 0x40, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5B, 0x11, 0x03, 0x0B, 0x6F, 0x72, 0x69, 0x65, 0x6E, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x11, 0x04, 0x02, 0x71, 0x31, 0x25, 0x02, 0x71, 0x32, 0x25, 0x02, 0x71, 0x33, 0x25, 0x02, 0x71, 0x34, 0x25, 0x0B, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x11, 0x03, 0x01, 0x78, 0x25, 0x01, 0x79, 0x25, 0x01, 0x7A, 0x25, 0x0D, 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x11, 0x04, 0x03, 0x63, 0x66, 0x31, 0x22, 0x03, 0x63, 0x66, 0x34, 0x22, 0x03, 0x63, 0x66, 0x36, 0x22, 0x03, 0x63, 0x66, 0x78, 0x22, 0x02, 0x47, 0x41, 0x09, 0x6D, 0x65, 0x74, 0x61, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x3B, 0x11, 0x07, 0x01, 0x78, 0x25, 0x01, 0x79, 0x25, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x03, 0x67, 0x61, 0x70, 0x25, 0x08, 0x6D, 0x69, 0x73, 0x6D, 0x61, 0x74, 0x63, 0x68, 0x25, 0x0C, 0x73, 0x68, 0x65, 0x65, 0x74, 0x31, 0x5F, 0x61, 0x6E, 0x67, 0x6C, 0x65, 0x25, 0x0C, 0x73, 0x68, 0x65, 0x65, 0x74, 0x32, 0x5F, 0x61, 0x6E, 0x67, 0x6C, 0x65, 0x25, 0x40, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x41, 0x00, 0x1C, 0x95, 0x40, 0xE7, 0xA9, 0x18, 0x00, 0x00, 0x3F, 0xEC, 0xCF, 0x74, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xD7, 0x04, 0x5F, 0x3F, 0xA5, 0xE6, 0xBE, 0x41, 0x1A, 0x40, 0xD9, 0x8C, 0x27, 0x40, 0xEF, 0x53, 0xA1, 0x00, 0x00, 0x40, 0x01, 0x3C, 0x64, 0x00, 0x00, 0x00, 0x00, 0xBB, 0x77, 0x21, 0xA3, 0x3F, 0x76, 0xF5, 0x4D, 0x41, 0x1A, 0x40, 0xCE, 0x9B, 0x89, 0x40, 0xF1, 0xC8, 0x4B, 0x00, 0x00, 0x3F, 0xFC, 0x36, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xBD, 0xF1, 0xB9, 0xF7, 0x3F, 0xDB, 0x79, 0xED, 0x41, 0x1A, 0x40, 0xC7, 0x6B, 0xC4, 0x40, 0xF3, 0x3F, 0xFA, 0x00, 0x00, 0x3F, 0xFF, 0x8B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x17, 0x42, 0x11, 0x3F, 0x65, 0x5C, 0xC5, 0x41, 0x1A, 0x40, 0xB4, 0x55, 0xD6, 0x40, 0xF6, 0x99, 0xAA, 0x00, 0x00, 0x40, 0x05, 0x5D, 0x86, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x7D, 0xFE, 0x51, 0x3F, 0x4F, 0x31, 0xD5, 0x41, 0x1A, 0x40, 0x92, 0x45, 0x8E, 0x40, 0xFC, 0x6D, 0x59, 0x00, 0x00, 0x40, 0x02, 0x84, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xAC, 0x7E, 0xCB, 0x3E, 0x58, 0xD4, 0x68, 0x41, 0x1A, 0x40, 0x5D, 0x9B, 0xD6, 0x41, 0x01, 0x9C, 0x60, 0x00, 0x00, 0x40, 0x08, 0x58, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xA2, 0x0F, 0x77, 0xBD, 0x19, 0x68, 0x9E, 0x41, 0x1A, 0x40, 0x23, 0x2B, 0xD5, 0x41, 0x04, 0x37, 0xE9, 0x00, 0x00, 0x40, 0x01, 0xC3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xDC, 0x35, 0x79, 0xBE, 0x50, 0xDC, 0xE6, 0x41, 0x1A, 0x40, 0x0B, 0x0A, 0xA2, 0x41, 0x05, 0x4E, 0xDA, 0x00, 0x00, 0x40, 0x05, 0x65, 0x9B, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFB, 0xF1, 0x6D, 0x3B, 0xE9, 0x06, 0xD6, 0x41, 0x1A, 0x40, 0x07, 0x94, 0x6C, 0x41, 0x05, 0x5C, 0xA4, 0x00, 0x00, 0x40, 0x01, 0xF2, 0x78, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xE3, 0x06, 0x9C, 0x3D, 0xE3, 0xBF, 0xA0, 0x41, 0x1A, 0x40, 0x0B, 0xE9, 0x38, 0x41, 0x05, 0x57, 0x39, 0x00, 0x00, 0x40, 0x07, 0x1E, 0x48, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xEB, 0x3D, 0xBC, 0xBC, 0xAA, 0x00, 0x86, 0x41, 0x1A, 0x40, 0x1E, 0x0A, 0x28, 0x41, 0x04, 0xB8, 0xFE, 0x00, 0x00, 0x40, 0x08, 0xBB, 0x09, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0x5D, 0xAF, 0x3F, 0x04, 0x07, 0xD4, 0x41, 0x1A, 0x40, 0x77, 0x99, 0xF4, 0x41, 0x01, 0xCA, 0x95, 0x00, 0x00, 0x40, 0x0B, 0x99, 0x51, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x21, 0xDA, 0xE5, 0x3F, 0xDA, 0xB7, 0x2E, 0x41, 0x1A, 0x40, 0xB2, 0x8F, 0x34, 0x40, 0xFB, 0x82, 0xE3, 0x00, 0x00, 0x40, 0x0E, 0x0C, 0xBE, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x67, 0xC9, 0x24, 0x3F, 0xD4, 0xAA, 0xD7, 0x41, 0x1A, 0x40, 0xD3, 0xB7, 0x84, 0x40, 0xF5, 0xFC, 0x5C, 0x00, 0x00, 0x40, 0x06, 0xC3, 0x1A, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x40, 0x4F, 0x42, 0x40, 0x10, 0x5A, 0x8E, 0x41, 0x1A, 0x40, 0xDD, 0x0E, 0x58, 0x40, 0xF4, 0x96, 0x9A, 0x00, 0x00, 0x40, 0x03, 0x25, 0x3A, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x0E, 0x3A, 0x29, 0x40, 0x02, 0xCD, 0xB4, 0x41, 0x1A, 0x40, 0xDE, 0xC0, 0x7E, 0x40, 0xF4, 0x66, 0x32, 0x00, 0x00, 0x40, 0x06, 0x63, 0x8E, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x3C, 0x95, 0x21, 0x3F, 0xCE, 0x07, 0xE9, 0x41, 0x1A, 0x40, 0xE2, 0xF4, 0xD0, 0x40, 0xF3, 0x5F, 0x06, 0x00, 0x00, 0x40, 0x02, 0xE1, 0x76, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x1D, 0x14, 0xE7, 0x3F, 0xE0, 0x78, 0x25, 0x41, 0x1A, 0x40, 0xED, 0x8C, 0x76, 0x40, 0xF1, 0xC8, 0x46, 0x00, 0x00, 0x40, 0x01, 0x03, 0x1A, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x47, 0x46, 0xE1, 0x40, 0x1B, 0x78, 0x7B, 0x41, 0x1A, 0x41, 0x01, 0xBE, 0x19, 0x40, 0xEE, 0x03, 0x90, 0x00, 0x00, 0x40, 0x04, 0x2A, 0x52, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xD2, 0xCE, 0xF2, 0x40, 0x48, 0x6F, 0xF3, 0x41, 0x1A, 0x41, 0x12, 0x4F, 0x9A, 0x40, 0xE7, 0xDB, 0xB7, 0x00, 0x00, 0x40, 0x08, 0x75, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xF9, 0x39, 0x6D, 0x40, 0x4B, 0x08, 0xA7, 0x41, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1A, 0x00, 0x00])).buffer;