Make JetStream 2
[WebKit-https.git] / PerformanceTests / JetStream2 / wasm / gcc-loops.js
1 function doRun() {
2 let __startupStartTime = benchmarkTime();
3 var moduleOverrides = {};
4 var key;
5 for (key in Module) {
6  if (Module.hasOwnProperty(key)) {
7   moduleOverrides[key] = Module[key];
8  }
9 }
10 Module["arguments"] = [];
11 Module["thisProgram"] = "./this.program";
12 Module["quit"] = (function(status, toThrow) {
13  throw toThrow;
14 });
15 Module["preRun"] = [];
16 Module["postRun"] = [];
17 var ENVIRONMENT_IS_WEB = false;
18 var ENVIRONMENT_IS_WORKER = false;
19 var ENVIRONMENT_IS_NODE = false;
20 var ENVIRONMENT_IS_SHELL = false;
21 if (Module["ENVIRONMENT"]) {
22  if (Module["ENVIRONMENT"] === "WEB") {
23   ENVIRONMENT_IS_WEB = true;
24  } else if (Module["ENVIRONMENT"] === "WORKER") {
25   ENVIRONMENT_IS_WORKER = true;
26  } else if (Module["ENVIRONMENT"] === "NODE") {
27   ENVIRONMENT_IS_NODE = true;
28  } else if (Module["ENVIRONMENT"] === "SHELL") {
29   ENVIRONMENT_IS_SHELL = true;
30  } else {
31   throw new Error("Module['ENVIRONMENT'] value is not valid. must be one of: WEB|WORKER|NODE|SHELL.");
32  }
33 } else {
34  ENVIRONMENT_IS_WEB = typeof window === "object";
35  ENVIRONMENT_IS_WORKER = typeof importScripts === "function";
36  ENVIRONMENT_IS_NODE = typeof process === "object" && typeof require === "function" && !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_WORKER;
37  ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
38 }
39 if (ENVIRONMENT_IS_NODE) {
40  var nodeFS;
41  var nodePath;
42  Module["read"] = function shell_read(filename, binary) {
43   var ret;
44   if (!nodeFS) nodeFS = require("fs");
45   if (!nodePath) nodePath = require("path");
46   filename = nodePath["normalize"](filename);
47   ret = nodeFS["readFileSync"](filename);
48   return binary ? ret : ret.toString();
49  };
50  Module["readBinary"] = function readBinary(filename) {
51   var ret = Module["read"](filename, true);
52   if (!ret.buffer) {
53    ret = new Uint8Array(ret);
54   }
55   assert(ret.buffer);
56   return ret;
57  };
58  if (process["argv"].length > 1) {
59   Module["thisProgram"] = process["argv"][1].replace(/\\/g, "/");
60  }
61  Module["arguments"] = process["argv"].slice(2);
62  if (typeof module !== "undefined") {
63   module["exports"] = Module;
64  }
65  process["on"]("uncaughtException", (function(ex) {
66   if (!(ex instanceof ExitStatus)) {
67    throw ex;
68   }
69  }));
70  process["on"]("unhandledRejection", (function(reason, p) {
71   process["exit"](1);
72  }));
73  Module["inspect"] = (function() {
74   return "[Emscripten Module object]";
75  });
76 } else if (ENVIRONMENT_IS_SHELL) {
77  if (typeof read != "undefined") {
78   Module["read"] = function shell_read(f) {
79    return read(f);
80   };
81  }
82  Module["readBinary"] = function readBinary(f) {
83   var data;
84   if (typeof readbuffer === "function") {
85    return new Uint8Array(readbuffer(f));
86   }
87   data = read(f, "binary");
88   assert(typeof data === "object");
89   return data;
90  };
91  if (typeof scriptArgs != "undefined") {
92   Module["arguments"] = scriptArgs;
93  } else if (typeof arguments != "undefined") {
94   Module["arguments"] = arguments;
95  }
96  if (typeof quit === "function") {
97   Module["quit"] = (function(status, toThrow) {
98    quit(status);
99   });
100  }
101 } else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
102  Module["read"] = function shell_read(url) {
103   var xhr = new XMLHttpRequest;
104   xhr.open("GET", url, false);
105   xhr.send(null);
106   return xhr.responseText;
107  };
108  if (ENVIRONMENT_IS_WORKER) {
109   Module["readBinary"] = function readBinary(url) {
110    var xhr = new XMLHttpRequest;
111    xhr.open("GET", url, false);
112    xhr.responseType = "arraybuffer";
113    xhr.send(null);
114    return new Uint8Array(xhr.response);
115   };
116  }
117  Module["readAsync"] = function readAsync(url, onload, onerror) {
118   var xhr = new XMLHttpRequest;
119   xhr.open("GET", url, true);
120   xhr.responseType = "arraybuffer";
121   xhr.onload = function xhr_onload() {
122    if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
123     onload(xhr.response);
124     return;
125    }
126    onerror();
127   };
128   xhr.onerror = onerror;
129   xhr.send(null);
130  };
131  Module["setWindowTitle"] = (function(title) {
132   document.title = title;
133  });
134 }
135 Module["print"] = typeof console !== "undefined" ? console.log.bind(console) : typeof print !== "undefined" ? print : null;
136 Module["printErr"] = typeof printErr !== "undefined" ? printErr : typeof console !== "undefined" && console.warn.bind(console) || Module["print"];
137 Module.print = Module["print"];
138 Module.printErr = Module["printErr"];
139 for (key in moduleOverrides) {
140  if (moduleOverrides.hasOwnProperty(key)) {
141   Module[key] = moduleOverrides[key];
142  }
143 }
144 moduleOverrides = undefined;
145 var STACK_ALIGN = 16;
146 function staticAlloc(size) {
147  assert(!staticSealed);
148  var ret = STATICTOP;
149  STATICTOP = STATICTOP + size + 15 & -16;
150  return ret;
151 }
152 function dynamicAlloc(size) {
153  assert(DYNAMICTOP_PTR);
154  var ret = HEAP32[DYNAMICTOP_PTR >> 2];
155  var end = ret + size + 15 & -16;
156  HEAP32[DYNAMICTOP_PTR >> 2] = end;
157  if (end >= TOTAL_MEMORY) {
158   var success = enlargeMemory();
159   if (!success) {
160    HEAP32[DYNAMICTOP_PTR >> 2] = ret;
161    return 0;
162   }
163  }
164  return ret;
165 }
166 function alignMemory(size, factor) {
167  if (!factor) factor = STACK_ALIGN;
168  var ret = size = Math.ceil(size / factor) * factor;
169  return ret;
170 }
171 function getNativeTypeSize(type) {
172  switch (type) {
173  case "i1":
174  case "i8":
175   return 1;
176  case "i16":
177   return 2;
178  case "i32":
179   return 4;
180  case "i64":
181   return 8;
182  case "float":
183   return 4;
184  case "double":
185   return 8;
186  default:
187   {
188    if (type[type.length - 1] === "*") {
189     return 4;
190    } else if (type[0] === "i") {
191     var bits = parseInt(type.substr(1));
192     assert(bits % 8 === 0);
193     return bits / 8;
194    } else {
195     return 0;
196    }
197   }
198  }
199 }
200 function warnOnce(text) {
201  if (!warnOnce.shown) warnOnce.shown = {};
202  if (!warnOnce.shown[text]) {
203   warnOnce.shown[text] = 1;
204   Module.printErr(text);
205  }
206 }
207 var jsCallStartIndex = 1;
208 var functionPointers = new Array(0);
209 var funcWrappers = {};
210 function dynCall(sig, ptr, args) {
211  if (args && args.length) {
212   return Module["dynCall_" + sig].apply(null, [ ptr ].concat(args));
213  } else {
214   return Module["dynCall_" + sig].call(null, ptr);
215  }
216 }
217 var GLOBAL_BASE = 1024;
218 var ABORT = 0;
219 var EXITSTATUS = 0;
220 function assert(condition, text) {
221  if (!condition) {
222   abort("Assertion failed: " + text);
223  }
224 }
225 function getCFunc(ident) {
226  var func = Module["_" + ident];
227  assert(func, "Cannot call unknown function " + ident + ", make sure it is exported");
228  return func;
229 }
230 var JSfuncs = {
231  "stackSave": (function() {
232   stackSave();
233  }),
234  "stackRestore": (function() {
235   stackRestore();
236  }),
237  "arrayToC": (function(arr) {
238   var ret = stackAlloc(arr.length);
239   writeArrayToMemory(arr, ret);
240   return ret;
241  }),
242  "stringToC": (function(str) {
243   var ret = 0;
244   if (str !== null && str !== undefined && str !== 0) {
245    var len = (str.length << 2) + 1;
246    ret = stackAlloc(len);
247    stringToUTF8(str, ret, len);
248   }
249   return ret;
250  })
251 };
252 var toC = {
253  "string": JSfuncs["stringToC"],
254  "array": JSfuncs["arrayToC"]
255 };
256 function ccall(ident, returnType, argTypes, args, opts) {
257  var func = getCFunc(ident);
258  var cArgs = [];
259  var stack = 0;
260  if (args) {
261   for (var i = 0; i < args.length; i++) {
262    var converter = toC[argTypes[i]];
263    if (converter) {
264     if (stack === 0) stack = stackSave();
265     cArgs[i] = converter(args[i]);
266    } else {
267     cArgs[i] = args[i];
268    }
269   }
270  }
271  var ret = func.apply(null, cArgs);
272  if (returnType === "string") ret = Pointer_stringify(ret); else if (returnType === "boolean") ret = Boolean(ret);
273  if (stack !== 0) {
274   stackRestore(stack);
275  }
276  return ret;
277 }
278 function setValue(ptr, value, type, noSafe) {
279  type = type || "i8";
280  if (type.charAt(type.length - 1) === "*") type = "i32";
281  switch (type) {
282  case "i1":
283   HEAP8[ptr >> 0] = value;
284   break;
285  case "i8":
286   HEAP8[ptr >> 0] = value;
287   break;
288  case "i16":
289   HEAP16[ptr >> 1] = value;
290   break;
291  case "i32":
292   HEAP32[ptr >> 2] = value;
293   break;
294  case "i64":
295   tempI64 = [ value >>> 0, (tempDouble = value, +Math_abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math_min(+Math_floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math_ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ], HEAP32[ptr >> 2] = tempI64[0], HEAP32[ptr + 4 >> 2] = tempI64[1];
296   break;
297  case "float":
298   HEAPF32[ptr >> 2] = value;
299   break;
300  case "double":
301   HEAPF64[ptr >> 3] = value;
302   break;
303  default:
304   abort("invalid type for setValue: " + type);
305  }
306 }
307 var ALLOC_STATIC = 2;
308 var ALLOC_NONE = 4;
309 function Pointer_stringify(ptr, length) {
310  if (length === 0 || !ptr) return "";
311  var hasUtf = 0;
312  var t;
313  var i = 0;
314  while (1) {
315   t = HEAPU8[ptr + i >> 0];
316   hasUtf |= t;
317   if (t == 0 && !length) break;
318   i++;
319   if (length && i == length) break;
320  }
321  if (!length) length = i;
322  var ret = "";
323  if (hasUtf < 128) {
324   var MAX_CHUNK = 1024;
325   var curr;
326   while (length > 0) {
327    curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK)));
328    ret = ret ? ret + curr : curr;
329    ptr += MAX_CHUNK;
330    length -= MAX_CHUNK;
331   }
332   return ret;
333  }
334  return UTF8ToString(ptr);
335 }
336 var UTF8Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf8") : undefined;
337 function UTF8ArrayToString(u8Array, idx) {
338  var endPtr = idx;
339  while (u8Array[endPtr]) ++endPtr;
340  if (endPtr - idx > 16 && u8Array.subarray && UTF8Decoder) {
341   return UTF8Decoder.decode(u8Array.subarray(idx, endPtr));
342  } else {
343   var u0, u1, u2, u3, u4, u5;
344   var str = "";
345   while (1) {
346    u0 = u8Array[idx++];
347    if (!u0) return str;
348    if (!(u0 & 128)) {
349     str += String.fromCharCode(u0);
350     continue;
351    }
352    u1 = u8Array[idx++] & 63;
353    if ((u0 & 224) == 192) {
354     str += String.fromCharCode((u0 & 31) << 6 | u1);
355     continue;
356    }
357    u2 = u8Array[idx++] & 63;
358    if ((u0 & 240) == 224) {
359     u0 = (u0 & 15) << 12 | u1 << 6 | u2;
360    } else {
361     u3 = u8Array[idx++] & 63;
362     if ((u0 & 248) == 240) {
363      u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | u3;
364     } else {
365      u4 = u8Array[idx++] & 63;
366      if ((u0 & 252) == 248) {
367       u0 = (u0 & 3) << 24 | u1 << 18 | u2 << 12 | u3 << 6 | u4;
368      } else {
369       u5 = u8Array[idx++] & 63;
370       u0 = (u0 & 1) << 30 | u1 << 24 | u2 << 18 | u3 << 12 | u4 << 6 | u5;
371      }
372     }
373    }
374    if (u0 < 65536) {
375     str += String.fromCharCode(u0);
376    } else {
377     var ch = u0 - 65536;
378     str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);
379    }
380   }
381  }
382 }
383 function UTF8ToString(ptr) {
384  return UTF8ArrayToString(HEAPU8, ptr);
385 }
386 function stringToUTF8Array(str, outU8Array, outIdx, maxBytesToWrite) {
387  if (!(maxBytesToWrite > 0)) return 0;
388  var startIdx = outIdx;
389  var endIdx = outIdx + maxBytesToWrite - 1;
390  for (var i = 0; i < str.length; ++i) {
391   var u = str.charCodeAt(i);
392   if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023;
393   if (u <= 127) {
394    if (outIdx >= endIdx) break;
395    outU8Array[outIdx++] = u;
396   } else if (u <= 2047) {
397    if (outIdx + 1 >= endIdx) break;
398    outU8Array[outIdx++] = 192 | u >> 6;
399    outU8Array[outIdx++] = 128 | u & 63;
400   } else if (u <= 65535) {
401    if (outIdx + 2 >= endIdx) break;
402    outU8Array[outIdx++] = 224 | u >> 12;
403    outU8Array[outIdx++] = 128 | u >> 6 & 63;
404    outU8Array[outIdx++] = 128 | u & 63;
405   } else if (u <= 2097151) {
406    if (outIdx + 3 >= endIdx) break;
407    outU8Array[outIdx++] = 240 | u >> 18;
408    outU8Array[outIdx++] = 128 | u >> 12 & 63;
409    outU8Array[outIdx++] = 128 | u >> 6 & 63;
410    outU8Array[outIdx++] = 128 | u & 63;
411   } else if (u <= 67108863) {
412    if (outIdx + 4 >= endIdx) break;
413    outU8Array[outIdx++] = 248 | u >> 24;
414    outU8Array[outIdx++] = 128 | u >> 18 & 63;
415    outU8Array[outIdx++] = 128 | u >> 12 & 63;
416    outU8Array[outIdx++] = 128 | u >> 6 & 63;
417    outU8Array[outIdx++] = 128 | u & 63;
418   } else {
419    if (outIdx + 5 >= endIdx) break;
420    outU8Array[outIdx++] = 252 | u >> 30;
421    outU8Array[outIdx++] = 128 | u >> 24 & 63;
422    outU8Array[outIdx++] = 128 | u >> 18 & 63;
423    outU8Array[outIdx++] = 128 | u >> 12 & 63;
424    outU8Array[outIdx++] = 128 | u >> 6 & 63;
425    outU8Array[outIdx++] = 128 | u & 63;
426   }
427  }
428  outU8Array[outIdx] = 0;
429  return outIdx - startIdx;
430 }
431 function stringToUTF8(str, outPtr, maxBytesToWrite) {
432  return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
433 }
434 function lengthBytesUTF8(str) {
435  var len = 0;
436  for (var i = 0; i < str.length; ++i) {
437   var u = str.charCodeAt(i);
438   if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023;
439   if (u <= 127) {
440    ++len;
441   } else if (u <= 2047) {
442    len += 2;
443   } else if (u <= 65535) {
444    len += 3;
445   } else if (u <= 2097151) {
446    len += 4;
447   } else if (u <= 67108863) {
448    len += 5;
449   } else {
450    len += 6;
451   }
452  }
453  return len;
454 }
455 var UTF16Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf-16le") : undefined;
456 function allocateUTF8(str) {
457  var size = lengthBytesUTF8(str) + 1;
458  var ret = _malloc(size);
459  if (ret) stringToUTF8Array(str, HEAP8, ret, size);
460  return ret;
461 }
462 function allocateUTF8OnStack(str) {
463  var size = lengthBytesUTF8(str) + 1;
464  var ret = stackAlloc(size);
465  stringToUTF8Array(str, HEAP8, ret, size);
466  return ret;
467 }
468 function demangle(func) {
469  return func;
470 }
471 function demangleAll(text) {
472  var regex = /__Z[\w\d_]+/g;
473  return text.replace(regex, (function(x) {
474   var y = demangle(x);
475   return x === y ? x : x + " [" + y + "]";
476  }));
477 }
478 function jsStackTrace() {
479  var err = new Error;
480  if (!err.stack) {
481   try {
482    throw new Error(0);
483   } catch (e) {
484    err = e;
485   }
486   if (!err.stack) {
487    return "(no stack trace available)";
488   }
489  }
490  return err.stack.toString();
491 }
492 function stackTrace() {
493  var js = jsStackTrace();
494  if (Module["extraStackTrace"]) js += "\n" + Module["extraStackTrace"]();
495  return demangleAll(js);
496 }
497 var WASM_PAGE_SIZE = 65536;
498 var ASMJS_PAGE_SIZE = 16777216;
499 function alignUp(x, multiple) {
500  if (x % multiple > 0) {
501   x += multiple - x % multiple;
502  }
503  return x;
504 }
505 var buffer, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
506 function updateGlobalBuffer(buf) {
507  Module["buffer"] = buffer = buf;
508 }
509 function updateGlobalBufferViews() {
510  Module["HEAP8"] = HEAP8 = new Int8Array(buffer);
511  Module["HEAP16"] = HEAP16 = new Int16Array(buffer);
512  Module["HEAP32"] = HEAP32 = new Int32Array(buffer);
513  Module["HEAPU8"] = HEAPU8 = new Uint8Array(buffer);
514  Module["HEAPU16"] = HEAPU16 = new Uint16Array(buffer);
515  Module["HEAPU32"] = HEAPU32 = new Uint32Array(buffer);
516  Module["HEAPF32"] = HEAPF32 = new Float32Array(buffer);
517  Module["HEAPF64"] = HEAPF64 = new Float64Array(buffer);
518 }
519 var STATIC_BASE, STATICTOP, staticSealed;
520 var STACK_BASE, STACKTOP, STACK_MAX;
521 var DYNAMIC_BASE, DYNAMICTOP_PTR;
522 STATIC_BASE = STATICTOP = STACK_BASE = STACKTOP = STACK_MAX = DYNAMIC_BASE = DYNAMICTOP_PTR = 0;
523 staticSealed = false;
524 function abortOnCannotGrowMemory() {
525  abort("Cannot enlarge memory arrays. Either (1) compile with  -s TOTAL_MEMORY=X  with X higher than the current value " + TOTAL_MEMORY + ", (2) compile with  -s ALLOW_MEMORY_GROWTH=1  which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with  -s ABORTING_MALLOC=0 ");
526 }
527 function enlargeMemory() {
528  abortOnCannotGrowMemory();
529 }
530 var TOTAL_STACK = Module["TOTAL_STACK"] || 5242880;
531 var TOTAL_MEMORY = Module["TOTAL_MEMORY"] || 67108864;
532 if (TOTAL_MEMORY < TOTAL_STACK) Module.printErr("TOTAL_MEMORY should be larger than TOTAL_STACK, was " + TOTAL_MEMORY + "! (TOTAL_STACK=" + TOTAL_STACK + ")");
533 if (Module["buffer"]) {
534  buffer = Module["buffer"];
535 } else {
536  if (typeof WebAssembly === "object" && typeof WebAssembly.Memory === "function") {
537   Module["wasmMemory"] = new WebAssembly.Memory({
538    "initial": TOTAL_MEMORY / WASM_PAGE_SIZE,
539    "maximum": TOTAL_MEMORY / WASM_PAGE_SIZE
540   });
541   buffer = Module["wasmMemory"].buffer;
542  } else {
543   buffer = new ArrayBuffer(TOTAL_MEMORY);
544  }
545  Module["buffer"] = buffer;
546 }
547 updateGlobalBufferViews();
548 function getTotalMemory() {
549  return TOTAL_MEMORY;
550 }
551 HEAP32[0] = 1668509029;
552 HEAP16[1] = 25459;
553 if (HEAPU8[2] !== 115 || HEAPU8[3] !== 99) throw "Runtime error: expected the system to be little-endian!";
554 function callRuntimeCallbacks(callbacks) {
555  while (callbacks.length > 0) {
556   var callback = callbacks.shift();
557   if (typeof callback == "function") {
558    callback();
559    continue;
560   }
561   var func = callback.func;
562   if (typeof func === "number") {
563    if (callback.arg === undefined) {
564     Module["dynCall_v"](func);
565    } else {
566     Module["dynCall_vi"](func, callback.arg);
567    }
568   } else {
569    func(callback.arg === undefined ? null : callback.arg);
570   }
571  }
572 }
573 var __ATPRERUN__ = [];
574 var __ATINIT__ = [];
575 var __ATMAIN__ = [];
576 var __ATEXIT__ = [];
577 var __ATPOSTRUN__ = [];
578 var runtimeInitialized = false;
579 var runtimeExited = false;
580 function preRun() {
581  if (Module["preRun"]) {
582   if (typeof Module["preRun"] == "function") Module["preRun"] = [ Module["preRun"] ];
583   while (Module["preRun"].length) {
584    addOnPreRun(Module["preRun"].shift());
585   }
586  }
587  callRuntimeCallbacks(__ATPRERUN__);
588 }
589 function ensureInitRuntime() {
590  if (runtimeInitialized) return;
591  runtimeInitialized = true;
592  callRuntimeCallbacks(__ATINIT__);
593 }
594 function preMain() {
595  callRuntimeCallbacks(__ATMAIN__);
596 }
597 function exitRuntime() {
598  callRuntimeCallbacks(__ATEXIT__);
599  runtimeExited = true;
600 }
601 function postRun() {
602  if (Module["postRun"]) {
603   if (typeof Module["postRun"] == "function") Module["postRun"] = [ Module["postRun"] ];
604   while (Module["postRun"].length) {
605    addOnPostRun(Module["postRun"].shift());
606   }
607  }
608  callRuntimeCallbacks(__ATPOSTRUN__);
609 }
610 function addOnPreRun(cb) {
611  __ATPRERUN__.unshift(cb);
612 }
613 function addOnPostRun(cb) {
614  __ATPOSTRUN__.unshift(cb);
615 }
616 function writeArrayToMemory(array, buffer) {
617  HEAP8.set(array, buffer);
618 }
619 function writeAsciiToMemory(str, buffer, dontAddNull) {
620  for (var i = 0; i < str.length; ++i) {
621   HEAP8[buffer++ >> 0] = str.charCodeAt(i);
622  }
623  if (!dontAddNull) HEAP8[buffer >> 0] = 0;
624 }
625 var Math_abs = Math.abs;
626 var Math_cos = Math.cos;
627 var Math_sin = Math.sin;
628 var Math_tan = Math.tan;
629 var Math_acos = Math.acos;
630 var Math_asin = Math.asin;
631 var Math_atan = Math.atan;
632 var Math_atan2 = Math.atan2;
633 var Math_exp = Math.exp;
634 var Math_log = Math.log;
635 var Math_sqrt = Math.sqrt;
636 var Math_ceil = Math.ceil;
637 var Math_floor = Math.floor;
638 var Math_pow = Math.pow;
639 var Math_imul = Math.imul;
640 var Math_fround = Math.fround;
641 var Math_round = Math.round;
642 var Math_min = Math.min;
643 var Math_max = Math.max;
644 var Math_clz32 = Math.clz32;
645 var Math_trunc = Math.trunc;
646 var runDependencies = 0;
647 var runDependencyWatcher = null;
648 var dependenciesFulfilled = null;
649 function getUniqueRunDependency(id) {
650  return id;
651 }
652 function addRunDependency(id) {
653  runDependencies++;
654  if (Module["monitorRunDependencies"]) {
655   Module["monitorRunDependencies"](runDependencies);
656  }
657 }
658 function removeRunDependency(id) {
659  runDependencies--;
660  if (Module["monitorRunDependencies"]) {
661   Module["monitorRunDependencies"](runDependencies);
662  }
663  if (runDependencies == 0) {
664   if (runDependencyWatcher !== null) {
665    clearInterval(runDependencyWatcher);
666    runDependencyWatcher = null;
667   }
668   if (dependenciesFulfilled) {
669    var callback = dependenciesFulfilled;
670    dependenciesFulfilled = null;
671    callback();
672   }
673  }
674 }
675 Module["preloadedImages"] = {};
676 Module["preloadedAudios"] = {};
677 var dataURIPrefix = "data:application/octet-stream;base64,";
678 function isDataURI(filename) {
679  return String.prototype.startsWith ? filename.startsWith(dataURIPrefix) : filename.indexOf(dataURIPrefix) === 0;
680 }
681 function integrateWasmJS() {
682  var wasmTextFile = "gcc-loops.wast";
683  var wasmBinaryFile = "gcc-loops.wasm";
684  var asmjsCodeFile = "gcc-loops.temp.asm.js";
685  if (typeof Module["locateFile"] === "function") {
686   if (!isDataURI(wasmTextFile)) {
687    wasmTextFile = Module["locateFile"](wasmTextFile);
688   }
689   if (!isDataURI(wasmBinaryFile)) {
690    wasmBinaryFile = Module["locateFile"](wasmBinaryFile);
691   }
692   if (!isDataURI(asmjsCodeFile)) {
693    asmjsCodeFile = Module["locateFile"](asmjsCodeFile);
694   }
695  }
696  var wasmPageSize = 64 * 1024;
697  var info = {
698   "global": null,
699   "env": null,
700   "asm2wasm": {
701    "f64-rem": (function(x, y) {
702     return x % y;
703    }),
704    "debugger": (function() {
705     debugger;
706    })
707   },
708   "parent": Module
709  };
710  var exports = null;
711  function mergeMemory(newBuffer) {
712   var oldBuffer = Module["buffer"];
713   if (newBuffer.byteLength < oldBuffer.byteLength) {
714    Module["printErr"]("the new buffer in mergeMemory is smaller than the previous one. in native wasm, we should grow memory here");
715   }
716   var oldView = new Int8Array(oldBuffer);
717   var newView = new Int8Array(newBuffer);
718   newView.set(oldView);
719   updateGlobalBuffer(newBuffer);
720   updateGlobalBufferViews();
721  }
722  function fixImports(imports) {
723   return imports;
724  }
725  function getBinary() {
726   try {
727    if (Module["wasmBinary"]) {
728     return new Uint8Array(Module["wasmBinary"]);
729    }
730     throw "on the web, we need the wasm binary to be preloaded and set on Module['wasmBinary']. emcc.py will do that for you when generating HTML (but not JS)";
731   } catch (err) {
732    abort(err);
733   }
734  }
735  function getBinaryPromise() {
736   if (!Module["wasmBinary"] && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && typeof fetch === "function") {
737    return fetch(wasmBinaryFile, {
738     credentials: "same-origin"
739    }).then((function(response) {
740     if (!response["ok"]) {
741      throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";
742     }
743     return response["arrayBuffer"]();
744    })).catch((function() {
745     return getBinary();
746    }));
747   }
748   return new Promise((function(resolve, reject) {
749    resolve(getBinary());
750   }));
751  }
752  function doNativeWasm(global, env, providedBuffer) {
753   if (typeof WebAssembly !== "object") {
754    Module["printErr"]("no native wasm support detected");
755    return false;
756   }
757   if (!(Module["wasmMemory"] instanceof WebAssembly.Memory)) {
758    Module["printErr"]("no native wasm Memory in use");
759    return false;
760   }
761   env["memory"] = Module["wasmMemory"];
762   info["global"] = {
763    "NaN": NaN,
764    "Infinity": Infinity
765   };
766   info["global.Math"] = Math;
767   info["env"] = env;
768   function receiveInstance(instance, module) {
769    exports = instance.exports;
770    if (exports.memory) mergeMemory(exports.memory);
771    Module["asm"] = exports;
772    Module["usingWasm"] = true;
773    removeRunDependency("wasm-instantiate");
774   }
775   addRunDependency("wasm-instantiate");
776   if (Module["instantiateWasm"]) {
777    try {
778     return Module["instantiateWasm"](info, receiveInstance);
779    } catch (e) {
780     Module["printErr"]("Module.instantiateWasm callback failed with error: " + e);
781     return false;
782    }
783   }
784   function receiveInstantiatedSource(output) {
785    receiveInstance(output["instance"], output["module"]);
786   }
787   function instantiateArrayBuffer(receiver) {
788    getBinaryPromise().then((function(binary) {
789     return WebAssembly.instantiate(binary, info);
790    }))
791    .then((...args) => {
792        reportCompileTime(benchmarkTime() - __startupStartTime);
793        return Promise.resolve(...args);
794    })
795    .then(receiver).catch((function(reason) {
796     Module["printErr"]("failed to asynchronously prepare wasm: " + reason);
797     abort(reason);
798    }));
799   }
800   if (!Module["wasmBinary"] && typeof WebAssembly.instantiateStreaming === "function" && !isDataURI(wasmBinaryFile) && typeof fetch === "function") {
801    WebAssembly.instantiateStreaming(fetch(wasmBinaryFile, {
802     credentials: "same-origin"
803    }), info).then(receiveInstantiatedSource).catch((function(reason) {
804     Module["printErr"]("wasm streaming compile failed: " + reason);
805     Module["printErr"]("falling back to ArrayBuffer instantiation");
806     instantiateArrayBuffer(receiveInstantiatedSource);
807    }));
808   } else {
809    instantiateArrayBuffer(receiveInstantiatedSource);
810   }
811   return {};
812  }
813  Module["asmPreload"] = Module["asm"];
814  var asmjsReallocBuffer = Module["reallocBuffer"];
815  var wasmReallocBuffer = (function(size) {
816   var PAGE_MULTIPLE = Module["usingWasm"] ? WASM_PAGE_SIZE : ASMJS_PAGE_SIZE;
817   size = alignUp(size, PAGE_MULTIPLE);
818   var old = Module["buffer"];
819   var oldSize = old.byteLength;
820   if (Module["usingWasm"]) {
821    try {
822     var result = Module["wasmMemory"].grow((size - oldSize) / wasmPageSize);
823     if (result !== (-1 | 0)) {
824      return Module["buffer"] = Module["wasmMemory"].buffer;
825     } else {
826      return null;
827     }
828    } catch (e) {
829     return null;
830    }
831   }
832  });
833  Module["reallocBuffer"] = (function(size) {
834   if (finalMethod === "asmjs") {
835    return asmjsReallocBuffer(size);
836   } else {
837    return wasmReallocBuffer(size);
838   }
839  });
840  var finalMethod = "";
841  Module["asm"] = (function(global, env, providedBuffer) {
842   env = fixImports(env);
843   if (!env["table"]) {
844    var TABLE_SIZE = Module["wasmTableSize"];
845    if (TABLE_SIZE === undefined) TABLE_SIZE = 1024;
846    var MAX_TABLE_SIZE = Module["wasmMaxTableSize"];
847    if (typeof WebAssembly === "object" && typeof WebAssembly.Table === "function") {
848     if (MAX_TABLE_SIZE !== undefined) {
849      env["table"] = new WebAssembly.Table({
850       "initial": TABLE_SIZE,
851       "maximum": MAX_TABLE_SIZE,
852       "element": "anyfunc"
853      });
854     } else {
855      env["table"] = new WebAssembly.Table({
856       "initial": TABLE_SIZE,
857       element: "anyfunc"
858      });
859     }
860    } else {
861     env["table"] = new Array(TABLE_SIZE);
862    }
863    Module["wasmTable"] = env["table"];
864   }
865   if (!env["memoryBase"]) {
866    env["memoryBase"] = Module["STATIC_BASE"];
867   }
868   if (!env["tableBase"]) {
869    env["tableBase"] = 0;
870   }
871   var exports;
872   exports = doNativeWasm(global, env, providedBuffer);
873   if (!exports) abort("no binaryen method succeeded. consider enabling more options, like interpreting, if you want that: https://github.com/kripken/emscripten/wiki/WebAssembly#binaryen-methods");
874   return exports;
875  });
876 }
877 integrateWasmJS();
878 STATIC_BASE = GLOBAL_BASE;
879 STATICTOP = STATIC_BASE + 242832;
880 __ATINIT__.push({
881  func: (function() {
882   __GLOBAL__I_000101();
883  })
884 }, {
885  func: (function() {
886   __GLOBAL__sub_I_iostream_cpp();
887  })
888 });
889 var STATIC_BUMP = 242832;
890 Module["STATIC_BASE"] = STATIC_BASE;
891 Module["STATIC_BUMP"] = STATIC_BUMP;
892 var tempDoublePtr = STATICTOP;
893 STATICTOP += 16;
894 function __ZSt18uncaught_exceptionv() {
895  return !!__ZSt18uncaught_exceptionv.uncaught_exception;
896 }
897 function ___cxa_allocate_exception(size) {
898  return _malloc(size);
899 }
900 var EXCEPTIONS = {
901  last: 0,
902  caught: [],
903  infos: {},
904  deAdjust: (function(adjusted) {
905   if (!adjusted || EXCEPTIONS.infos[adjusted]) return adjusted;
906   for (var key in EXCEPTIONS.infos) {
907    var ptr = +key;
908    var info = EXCEPTIONS.infos[ptr];
909    if (info.adjusted === adjusted) {
910     return ptr;
911    }
912   }
913   return adjusted;
914  }),
915  addRef: (function(ptr) {
916   if (!ptr) return;
917   var info = EXCEPTIONS.infos[ptr];
918   info.refcount++;
919  }),
920  decRef: (function(ptr) {
921   if (!ptr) return;
922   var info = EXCEPTIONS.infos[ptr];
923   assert(info.refcount > 0);
924   info.refcount--;
925   if (info.refcount === 0 && !info.rethrown) {
926    if (info.destructor) {
927     Module["dynCall_vi"](info.destructor, ptr);
928    }
929    delete EXCEPTIONS.infos[ptr];
930    ___cxa_free_exception(ptr);
931   }
932  }),
933  clearRef: (function(ptr) {
934   if (!ptr) return;
935   var info = EXCEPTIONS.infos[ptr];
936   info.refcount = 0;
937  })
938 };
939 function ___cxa_begin_catch(ptr) {
940  var info = EXCEPTIONS.infos[ptr];
941  if (info && !info.caught) {
942   info.caught = true;
943   __ZSt18uncaught_exceptionv.uncaught_exception--;
944  }
945  if (info) info.rethrown = false;
946  EXCEPTIONS.caught.push(ptr);
947  EXCEPTIONS.addRef(EXCEPTIONS.deAdjust(ptr));
948  return ptr;
949 }
950 function ___resumeException(ptr) {
951  if (!EXCEPTIONS.last) {
952   EXCEPTIONS.last = ptr;
953  }
954  throw ptr + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.";
955 }
956 function ___cxa_find_matching_catch() {
957  var thrown = EXCEPTIONS.last;
958  if (!thrown) {
959   return (setTempRet0(0), 0) | 0;
960  }
961  var info = EXCEPTIONS.infos[thrown];
962  var throwntype = info.type;
963  if (!throwntype) {
964   return (setTempRet0(0), thrown) | 0;
965  }
966  var typeArray = Array.prototype.slice.call(arguments);
967  var pointer = Module["___cxa_is_pointer_type"](throwntype);
968  if (!___cxa_find_matching_catch.buffer) ___cxa_find_matching_catch.buffer = _malloc(4);
969  HEAP32[___cxa_find_matching_catch.buffer >> 2] = thrown;
970  thrown = ___cxa_find_matching_catch.buffer;
971  for (var i = 0; i < typeArray.length; i++) {
972   if (typeArray[i] && Module["___cxa_can_catch"](typeArray[i], throwntype, thrown)) {
973    thrown = HEAP32[thrown >> 2];
974    info.adjusted = thrown;
975    return (setTempRet0(typeArray[i]), thrown) | 0;
976   }
977  }
978  thrown = HEAP32[thrown >> 2];
979  return (setTempRet0(throwntype), thrown) | 0;
980 }
981 function ___cxa_throw(ptr, type, destructor) {
982  EXCEPTIONS.infos[ptr] = {
983   ptr: ptr,
984   adjusted: ptr,
985   type: type,
986   destructor: destructor,
987   refcount: 0,
988   caught: false,
989   rethrown: false
990  };
991  EXCEPTIONS.last = ptr;
992  if (!("uncaught_exception" in __ZSt18uncaught_exceptionv)) {
993   __ZSt18uncaught_exceptionv.uncaught_exception = 1;
994  } else {
995   __ZSt18uncaught_exceptionv.uncaught_exception++;
996  }
997  throw ptr + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.";
998 }
999 function ___gxx_personality_v0() {}
1000 function ___lock() {}
1001 var ERRNO_CODES = {
1002  EPERM: 1,
1003  ENOENT: 2,
1004  ESRCH: 3,
1005  EINTR: 4,
1006  EIO: 5,
1007  ENXIO: 6,
1008  E2BIG: 7,
1009  ENOEXEC: 8,
1010  EBADF: 9,
1011  ECHILD: 10,
1012  EAGAIN: 11,
1013  EWOULDBLOCK: 11,
1014  ENOMEM: 12,
1015  EACCES: 13,
1016  EFAULT: 14,
1017  ENOTBLK: 15,
1018  EBUSY: 16,
1019  EEXIST: 17,
1020  EXDEV: 18,
1021  ENODEV: 19,
1022  ENOTDIR: 20,
1023  EISDIR: 21,
1024  EINVAL: 22,
1025  ENFILE: 23,
1026  EMFILE: 24,
1027  ENOTTY: 25,
1028  ETXTBSY: 26,
1029  EFBIG: 27,
1030  ENOSPC: 28,
1031  ESPIPE: 29,
1032  EROFS: 30,
1033  EMLINK: 31,
1034  EPIPE: 32,
1035  EDOM: 33,
1036  ERANGE: 34,
1037  ENOMSG: 42,
1038  EIDRM: 43,
1039  ECHRNG: 44,
1040  EL2NSYNC: 45,
1041  EL3HLT: 46,
1042  EL3RST: 47,
1043  ELNRNG: 48,
1044  EUNATCH: 49,
1045  ENOCSI: 50,
1046  EL2HLT: 51,
1047  EDEADLK: 35,
1048  ENOLCK: 37,
1049  EBADE: 52,
1050  EBADR: 53,
1051  EXFULL: 54,
1052  ENOANO: 55,
1053  EBADRQC: 56,
1054  EBADSLT: 57,
1055  EDEADLOCK: 35,
1056  EBFONT: 59,
1057  ENOSTR: 60,
1058  ENODATA: 61,
1059  ETIME: 62,
1060  ENOSR: 63,
1061  ENONET: 64,
1062  ENOPKG: 65,
1063  EREMOTE: 66,
1064  ENOLINK: 67,
1065  EADV: 68,
1066  ESRMNT: 69,
1067  ECOMM: 70,
1068  EPROTO: 71,
1069  EMULTIHOP: 72,
1070  EDOTDOT: 73,
1071  EBADMSG: 74,
1072  ENOTUNIQ: 76,
1073  EBADFD: 77,
1074  EREMCHG: 78,
1075  ELIBACC: 79,
1076  ELIBBAD: 80,
1077  ELIBSCN: 81,
1078  ELIBMAX: 82,
1079  ELIBEXEC: 83,
1080  ENOSYS: 38,
1081  ENOTEMPTY: 39,
1082  ENAMETOOLONG: 36,
1083  ELOOP: 40,
1084  EOPNOTSUPP: 95,
1085  EPFNOSUPPORT: 96,
1086  ECONNRESET: 104,
1087  ENOBUFS: 105,
1088  EAFNOSUPPORT: 97,
1089  EPROTOTYPE: 91,
1090  ENOTSOCK: 88,
1091  ENOPROTOOPT: 92,
1092  ESHUTDOWN: 108,
1093  ECONNREFUSED: 111,
1094  EADDRINUSE: 98,
1095  ECONNABORTED: 103,
1096  ENETUNREACH: 101,
1097  ENETDOWN: 100,
1098  ETIMEDOUT: 110,
1099  EHOSTDOWN: 112,
1100  EHOSTUNREACH: 113,
1101  EINPROGRESS: 115,
1102  EALREADY: 114,
1103  EDESTADDRREQ: 89,
1104  EMSGSIZE: 90,
1105  EPROTONOSUPPORT: 93,
1106  ESOCKTNOSUPPORT: 94,
1107  EADDRNOTAVAIL: 99,
1108  ENETRESET: 102,
1109  EISCONN: 106,
1110  ENOTCONN: 107,
1111  ETOOMANYREFS: 109,
1112  EUSERS: 87,
1113  EDQUOT: 122,
1114  ESTALE: 116,
1115  ENOTSUP: 95,
1116  ENOMEDIUM: 123,
1117  EILSEQ: 84,
1118  EOVERFLOW: 75,
1119  ECANCELED: 125,
1120  ENOTRECOVERABLE: 131,
1121  EOWNERDEAD: 130,
1122  ESTRPIPE: 86
1123 };
1124 function ___setErrNo(value) {
1125  if (Module["___errno_location"]) HEAP32[Module["___errno_location"]() >> 2] = value;
1126  return value;
1127 }
1128 function ___map_file(pathname, size) {
1129  ___setErrNo(ERRNO_CODES.EPERM);
1130  return -1;
1131 }
1132 var ERRNO_MESSAGES = {
1133  0: "Success",
1134  1: "Not super-user",
1135  2: "No such file or directory",
1136  3: "No such process",
1137  4: "Interrupted system call",
1138  5: "I/O error",
1139  6: "No such device or address",
1140  7: "Arg list too long",
1141  8: "Exec format error",
1142  9: "Bad file number",
1143  10: "No children",
1144  11: "No more processes",
1145  12: "Not enough core",
1146  13: "Permission denied",
1147  14: "Bad address",
1148  15: "Block device required",
1149  16: "Mount device busy",
1150  17: "File exists",
1151  18: "Cross-device link",
1152  19: "No such device",
1153  20: "Not a directory",
1154  21: "Is a directory",
1155  22: "Invalid argument",
1156  23: "Too many open files in system",
1157  24: "Too many open files",
1158  25: "Not a typewriter",
1159  26: "Text file busy",
1160  27: "File too large",
1161  28: "No space left on device",
1162  29: "Illegal seek",
1163  30: "Read only file system",
1164  31: "Too many links",
1165  32: "Broken pipe",
1166  33: "Math arg out of domain of func",
1167  34: "Math result not representable",
1168  35: "File locking deadlock error",
1169  36: "File or path name too long",
1170  37: "No record locks available",
1171  38: "Function not implemented",
1172  39: "Directory not empty",
1173  40: "Too many symbolic links",
1174  42: "No message of desired type",
1175  43: "Identifier removed",
1176  44: "Channel number out of range",
1177  45: "Level 2 not synchronized",
1178  46: "Level 3 halted",
1179  47: "Level 3 reset",
1180  48: "Link number out of range",
1181  49: "Protocol driver not attached",
1182  50: "No CSI structure available",
1183  51: "Level 2 halted",
1184  52: "Invalid exchange",
1185  53: "Invalid request descriptor",
1186  54: "Exchange full",
1187  55: "No anode",
1188  56: "Invalid request code",
1189  57: "Invalid slot",
1190  59: "Bad font file fmt",
1191  60: "Device not a stream",
1192  61: "No data (for no delay io)",
1193  62: "Timer expired",
1194  63: "Out of streams resources",
1195  64: "Machine is not on the network",
1196  65: "Package not installed",
1197  66: "The object is remote",
1198  67: "The link has been severed",
1199  68: "Advertise error",
1200  69: "Srmount error",
1201  70: "Communication error on send",
1202  71: "Protocol error",
1203  72: "Multihop attempted",
1204  73: "Cross mount point (not really error)",
1205  74: "Trying to read unreadable message",
1206  75: "Value too large for defined data type",
1207  76: "Given log. name not unique",
1208  77: "f.d. invalid for this operation",
1209  78: "Remote address changed",
1210  79: "Can   access a needed shared lib",
1211  80: "Accessing a corrupted shared lib",
1212  81: ".lib section in a.out corrupted",
1213  82: "Attempting to link in too many libs",
1214  83: "Attempting to exec a shared library",
1215  84: "Illegal byte sequence",
1216  86: "Streams pipe error",
1217  87: "Too many users",
1218  88: "Socket operation on non-socket",
1219  89: "Destination address required",
1220  90: "Message too long",
1221  91: "Protocol wrong type for socket",
1222  92: "Protocol not available",
1223  93: "Unknown protocol",
1224  94: "Socket type not supported",
1225  95: "Not supported",
1226  96: "Protocol family not supported",
1227  97: "Address family not supported by protocol family",
1228  98: "Address already in use",
1229  99: "Address not available",
1230  100: "Network interface is not configured",
1231  101: "Network is unreachable",
1232  102: "Connection reset by network",
1233  103: "Connection aborted",
1234  104: "Connection reset by peer",
1235  105: "No buffer space available",
1236  106: "Socket is already connected",
1237  107: "Socket is not connected",
1238  108: "Can't send after socket shutdown",
1239  109: "Too many references",
1240  110: "Connection timed out",
1241  111: "Connection refused",
1242  112: "Host is down",
1243  113: "Host is unreachable",
1244  114: "Socket already connected",
1245  115: "Connection already in progress",
1246  116: "Stale file handle",
1247  122: "Quota exceeded",
1248  123: "No medium (in tape drive)",
1249  125: "Operation canceled",
1250  130: "Previous owner died",
1251  131: "State not recoverable"
1252 };
1253 var PATH = {
1254  splitPath: (function(filename) {
1255   var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
1256   return splitPathRe.exec(filename).slice(1);
1257  }),
1258  normalizeArray: (function(parts, allowAboveRoot) {
1259   var up = 0;
1260   for (var i = parts.length - 1; i >= 0; i--) {
1261    var last = parts[i];
1262    if (last === ".") {
1263     parts.splice(i, 1);
1264    } else if (last === "..") {
1265     parts.splice(i, 1);
1266     up++;
1267    } else if (up) {
1268     parts.splice(i, 1);
1269     up--;
1270    }
1271   }
1272   if (allowAboveRoot) {
1273    for (; up; up--) {
1274     parts.unshift("..");
1275    }
1276   }
1277   return parts;
1278  }),
1279  normalize: (function(path) {
1280   var isAbsolute = path.charAt(0) === "/", trailingSlash = path.substr(-1) === "/";
1281   path = PATH.normalizeArray(path.split("/").filter((function(p) {
1282    return !!p;
1283   })), !isAbsolute).join("/");
1284   if (!path && !isAbsolute) {
1285    path = ".";
1286   }
1287   if (path && trailingSlash) {
1288    path += "/";
1289   }
1290   return (isAbsolute ? "/" : "") + path;
1291  }),
1292  dirname: (function(path) {
1293   var result = PATH.splitPath(path), root = result[0], dir = result[1];
1294   if (!root && !dir) {
1295    return ".";
1296   }
1297   if (dir) {
1298    dir = dir.substr(0, dir.length - 1);
1299   }
1300   return root + dir;
1301  }),
1302  basename: (function(path) {
1303   if (path === "/") return "/";
1304   var lastSlash = path.lastIndexOf("/");
1305   if (lastSlash === -1) return path;
1306   return path.substr(lastSlash + 1);
1307  }),
1308  extname: (function(path) {
1309   return PATH.splitPath(path)[3];
1310  }),
1311  join: (function() {
1312   var paths = Array.prototype.slice.call(arguments, 0);
1313   return PATH.normalize(paths.join("/"));
1314  }),
1315  join2: (function(l, r) {
1316   return PATH.normalize(l + "/" + r);
1317  }),
1318  resolve: (function() {
1319   var resolvedPath = "", resolvedAbsolute = false;
1320   for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
1321    var path = i >= 0 ? arguments[i] : FS.cwd();
1322    if (typeof path !== "string") {
1323     throw new TypeError("Arguments to path.resolve must be strings");
1324    } else if (!path) {
1325     return "";
1326    }
1327    resolvedPath = path + "/" + resolvedPath;
1328    resolvedAbsolute = path.charAt(0) === "/";
1329   }
1330   resolvedPath = PATH.normalizeArray(resolvedPath.split("/").filter((function(p) {
1331    return !!p;
1332   })), !resolvedAbsolute).join("/");
1333   return (resolvedAbsolute ? "/" : "") + resolvedPath || ".";
1334  }),
1335  relative: (function(from, to) {
1336   from = PATH.resolve(from).substr(1);
1337   to = PATH.resolve(to).substr(1);
1338   function trim(arr) {
1339    var start = 0;
1340    for (; start < arr.length; start++) {
1341     if (arr[start] !== "") break;
1342    }
1343    var end = arr.length - 1;
1344    for (; end >= 0; end--) {
1345     if (arr[end] !== "") break;
1346    }
1347    if (start > end) return [];
1348    return arr.slice(start, end - start + 1);
1349   }
1350   var fromParts = trim(from.split("/"));
1351   var toParts = trim(to.split("/"));
1352   var length = Math.min(fromParts.length, toParts.length);
1353   var samePartsLength = length;
1354   for (var i = 0; i < length; i++) {
1355    if (fromParts[i] !== toParts[i]) {
1356     samePartsLength = i;
1357     break;
1358    }
1359   }
1360   var outputParts = [];
1361   for (var i = samePartsLength; i < fromParts.length; i++) {
1362    outputParts.push("..");
1363   }
1364   outputParts = outputParts.concat(toParts.slice(samePartsLength));
1365   return outputParts.join("/");
1366  })
1367 };
1368 var TTY = {
1369  ttys: [],
1370  init: (function() {}),
1371  shutdown: (function() {}),
1372  register: (function(dev, ops) {
1373   TTY.ttys[dev] = {
1374    input: [],
1375    output: [],
1376    ops: ops
1377   };
1378   FS.registerDevice(dev, TTY.stream_ops);
1379  }),
1380  stream_ops: {
1381   open: (function(stream) {
1382    var tty = TTY.ttys[stream.node.rdev];
1383    if (!tty) {
1384     throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
1385    }
1386    stream.tty = tty;
1387    stream.seekable = false;
1388   }),
1389   close: (function(stream) {
1390    stream.tty.ops.flush(stream.tty);
1391   }),
1392   flush: (function(stream) {
1393    stream.tty.ops.flush(stream.tty);
1394   }),
1395   read: (function(stream, buffer, offset, length, pos) {
1396    if (!stream.tty || !stream.tty.ops.get_char) {
1397     throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
1398    }
1399    var bytesRead = 0;
1400    for (var i = 0; i < length; i++) {
1401     var result;
1402     try {
1403      result = stream.tty.ops.get_char(stream.tty);
1404     } catch (e) {
1405      throw new FS.ErrnoError(ERRNO_CODES.EIO);
1406     }
1407     if (result === undefined && bytesRead === 0) {
1408      throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
1409     }
1410     if (result === null || result === undefined) break;
1411     bytesRead++;
1412     buffer[offset + i] = result;
1413    }
1414    if (bytesRead) {
1415     stream.node.timestamp = Date.now();
1416    }
1417    return bytesRead;
1418   }),
1419   write: (function(stream, buffer, offset, length, pos) {
1420    if (!stream.tty || !stream.tty.ops.put_char) {
1421     throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
1422    }
1423    for (var i = 0; i < length; i++) {
1424     try {
1425      stream.tty.ops.put_char(stream.tty, buffer[offset + i]);
1426     } catch (e) {
1427      throw new FS.ErrnoError(ERRNO_CODES.EIO);
1428     }
1429    }
1430    if (length) {
1431     stream.node.timestamp = Date.now();
1432    }
1433    return i;
1434   })
1435  },
1436  default_tty_ops: {
1437   get_char: (function(tty) {
1438    if (!tty.input.length) {
1439     var result = null;
1440     if (ENVIRONMENT_IS_NODE) {
1441      var BUFSIZE = 256;
1442      var buf = new Buffer(BUFSIZE);
1443      var bytesRead = 0;
1444      var isPosixPlatform = process.platform != "win32";
1445      var fd = process.stdin.fd;
1446      if (isPosixPlatform) {
1447       var usingDevice = false;
1448       try {
1449        fd = fs.openSync("/dev/stdin", "r");
1450        usingDevice = true;
1451       } catch (e) {}
1452      }
1453      try {
1454       bytesRead = fs.readSync(fd, buf, 0, BUFSIZE, null);
1455      } catch (e) {
1456       if (e.toString().indexOf("EOF") != -1) bytesRead = 0; else throw e;
1457      }
1458      if (usingDevice) {
1459       fs.closeSync(fd);
1460      }
1461      if (bytesRead > 0) {
1462       result = buf.slice(0, bytesRead).toString("utf-8");
1463      } else {
1464       result = null;
1465      }
1466     } else if (typeof window != "undefined" && typeof window.prompt == "function") {
1467      result = window.prompt("Input: ");
1468      if (result !== null) {
1469       result += "\n";
1470      }
1471     } else if (typeof readline == "function") {
1472      result = readline();
1473      if (result !== null) {
1474       result += "\n";
1475      }
1476     }
1477     if (!result) {
1478      return null;
1479     }
1480     tty.input = intArrayFromString(result, true);
1481    }
1482    return tty.input.shift();
1483   }),
1484   put_char: (function(tty, val) {
1485    if (val === null || val === 10) {
1486     Module["print"](UTF8ArrayToString(tty.output, 0));
1487     tty.output = [];
1488    } else {
1489     if (val != 0) tty.output.push(val);
1490    }
1491   }),
1492   flush: (function(tty) {
1493    if (tty.output && tty.output.length > 0) {
1494     Module["print"](UTF8ArrayToString(tty.output, 0));
1495     tty.output = [];
1496    }
1497   })
1498  },
1499  default_tty1_ops: {
1500   put_char: (function(tty, val) {
1501    if (val === null || val === 10) {
1502     Module["printErr"](UTF8ArrayToString(tty.output, 0));
1503     tty.output = [];
1504    } else {
1505     if (val != 0) tty.output.push(val);
1506    }
1507   }),
1508   flush: (function(tty) {
1509    if (tty.output && tty.output.length > 0) {
1510     Module["printErr"](UTF8ArrayToString(tty.output, 0));
1511     tty.output = [];
1512    }
1513   })
1514  }
1515 };
1516 var MEMFS = {
1517  ops_table: null,
1518  mount: (function(mount) {
1519   return MEMFS.createNode(null, "/", 16384 | 511, 0);
1520  }),
1521  createNode: (function(parent, name, mode, dev) {
1522   if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
1523    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
1524   }
1525   if (!MEMFS.ops_table) {
1526    MEMFS.ops_table = {
1527     dir: {
1528      node: {
1529       getattr: MEMFS.node_ops.getattr,
1530       setattr: MEMFS.node_ops.setattr,
1531       lookup: MEMFS.node_ops.lookup,
1532       mknod: MEMFS.node_ops.mknod,
1533       rename: MEMFS.node_ops.rename,
1534       unlink: MEMFS.node_ops.unlink,
1535       rmdir: MEMFS.node_ops.rmdir,
1536       readdir: MEMFS.node_ops.readdir,
1537       symlink: MEMFS.node_ops.symlink
1538      },
1539      stream: {
1540       llseek: MEMFS.stream_ops.llseek
1541      }
1542     },
1543     file: {
1544      node: {
1545       getattr: MEMFS.node_ops.getattr,
1546       setattr: MEMFS.node_ops.setattr
1547      },
1548      stream: {
1549       llseek: MEMFS.stream_ops.llseek,
1550       read: MEMFS.stream_ops.read,
1551       write: MEMFS.stream_ops.write,
1552       allocate: MEMFS.stream_ops.allocate,
1553       mmap: MEMFS.stream_ops.mmap,
1554       msync: MEMFS.stream_ops.msync
1555      }
1556     },
1557     link: {
1558      node: {
1559       getattr: MEMFS.node_ops.getattr,
1560       setattr: MEMFS.node_ops.setattr,
1561       readlink: MEMFS.node_ops.readlink
1562      },
1563      stream: {}
1564     },
1565     chrdev: {
1566      node: {
1567       getattr: MEMFS.node_ops.getattr,
1568       setattr: MEMFS.node_ops.setattr
1569      },
1570      stream: FS.chrdev_stream_ops
1571     }
1572    };
1573   }
1574   var node = FS.createNode(parent, name, mode, dev);
1575   if (FS.isDir(node.mode)) {
1576    node.node_ops = MEMFS.ops_table.dir.node;
1577    node.stream_ops = MEMFS.ops_table.dir.stream;
1578    node.contents = {};
1579   } else if (FS.isFile(node.mode)) {
1580    node.node_ops = MEMFS.ops_table.file.node;
1581    node.stream_ops = MEMFS.ops_table.file.stream;
1582    node.usedBytes = 0;
1583    node.contents = null;
1584   } else if (FS.isLink(node.mode)) {
1585    node.node_ops = MEMFS.ops_table.link.node;
1586    node.stream_ops = MEMFS.ops_table.link.stream;
1587   } else if (FS.isChrdev(node.mode)) {
1588    node.node_ops = MEMFS.ops_table.chrdev.node;
1589    node.stream_ops = MEMFS.ops_table.chrdev.stream;
1590   }
1591   node.timestamp = Date.now();
1592   if (parent) {
1593    parent.contents[name] = node;
1594   }
1595   return node;
1596  }),
1597  getFileDataAsRegularArray: (function(node) {
1598   if (node.contents && node.contents.subarray) {
1599    var arr = [];
1600    for (var i = 0; i < node.usedBytes; ++i) arr.push(node.contents[i]);
1601    return arr;
1602   }
1603   return node.contents;
1604  }),
1605  getFileDataAsTypedArray: (function(node) {
1606   if (!node.contents) return new Uint8Array;
1607   if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes);
1608   return new Uint8Array(node.contents);
1609  }),
1610  expandFileStorage: (function(node, newCapacity) {
1611   if (node.contents && node.contents.subarray && newCapacity > node.contents.length) {
1612    node.contents = MEMFS.getFileDataAsRegularArray(node);
1613    node.usedBytes = node.contents.length;
1614   }
1615   if (!node.contents || node.contents.subarray) {
1616    var prevCapacity = node.contents ? node.contents.length : 0;
1617    if (prevCapacity >= newCapacity) return;
1618    var CAPACITY_DOUBLING_MAX = 1024 * 1024;
1619    newCapacity = Math.max(newCapacity, prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125) | 0);
1620    if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256);
1621    var oldContents = node.contents;
1622    node.contents = new Uint8Array(newCapacity);
1623    if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0);
1624    return;
1625   }
1626   if (!node.contents && newCapacity > 0) node.contents = [];
1627   while (node.contents.length < newCapacity) node.contents.push(0);
1628  }),
1629  resizeFileStorage: (function(node, newSize) {
1630   if (node.usedBytes == newSize) return;
1631   if (newSize == 0) {
1632    node.contents = null;
1633    node.usedBytes = 0;
1634    return;
1635   }
1636   if (!node.contents || node.contents.subarray) {
1637    var oldContents = node.contents;
1638    node.contents = new Uint8Array(new ArrayBuffer(newSize));
1639    if (oldContents) {
1640     node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes)));
1641    }
1642    node.usedBytes = newSize;
1643    return;
1644   }
1645   if (!node.contents) node.contents = [];
1646   if (node.contents.length > newSize) node.contents.length = newSize; else while (node.contents.length < newSize) node.contents.push(0);
1647   node.usedBytes = newSize;
1648  }),
1649  node_ops: {
1650   getattr: (function(node) {
1651    var attr = {};
1652    attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
1653    attr.ino = node.id;
1654    attr.mode = node.mode;
1655    attr.nlink = 1;
1656    attr.uid = 0;
1657    attr.gid = 0;
1658    attr.rdev = node.rdev;
1659    if (FS.isDir(node.mode)) {
1660     attr.size = 4096;
1661    } else if (FS.isFile(node.mode)) {
1662     attr.size = node.usedBytes;
1663    } else if (FS.isLink(node.mode)) {
1664     attr.size = node.link.length;
1665    } else {
1666     attr.size = 0;
1667    }
1668    attr.atime = new Date(node.timestamp);
1669    attr.mtime = new Date(node.timestamp);
1670    attr.ctime = new Date(node.timestamp);
1671    attr.blksize = 4096;
1672    attr.blocks = Math.ceil(attr.size / attr.blksize);
1673    return attr;
1674   }),
1675   setattr: (function(node, attr) {
1676    if (attr.mode !== undefined) {
1677     node.mode = attr.mode;
1678    }
1679    if (attr.timestamp !== undefined) {
1680     node.timestamp = attr.timestamp;
1681    }
1682    if (attr.size !== undefined) {
1683     MEMFS.resizeFileStorage(node, attr.size);
1684    }
1685   }),
1686   lookup: (function(parent, name) {
1687    throw FS.genericErrors[ERRNO_CODES.ENOENT];
1688   }),
1689   mknod: (function(parent, name, mode, dev) {
1690    return MEMFS.createNode(parent, name, mode, dev);
1691   }),
1692   rename: (function(old_node, new_dir, new_name) {
1693    if (FS.isDir(old_node.mode)) {
1694     var new_node;
1695     try {
1696      new_node = FS.lookupNode(new_dir, new_name);
1697     } catch (e) {}
1698     if (new_node) {
1699      for (var i in new_node.contents) {
1700       throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
1701      }
1702     }
1703    }
1704    delete old_node.parent.contents[old_node.name];
1705    old_node.name = new_name;
1706    new_dir.contents[new_name] = old_node;
1707    old_node.parent = new_dir;
1708   }),
1709   unlink: (function(parent, name) {
1710    delete parent.contents[name];
1711   }),
1712   rmdir: (function(parent, name) {
1713    var node = FS.lookupNode(parent, name);
1714    for (var i in node.contents) {
1715     throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
1716    }
1717    delete parent.contents[name];
1718   }),
1719   readdir: (function(node) {
1720    var entries = [ ".", ".." ];
1721    for (var key in node.contents) {
1722     if (!node.contents.hasOwnProperty(key)) {
1723      continue;
1724     }
1725     entries.push(key);
1726    }
1727    return entries;
1728   }),
1729   symlink: (function(parent, newname, oldpath) {
1730    var node = MEMFS.createNode(parent, newname, 511 | 40960, 0);
1731    node.link = oldpath;
1732    return node;
1733   }),
1734   readlink: (function(node) {
1735    if (!FS.isLink(node.mode)) {
1736     throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
1737    }
1738    return node.link;
1739   })
1740  },
1741  stream_ops: {
1742   read: (function(stream, buffer, offset, length, position) {
1743    var contents = stream.node.contents;
1744    if (position >= stream.node.usedBytes) return 0;
1745    var size = Math.min(stream.node.usedBytes - position, length);
1746    assert(size >= 0);
1747    if (size > 8 && contents.subarray) {
1748     buffer.set(contents.subarray(position, position + size), offset);
1749    } else {
1750     for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
1751    }
1752    return size;
1753   }),
1754   write: (function(stream, buffer, offset, length, position, canOwn) {
1755    if (!length) return 0;
1756    var node = stream.node;
1757    node.timestamp = Date.now();
1758    if (buffer.subarray && (!node.contents || node.contents.subarray)) {
1759     if (canOwn) {
1760      node.contents = buffer.subarray(offset, offset + length);
1761      node.usedBytes = length;
1762      return length;
1763     } else if (node.usedBytes === 0 && position === 0) {
1764      node.contents = new Uint8Array(buffer.subarray(offset, offset + length));
1765      node.usedBytes = length;
1766      return length;
1767     } else if (position + length <= node.usedBytes) {
1768      node.contents.set(buffer.subarray(offset, offset + length), position);
1769      return length;
1770     }
1771    }
1772    MEMFS.expandFileStorage(node, position + length);
1773    if (node.contents.subarray && buffer.subarray) node.contents.set(buffer.subarray(offset, offset + length), position); else {
1774     for (var i = 0; i < length; i++) {
1775      node.contents[position + i] = buffer[offset + i];
1776     }
1777    }
1778    node.usedBytes = Math.max(node.usedBytes, position + length);
1779    return length;
1780   }),
1781   llseek: (function(stream, offset, whence) {
1782    var position = offset;
1783    if (whence === 1) {
1784     position += stream.position;
1785    } else if (whence === 2) {
1786     if (FS.isFile(stream.node.mode)) {
1787      position += stream.node.usedBytes;
1788     }
1789    }
1790    if (position < 0) {
1791     throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
1792    }
1793    return position;
1794   }),
1795   allocate: (function(stream, offset, length) {
1796    MEMFS.expandFileStorage(stream.node, offset + length);
1797    stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length);
1798   }),
1799   mmap: (function(stream, buffer, offset, length, position, prot, flags) {
1800    if (!FS.isFile(stream.node.mode)) {
1801     throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
1802    }
1803    var ptr;
1804    var allocated;
1805    var contents = stream.node.contents;
1806    if (!(flags & 2) && (contents.buffer === buffer || contents.buffer === buffer.buffer)) {
1807     allocated = false;
1808     ptr = contents.byteOffset;
1809    } else {
1810     if (position > 0 || position + length < stream.node.usedBytes) {
1811      if (contents.subarray) {
1812       contents = contents.subarray(position, position + length);
1813      } else {
1814       contents = Array.prototype.slice.call(contents, position, position + length);
1815      }
1816     }
1817     allocated = true;
1818     ptr = _malloc(length);
1819     if (!ptr) {
1820      throw new FS.ErrnoError(ERRNO_CODES.ENOMEM);
1821     }
1822     buffer.set(contents, ptr);
1823    }
1824    return {
1825     ptr: ptr,
1826     allocated: allocated
1827    };
1828   }),
1829   msync: (function(stream, buffer, offset, length, mmapFlags) {
1830    if (!FS.isFile(stream.node.mode)) {
1831     throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
1832    }
1833    if (mmapFlags & 2) {
1834     return 0;
1835    }
1836    var bytesWritten = MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
1837    return 0;
1838   })
1839  }
1840 };
1841 var IDBFS = {
1842  dbs: {},
1843  indexedDB: (function() {
1844   if (typeof indexedDB !== "undefined") return indexedDB;
1845   var ret = null;
1846   if (typeof window === "object") ret = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
1847   assert(ret, "IDBFS used, but indexedDB not supported");
1848   return ret;
1849  }),
1850  DB_VERSION: 21,
1851  DB_STORE_NAME: "FILE_DATA",
1852  mount: (function(mount) {
1853   return MEMFS.mount.apply(null, arguments);
1854  }),
1855  syncfs: (function(mount, populate, callback) {
1856   IDBFS.getLocalSet(mount, (function(err, local) {
1857    if (err) return callback(err);
1858    IDBFS.getRemoteSet(mount, (function(err, remote) {
1859     if (err) return callback(err);
1860     var src = populate ? remote : local;
1861     var dst = populate ? local : remote;
1862     IDBFS.reconcile(src, dst, callback);
1863    }));
1864   }));
1865  }),
1866  getDB: (function(name, callback) {
1867   var db = IDBFS.dbs[name];
1868   if (db) {
1869    return callback(null, db);
1870   }
1871   var req;
1872   try {
1873    req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION);
1874   } catch (e) {
1875    return callback(e);
1876   }
1877   if (!req) {
1878    return callback("Unable to connect to IndexedDB");
1879   }
1880   req.onupgradeneeded = (function(e) {
1881    var db = e.target.result;
1882    var transaction = e.target.transaction;
1883    var fileStore;
1884    if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) {
1885     fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME);
1886    } else {
1887     fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME);
1888    }
1889    if (!fileStore.indexNames.contains("timestamp")) {
1890     fileStore.createIndex("timestamp", "timestamp", {
1891      unique: false
1892     });
1893    }
1894   });
1895   req.onsuccess = (function() {
1896    db = req.result;
1897    IDBFS.dbs[name] = db;
1898    callback(null, db);
1899   });
1900   req.onerror = (function(e) {
1901    callback(this.error);
1902    e.preventDefault();
1903   });
1904  }),
1905  getLocalSet: (function(mount, callback) {
1906   var entries = {};
1907   function isRealDir(p) {
1908    return p !== "." && p !== "..";
1909   }
1910   function toAbsolute(root) {
1911    return (function(p) {
1912     return PATH.join2(root, p);
1913    });
1914   }
1915   var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint));
1916   while (check.length) {
1917    var path = check.pop();
1918    var stat;
1919    try {
1920     stat = FS.stat(path);
1921    } catch (e) {
1922     return callback(e);
1923    }
1924    if (FS.isDir(stat.mode)) {
1925     check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
1926    }
1927    entries[path] = {
1928     timestamp: stat.mtime
1929    };
1930   }
1931   return callback(null, {
1932    type: "local",
1933    entries: entries
1934   });
1935  }),
1936  getRemoteSet: (function(mount, callback) {
1937   var entries = {};
1938   IDBFS.getDB(mount.mountpoint, (function(err, db) {
1939    if (err) return callback(err);
1940    try {
1941     var transaction = db.transaction([ IDBFS.DB_STORE_NAME ], "readonly");
1942     transaction.onerror = (function(e) {
1943      callback(this.error);
1944      e.preventDefault();
1945     });
1946     var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
1947     var index = store.index("timestamp");
1948     index.openKeyCursor().onsuccess = (function(event) {
1949      var cursor = event.target.result;
1950      if (!cursor) {
1951       return callback(null, {
1952        type: "remote",
1953        db: db,
1954        entries: entries
1955       });
1956      }
1957      entries[cursor.primaryKey] = {
1958       timestamp: cursor.key
1959      };
1960      cursor.continue();
1961     });
1962    } catch (e) {
1963     return callback(e);
1964    }
1965   }));
1966  }),
1967  loadLocalEntry: (function(path, callback) {
1968   var stat, node;
1969   try {
1970    var lookup = FS.lookupPath(path);
1971    node = lookup.node;
1972    stat = FS.stat(path);
1973   } catch (e) {
1974    return callback(e);
1975   }
1976   if (FS.isDir(stat.mode)) {
1977    return callback(null, {
1978     timestamp: stat.mtime,
1979     mode: stat.mode
1980    });
1981   } else if (FS.isFile(stat.mode)) {
1982    node.contents = MEMFS.getFileDataAsTypedArray(node);
1983    return callback(null, {
1984     timestamp: stat.mtime,
1985     mode: stat.mode,
1986     contents: node.contents
1987    });
1988   } else {
1989    return callback(new Error("node type not supported"));
1990   }
1991  }),
1992  storeLocalEntry: (function(path, entry, callback) {
1993   try {
1994    if (FS.isDir(entry.mode)) {
1995     FS.mkdir(path, entry.mode);
1996    } else if (FS.isFile(entry.mode)) {
1997     FS.writeFile(path, entry.contents, {
1998      canOwn: true
1999     });
2000    } else {
2001     return callback(new Error("node type not supported"));
2002    }
2003    FS.chmod(path, entry.mode);
2004    FS.utime(path, entry.timestamp, entry.timestamp);
2005   } catch (e) {
2006    return callback(e);
2007   }
2008   callback(null);
2009  }),
2010  removeLocalEntry: (function(path, callback) {
2011   try {
2012    var lookup = FS.lookupPath(path);
2013    var stat = FS.stat(path);
2014    if (FS.isDir(stat.mode)) {
2015     FS.rmdir(path);
2016    } else if (FS.isFile(stat.mode)) {
2017     FS.unlink(path);
2018    }
2019   } catch (e) {
2020    return callback(e);
2021   }
2022   callback(null);
2023  }),
2024  loadRemoteEntry: (function(store, path, callback) {
2025   var req = store.get(path);
2026   req.onsuccess = (function(event) {
2027    callback(null, event.target.result);
2028   });
2029   req.onerror = (function(e) {
2030    callback(this.error);
2031    e.preventDefault();
2032   });
2033  }),
2034  storeRemoteEntry: (function(store, path, entry, callback) {
2035   var req = store.put(entry, path);
2036   req.onsuccess = (function() {
2037    callback(null);
2038   });
2039   req.onerror = (function(e) {
2040    callback(this.error);
2041    e.preventDefault();
2042   });
2043  }),
2044  removeRemoteEntry: (function(store, path, callback) {
2045   var req = store.delete(path);
2046   req.onsuccess = (function() {
2047    callback(null);
2048   });
2049   req.onerror = (function(e) {
2050    callback(this.error);
2051    e.preventDefault();
2052   });
2053  }),
2054  reconcile: (function(src, dst, callback) {
2055   var total = 0;
2056   var create = [];
2057   Object.keys(src.entries).forEach((function(key) {
2058    var e = src.entries[key];
2059    var e2 = dst.entries[key];
2060    if (!e2 || e.timestamp > e2.timestamp) {
2061     create.push(key);
2062     total++;
2063    }
2064   }));
2065   var remove = [];
2066   Object.keys(dst.entries).forEach((function(key) {
2067    var e = dst.entries[key];
2068    var e2 = src.entries[key];
2069    if (!e2) {
2070     remove.push(key);
2071     total++;
2072    }
2073   }));
2074   if (!total) {
2075    return callback(null);
2076   }
2077   var completed = 0;
2078   var db = src.type === "remote" ? src.db : dst.db;
2079   var transaction = db.transaction([ IDBFS.DB_STORE_NAME ], "readwrite");
2080   var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
2081   function done(err) {
2082    if (err) {
2083     if (!done.errored) {
2084      done.errored = true;
2085      return callback(err);
2086     }
2087     return;
2088    }
2089    if (++completed >= total) {
2090     return callback(null);
2091    }
2092   }
2093   transaction.onerror = (function(e) {
2094    done(this.error);
2095    e.preventDefault();
2096   });
2097   create.sort().forEach((function(path) {
2098    if (dst.type === "local") {
2099     IDBFS.loadRemoteEntry(store, path, (function(err, entry) {
2100      if (err) return done(err);
2101      IDBFS.storeLocalEntry(path, entry, done);
2102     }));
2103    } else {
2104     IDBFS.loadLocalEntry(path, (function(err, entry) {
2105      if (err) return done(err);
2106      IDBFS.storeRemoteEntry(store, path, entry, done);
2107     }));
2108    }
2109   }));
2110   remove.sort().reverse().forEach((function(path) {
2111    if (dst.type === "local") {
2112     IDBFS.removeLocalEntry(path, done);
2113    } else {
2114     IDBFS.removeRemoteEntry(store, path, done);
2115    }
2116   }));
2117  })
2118 };
2119 var NODEFS = {
2120  isWindows: false,
2121  staticInit: (function() {
2122   NODEFS.isWindows = !!process.platform.match(/^win/);
2123   var flags = process["binding"]("constants");
2124   if (flags["fs"]) {
2125    flags = flags["fs"];
2126   }
2127   NODEFS.flagsForNodeMap = {
2128    "1024": flags["O_APPEND"],
2129    "64": flags["O_CREAT"],
2130    "128": flags["O_EXCL"],
2131    "0": flags["O_RDONLY"],
2132    "2": flags["O_RDWR"],
2133    "4096": flags["O_SYNC"],
2134    "512": flags["O_TRUNC"],
2135    "1": flags["O_WRONLY"]
2136   };
2137  }),
2138  bufferFrom: (function(arrayBuffer) {
2139   return Buffer.alloc ? Buffer.from(arrayBuffer) : new Buffer(arrayBuffer);
2140  }),
2141  mount: (function(mount) {
2142   assert(ENVIRONMENT_IS_NODE);
2143   return NODEFS.createNode(null, "/", NODEFS.getMode(mount.opts.root), 0);
2144  }),
2145  createNode: (function(parent, name, mode, dev) {
2146   if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) {
2147    throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
2148   }
2149   var node = FS.createNode(parent, name, mode);
2150   node.node_ops = NODEFS.node_ops;
2151   node.stream_ops = NODEFS.stream_ops;
2152   return node;
2153  }),
2154  getMode: (function(path) {
2155   var stat;
2156   try {
2157    stat = fs.lstatSync(path);
2158    if (NODEFS.isWindows) {
2159     stat.mode = stat.mode | (stat.mode & 292) >> 2;
2160    }
2161   } catch (e) {
2162    if (!e.code) throw e;
2163    throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2164   }
2165   return stat.mode;
2166  }),
2167  realPath: (function(node) {
2168   var parts = [];
2169   while (node.parent !== node) {
2170    parts.push(node.name);
2171    node = node.parent;
2172   }
2173   parts.push(node.mount.opts.root);
2174   parts.reverse();
2175   return PATH.join.apply(null, parts);
2176  }),
2177  flagsForNode: (function(flags) {
2178   flags &= ~2097152;
2179   flags &= ~2048;
2180   flags &= ~32768;
2181   flags &= ~524288;
2182   var newFlags = 0;
2183   for (var k in NODEFS.flagsForNodeMap) {
2184    if (flags & k) {
2185     newFlags |= NODEFS.flagsForNodeMap[k];
2186     flags ^= k;
2187    }
2188   }
2189   if (!flags) {
2190    return newFlags;
2191   } else {
2192    throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
2193   }
2194  }),
2195  node_ops: {
2196   getattr: (function(node) {
2197    var path = NODEFS.realPath(node);
2198    var stat;
2199    try {
2200     stat = fs.lstatSync(path);
2201    } catch (e) {
2202     if (!e.code) throw e;
2203     throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2204    }
2205    if (NODEFS.isWindows && !stat.blksize) {
2206     stat.blksize = 4096;
2207    }
2208    if (NODEFS.isWindows && !stat.blocks) {
2209     stat.blocks = (stat.size + stat.blksize - 1) / stat.blksize | 0;
2210    }
2211    return {
2212     dev: stat.dev,
2213     ino: stat.ino,
2214     mode: stat.mode,
2215     nlink: stat.nlink,
2216     uid: stat.uid,
2217     gid: stat.gid,
2218     rdev: stat.rdev,
2219     size: stat.size,
2220     atime: stat.atime,
2221     mtime: stat.mtime,
2222     ctime: stat.ctime,
2223     blksize: stat.blksize,
2224     blocks: stat.blocks
2225    };
2226   }),
2227   setattr: (function(node, attr) {
2228    var path = NODEFS.realPath(node);
2229    try {
2230     if (attr.mode !== undefined) {
2231      fs.chmodSync(path, attr.mode);
2232      node.mode = attr.mode;
2233     }
2234     if (attr.timestamp !== undefined) {
2235      var date = new Date(attr.timestamp);
2236      fs.utimesSync(path, date, date);
2237     }
2238     if (attr.size !== undefined) {
2239      fs.truncateSync(path, attr.size);
2240     }
2241    } catch (e) {
2242     if (!e.code) throw e;
2243     throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2244    }
2245   }),
2246   lookup: (function(parent, name) {
2247    var path = PATH.join2(NODEFS.realPath(parent), name);
2248    var mode = NODEFS.getMode(path);
2249    return NODEFS.createNode(parent, name, mode);
2250   }),
2251   mknod: (function(parent, name, mode, dev) {
2252    var node = NODEFS.createNode(parent, name, mode, dev);
2253    var path = NODEFS.realPath(node);
2254    try {
2255     if (FS.isDir(node.mode)) {
2256      fs.mkdirSync(path, node.mode);
2257     } else {
2258      fs.writeFileSync(path, "", {
2259       mode: node.mode
2260      });
2261     }
2262    } catch (e) {
2263     if (!e.code) throw e;
2264     throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2265    }
2266    return node;
2267   }),
2268   rename: (function(oldNode, newDir, newName) {
2269    var oldPath = NODEFS.realPath(oldNode);
2270    var newPath = PATH.join2(NODEFS.realPath(newDir), newName);
2271    try {
2272     fs.renameSync(oldPath, newPath);
2273    } catch (e) {
2274     if (!e.code) throw e;
2275     throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2276    }
2277   }),
2278   unlink: (function(parent, name) {
2279    var path = PATH.join2(NODEFS.realPath(parent), name);
2280    try {
2281     fs.unlinkSync(path);
2282    } catch (e) {
2283     if (!e.code) throw e;
2284     throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2285    }
2286   }),
2287   rmdir: (function(parent, name) {
2288    var path = PATH.join2(NODEFS.realPath(parent), name);
2289    try {
2290     fs.rmdirSync(path);
2291    } catch (e) {
2292     if (!e.code) throw e;
2293     throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2294    }
2295   }),
2296   readdir: (function(node) {
2297    var path = NODEFS.realPath(node);
2298    try {
2299     return fs.readdirSync(path);
2300    } catch (e) {
2301     if (!e.code) throw e;
2302     throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2303    }
2304   }),
2305   symlink: (function(parent, newName, oldPath) {
2306    var newPath = PATH.join2(NODEFS.realPath(parent), newName);
2307    try {
2308     fs.symlinkSync(oldPath, newPath);
2309    } catch (e) {
2310     if (!e.code) throw e;
2311     throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2312    }
2313   }),
2314   readlink: (function(node) {
2315    var path = NODEFS.realPath(node);
2316    try {
2317     path = fs.readlinkSync(path);
2318     path = NODEJS_PATH.relative(NODEJS_PATH.resolve(node.mount.opts.root), path);
2319     return path;
2320    } catch (e) {
2321     if (!e.code) throw e;
2322     throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2323    }
2324   })
2325  },
2326  stream_ops: {
2327   open: (function(stream) {
2328    var path = NODEFS.realPath(stream.node);
2329    try {
2330     if (FS.isFile(stream.node.mode)) {
2331      stream.nfd = fs.openSync(path, NODEFS.flagsForNode(stream.flags));
2332     }
2333    } catch (e) {
2334     if (!e.code) throw e;
2335     throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2336    }
2337   }),
2338   close: (function(stream) {
2339    try {
2340     if (FS.isFile(stream.node.mode) && stream.nfd) {
2341      fs.closeSync(stream.nfd);
2342     }
2343    } catch (e) {
2344     if (!e.code) throw e;
2345     throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2346    }
2347   }),
2348   read: (function(stream, buffer, offset, length, position) {
2349    if (length === 0) return 0;
2350    try {
2351     return fs.readSync(stream.nfd, NODEFS.bufferFrom(buffer.buffer), offset, length, position);
2352    } catch (e) {
2353     throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2354    }
2355   }),
2356   write: (function(stream, buffer, offset, length, position) {
2357    try {
2358     return fs.writeSync(stream.nfd, NODEFS.bufferFrom(buffer.buffer), offset, length, position);
2359    } catch (e) {
2360     throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2361    }
2362   }),
2363   llseek: (function(stream, offset, whence) {
2364    var position = offset;
2365    if (whence === 1) {
2366     position += stream.position;
2367    } else if (whence === 2) {
2368     if (FS.isFile(stream.node.mode)) {
2369      try {
2370       var stat = fs.fstatSync(stream.nfd);
2371       position += stat.size;
2372      } catch (e) {
2373       throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2374      }
2375     }
2376    }
2377    if (position < 0) {
2378     throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
2379    }
2380    return position;
2381   })
2382  }
2383 };
2384 var WORKERFS = {
2385  DIR_MODE: 16895,
2386  FILE_MODE: 33279,
2387  reader: null,
2388  mount: (function(mount) {
2389   assert(ENVIRONMENT_IS_WORKER);
2390   if (!WORKERFS.reader) WORKERFS.reader = new FileReaderSync;
2391   var root = WORKERFS.createNode(null, "/", WORKERFS.DIR_MODE, 0);
2392   var createdParents = {};
2393   function ensureParent(path) {
2394    var parts = path.split("/");
2395    var parent = root;
2396    for (var i = 0; i < parts.length - 1; i++) {
2397     var curr = parts.slice(0, i + 1).join("/");
2398     if (!createdParents[curr]) {
2399      createdParents[curr] = WORKERFS.createNode(parent, parts[i], WORKERFS.DIR_MODE, 0);
2400     }
2401     parent = createdParents[curr];
2402    }
2403    return parent;
2404   }
2405   function base(path) {
2406    var parts = path.split("/");
2407    return parts[parts.length - 1];
2408   }
2409   Array.prototype.forEach.call(mount.opts["files"] || [], (function(file) {
2410    WORKERFS.createNode(ensureParent(file.name), base(file.name), WORKERFS.FILE_MODE, 0, file, file.lastModifiedDate);
2411   }));
2412   (mount.opts["blobs"] || []).forEach((function(obj) {
2413    WORKERFS.createNode(ensureParent(obj["name"]), base(obj["name"]), WORKERFS.FILE_MODE, 0, obj["data"]);
2414   }));
2415   (mount.opts["packages"] || []).forEach((function(pack) {
2416    pack["metadata"].files.forEach((function(file) {
2417     var name = file.filename.substr(1);
2418     WORKERFS.createNode(ensureParent(name), base(name), WORKERFS.FILE_MODE, 0, pack["blob"].slice(file.start, file.end));
2419    }));
2420   }));
2421   return root;
2422  }),
2423  createNode: (function(parent, name, mode, dev, contents, mtime) {
2424   var node = FS.createNode(parent, name, mode);
2425   node.mode = mode;
2426   node.node_ops = WORKERFS.node_ops;
2427   node.stream_ops = WORKERFS.stream_ops;
2428   node.timestamp = (mtime || new Date).getTime();
2429   assert(WORKERFS.FILE_MODE !== WORKERFS.DIR_MODE);
2430   if (mode === WORKERFS.FILE_MODE) {
2431    node.size = contents.size;
2432    node.contents = contents;
2433   } else {
2434    node.size = 4096;
2435    node.contents = {};
2436   }
2437   if (parent) {
2438    parent.contents[name] = node;
2439   }
2440   return node;
2441  }),
2442  node_ops: {
2443   getattr: (function(node) {
2444    return {
2445     dev: 1,
2446     ino: undefined,
2447     mode: node.mode,
2448     nlink: 1,
2449     uid: 0,
2450     gid: 0,
2451     rdev: undefined,
2452     size: node.size,
2453     atime: new Date(node.timestamp),
2454     mtime: new Date(node.timestamp),
2455     ctime: new Date(node.timestamp),
2456     blksize: 4096,
2457     blocks: Math.ceil(node.size / 4096)
2458    };
2459   }),
2460   setattr: (function(node, attr) {
2461    if (attr.mode !== undefined) {
2462     node.mode = attr.mode;
2463    }
2464    if (attr.timestamp !== undefined) {
2465     node.timestamp = attr.timestamp;
2466    }
2467   }),
2468   lookup: (function(parent, name) {
2469    throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
2470   }),
2471   mknod: (function(parent, name, mode, dev) {
2472    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
2473   }),
2474   rename: (function(oldNode, newDir, newName) {
2475    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
2476   }),
2477   unlink: (function(parent, name) {
2478    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
2479   }),
2480   rmdir: (function(parent, name) {
2481    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
2482   }),
2483   readdir: (function(node) {
2484    var entries = [ ".", ".." ];
2485    for (var key in node.contents) {
2486     if (!node.contents.hasOwnProperty(key)) {
2487      continue;
2488     }
2489     entries.push(key);
2490    }
2491    return entries;
2492   }),
2493   symlink: (function(parent, newName, oldPath) {
2494    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
2495   }),
2496   readlink: (function(node) {
2497    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
2498   })
2499  },
2500  stream_ops: {
2501   read: (function(stream, buffer, offset, length, position) {
2502    if (position >= stream.node.size) return 0;
2503    var chunk = stream.node.contents.slice(position, position + length);
2504    var ab = WORKERFS.reader.readAsArrayBuffer(chunk);
2505    buffer.set(new Uint8Array(ab), offset);
2506    return chunk.size;
2507   }),
2508   write: (function(stream, buffer, offset, length, position) {
2509    throw new FS.ErrnoError(ERRNO_CODES.EIO);
2510   }),
2511   llseek: (function(stream, offset, whence) {
2512    var position = offset;
2513    if (whence === 1) {
2514     position += stream.position;
2515    } else if (whence === 2) {
2516     if (FS.isFile(stream.node.mode)) {
2517      position += stream.node.size;
2518     }
2519    }
2520    if (position < 0) {
2521     throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
2522    }
2523    return position;
2524   })
2525  }
2526 };
2527 STATICTOP += 16;
2528 STATICTOP += 16;
2529 STATICTOP += 16;
2530 var FS = {
2531  root: null,
2532  mounts: [],
2533  devices: {},
2534  streams: [],
2535  nextInode: 1,
2536  nameTable: null,
2537  currentPath: "/",
2538  initialized: false,
2539  ignorePermissions: true,
2540  trackingDelegate: {},
2541  tracking: {
2542   openFlags: {
2543    READ: 1,
2544    WRITE: 2
2545   }
2546  },
2547  ErrnoError: null,
2548  genericErrors: {},
2549  filesystems: null,
2550  syncFSRequests: 0,
2551  handleFSError: (function(e) {
2552   if (!(e instanceof FS.ErrnoError)) throw e + " : " + stackTrace();
2553   return ___setErrNo(e.errno);
2554  }),
2555  lookupPath: (function(path, opts) {
2556   path = PATH.resolve(FS.cwd(), path);
2557   opts = opts || {};
2558   if (!path) return {
2559    path: "",
2560    node: null
2561   };
2562   var defaults = {
2563    follow_mount: true,
2564    recurse_count: 0
2565   };
2566   for (var key in defaults) {
2567    if (opts[key] === undefined) {
2568     opts[key] = defaults[key];
2569    }
2570   }
2571   if (opts.recurse_count > 8) {
2572    throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
2573   }
2574   var parts = PATH.normalizeArray(path.split("/").filter((function(p) {
2575    return !!p;
2576   })), false);
2577   var current = FS.root;
2578   var current_path = "/";
2579   for (var i = 0; i < parts.length; i++) {
2580    var islast = i === parts.length - 1;
2581    if (islast && opts.parent) {
2582     break;
2583    }
2584    current = FS.lookupNode(current, parts[i]);
2585    current_path = PATH.join2(current_path, parts[i]);
2586    if (FS.isMountpoint(current)) {
2587     if (!islast || islast && opts.follow_mount) {
2588      current = current.mounted.root;
2589     }
2590    }
2591    if (!islast || opts.follow) {
2592     var count = 0;
2593     while (FS.isLink(current.mode)) {
2594      var link = FS.readlink(current_path);
2595      current_path = PATH.resolve(PATH.dirname(current_path), link);
2596      var lookup = FS.lookupPath(current_path, {
2597       recurse_count: opts.recurse_count
2598      });
2599      current = lookup.node;
2600      if (count++ > 40) {
2601       throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
2602      }
2603     }
2604    }
2605   }
2606   return {
2607    path: current_path,
2608    node: current
2609   };
2610  }),
2611  getPath: (function(node) {
2612   var path;
2613   while (true) {
2614    if (FS.isRoot(node)) {
2615     var mount = node.mount.mountpoint;
2616     if (!path) return mount;
2617     return mount[mount.length - 1] !== "/" ? mount + "/" + path : mount + path;
2618    }
2619    path = path ? node.name + "/" + path : node.name;
2620    node = node.parent;
2621   }
2622  }),
2623  hashName: (function(parentid, name) {
2624   var hash = 0;
2625   for (var i = 0; i < name.length; i++) {
2626    hash = (hash << 5) - hash + name.charCodeAt(i) | 0;
2627   }
2628   return (parentid + hash >>> 0) % FS.nameTable.length;
2629  }),
2630  hashAddNode: (function(node) {
2631   var hash = FS.hashName(node.parent.id, node.name);
2632   node.name_next = FS.nameTable[hash];
2633   FS.nameTable[hash] = node;
2634  }),
2635  hashRemoveNode: (function(node) {
2636   var hash = FS.hashName(node.parent.id, node.name);
2637   if (FS.nameTable[hash] === node) {
2638    FS.nameTable[hash] = node.name_next;
2639   } else {
2640    var current = FS.nameTable[hash];
2641    while (current) {
2642     if (current.name_next === node) {
2643      current.name_next = node.name_next;
2644      break;
2645     }
2646     current = current.name_next;
2647    }
2648   }
2649  }),
2650  lookupNode: (function(parent, name) {
2651   var err = FS.mayLookup(parent);
2652   if (err) {
2653    throw new FS.ErrnoError(err, parent);
2654   }
2655   var hash = FS.hashName(parent.id, name);
2656   for (var node = FS.nameTable[hash]; node; node = node.name_next) {
2657    var nodeName = node.name;
2658    if (node.parent.id === parent.id && nodeName === name) {
2659     return node;
2660    }
2661   }
2662   return FS.lookup(parent, name);
2663  }),
2664  createNode: (function(parent, name, mode, rdev) {
2665   if (!FS.FSNode) {
2666    FS.FSNode = (function(parent, name, mode, rdev) {
2667     if (!parent) {
2668      parent = this;
2669     }
2670     this.parent = parent;
2671     this.mount = parent.mount;
2672     this.mounted = null;
2673     this.id = FS.nextInode++;
2674     this.name = name;
2675     this.mode = mode;
2676     this.node_ops = {};
2677     this.stream_ops = {};
2678     this.rdev = rdev;
2679    });
2680    FS.FSNode.prototype = {};
2681    var readMode = 292 | 73;
2682    var writeMode = 146;
2683    Object.defineProperties(FS.FSNode.prototype, {
2684     read: {
2685      get: (function() {
2686       return (this.mode & readMode) === readMode;
2687      }),
2688      set: (function(val) {
2689       val ? this.mode |= readMode : this.mode &= ~readMode;
2690      })
2691     },
2692     write: {
2693      get: (function() {
2694       return (this.mode & writeMode) === writeMode;
2695      }),
2696      set: (function(val) {
2697       val ? this.mode |= writeMode : this.mode &= ~writeMode;
2698      })
2699     },
2700     isFolder: {
2701      get: (function() {
2702       return FS.isDir(this.mode);
2703      })
2704     },
2705     isDevice: {
2706      get: (function() {
2707       return FS.isChrdev(this.mode);
2708      })
2709     }
2710    });
2711   }
2712   var node = new FS.FSNode(parent, name, mode, rdev);
2713   FS.hashAddNode(node);
2714   return node;
2715  }),
2716  destroyNode: (function(node) {
2717   FS.hashRemoveNode(node);
2718  }),
2719  isRoot: (function(node) {
2720   return node === node.parent;
2721  }),
2722  isMountpoint: (function(node) {
2723   return !!node.mounted;
2724  }),
2725  isFile: (function(mode) {
2726   return (mode & 61440) === 32768;
2727  }),
2728  isDir: (function(mode) {
2729   return (mode & 61440) === 16384;
2730  }),
2731  isLink: (function(mode) {
2732   return (mode & 61440) === 40960;
2733  }),
2734  isChrdev: (function(mode) {
2735   return (mode & 61440) === 8192;
2736  }),
2737  isBlkdev: (function(mode) {
2738   return (mode & 61440) === 24576;
2739  }),
2740  isFIFO: (function(mode) {
2741   return (mode & 61440) === 4096;
2742  }),
2743  isSocket: (function(mode) {
2744   return (mode & 49152) === 49152;
2745  }),
2746  flagModes: {
2747   "r": 0,
2748   "rs": 1052672,
2749   "r+": 2,
2750   "w": 577,
2751   "wx": 705,
2752   "xw": 705,
2753   "w+": 578,
2754   "wx+": 706,
2755   "xw+": 706,
2756   "a": 1089,
2757   "ax": 1217,
2758   "xa": 1217,
2759   "a+": 1090,
2760   "ax+": 1218,
2761   "xa+": 1218
2762  },
2763  modeStringToFlags: (function(str) {
2764   var flags = FS.flagModes[str];
2765   if (typeof flags === "undefined") {
2766    throw new Error("Unknown file open mode: " + str);
2767   }
2768   return flags;
2769  }),
2770  flagsToPermissionString: (function(flag) {
2771   var perms = [ "r", "w", "rw" ][flag & 3];
2772   if (flag & 512) {
2773    perms += "w";
2774   }
2775   return perms;
2776  }),
2777  nodePermissions: (function(node, perms) {
2778   if (FS.ignorePermissions) {
2779    return 0;
2780   }
2781   if (perms.indexOf("r") !== -1 && !(node.mode & 292)) {
2782    return ERRNO_CODES.EACCES;
2783   } else if (perms.indexOf("w") !== -1 && !(node.mode & 146)) {
2784    return ERRNO_CODES.EACCES;
2785   } else if (perms.indexOf("x") !== -1 && !(node.mode & 73)) {
2786    return ERRNO_CODES.EACCES;
2787   }
2788   return 0;
2789  }),
2790  mayLookup: (function(dir) {
2791   var err = FS.nodePermissions(dir, "x");
2792   if (err) return err;
2793   if (!dir.node_ops.lookup) return ERRNO_CODES.EACCES;
2794   return 0;
2795  }),
2796  mayCreate: (function(dir, name) {
2797   try {
2798    var node = FS.lookupNode(dir, name);
2799    return ERRNO_CODES.EEXIST;
2800   } catch (e) {}
2801   return FS.nodePermissions(dir, "wx");
2802  }),
2803  mayDelete: (function(dir, name, isdir) {
2804   var node;
2805   try {
2806    node = FS.lookupNode(dir, name);
2807   } catch (e) {
2808    return e.errno;
2809   }
2810   var err = FS.nodePermissions(dir, "wx");
2811   if (err) {
2812    return err;
2813   }
2814   if (isdir) {
2815    if (!FS.isDir(node.mode)) {
2816     return ERRNO_CODES.ENOTDIR;
2817    }
2818    if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
2819     return ERRNO_CODES.EBUSY;
2820    }
2821   } else {
2822    if (FS.isDir(node.mode)) {
2823     return ERRNO_CODES.EISDIR;
2824    }
2825   }
2826   return 0;
2827  }),
2828  mayOpen: (function(node, flags) {
2829   if (!node) {
2830    return ERRNO_CODES.ENOENT;
2831   }
2832   if (FS.isLink(node.mode)) {
2833    return ERRNO_CODES.ELOOP;
2834   } else if (FS.isDir(node.mode)) {
2835    if (FS.flagsToPermissionString(flags) !== "r" || flags & 512) {
2836     return ERRNO_CODES.EISDIR;
2837    }
2838   }
2839   return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
2840  }),
2841  MAX_OPEN_FDS: 4096,
2842  nextfd: (function(fd_start, fd_end) {
2843   fd_start = fd_start || 0;
2844   fd_end = fd_end || FS.MAX_OPEN_FDS;
2845   for (var fd = fd_start; fd <= fd_end; fd++) {
2846    if (!FS.streams[fd]) {
2847     return fd;
2848    }
2849   }
2850   throw new FS.ErrnoError(ERRNO_CODES.EMFILE);
2851  }),
2852  getStream: (function(fd) {
2853   return FS.streams[fd];
2854  }),
2855  createStream: (function(stream, fd_start, fd_end) {
2856   if (!FS.FSStream) {
2857    FS.FSStream = (function() {});
2858    FS.FSStream.prototype = {};
2859    Object.defineProperties(FS.FSStream.prototype, {
2860     object: {
2861      get: (function() {
2862       return this.node;
2863      }),
2864      set: (function(val) {
2865       this.node = val;
2866      })
2867     },
2868     isRead: {
2869      get: (function() {
2870       return (this.flags & 2097155) !== 1;
2871      })
2872     },
2873     isWrite: {
2874      get: (function() {
2875       return (this.flags & 2097155) !== 0;
2876      })
2877     },
2878     isAppend: {
2879      get: (function() {
2880       return this.flags & 1024;
2881      })
2882     }
2883    });
2884   }
2885   var newStream = new FS.FSStream;
2886   for (var p in stream) {
2887    newStream[p] = stream[p];
2888   }
2889   stream = newStream;
2890   var fd = FS.nextfd(fd_start, fd_end);
2891   stream.fd = fd;
2892   FS.streams[fd] = stream;
2893   return stream;
2894  }),
2895  closeStream: (function(fd) {
2896   FS.streams[fd] = null;
2897  }),
2898  chrdev_stream_ops: {
2899   open: (function(stream) {
2900    var device = FS.getDevice(stream.node.rdev);
2901    stream.stream_ops = device.stream_ops;
2902    if (stream.stream_ops.open) {
2903     stream.stream_ops.open(stream);
2904    }
2905   }),
2906   llseek: (function() {
2907    throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
2908   })
2909  },
2910  major: (function(dev) {
2911   return dev >> 8;
2912  }),
2913  minor: (function(dev) {
2914   return dev & 255;
2915  }),
2916  makedev: (function(ma, mi) {
2917   return ma << 8 | mi;
2918  }),
2919  registerDevice: (function(dev, ops) {
2920   FS.devices[dev] = {
2921    stream_ops: ops
2922   };
2923  }),
2924  getDevice: (function(dev) {
2925   return FS.devices[dev];
2926  }),
2927  getMounts: (function(mount) {
2928   var mounts = [];
2929   var check = [ mount ];
2930   while (check.length) {
2931    var m = check.pop();
2932    mounts.push(m);
2933    check.push.apply(check, m.mounts);
2934   }
2935   return mounts;
2936  }),
2937  syncfs: (function(populate, callback) {
2938   if (typeof populate === "function") {
2939    callback = populate;
2940    populate = false;
2941   }
2942   FS.syncFSRequests++;
2943   if (FS.syncFSRequests > 1) {
2944    console.log("warning: " + FS.syncFSRequests + " FS.syncfs operations in flight at once, probably just doing extra work");
2945   }
2946   var mounts = FS.getMounts(FS.root.mount);
2947   var completed = 0;
2948   function doCallback(err) {
2949    assert(FS.syncFSRequests > 0);
2950    FS.syncFSRequests--;
2951    return callback(err);
2952   }
2953   function done(err) {
2954    if (err) {
2955     if (!done.errored) {
2956      done.errored = true;
2957      return doCallback(err);
2958     }
2959     return;
2960    }
2961    if (++completed >= mounts.length) {
2962     doCallback(null);
2963    }
2964   }
2965   mounts.forEach((function(mount) {
2966    if (!mount.type.syncfs) {
2967     return done(null);
2968    }
2969    mount.type.syncfs(mount, populate, done);
2970   }));
2971  }),
2972  mount: (function(type, opts, mountpoint) {
2973   var root = mountpoint === "/";
2974   var pseudo = !mountpoint;
2975   var node;
2976   if (root && FS.root) {
2977    throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
2978   } else if (!root && !pseudo) {
2979    var lookup = FS.lookupPath(mountpoint, {
2980     follow_mount: false
2981    });
2982    mountpoint = lookup.path;
2983    node = lookup.node;
2984    if (FS.isMountpoint(node)) {
2985     throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
2986    }
2987    if (!FS.isDir(node.mode)) {
2988     throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
2989    }
2990   }
2991   var mount = {
2992    type: type,
2993    opts: opts,
2994    mountpoint: mountpoint,
2995    mounts: []
2996   };
2997   var mountRoot = type.mount(mount);
2998   mountRoot.mount = mount;
2999   mount.root = mountRoot;
3000   if (root) {
3001    FS.root = mountRoot;
3002   } else if (node) {
3003    node.mounted = mount;
3004    if (node.mount) {
3005     node.mount.mounts.push(mount);
3006    }
3007   }
3008   return mountRoot;
3009  }),
3010  unmount: (function(mountpoint) {
3011   var lookup = FS.lookupPath(mountpoint, {
3012    follow_mount: false
3013   });
3014   if (!FS.isMountpoint(lookup.node)) {
3015    throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3016   }
3017   var node = lookup.node;
3018   var mount = node.mounted;
3019   var mounts = FS.getMounts(mount);
3020   Object.keys(FS.nameTable).forEach((function(hash) {
3021    var current = FS.nameTable[hash];
3022    while (current) {
3023     var next = current.name_next;
3024     if (mounts.indexOf(current.mount) !== -1) {
3025      FS.destroyNode(current);
3026     }
3027     current = next;
3028    }
3029   }));
3030   node.mounted = null;
3031   var idx = node.mount.mounts.indexOf(mount);
3032   assert(idx !== -1);
3033   node.mount.mounts.splice(idx, 1);
3034  }),
3035  lookup: (function(parent, name) {
3036   return parent.node_ops.lookup(parent, name);
3037  }),
3038  mknod: (function(path, mode, dev) {
3039   var lookup = FS.lookupPath(path, {
3040    parent: true
3041   });
3042   var parent = lookup.node;
3043   var name = PATH.basename(path);
3044   if (!name || name === "." || name === "..") {
3045    throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3046   }
3047   var err = FS.mayCreate(parent, name);
3048   if (err) {
3049    throw new FS.ErrnoError(err);
3050   }
3051   if (!parent.node_ops.mknod) {
3052    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3053   }
3054   return parent.node_ops.mknod(parent, name, mode, dev);
3055  }),
3056  create: (function(path, mode) {
3057   mode = mode !== undefined ? mode : 438;
3058   mode &= 4095;
3059   mode |= 32768;
3060   return FS.mknod(path, mode, 0);
3061  }),
3062  mkdir: (function(path, mode) {
3063   mode = mode !== undefined ? mode : 511;
3064   mode &= 511 | 512;
3065   mode |= 16384;
3066   return FS.mknod(path, mode, 0);
3067  }),
3068  mkdirTree: (function(path, mode) {
3069   var dirs = path.split("/");
3070   var d = "";
3071   for (var i = 0; i < dirs.length; ++i) {
3072    if (!dirs[i]) continue;
3073    d += "/" + dirs[i];
3074    try {
3075     FS.mkdir(d, mode);
3076    } catch (e) {
3077     if (e.errno != ERRNO_CODES.EEXIST) throw e;
3078    }
3079   }
3080  }),
3081  mkdev: (function(path, mode, dev) {
3082   if (typeof dev === "undefined") {
3083    dev = mode;
3084    mode = 438;
3085   }
3086   mode |= 8192;
3087   return FS.mknod(path, mode, dev);
3088  }),
3089  symlink: (function(oldpath, newpath) {
3090   if (!PATH.resolve(oldpath)) {
3091    throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
3092   }
3093   var lookup = FS.lookupPath(newpath, {
3094    parent: true
3095   });
3096   var parent = lookup.node;
3097   if (!parent) {
3098    throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
3099   }
3100   var newname = PATH.basename(newpath);
3101   var err = FS.mayCreate(parent, newname);
3102   if (err) {
3103    throw new FS.ErrnoError(err);
3104   }
3105   if (!parent.node_ops.symlink) {
3106    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3107   }
3108   return parent.node_ops.symlink(parent, newname, oldpath);
3109  }),
3110  rename: (function(old_path, new_path) {
3111   var old_dirname = PATH.dirname(old_path);
3112   var new_dirname = PATH.dirname(new_path);
3113   var old_name = PATH.basename(old_path);
3114   var new_name = PATH.basename(new_path);
3115   var lookup, old_dir, new_dir;
3116   try {
3117    lookup = FS.lookupPath(old_path, {
3118     parent: true
3119    });
3120    old_dir = lookup.node;
3121    lookup = FS.lookupPath(new_path, {
3122     parent: true
3123    });
3124    new_dir = lookup.node;
3125   } catch (e) {
3126    throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
3127   }
3128   if (!old_dir || !new_dir) throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
3129   if (old_dir.mount !== new_dir.mount) {
3130    throw new FS.ErrnoError(ERRNO_CODES.EXDEV);
3131   }
3132   var old_node = FS.lookupNode(old_dir, old_name);
3133   var relative = PATH.relative(old_path, new_dirname);
3134   if (relative.charAt(0) !== ".") {
3135    throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3136   }
3137   relative = PATH.relative(new_path, old_dirname);
3138   if (relative.charAt(0) !== ".") {
3139    throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
3140   }
3141   var new_node;
3142   try {
3143    new_node = FS.lookupNode(new_dir, new_name);
3144   } catch (e) {}
3145   if (old_node === new_node) {
3146    return;
3147   }
3148   var isdir = FS.isDir(old_node.mode);
3149   var err = FS.mayDelete(old_dir, old_name, isdir);
3150   if (err) {
3151    throw new FS.ErrnoError(err);
3152   }
3153   err = new_node ? FS.mayDelete(new_dir, new_name, isdir) : FS.mayCreate(new_dir, new_name);
3154   if (err) {
3155    throw new FS.ErrnoError(err);
3156   }
3157   if (!old_dir.node_ops.rename) {
3158    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3159   }
3160   if (FS.isMountpoint(old_node) || new_node && FS.isMountpoint(new_node)) {
3161    throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
3162   }
3163   if (new_dir !== old_dir) {
3164    err = FS.nodePermissions(old_dir, "w");
3165    if (err) {
3166     throw new FS.ErrnoError(err);
3167    }
3168   }
3169   try {
3170    if (FS.trackingDelegate["willMovePath"]) {
3171     FS.trackingDelegate["willMovePath"](old_path, new_path);
3172    }
3173   } catch (e) {
3174    console.log("FS.trackingDelegate['willMovePath']('" + old_path + "', '" + new_path + "') threw an exception: " + e.message);
3175   }
3176   FS.hashRemoveNode(old_node);
3177   try {
3178    old_dir.node_ops.rename(old_node, new_dir, new_name);
3179   } catch (e) {
3180    throw e;
3181   } finally {
3182    FS.hashAddNode(old_node);
3183   }
3184   try {
3185    if (FS.trackingDelegate["onMovePath"]) FS.trackingDelegate["onMovePath"](old_path, new_path);
3186   } catch (e) {
3187    console.log("FS.trackingDelegate['onMovePath']('" + old_path + "', '" + new_path + "') threw an exception: " + e.message);
3188   }
3189  }),
3190  rmdir: (function(path) {
3191   var lookup = FS.lookupPath(path, {
3192    parent: true
3193   });
3194   var parent = lookup.node;
3195   var name = PATH.basename(path);
3196   var node = FS.lookupNode(parent, name);
3197   var err = FS.mayDelete(parent, name, true);
3198   if (err) {
3199    throw new FS.ErrnoError(err);
3200   }
3201   if (!parent.node_ops.rmdir) {
3202    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3203   }
3204   if (FS.isMountpoint(node)) {
3205    throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
3206   }
3207   try {
3208    if (FS.trackingDelegate["willDeletePath"]) {
3209     FS.trackingDelegate["willDeletePath"](path);
3210    }
3211   } catch (e) {
3212    console.log("FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e.message);
3213   }
3214   parent.node_ops.rmdir(parent, name);
3215   FS.destroyNode(node);
3216   try {
3217    if (FS.trackingDelegate["onDeletePath"]) FS.trackingDelegate["onDeletePath"](path);
3218   } catch (e) {
3219    console.log("FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e.message);
3220   }
3221  }),
3222  readdir: (function(path) {
3223   var lookup = FS.lookupPath(path, {
3224    follow: true
3225   });
3226   var node = lookup.node;
3227   if (!node.node_ops.readdir) {
3228    throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
3229   }
3230   return node.node_ops.readdir(node);
3231  }),
3232  unlink: (function(path) {
3233   var lookup = FS.lookupPath(path, {
3234    parent: true
3235   });
3236   var parent = lookup.node;
3237   var name = PATH.basename(path);
3238   var node = FS.lookupNode(parent, name);
3239   var err = FS.mayDelete(parent, name, false);
3240   if (err) {
3241    throw new FS.ErrnoError(err);
3242   }
3243   if (!parent.node_ops.unlink) {
3244    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3245   }
3246   if (FS.isMountpoint(node)) {
3247    throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
3248   }
3249   try {
3250    if (FS.trackingDelegate["willDeletePath"]) {
3251     FS.trackingDelegate["willDeletePath"](path);
3252    }
3253   } catch (e) {
3254    console.log("FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e.message);
3255   }
3256   parent.node_ops.unlink(parent, name);
3257   FS.destroyNode(node);
3258   try {
3259    if (FS.trackingDelegate["onDeletePath"]) FS.trackingDelegate["onDeletePath"](path);
3260   } catch (e) {
3261    console.log("FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e.message);
3262   }
3263  }),
3264  readlink: (function(path) {
3265   var lookup = FS.lookupPath(path);
3266   var link = lookup.node;
3267   if (!link) {
3268    throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
3269   }
3270   if (!link.node_ops.readlink) {
3271    throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3272   }
3273   return PATH.resolve(FS.getPath(link.parent), link.node_ops.readlink(link));
3274  }),
3275  stat: (function(path, dontFollow) {
3276   var lookup = FS.lookupPath(path, {
3277    follow: !dontFollow
3278   });
3279   var node = lookup.node;
3280   if (!node) {
3281    throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
3282   }
3283   if (!node.node_ops.getattr) {
3284    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3285   }
3286   return node.node_ops.getattr(node);
3287  }),
3288  lstat: (function(path) {
3289   return FS.stat(path, true);
3290  }),
3291  chmod: (function(path, mode, dontFollow) {
3292   var node;
3293   if (typeof path === "string") {
3294    var lookup = FS.lookupPath(path, {
3295     follow: !dontFollow
3296    });
3297    node = lookup.node;
3298   } else {
3299    node = path;
3300   }
3301   if (!node.node_ops.setattr) {
3302    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3303   }
3304   node.node_ops.setattr(node, {
3305    mode: mode & 4095 | node.mode & ~4095,
3306    timestamp: Date.now()
3307   });
3308  }),
3309  lchmod: (function(path, mode) {
3310   FS.chmod(path, mode, true);
3311  }),
3312  fchmod: (function(fd, mode) {
3313   var stream = FS.getStream(fd);
3314   if (!stream) {
3315    throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3316   }
3317   FS.chmod(stream.node, mode);
3318  }),
3319  chown: (function(path, uid, gid, dontFollow) {
3320   var node;
3321   if (typeof path === "string") {
3322    var lookup = FS.lookupPath(path, {
3323     follow: !dontFollow
3324    });
3325    node = lookup.node;
3326   } else {
3327    node = path;
3328   }
3329   if (!node.node_ops.setattr) {
3330    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3331   }
3332   node.node_ops.setattr(node, {
3333    timestamp: Date.now()
3334   });
3335  }),
3336  lchown: (function(path, uid, gid) {
3337   FS.chown(path, uid, gid, true);
3338  }),
3339  fchown: (function(fd, uid, gid) {
3340   var stream = FS.getStream(fd);
3341   if (!stream) {
3342    throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3343   }
3344   FS.chown(stream.node, uid, gid);
3345  }),
3346  truncate: (function(path, len) {
3347   if (len < 0) {
3348    throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3349   }
3350   var node;
3351   if (typeof path === "string") {
3352    var lookup = FS.lookupPath(path, {
3353     follow: true
3354    });
3355    node = lookup.node;
3356   } else {
3357    node = path;
3358   }
3359   if (!node.node_ops.setattr) {
3360    throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3361   }
3362   if (FS.isDir(node.mode)) {
3363    throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
3364   }
3365   if (!FS.isFile(node.mode)) {
3366    throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3367   }
3368   var err = FS.nodePermissions(node, "w");
3369   if (err) {
3370    throw new FS.ErrnoError(err);
3371   }
3372   node.node_ops.setattr(node, {
3373    size: len,
3374    timestamp: Date.now()
3375   });
3376  }),
3377  ftruncate: (function(fd, len) {
3378   var stream = FS.getStream(fd);
3379   if (!stream) {
3380    throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3381   }
3382   if ((stream.flags & 2097155) === 0) {
3383    throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3384   }
3385   FS.truncate(stream.node, len);
3386  }),
3387  utime: (function(path, atime, mtime) {
3388   var lookup = FS.lookupPath(path, {
3389    follow: true
3390   });
3391   var node = lookup.node;
3392   node.node_ops.setattr(node, {
3393    timestamp: Math.max(atime, mtime)
3394   });
3395  }),
3396  open: (function(path, flags, mode, fd_start, fd_end) {
3397   if (path === "") {
3398    throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
3399   }
3400   flags = typeof flags === "string" ? FS.modeStringToFlags(flags) : flags;
3401   mode = typeof mode === "undefined" ? 438 : mode;
3402   if (flags & 64) {
3403    mode = mode & 4095 | 32768;
3404   } else {
3405    mode = 0;
3406   }
3407   var node;
3408   if (typeof path === "object") {
3409    node = path;
3410   } else {
3411    path = PATH.normalize(path);
3412    try {
3413     var lookup = FS.lookupPath(path, {
3414      follow: !(flags & 131072)
3415     });
3416     node = lookup.node;
3417    } catch (e) {}
3418   }
3419   var created = false;
3420   if (flags & 64) {
3421    if (node) {
3422     if (flags & 128) {
3423      throw new FS.ErrnoError(ERRNO_CODES.EEXIST);
3424     }
3425    } else {
3426     node = FS.mknod(path, mode, 0);
3427     created = true;
3428    }
3429   }
3430   if (!node) {
3431    throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
3432   }
3433   if (FS.isChrdev(node.mode)) {
3434    flags &= ~512;
3435   }
3436   if (flags & 65536 && !FS.isDir(node.mode)) {
3437    throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
3438   }
3439   if (!created) {
3440    var err = FS.mayOpen(node, flags);
3441    if (err) {
3442     throw new FS.ErrnoError(err);
3443    }
3444   }
3445   if (flags & 512) {
3446    FS.truncate(node, 0);
3447   }
3448   flags &= ~(128 | 512);
3449   var stream = FS.createStream({
3450    node: node,
3451    path: FS.getPath(node),
3452    flags: flags,
3453    seekable: true,
3454    position: 0,
3455    stream_ops: node.stream_ops,
3456    ungotten: [],
3457    error: false
3458   }, fd_start, fd_end);
3459   if (stream.stream_ops.open) {
3460    stream.stream_ops.open(stream);
3461   }
3462   if (Module["logReadFiles"] && !(flags & 1)) {
3463    if (!FS.readFiles) FS.readFiles = {};
3464    if (!(path in FS.readFiles)) {
3465     FS.readFiles[path] = 1;
3466     Module["printErr"]("read file: " + path);
3467    }
3468   }
3469   try {
3470    if (FS.trackingDelegate["onOpenFile"]) {
3471     var trackingFlags = 0;
3472     if ((flags & 2097155) !== 1) {
3473      trackingFlags |= FS.tracking.openFlags.READ;
3474     }
3475     if ((flags & 2097155) !== 0) {
3476      trackingFlags |= FS.tracking.openFlags.WRITE;
3477     }
3478     FS.trackingDelegate["onOpenFile"](path, trackingFlags);
3479    }
3480   } catch (e) {
3481    console.log("FS.trackingDelegate['onOpenFile']('" + path + "', flags) threw an exception: " + e.message);
3482   }
3483   return stream;
3484  }),
3485  close: (function(stream) {
3486   if (FS.isClosed(stream)) {
3487    throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3488   }
3489   if (stream.getdents) stream.getdents = null;
3490   try {
3491    if (stream.stream_ops.close) {
3492     stream.stream_ops.close(stream);
3493    }
3494   } catch (e) {
3495    throw e;
3496   } finally {
3497    FS.closeStream(stream.fd);
3498   }
3499   stream.fd = null;
3500  }),
3501  isClosed: (function(stream) {
3502   return stream.fd === null;
3503  }),
3504  llseek: (function(stream, offset, whence) {
3505   if (FS.isClosed(stream)) {
3506    throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3507   }
3508   if (!stream.seekable || !stream.stream_ops.llseek) {
3509    throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
3510   }
3511   stream.position = stream.stream_ops.llseek(stream, offset, whence);
3512   stream.ungotten = [];
3513   return stream.position;
3514  }),
3515  read: (function(stream, buffer, offset, length, position) {
3516   if (length < 0 || position < 0) {
3517    throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3518   }
3519   if (FS.isClosed(stream)) {
3520    throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3521   }
3522   if ((stream.flags & 2097155) === 1) {
3523    throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3524   }
3525   if (FS.isDir(stream.node.mode)) {
3526    throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
3527   }
3528   if (!stream.stream_ops.read) {
3529    throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3530   }
3531   var seeking = typeof position !== "undefined";
3532   if (!seeking) {
3533    position = stream.position;
3534   } else if (!stream.seekable) {
3535    throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
3536   }
3537   var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
3538   if (!seeking) stream.position += bytesRead;
3539   return bytesRead;
3540  }),
3541  write: (function(stream, buffer, offset, length, position, canOwn) {
3542   if (length < 0 || position < 0) {
3543    throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3544   }
3545   if (FS.isClosed(stream)) {
3546    throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3547   }
3548   if ((stream.flags & 2097155) === 0) {
3549    throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3550   }
3551   if (FS.isDir(stream.node.mode)) {
3552    throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
3553   }
3554   if (!stream.stream_ops.write) {
3555    throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3556   }
3557   if (stream.flags & 1024) {
3558    FS.llseek(stream, 0, 2);
3559   }
3560   var seeking = typeof position !== "undefined";
3561   if (!seeking) {
3562    position = stream.position;
3563   } else if (!stream.seekable) {
3564    throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
3565   }
3566   var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
3567   if (!seeking) stream.position += bytesWritten;
3568   try {
3569    if (stream.path && FS.trackingDelegate["onWriteToFile"]) FS.trackingDelegate["onWriteToFile"](stream.path);
3570   } catch (e) {
3571    console.log("FS.trackingDelegate['onWriteToFile']('" + path + "') threw an exception: " + e.message);
3572   }
3573   return bytesWritten;
3574  }),
3575  allocate: (function(stream, offset, length) {
3576   if (FS.isClosed(stream)) {
3577    throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3578   }
3579   if (offset < 0 || length <= 0) {
3580    throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3581   }
3582   if ((stream.flags & 2097155) === 0) {
3583    throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3584   }
3585   if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) {
3586    throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
3587   }
3588   if (!stream.stream_ops.allocate) {
3589    throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
3590   }
3591   stream.stream_ops.allocate(stream, offset, length);
3592  }),
3593  mmap: (function(stream, buffer, offset, length, position, prot, flags) {
3594   if ((stream.flags & 2097155) === 1) {
3595    throw new FS.ErrnoError(ERRNO_CODES.EACCES);
3596   }
3597   if (!stream.stream_ops.mmap) {
3598    throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
3599   }
3600   return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags);
3601  }),
3602  msync: (function(stream, buffer, offset, length, mmapFlags) {
3603   if (!stream || !stream.stream_ops.msync) {
3604    return 0;
3605   }
3606   return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags);
3607  }),
3608  munmap: (function(stream) {
3609   return 0;
3610  }),
3611  ioctl: (function(stream, cmd, arg) {
3612   if (!stream.stream_ops.ioctl) {
3613    throw new FS.ErrnoError(ERRNO_CODES.ENOTTY);
3614   }
3615   return stream.stream_ops.ioctl(stream, cmd, arg);
3616  }),
3617  readFile: (function(path, opts) {
3618   opts = opts || {};
3619   opts.flags = opts.flags || "r";
3620   opts.encoding = opts.encoding || "binary";
3621   if (opts.encoding !== "utf8" && opts.encoding !== "binary") {
3622    throw new Error('Invalid encoding type "' + opts.encoding + '"');
3623