diff --git a/evopedia-html5/.project b/evopedia-html5/.project new file mode 100644 index 00000000..a6991aae --- /dev/null +++ b/evopedia-html5/.project @@ -0,0 +1,29 @@ + + + evopedia-html5 + + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.wst.jsdt.core.jsNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + + diff --git a/evopedia-html5/.settings/.jsdtscope b/evopedia-html5/.settings/.jsdtscope new file mode 100644 index 00000000..3a28de0c --- /dev/null +++ b/evopedia-html5/.settings/.jsdtscope @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/evopedia-html5/.settings/org.eclipse.wst.common.component b/evopedia-html5/.settings/org.eclipse.wst.common.component new file mode 100644 index 00000000..df6076df --- /dev/null +++ b/evopedia-html5/.settings/org.eclipse.wst.common.component @@ -0,0 +1,6 @@ + + + + + + diff --git a/evopedia-html5/.settings/org.eclipse.wst.common.project.facet.core.xml b/evopedia-html5/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 00000000..15639c42 --- /dev/null +++ b/evopedia-html5/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/evopedia-html5/.settings/org.eclipse.wst.jsdt.ui.superType.container b/evopedia-html5/.settings/org.eclipse.wst.jsdt.ui.superType.container new file mode 100644 index 00000000..3bd5d0a4 --- /dev/null +++ b/evopedia-html5/.settings/org.eclipse.wst.jsdt.ui.superType.container @@ -0,0 +1 @@ +org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/evopedia-html5/.settings/org.eclipse.wst.jsdt.ui.superType.name b/evopedia-html5/.settings/org.eclipse.wst.jsdt.ui.superType.name new file mode 100644 index 00000000..05bd71b6 --- /dev/null +++ b/evopedia-html5/.settings/org.eclipse.wst.jsdt.ui.superType.name @@ -0,0 +1 @@ +Window \ No newline at end of file diff --git a/evopedia-html5/WebContent/bzip2-antimatter15.js b/evopedia-html5/WebContent/bzip2-antimatter15.js new file mode 100644 index 00000000..1d90aa56 --- /dev/null +++ b/evopedia-html5/WebContent/bzip2-antimatter15.js @@ -0,0 +1,250 @@ +/* + bzip2.js - a small bzip2 decompression implementation + + Copyright 2011 by antimatter15 (antimatter15@gmail.com) + + Based on micro-bunzip by Rob Landley (rob@landley.net). + + Based on bzip2 decompression code by Julian R Seward (jseward@acm.org), + which also acknowledges contributions by Mike Burrows, David Wheeler, + Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten, + Robert Sedgewick, and Jon L. Bentley. + + I hereby release this code under the GNU Library General Public License + (LGPL) version 2, available at http://www.gnu.org/copyleft/lgpl.html +*/ + +var bzip2 = {}; + +bzip2.array = function(bytes){ + var bit = 0, byte = 0; + var BITMASK = [0, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF ]; + return function(n){ + var result = 0; + while(n > 0){ + var left = 8 - bit; + if(n >= left){ + result <<= left; + result |= (BITMASK[left] & bytes[byte++]); + bit = 0; + n -= left; + }else{ + result <<= n; + result |= ((bytes[byte] & (BITMASK[n] << (8 - n - bit))) >> (8 - n - bit)); + bit += n; + n = 0; + } + } + return result + } +} + +bzip2.simple = function(bits){ + var size = bzip2.header(bits); + var all = '', chunk = ''; + do{ + all += chunk; + chunk = bzip2.decompress(bits, size); + }while(chunk != -1); + return all; +} + +bzip2.header = function(bits){ + if(bits(8*3) != 4348520) throw "No magic number found"; + var i = bits(8) - 48; + if(i < 1 || i > 9) throw "Not a BZIP archive"; + return i; +}; + + +//takes a function for reading the block data (starting with 0x314159265359) +//a block size (0-9) (optional, defaults to 9) +//a length at which to stop decompressing and return the output +bzip2.decompress = function(bits, size, len){ + var MAX_HUFCODE_BITS = 20; + var MAX_SYMBOLS = 258; + var SYMBOL_RUNA = 0; + var SYMBOL_RUNB = 1; + var GROUP_SIZE = 50; + + var bufsize = 100000 * size; + for(var h = '', i = 0; i < 6; i++) h += bits(8).toString(16); + if(h == "177245385090") return -1; //last block + if(h != "314159265359") throw "eek not valid bzip data"; + bits(32); //ignore CRC codes + if(bits(1)) throw "unsupported obsolete version"; + var origPtr = bits(24); + if(origPtr > bufsize) throw "Initial position larger than buffer size"; + var t = bits(16); + var symToByte = new Uint8Array(256), + symTotal = 0; + for (i = 0; i < 16; i++) { + if(t & (1 << (15 - i))) { + var k = bits(16); + for(j = 0; j < 16; j++){ + if(k & (1 << (15 - j))){ + symToByte[symTotal++] = (16 * i) + j; + } + } + } + } + + var groupCount = bits(3); + if(groupCount < 2 || groupCount > 6) throw "another error"; + var nSelectors = bits(15); + if(nSelectors == 0) throw "meh"; + var mtfSymbol = []; //TODO: possibly replace JS array with typed arrays + for(var i = 0; i < groupCount; i++) mtfSymbol[i] = i; + var selectors = new Uint8Array(32768); + + for(var i = 0; i < nSelectors; i++){ + for(var j = 0; bits(1); j++) if(j >= groupCount) throw "whoops another error"; + var uc = mtfSymbol[j]; + mtfSymbol.splice(j, 1); //this is a probably inefficient MTF transform + mtfSymbol.splice(0, 0, uc); + selectors[i] = uc; + } + + var symCount = symTotal + 2; + var groups = []; + for(var j = 0; j < groupCount; j++){ + var length = new Uint8Array(MAX_SYMBOLS), + temp = new Uint8Array(MAX_HUFCODE_BITS+1); + t = bits(5); //lengths + for(var i = 0; i < symCount; i++){ + while(true){ + if (t < 1 || t > MAX_HUFCODE_BITS) throw "I gave up a while ago on writing error messages"; + if(!bits(1)) break; + if(!bits(1)) t++; + else t--; + } + length[i] = t; + } + var minLen, maxLen; + minLen = maxLen = length[0]; + for(var i = 1; i < symCount; i++){ + if(length[i] > maxLen) maxLen = length[i]; + else if(length[i] < minLen) minLen = length[i]; + } + var hufGroup; + hufGroup = groups[j] = {}; + hufGroup.permute = new Uint32Array(MAX_SYMBOLS); + hufGroup.limit = new Uint32Array(MAX_HUFCODE_BITS + 1); + hufGroup.base = new Uint32Array(MAX_HUFCODE_BITS + 1); + hufGroup.minLen = minLen; + hufGroup.maxLen = maxLen; + var base = hufGroup.base.subarray(1); + var limit = hufGroup.limit.subarray(1); + var pp = 0; + for(var i = minLen; i <= maxLen; i++) + for(var t = 0; t < symCount; t++) + if(length[t] == i) hufGroup.permute[pp++] = t; + for(i = minLen; i <= maxLen; i++) temp[i] = limit[i] = 0; + for(i = 0; i < symCount; i++) temp[length[i]]++; + pp = t = 0; + for(i = minLen; i < maxLen; i++) { + pp += temp[i]; + limit[i] = pp - 1; + pp <<= 1; + base[i+1] = pp - (t += temp[i]); + } + limit[maxLen]=pp+temp[maxLen]-1; + base[minLen]=0; + } + var byteCount = new Uint32Array(256); + for(var i = 0; i < 256; i++) mtfSymbol[i] = i; + var runPos, count, symCount, selector; + runPos = count = symCount = selector = 0; + var buf = new Uint32Array(bufsize); + while(true){ + if(!(symCount--)){ + symCount = GROUP_SIZE - 1; + if(selector >= nSelectors) throw "meow i'm a kitty, that's an error"; + hufGroup = groups[selectors[selector++]]; + base = hufGroup.base.subarray(1); + limit = hufGroup.limit.subarray(1); + } + i = hufGroup.minLen; + j = bits(i); + while(true){ + if(i > hufGroup.maxLen) throw "rawr i'm a dinosaur"; + if(j <= limit[i]) break; + i++; + j = (j << 1) | bits(1); + } + j -= base[i]; + if(j < 0 || j >= MAX_SYMBOLS) throw "moo i'm a cow"; + var nextSym = hufGroup.permute[j]; + if (nextSym == SYMBOL_RUNA || nextSym == SYMBOL_RUNB) { + if(!runPos){ + runPos = 1; + t = 0; + } + if(nextSym == SYMBOL_RUNA) t += runPos; + else t += 2 * runPos; + runPos <<= 1; + continue; + } + if(runPos){ + runPos = 0; + if(count + t >= bufsize) throw "Boom."; + uc = symToByte[mtfSymbol[0]]; + byteCount[uc] += t; + while(t--) buf[count++] = uc; + } + if(nextSym > symTotal) break; + if(count >= bufsize) throw "I can't think of anything. Error"; + i = nextSym -1; + uc = mtfSymbol[i]; + mtfSymbol.splice(i, 1); + mtfSymbol.splice(0, 0, uc); + uc = symToByte[uc]; + byteCount[uc]++; + buf[count++] = uc; + } + if(origPtr < 0 || origPtr >= count) throw "I'm a monkey and I'm throwing something at someone, namely you"; + var j = 0; + for(var i = 0; i < 256; i++){ + k = j + byteCount[i]; + byteCount[i] = j; + j = k; + } + for(var i = 0; i < count; i++){ + uc = buf[i] & 0xff; + buf[byteCount[uc]] |= (i << 8); + byteCount[uc]++; + } + var pos = 0, current = 0, run = 0; + if(count) { + pos = buf[origPtr]; + current = (pos & 0xff); + pos >>= 8; + run = -1; + } + count = count; + var output = ''; + var copies, previous, outbyte; + if(!len) len = Infinity; + while(count){ + count--; + previous = current; + pos = buf[pos]; + current = pos & 0xff; + pos >>= 8; + if(run++ == 3){ + copies = current; + outbyte = previous; + current = -1; + }else{ + copies = 1; + outbyte = current; + } + while(copies--){ + output += (String.fromCharCode(outbyte)); + if(!--len) return output; + } + if(current != previous) run = 0; + } + return output; +} + diff --git a/evopedia-html5/WebContent/bzip2-killiroid.js b/evopedia-html5/WebContent/bzip2-killiroid.js new file mode 100644 index 00000000..45e25e2d --- /dev/null +++ b/evopedia-html5/WebContent/bzip2-killiroid.js @@ -0,0 +1,328 @@ +/** + * this is a port of pyflate + * @url http://www.paul.sladen.org/projects/pyflate/ + * @author kirilloid + * @license CC-SA 3.0 + * @usage ArchUtils.bz2.decode(str) + * @example ArchUtils.bz2.decode( + * "BZh91AY&SYN\xEC\xE86\0\0\2Q\x80\0\x10@\0\6D\x90\x80 " + + * "\x001\6LA\1\xA7\xA9\xA5\x80\xBB\x941\xF8\xBB\x92)\xC2\x84\x82wgA\xB0" + * ) == "hello world\n"; + */ + +var ArchUtils = (function(){ + 'use strict'; + + // python functions eliminated, Gonzalo + + /** + * bwt_reverse code from wikipedia (slightly modified) + * @url http://en.wikipedia.org/wiki/Burrows%E2%80%93Wheeler_transform + * @license: CC-SA 3.0 + */ + + function bwt_reverse(src, primary) { + var len = src.length; + if (primary >= len) throw RangeError("Out of bound"); + if (primary < 0) throw RangeError("Out of bound"); + + //only used on arrays, optimized, Gonzalo + var A = src; + src = src.join(''); + A.sort(); + + var start = {}; + for (var i = len-1; i >= 0; i--) start[A[i]] = i; + + var links = []; + for (i = 0; i < len; i++) links.push(start[src[i]]++); + + var i, first = A[i = primary], ret = []; + + for (var j = 1; j < len; j++) { + ret.push(A[i = links[i]]); + } + return first + ret.reverse().join(''); + } + + //move_to_front is always used to store reslt in array, optimized, Gonzalo + function move_to_front_and_store(a, c, buff) { + var v = a[c]; + for (var i = c; i > 0; a[i] = a[--i]); + buff.push(a[0] = v); + } + + // BitfieldBase never used directly, optimized, Gonzalo + /** + * @class RBitfield + * right-sided bitfield for reading bits in byte from right to left + */ + var RBitfield = function() { + this.init = function(x) { + this.masks = []; + for (var i = 0; i < 31; i++) this.masks[i] = (1 << i) - 1; + this.masks[31] = -0x80000000; + //eliminated support for RBitfield.init( RBitfield ), never used, Gonzalo + this.f = x; + this.bits = 0; + this.bitfield = 0x0; + this.count = 0; + } + //_read not used, optimized, Gonzalo + //readByte inlined, Gonzalo + //needbits inlined, Gonzalo + //align inlined, Gonzalo + //toskip inlined, Gonzalo + // this.dropbytes not used, eliminated, Gonzalo + // this.tell not used, eliminated, Gonzalo + // since js truncate args to int32 with bit operators + // we need to specific processing for n >= 32 bits reading + // separate function is created for optimization purposes + //readbits2 always called ith constants >=32, check removed, Gonzalo + this.readbits2 = function readbits2(n) { + //only for n>=32!!!, check removed + var n2 = n >> 1; + return this.readbits(n2) * (1 << n2) + this.readbits(n - n2); + } + this.readbits = function readbits(n) { + //if (n > this.bits) this.needbits(n); + // INLINED: needbits, readByte + while (this.bits < n) { + this.bitfield = (this.bitfield << 8) + this.f.charCodeAt(this.count++); + this.bits += 8; + } + var m = this.masks[n]; + var r = (this.bitfield >> (this.bits - n)) & m; + this.bits -= n; + this.bitfield &= ~(m << this.bits); + return r; + } + } + + /** + * @class HuffmanLength + * utility class, used for comparison of huffman codes + */ + var HuffmanLength = function(code, bits) { + this.code = code; + this.bits = bits; + this.symbol = undefined; + } //cropped unused functions and needless checks, Gonzalo + + //class HuffmanTable never used directly..., optimized, Gonzalo + + /** + * @class OrderedHuffmanTable + * utility class for working with huffman table + */ + var OrderedHuffmanTable = function() { + this.process = function(lengths) { + var len = lengths.length; + var z = []; + for (var i = 0; i < len; i++) { + z.push([i, lengths[i]]); + } + z.push([len, -1]); + + var l = []; + var b = z[0]; + var start = b[0], bits = b[1]; + for (var p = 1; p < z.length; p++) { + var finish = z[p][0], endbits = z[p][1]; + if (bits) + for (var code = start; code < finish; code++) + l.push(new HuffmanLength(code, bits)); + start = finish; + bits = endbits; + if (endbits == -1) break; + } + l.sort(function (a, b) { //function cmpHuffmanTable(a, b), can be anonymous, optimized, Gonzalo + return (a.bits - b.bits) || (a.code - b.code); + }); + this.table = l; + + //inlined populate_huffman_symbols, Gonzalo + var temp_bits = 0; + var symbol = -1; + // faht = Fast Access Huffman Table + this.faht = []; + var cb = null; + for (var i = 0; i < this.table.length; i++) { + var x = this.table[i]; + symbol += 1; + if (x.bits != temp_bits ) { + symbol <<= x.bits - temp_bits ; + cb = this.faht[temp_bits = x.bits] = {}; + } + cb[x.symbol = symbol] = x; + } + + //inlined min_max_bits + + this.min_bits = 16; + this.max_bits = -1; + this.table.forEach(function(x){ + if (x.bits < this.min_bits) this.min_bits = x.bits; + if (x.bits > this.max_bits) this.max_bits = x.bits; + }, this); + } + } + + return ({ bz2: { decode: function(input) { //eliminated unused unpackSize, Gonzalo + var b = new RBitfield(); + b.init(input); + b.readbits(16); + var method = b.readbits(8); + if (method != 104) { //char 'h' + throw "Unknown (not type 'h'uffman Bzip2) compression method"; + } + + var blocksize = b.readbits(8); + if ( 49 <= blocksize && blocksize <= 57) { //char '1' && char '9' + blocksize -= 48; //char 0 + } else { + throw "Unknown (not size '1'-'9') Bzip2 blocksize"; + } + + function getUsedCharTable(b) { + var a = []; + var used_groups = b.readbits(16); + for (var m1 = 1 << 15; m1 > 0; m1 >>= 1) { + if (!(used_groups & m1)) { + for (var i = 0; i < 16; i++) a.push(false); + continue; + } + var used_chars = b.readbits(16); + for (var m2 = 1 << 15; m2 > 0; m2 >>= 1) { + a.push( Boolean(used_chars & m2) ); + } + } + return a; + } + + var out = []; + + function main_loop() { while (true) { + var blocktype = b.readbits2(48); + var crc = b.readbits2(32); + if (blocktype == 0x314159265359) { // (pi) + if (b.readbits(1)) throw "Bzip2 randomised support not implemented"; + var pointer = b.readbits(24); + var used = getUsedCharTable(b); + + var huffman_groups = b.readbits(3); + if (2 > huffman_groups || huffman_groups > 6) + throw RangeError("Bzip2: Number of Huffman groups not in range 2..6"); + var mtf = [0,1,2,3,4,5,6].slice(0,huffman_groups); //eliminate use of range, Gonzalo + var selectors_list = []; + for (var i = 0, selectors_used = b.readbits(15); i < selectors_used; i++) { + // zero-terminated bit runs (0..62) of MTF'ed huffman table + var c = 0; + while (b.readbits(1)) { + if (c++ >= huffman_groups) + throw RangeError("More than max ("+huffman_groups+") groups"); + } + move_to_front_and_store(mtf, c, selectors_list); //optimized to single function, Gonzalo + } + var groups_lengths = []; + + // INLINE: sum used only once, Gonzalo + var symbols_in_use = used.reduce( function(a, b) {return a + b}, 0 ) + 2; //sum(used) + 2 // remember RUN[AB] RLE symbols + + for (var j = 0; j < huffman_groups; j++) { + var length = b.readbits(5); + var lengths = []; + for (var i = 0; i < symbols_in_use; i++) { + if (length < 0 || length > 20) + throw RangeError("Bzip2 Huffman length code outside range 0..20"); + while (b.readbits(1)) length -= (b.readbits(1) * 2) - 1; + lengths.push(length); + } + groups_lengths.push(lengths); + } + var tables = []; + for (var g = 0; g < groups_lengths.length; g++) { + var codes = new OrderedHuffmanTable(); + codes.process(groups_lengths[g]); //consolidated function calls + tables.push(codes); + } + var favourites = []; + for (var c = used.length - 1; c >= 0; c--) { + if (used[c]) favourites.push(String.fromCharCode(c)); //inlined chr, used once, Gonzalo + } + favourites.reverse(); + var selector_pointer = 0; + var decoded = 0; + var t; + + // Main Huffman loop + var repeat = 0; + var repeat_power = 0; + var buffer = [], r; + + while (true) { + if (--decoded <= 0) { + decoded = 50; + if (selector_pointer <= selectors_list.length) + t = tables[selectors_list[selector_pointer++]]; + } + + // INLINED: find_next_symbol + for (var bb in t.faht) { + if (b.bits < bb) { + b.bitfield = (b.bitfield << 8) + b.f.charCodeAt(b.count++); + b.bits += 8; + } + if (r = t.faht[bb][ b.bitfield >> (b.bits - bb) ]) { + b.bitfield &= b.masks[b.bits -= bb]; + r = r.code; + break; + } + } + + if (0 <= r && r <= 1) { + if (repeat == 0) repeat_power = 1; + repeat += repeat_power << r; + repeat_power <<= 1; + continue; + } else { + var v = favourites[0]; + for ( ; repeat > 0; repeat--) buffer.push(v); + } + if (r == symbols_in_use - 1) { // eof symbol + break; + } else { + move_to_front_and_store(favourites,r-1,buffer); //Uninlined, size efficiency, Gonzalo + } + } + var nt = bwt_reverse(buffer, pointer); + var done = []; + var i = 0; + var len = nt.length; + // RLE decoding + while (i < len) { + var c = nt.charCodeAt(i); + if ((i < len - 4) + && nt.charCodeAt(i+1) == c + && nt.charCodeAt(i+2) == c + && nt.charCodeAt(i+3) == c) { + var c = nt.charAt(i); + var rep = nt.charCodeAt(i+4)+4; + for (; rep > 0; rep--) done.push(c); + i += 5; + } else { + done.push(nt[i++]); + } + } + out.push(done.join('')); + } else if (blocktype == 0x177245385090) { // sqrt(pi) + b.readbits(b.bits & 0x7); //align + break; + } else { + throw "Illegal Bzip2 blocktype = 0x" + blocktype.toString(16); + } + } } + main_loop(); + return out.join(''); + } } }); +})(); diff --git a/evopedia-html5/WebContent/evopedia.html b/evopedia-html5/WebContent/evopedia.html new file mode 100644 index 00000000..66635fbc --- /dev/null +++ b/evopedia-html5/WebContent/evopedia.html @@ -0,0 +1,32 @@ + + + + + +Evopedia HTML5 + + + + +

