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