Evopedia

+
+Blockstart : +
+Blockoffset : +
+Length : +
+ +
+ +
+
 
+
+
 
+ + + + diff --git a/evopedia-html5/WebContent/evopedia.js b/evopedia-html5/WebContent/evopedia.js new file mode 100644 index 00000000..34ff4e6b --- /dev/null +++ b/evopedia-html5/WebContent/evopedia.js @@ -0,0 +1,88 @@ + +var file=document.getElementById('files').files[0]; + +var storage = navigator.getDeviceStorage('music'); +//alert(storage); + +if (!storage) { + //alert("no device storage available"); + document.getElementById('openLocalFiles').style.visibility="visible"; + document.getElementById('files').addEventListener('change', handleFileSelect, false); + document.getElementById('files').addEventListener('load', handleFileSelect, false); +} +else { + var filerequest = storage.get('wikipedia_small_2010-08-14/wikipedia_00.dat'); + //alert(filerequest); + filerequest.onsuccess = function() { + file = filerequest.result; + //alert(file); + //readArticleFromHtmlForm(file); + }; + filerequest.onerror = function() { + alert("error reading file"); + }; +} + +function readArticleFromHtmlForm(file) { + if (file) { + var blockstart = document.getElementById('blockstart').value; + var blockoffset = document.getElementById('blockoffset').value; + var length = document.getElementById('length').value; + readArticleFromOffset(file, blockstart, blockoffset, length); + } + else { + alert("File not set"); + } +} + +function readArticleFromOffset(file, blockstart, blockoffset, length) { + + var reader = new FileReader(); + reader.onerror = errorHandler; + reader.onabort = function(e) { + alert('File read cancelled'); + }; + reader.onload = function(e) { + var compressedArticles = e.target.result; + //var htmlArticle = compressedArticles; + //alert(typeof compressedArticles); + //var htmlArticle = ArchUtils.bz2.decode(compressedArticles); + // TODO : should be improved by uncompressing the content chunk by chunk, + // until the length is reached, instead of uncompressing everything + var htmlArticles = bzip2.simple(bzip2.array(new Uint8Array(compressedArticles))); + var htmlArticle = htmlArticles.substring(blockoffset,length); + // Decode UTF-8 encoding + htmlArticle = decodeURIComponent(escape(htmlArticle)); + + document.getElementById('articleContent').innerHTML = htmlArticle; + // For testing purpose + document.getElementById('rawArticleContent').innerHTML = htmlArticle.replace(/&/g,'&').replace(//g,'>'); + }; + + //var blob = file; + // TODO : should be improved by reading the file chunks by chunks until the article is found, + // instead of reading the whole file starting at blockstart + var blob = file.slice(blockstart); + + // Read in the image file as a binary string. + reader.readAsArrayBuffer(blob); +} + +function errorHandler(evt) { + switch(evt.target.error.code) { + case evt.target.error.NOT_FOUND_ERR: + alert('File Not Found!'); + break; + case evt.target.error.NOT_READABLE_ERR: + alert('File is not readable'); + break; + case evt.target.error.ABORT_ERR: + break; // noop + default: + alert('An error occurred reading this file.'); + }; + } + +function handleFileSelect(evt) { + file = evt.target.files[0]; +}