1// Modified embenchen to direct to asm-wasm.
2// Flags: --expose-wasm
3
4var EXPECTED_OUTPUT =
5  'GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA\n' +
6  'TCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT\n' +
7  'AAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG\n' +
8  'GCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG\n' +
9  'CCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT\n' +
10  'GGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA\n' +
11  'GGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA\n' +
12  'TTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG\n' +
13  'AATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA\n' +
14  'GCCTGGGCGA\n';
15var Module = {
16  arguments: [1],
17  print: function(x) {Module.printBuffer += x + '\n';},
18  preRun: [function() {Module.printBuffer = ''}],
19  postRun: [function() {
20    assertEquals(EXPECTED_OUTPUT, Module.printBuffer);
21  }],
22};
23// The Module object: Our interface to the outside world. We import
24// and export values on it, and do the work to get that through
25// closure compiler if necessary. There are various ways Module can be used:
26// 1. Not defined. We create it here
27// 2. A function parameter, function(Module) { ..generated code.. }
28// 3. pre-run appended it, var Module = {}; ..generated code..
29// 4. External script tag defines var Module.
30// We need to do an eval in order to handle the closure compiler
31// case, where this code here is minified but Module was defined
32// elsewhere (e.g. case 4 above). We also need to check if Module
33// already exists (e.g. case 3 above).
34// Note that if you want to run closure, and also to use Module
35// after the generated code, you will need to define   var Module = {};
36// before the code. Then that object will be used in the code, and you
37// can continue to use Module afterwards as well.
38var Module;
39if (!Module) Module = (typeof Module !== 'undefined' ? Module : null) || {};
40
41// Sometimes an existing Module object exists with properties
42// meant to overwrite the default module functionality. Here
43// we collect those properties and reapply _after_ we configure
44// the current environment's defaults to avoid having to be so
45// defensive during initialization.
46var moduleOverrides = {};
47for (var key in Module) {
48  if (Module.hasOwnProperty(key)) {
49    moduleOverrides[key] = Module[key];
50  }
51}
52
53// The environment setup code below is customized to use Module.
54// *** Environment setup code ***
55var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
56var ENVIRONMENT_IS_WEB = typeof window === 'object';
57var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
58var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
59
60if (ENVIRONMENT_IS_NODE) {
61  // Expose functionality in the same simple way that the shells work
62  // Note that we pollute the global namespace here, otherwise we break in node
63  if (!Module['print']) Module['print'] = function print(x) {
64    process['stdout'].write(x + '\n');
65  };
66  if (!Module['printErr']) Module['printErr'] = function printErr(x) {
67    process['stderr'].write(x + '\n');
68  };
69
70  var nodeFS = require('fs');
71  var nodePath = require('path');
72
73  Module['read'] = function read(filename, binary) {
74    filename = nodePath['normalize'](filename);
75    var ret = nodeFS['readFileSync'](filename);
76    // The path is absolute if the normalized version is the same as the resolved.
77    if (!ret && filename != nodePath['resolve'](filename)) {
78      filename = path.join(__dirname, '..', 'src', filename);
79      ret = nodeFS['readFileSync'](filename);
80    }
81    if (ret && !binary) ret = ret.toString();
82    return ret;
83  };
84
85  Module['readBinary'] = function readBinary(filename) { return Module['read'](filename, true) };
86
87  Module['load'] = function load(f) {
88    globalEval(read(f));
89  };
90
91  Module['arguments'] = process['argv'].slice(2);
92
93  module['exports'] = Module;
94}
95else if (ENVIRONMENT_IS_SHELL) {
96  if (!Module['print']) Module['print'] = print;
97  if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm
98
99  if (typeof read != 'undefined') {
100    Module['read'] = read;
101  } else {
102    Module['read'] = function read() { throw 'no read() available (jsc?)' };
103  }
104
105  Module['readBinary'] = function readBinary(f) {
106    return read(f, 'binary');
107  };
108
109  if (typeof scriptArgs != 'undefined') {
110    Module['arguments'] = scriptArgs;
111  } else if (typeof arguments != 'undefined') {
112    Module['arguments'] = arguments;
113  }
114
115  this['Module'] = Module;
116
117  eval("if (typeof gc === 'function' && gc.toString().indexOf('[native code]') > 0) var gc = undefined"); // wipe out the SpiderMonkey shell 'gc' function, which can confuse closure (uses it as a minified name, and it is then initted to a non-falsey value unexpectedly)
118}
119else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
120  Module['read'] = function read(url) {
121    var xhr = new XMLHttpRequest();
122    xhr.open('GET', url, false);
123    xhr.send(null);
124    return xhr.responseText;
125  };
126
127  if (typeof arguments != 'undefined') {
128    Module['arguments'] = arguments;
129  }
130
131  if (typeof console !== 'undefined') {
132    if (!Module['print']) Module['print'] = function print(x) {
133      console.log(x);
134    };
135    if (!Module['printErr']) Module['printErr'] = function printErr(x) {
136      console.log(x);
137    };
138  } else {
139    // Probably a worker, and without console.log. We can do very little here...
140    var TRY_USE_DUMP = false;
141    if (!Module['print']) Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) {
142      dump(x);
143    }) : (function(x) {
144      // self.postMessage(x); // enable this if you want stdout to be sent as messages
145    }));
146  }
147
148  if (ENVIRONMENT_IS_WEB) {
149    window['Module'] = Module;
150  } else {
151    Module['load'] = importScripts;
152  }
153}
154else {
155  // Unreachable because SHELL is dependant on the others
156  throw 'Unknown runtime environment. Where are we?';
157}
158
159function globalEval(x) {
160  eval.call(null, x);
161}
162if (!Module['load'] == 'undefined' && Module['read']) {
163  Module['load'] = function load(f) {
164    globalEval(Module['read'](f));
165  };
166}
167if (!Module['print']) {
168  Module['print'] = function(){};
169}
170if (!Module['printErr']) {
171  Module['printErr'] = Module['print'];
172}
173if (!Module['arguments']) {
174  Module['arguments'] = [];
175}
176// *** Environment setup code ***
177
178// Closure helpers
179Module.print = Module['print'];
180Module.printErr = Module['printErr'];
181
182// Callbacks
183Module['preRun'] = [];
184Module['postRun'] = [];
185
186// Merge back in the overrides
187for (var key in moduleOverrides) {
188  if (moduleOverrides.hasOwnProperty(key)) {
189    Module[key] = moduleOverrides[key];
190  }
191}
192
193
194
195// === Auto-generated preamble library stuff ===
196
197//========================================
198// Runtime code shared with compiler
199//========================================
200
201var Runtime = {
202  stackSave: function () {
203    return STACKTOP;
204  },
205  stackRestore: function (stackTop) {
206    STACKTOP = stackTop;
207  },
208  forceAlign: function (target, quantum) {
209    quantum = quantum || 4;
210    if (quantum == 1) return target;
211    if (isNumber(target) && isNumber(quantum)) {
212      return Math.ceil(target/quantum)*quantum;
213    } else if (isNumber(quantum) && isPowerOfTwo(quantum)) {
214      return '(((' +target + ')+' + (quantum-1) + ')&' + -quantum + ')';
215    }
216    return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum;
217  },
218  isNumberType: function (type) {
219    return type in Runtime.INT_TYPES || type in Runtime.FLOAT_TYPES;
220  },
221  isPointerType: function isPointerType(type) {
222  return type[type.length-1] == '*';
223},
224  isStructType: function isStructType(type) {
225  if (isPointerType(type)) return false;
226  if (isArrayType(type)) return true;
227  if (/<?\{ ?[^}]* ?\}>?/.test(type)) return true; // { i32, i8 } etc. - anonymous struct types
228  // See comment in isStructPointerType()
229  return type[0] == '%';
230},
231  INT_TYPES: {"i1":0,"i8":0,"i16":0,"i32":0,"i64":0},
232  FLOAT_TYPES: {"float":0,"double":0},
233  or64: function (x, y) {
234    var l = (x | 0) | (y | 0);
235    var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296;
236    return l + h;
237  },
238  and64: function (x, y) {
239    var l = (x | 0) & (y | 0);
240    var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296;
241    return l + h;
242  },
243  xor64: function (x, y) {
244    var l = (x | 0) ^ (y | 0);
245    var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296;
246    return l + h;
247  },
248  getNativeTypeSize: function (type) {
249    switch (type) {
250      case 'i1': case 'i8': return 1;
251      case 'i16': return 2;
252      case 'i32': return 4;
253      case 'i64': return 8;
254      case 'float': return 4;
255      case 'double': return 8;
256      default: {
257        if (type[type.length-1] === '*') {
258          return Runtime.QUANTUM_SIZE; // A pointer
259        } else if (type[0] === 'i') {
260          var bits = parseInt(type.substr(1));
261          assert(bits % 8 === 0);
262          return bits/8;
263        } else {
264          return 0;
265        }
266      }
267    }
268  },
269  getNativeFieldSize: function (type) {
270    return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE);
271  },
272  dedup: function dedup(items, ident) {
273  var seen = {};
274  if (ident) {
275    return items.filter(function(item) {
276      if (seen[item[ident]]) return false;
277      seen[item[ident]] = true;
278      return true;
279    });
280  } else {
281    return items.filter(function(item) {
282      if (seen[item]) return false;
283      seen[item] = true;
284      return true;
285    });
286  }
287},
288  set: function set() {
289  var args = typeof arguments[0] === 'object' ? arguments[0] : arguments;
290  var ret = {};
291  for (var i = 0; i < args.length; i++) {
292    ret[args[i]] = 0;
293  }
294  return ret;
295},
296  STACK_ALIGN: 8,
297  getAlignSize: function (type, size, vararg) {
298    // we align i64s and doubles on 64-bit boundaries, unlike x86
299    if (!vararg && (type == 'i64' || type == 'double')) return 8;
300    if (!type) return Math.min(size, 8); // align structures internally to 64 bits
301    return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE);
302  },
303  calculateStructAlignment: function calculateStructAlignment(type) {
304    type.flatSize = 0;
305    type.alignSize = 0;
306    var diffs = [];
307    var prev = -1;
308    var index = 0;
309    type.flatIndexes = type.fields.map(function(field) {
310      index++;
311      var size, alignSize;
312      if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) {
313        size = Runtime.getNativeTypeSize(field); // pack char; char; in structs, also char[X]s.
314        alignSize = Runtime.getAlignSize(field, size);
315      } else if (Runtime.isStructType(field)) {
316        if (field[1] === '0') {
317          // this is [0 x something]. When inside another structure like here, it must be at the end,
318          // and it adds no size
319          // XXX this happens in java-nbody for example... assert(index === type.fields.length, 'zero-length in the middle!');
320          size = 0;
321          if (Types.types[field]) {
322            alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
323          } else {
324            alignSize = type.alignSize || QUANTUM_SIZE;
325          }
326        } else {
327          size = Types.types[field].flatSize;
328          alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
329        }
330      } else if (field[0] == 'b') {
331        // bN, large number field, like a [N x i8]
332        size = field.substr(1)|0;
333        alignSize = 1;
334      } else if (field[0] === '<') {
335        // vector type
336        size = alignSize = Types.types[field].flatSize; // fully aligned
337      } else if (field[0] === 'i') {
338        // illegal integer field, that could not be legalized because it is an internal structure field
339        // it is ok to have such fields, if we just use them as markers of field size and nothing more complex
340        size = alignSize = parseInt(field.substr(1))/8;
341        assert(size % 1 === 0, 'cannot handle non-byte-size field ' + field);
342      } else {
343        assert(false, 'invalid type for calculateStructAlignment');
344      }
345      if (type.packed) alignSize = 1;
346      type.alignSize = Math.max(type.alignSize, alignSize);
347      var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory
348      type.flatSize = curr + size;
349      if (prev >= 0) {
350        diffs.push(curr-prev);
351      }
352      prev = curr;
353      return curr;
354    });
355    if (type.name_ && type.name_[0] === '[') {
356      // arrays have 2 elements, so we get the proper difference. then we scale here. that way we avoid
357      // allocating a potentially huge array for [999999 x i8] etc.
358      type.flatSize = parseInt(type.name_.substr(1))*type.flatSize/2;
359    }
360    type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize);
361    if (diffs.length == 0) {
362      type.flatFactor = type.flatSize;
363    } else if (Runtime.dedup(diffs).length == 1) {
364      type.flatFactor = diffs[0];
365    }
366    type.needsFlattening = (type.flatFactor != 1);
367    return type.flatIndexes;
368  },
369  generateStructInfo: function (struct, typeName, offset) {
370    var type, alignment;
371    if (typeName) {
372      offset = offset || 0;
373      type = (typeof Types === 'undefined' ? Runtime.typeInfo : Types.types)[typeName];
374      if (!type) return null;
375      if (type.fields.length != struct.length) {
376        printErr('Number of named fields must match the type for ' + typeName + ': possibly duplicate struct names. Cannot return structInfo');
377        return null;
378      }
379      alignment = type.flatIndexes;
380    } else {
381      var type = { fields: struct.map(function(item) { return item[0] }) };
382      alignment = Runtime.calculateStructAlignment(type);
383    }
384    var ret = {
385      __size__: type.flatSize
386    };
387    if (typeName) {
388      struct.forEach(function(item, i) {
389        if (typeof item === 'string') {
390          ret[item] = alignment[i] + offset;
391        } else {
392          // embedded struct
393          var key;
394          for (var k in item) key = k;
395          ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]);
396        }
397      });
398    } else {
399      struct.forEach(function(item, i) {
400        ret[item[1]] = alignment[i];
401      });
402    }
403    return ret;
404  },
405  dynCall: function (sig, ptr, args) {
406    if (args && args.length) {
407      if (!args.splice) args = Array.prototype.slice.call(args);
408      args.splice(0, 0, ptr);
409      return Module['dynCall_' + sig].apply(null, args);
410    } else {
411      return Module['dynCall_' + sig].call(null, ptr);
412    }
413  },
414  functionPointers: [],
415  addFunction: function (func) {
416    for (var i = 0; i < Runtime.functionPointers.length; i++) {
417      if (!Runtime.functionPointers[i]) {
418        Runtime.functionPointers[i] = func;
419        return 2*(1 + i);
420      }
421    }
422    throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.';
423  },
424  removeFunction: function (index) {
425    Runtime.functionPointers[(index-2)/2] = null;
426  },
427  getAsmConst: function (code, numArgs) {
428    // code is a constant string on the heap, so we can cache these
429    if (!Runtime.asmConstCache) Runtime.asmConstCache = {};
430    var func = Runtime.asmConstCache[code];
431    if (func) return func;
432    var args = [];
433    for (var i = 0; i < numArgs; i++) {
434      args.push(String.fromCharCode(36) + i); // $0, $1 etc
435    }
436    var source = Pointer_stringify(code);
437    if (source[0] === '"') {
438      // tolerate EM_ASM("..code..") even though EM_ASM(..code..) is correct
439      if (source.indexOf('"', 1) === source.length-1) {
440        source = source.substr(1, source.length-2);
441      } else {
442        // something invalid happened, e.g. EM_ASM("..code($0)..", input)
443        abort('invalid EM_ASM input |' + source + '|. Please use EM_ASM(..code..) (no quotes) or EM_ASM({ ..code($0).. }, input) (to input values)');
444      }
445    }
446    try {
447      var evalled = eval('(function(' + args.join(',') + '){ ' + source + ' })'); // new Function does not allow upvars in node
448    } catch(e) {
449      Module.printErr('error in executing inline EM_ASM code: ' + e + ' on: \n\n' + source + '\n\nwith args |' + args + '| (make sure to use the right one out of EM_ASM, EM_ASM_ARGS, etc.)');
450      throw e;
451    }
452    return Runtime.asmConstCache[code] = evalled;
453  },
454  warnOnce: function (text) {
455    if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {};
456    if (!Runtime.warnOnce.shown[text]) {
457      Runtime.warnOnce.shown[text] = 1;
458      Module.printErr(text);
459    }
460  },
461  funcWrappers: {},
462  getFuncWrapper: function (func, sig) {
463    assert(sig);
464    if (!Runtime.funcWrappers[func]) {
465      Runtime.funcWrappers[func] = function dynCall_wrapper() {
466        return Runtime.dynCall(sig, func, arguments);
467      };
468    }
469    return Runtime.funcWrappers[func];
470  },
471  UTF8Processor: function () {
472    var buffer = [];
473    var needed = 0;
474    this.processCChar = function (code) {
475      code = code & 0xFF;
476
477      if (buffer.length == 0) {
478        if ((code & 0x80) == 0x00) {        // 0xxxxxxx
479          return String.fromCharCode(code);
480        }
481        buffer.push(code);
482        if ((code & 0xE0) == 0xC0) {        // 110xxxxx
483          needed = 1;
484        } else if ((code & 0xF0) == 0xE0) { // 1110xxxx
485          needed = 2;
486        } else {                            // 11110xxx
487          needed = 3;
488        }
489        return '';
490      }
491
492      if (needed) {
493        buffer.push(code);
494        needed--;
495        if (needed > 0) return '';
496      }
497
498      var c1 = buffer[0];
499      var c2 = buffer[1];
500      var c3 = buffer[2];
501      var c4 = buffer[3];
502      var ret;
503      if (buffer.length == 2) {
504        ret = String.fromCharCode(((c1 & 0x1F) << 6)  | (c2 & 0x3F));
505      } else if (buffer.length == 3) {
506        ret = String.fromCharCode(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6)  | (c3 & 0x3F));
507      } else {
508        // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
509        var codePoint = ((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
510                        ((c3 & 0x3F) << 6)  | (c4 & 0x3F);
511        ret = String.fromCharCode(
512          Math.floor((codePoint - 0x10000) / 0x400) + 0xD800,
513          (codePoint - 0x10000) % 0x400 + 0xDC00);
514      }
515      buffer.length = 0;
516      return ret;
517    }
518    this.processJSString = function processJSString(string) {
519      /* TODO: use TextEncoder when present,
520        var encoder = new TextEncoder();
521        encoder['encoding'] = "utf-8";
522        var utf8Array = encoder['encode'](aMsg.data);
523      */
524      string = unescape(encodeURIComponent(string));
525      var ret = [];
526      for (var i = 0; i < string.length; i++) {
527        ret.push(string.charCodeAt(i));
528      }
529      return ret;
530    }
531  },
532  getCompilerSetting: function (name) {
533    throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work';
534  },
535  stackAlloc: function (size) { var ret = STACKTOP;STACKTOP = (STACKTOP + size)|0;STACKTOP = (((STACKTOP)+7)&-8); return ret; },
536  staticAlloc: function (size) { var ret = STATICTOP;STATICTOP = (STATICTOP + size)|0;STATICTOP = (((STATICTOP)+7)&-8); return ret; },
537  dynamicAlloc: function (size) { var ret = DYNAMICTOP;DYNAMICTOP = (DYNAMICTOP + size)|0;DYNAMICTOP = (((DYNAMICTOP)+7)&-8); if (DYNAMICTOP >= TOTAL_MEMORY) enlargeMemory();; return ret; },
538  alignMemory: function (size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 8))*(quantum ? quantum : 8); return ret; },
539  makeBigInt: function (low,high,unsigned) { var ret = (unsigned ? ((+((low>>>0)))+((+((high>>>0)))*(+4294967296))) : ((+((low>>>0)))+((+((high|0)))*(+4294967296)))); return ret; },
540  GLOBAL_BASE: 8,
541  QUANTUM_SIZE: 4,
542  __dummy__: 0
543}
544
545
546Module['Runtime'] = Runtime;
547
548
549
550
551
552
553
554
555
556//========================================
557// Runtime essentials
558//========================================
559
560var __THREW__ = 0; // Used in checking for thrown exceptions.
561
562var ABORT = false; // whether we are quitting the application. no code should run after this. set in exit() and abort()
563var EXITSTATUS = 0;
564
565var undef = 0;
566// tempInt is used for 32-bit signed values or smaller. tempBigInt is used
567// for 32-bit unsigned values or more than 32 bits. TODO: audit all uses of tempInt
568var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD, tempDouble, tempFloat;
569var tempI64, tempI64b;
570var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9;
571
572function assert(condition, text) {
573  if (!condition) {
574    abort('Assertion failed: ' + text);
575  }
576}
577
578var globalScope = this;
579
580// C calling interface. A convenient way to call C functions (in C files, or
581// defined with extern "C").
582//
583// Note: LLVM optimizations can inline and remove functions, after which you will not be
584//       able to call them. Closure can also do so. To avoid that, add your function to
585//       the exports using something like
586//
587//         -s EXPORTED_FUNCTIONS='["_main", "_myfunc"]'
588//
589// @param ident      The name of the C function (note that C++ functions will be name-mangled - use extern "C")
590// @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and
591//                   'array' for JavaScript arrays and typed arrays; note that arrays are 8-bit).
592// @param argTypes   An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType,
593//                   except that 'array' is not possible (there is no way for us to know the length of the array)
594// @param args       An array of the arguments to the function, as native JS values (as in returnType)
595//                   Note that string arguments will be stored on the stack (the JS string will become a C string on the stack).
596// @return           The return value, as a native JS value (as in returnType)
597function ccall(ident, returnType, argTypes, args) {
598  return ccallFunc(getCFunc(ident), returnType, argTypes, args);
599}
600Module["ccall"] = ccall;
601
602// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
603function getCFunc(ident) {
604  try {
605    var func = Module['_' + ident]; // closure exported function
606    if (!func) func = eval('_' + ident); // explicit lookup
607  } catch(e) {
608  }
609  assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)');
610  return func;
611}
612
613// Internal function that does a C call using a function, not an identifier
614function ccallFunc(func, returnType, argTypes, args) {
615  var stack = 0;
616  function toC(value, type) {
617    if (type == 'string') {
618      if (value === null || value === undefined || value === 0) return 0; // null string
619      value = intArrayFromString(value);
620      type = 'array';
621    }
622    if (type == 'array') {
623      if (!stack) stack = Runtime.stackSave();
624      var ret = Runtime.stackAlloc(value.length);
625      writeArrayToMemory(value, ret);
626      return ret;
627    }
628    return value;
629  }
630  function fromC(value, type) {
631    if (type == 'string') {
632      return Pointer_stringify(value);
633    }
634    assert(type != 'array');
635    return value;
636  }
637  var i = 0;
638  var cArgs = args ? args.map(function(arg) {
639    return toC(arg, argTypes[i++]);
640  }) : [];
641  var ret = fromC(func.apply(null, cArgs), returnType);
642  if (stack) Runtime.stackRestore(stack);
643  return ret;
644}
645
646// Returns a native JS wrapper for a C function. This is similar to ccall, but
647// returns a function you can call repeatedly in a normal way. For example:
648//
649//   var my_function = cwrap('my_c_function', 'number', ['number', 'number']);
650//   alert(my_function(5, 22));
651//   alert(my_function(99, 12));
652//
653function cwrap(ident, returnType, argTypes) {
654  var func = getCFunc(ident);
655  return function() {
656    return ccallFunc(func, returnType, argTypes, Array.prototype.slice.call(arguments));
657  }
658}
659Module["cwrap"] = cwrap;
660
661// Sets a value in memory in a dynamic way at run-time. Uses the
662// type data. This is the same as makeSetValue, except that
663// makeSetValue is done at compile-time and generates the needed
664// code then, whereas this function picks the right code at
665// run-time.
666// Note that setValue and getValue only do *aligned* writes and reads!
667// Note that ccall uses JS types as for defining types, while setValue and
668// getValue need LLVM types ('i8', 'i32') - this is a lower-level operation
669function setValue(ptr, value, type, noSafe) {
670  type = type || 'i8';
671  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
672    switch(type) {
673      case 'i1': HEAP8[(ptr)]=value; break;
674      case 'i8': HEAP8[(ptr)]=value; break;
675      case 'i16': HEAP16[((ptr)>>1)]=value; break;
676      case 'i32': HEAP32[((ptr)>>2)]=value; break;
677      case 'i64': (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]); break;
678      case 'float': HEAPF32[((ptr)>>2)]=value; break;
679      case 'double': HEAPF64[((ptr)>>3)]=value; break;
680      default: abort('invalid type for setValue: ' + type);
681    }
682}
683Module['setValue'] = setValue;
684
685// Parallel to setValue.
686function getValue(ptr, type, noSafe) {
687  type = type || 'i8';
688  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
689    switch(type) {
690      case 'i1': return HEAP8[(ptr)];
691      case 'i8': return HEAP8[(ptr)];
692      case 'i16': return HEAP16[((ptr)>>1)];
693      case 'i32': return HEAP32[((ptr)>>2)];
694      case 'i64': return HEAP32[((ptr)>>2)];
695      case 'float': return HEAPF32[((ptr)>>2)];
696      case 'double': return HEAPF64[((ptr)>>3)];
697      default: abort('invalid type for setValue: ' + type);
698    }
699  return null;
700}
701Module['getValue'] = getValue;
702
703var ALLOC_NORMAL = 0; // Tries to use _malloc()
704var ALLOC_STACK = 1; // Lives for the duration of the current function call
705var ALLOC_STATIC = 2; // Cannot be freed
706var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk
707var ALLOC_NONE = 4; // Do not allocate
708Module['ALLOC_NORMAL'] = ALLOC_NORMAL;
709Module['ALLOC_STACK'] = ALLOC_STACK;
710Module['ALLOC_STATIC'] = ALLOC_STATIC;
711Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC;
712Module['ALLOC_NONE'] = ALLOC_NONE;
713
714// allocate(): This is for internal use. You can use it yourself as well, but the interface
715//             is a little tricky (see docs right below). The reason is that it is optimized
716//             for multiple syntaxes to save space in generated code. So you should
717//             normally not use allocate(), and instead allocate memory using _malloc(),
718//             initialize it with setValue(), and so forth.
719// @slab: An array of data, or a number. If a number, then the size of the block to allocate,
720//        in *bytes* (note that this is sometimes confusing: the next parameter does not
721//        affect this!)
722// @types: Either an array of types, one for each byte (or 0 if no type at that position),
723//         or a single type which is used for the entire block. This only matters if there
724//         is initial data - if @slab is a number, then this does not matter at all and is
725//         ignored.
726// @allocator: How to allocate memory, see ALLOC_*
727function allocate(slab, types, allocator, ptr) {
728  var zeroinit, size;
729  if (typeof slab === 'number') {
730    zeroinit = true;
731    size = slab;
732  } else {
733    zeroinit = false;
734    size = slab.length;
735  }
736
737  var singleType = typeof types === 'string' ? types : null;
738
739  var ret;
740  if (allocator == ALLOC_NONE) {
741    ret = ptr;
742  } else {
743    ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc, Runtime.dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length));
744  }
745
746  if (zeroinit) {
747    var ptr = ret, stop;
748    assert((ret & 3) == 0);
749    stop = ret + (size & ~3);
750    for (; ptr < stop; ptr += 4) {
751      HEAP32[((ptr)>>2)]=0;
752    }
753    stop = ret + size;
754    while (ptr < stop) {
755      HEAP8[((ptr++)|0)]=0;
756    }
757    return ret;
758  }
759
760  if (singleType === 'i8') {
761    if (slab.subarray || slab.slice) {
762      HEAPU8.set(slab, ret);
763    } else {
764      HEAPU8.set(new Uint8Array(slab), ret);
765    }
766    return ret;
767  }
768
769  var i = 0, type, typeSize, previousType;
770  while (i < size) {
771    var curr = slab[i];
772
773    if (typeof curr === 'function') {
774      curr = Runtime.getFunctionIndex(curr);
775    }
776
777    type = singleType || types[i];
778    if (type === 0) {
779      i++;
780      continue;
781    }
782
783    if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
784
785    setValue(ret+i, curr, type);
786
787    // no need to look up size unless type changes, so cache it
788    if (previousType !== type) {
789      typeSize = Runtime.getNativeTypeSize(type);
790      previousType = type;
791    }
792    i += typeSize;
793  }
794
795  return ret;
796}
797Module['allocate'] = allocate;
798
799function Pointer_stringify(ptr, /* optional */ length) {
800  // TODO: use TextDecoder
801  // Find the length, and check for UTF while doing so
802  var hasUtf = false;
803  var t;
804  var i = 0;
805  while (1) {
806    t = HEAPU8[(((ptr)+(i))|0)];
807    if (t >= 128) hasUtf = true;
808    else if (t == 0 && !length) break;
809    i++;
810    if (length && i == length) break;
811  }
812  if (!length) length = i;
813
814  var ret = '';
815
816  if (!hasUtf) {
817    var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack
818    var curr;
819    while (length > 0) {
820      curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK)));
821      ret = ret ? ret + curr : curr;
822      ptr += MAX_CHUNK;
823      length -= MAX_CHUNK;
824    }
825    return ret;
826  }
827
828  var utf8 = new Runtime.UTF8Processor();
829  for (i = 0; i < length; i++) {
830    t = HEAPU8[(((ptr)+(i))|0)];
831    ret += utf8.processCChar(t);
832  }
833  return ret;
834}
835Module['Pointer_stringify'] = Pointer_stringify;
836
837// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
838// a copy of that string as a Javascript String object.
839function UTF16ToString(ptr) {
840  var i = 0;
841
842  var str = '';
843  while (1) {
844    var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
845    if (codeUnit == 0)
846      return str;
847    ++i;
848    // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
849    str += String.fromCharCode(codeUnit);
850  }
851}
852Module['UTF16ToString'] = UTF16ToString;
853
854// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
855// null-terminated and encoded in UTF16LE form. The copy will require at most (str.length*2+1)*2 bytes of space in the HEAP.
856function stringToUTF16(str, outPtr) {
857  for(var i = 0; i < str.length; ++i) {
858    // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
859    var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
860    HEAP16[(((outPtr)+(i*2))>>1)]=codeUnit;
861  }
862  // Null-terminate the pointer to the HEAP.
863  HEAP16[(((outPtr)+(str.length*2))>>1)]=0;
864}
865Module['stringToUTF16'] = stringToUTF16;
866
867// Given a pointer 'ptr' to a null-terminated UTF32LE-encoded string in the emscripten HEAP, returns
868// a copy of that string as a Javascript String object.
869function UTF32ToString(ptr) {
870  var i = 0;
871
872  var str = '';
873  while (1) {
874    var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
875    if (utf32 == 0)
876      return str;
877    ++i;
878    // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
879    if (utf32 >= 0x10000) {
880      var ch = utf32 - 0x10000;
881      str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
882    } else {
883      str += String.fromCharCode(utf32);
884    }
885  }
886}
887Module['UTF32ToString'] = UTF32ToString;
888
889// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
890// null-terminated and encoded in UTF32LE form. The copy will require at most (str.length+1)*4 bytes of space in the HEAP,
891// but can use less, since str.length does not return the number of characters in the string, but the number of UTF-16 code units in the string.
892function stringToUTF32(str, outPtr) {
893  var iChar = 0;
894  for(var iCodeUnit = 0; iCodeUnit < str.length; ++iCodeUnit) {
895    // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
896    var codeUnit = str.charCodeAt(iCodeUnit); // possibly a lead surrogate
897    if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
898      var trailSurrogate = str.charCodeAt(++iCodeUnit);
899      codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
900    }
901    HEAP32[(((outPtr)+(iChar*4))>>2)]=codeUnit;
902    ++iChar;
903  }
904  // Null-terminate the pointer to the HEAP.
905  HEAP32[(((outPtr)+(iChar*4))>>2)]=0;
906}
907Module['stringToUTF32'] = stringToUTF32;
908
909function demangle(func) {
910  var i = 3;
911  // params, etc.
912  var basicTypes = {
913    'v': 'void',
914    'b': 'bool',
915    'c': 'char',
916    's': 'short',
917    'i': 'int',
918    'l': 'long',
919    'f': 'float',
920    'd': 'double',
921    'w': 'wchar_t',
922    'a': 'signed char',
923    'h': 'unsigned char',
924    't': 'unsigned short',
925    'j': 'unsigned int',
926    'm': 'unsigned long',
927    'x': 'long long',
928    'y': 'unsigned long long',
929    'z': '...'
930  };
931  var subs = [];
932  var first = true;
933  function dump(x) {
934    //return;
935    if (x) Module.print(x);
936    Module.print(func);
937    var pre = '';
938    for (var a = 0; a < i; a++) pre += ' ';
939    Module.print (pre + '^');
940  }
941  function parseNested() {
942    i++;
943    if (func[i] === 'K') i++; // ignore const
944    var parts = [];
945    while (func[i] !== 'E') {
946      if (func[i] === 'S') { // substitution
947        i++;
948        var next = func.indexOf('_', i);
949        var num = func.substring(i, next) || 0;
950        parts.push(subs[num] || '?');
951        i = next+1;
952        continue;
953      }
954      if (func[i] === 'C') { // constructor
955        parts.push(parts[parts.length-1]);
956        i += 2;
957        continue;
958      }
959      var size = parseInt(func.substr(i));
960      var pre = size.toString().length;
961      if (!size || !pre) { i--; break; } // counter i++ below us
962      var curr = func.substr(i + pre, size);
963      parts.push(curr);
964      subs.push(curr);
965      i += pre + size;
966    }
967    i++; // skip E
968    return parts;
969  }
970  function parse(rawList, limit, allowVoid) { // main parser
971    limit = limit || Infinity;
972    var ret = '', list = [];
973    function flushList() {
974      return '(' + list.join(', ') + ')';
975    }
976    var name;
977    if (func[i] === 'N') {
978      // namespaced N-E
979      name = parseNested().join('::');
980      limit--;
981      if (limit === 0) return rawList ? [name] : name;
982    } else {
983      // not namespaced
984      if (func[i] === 'K' || (first && func[i] === 'L')) i++; // ignore const and first 'L'
985      var size = parseInt(func.substr(i));
986      if (size) {
987        var pre = size.toString().length;
988        name = func.substr(i + pre, size);
989        i += pre + size;
990      }
991    }
992    first = false;
993    if (func[i] === 'I') {
994      i++;
995      var iList = parse(true);
996      var iRet = parse(true, 1, true);
997      ret += iRet[0] + ' ' + name + '<' + iList.join(', ') + '>';
998    } else {
999      ret = name;
1000    }
1001    paramLoop: while (i < func.length && limit-- > 0) {
1002      //dump('paramLoop');
1003      var c = func[i++];
1004      if (c in basicTypes) {
1005        list.push(basicTypes[c]);
1006      } else {
1007        switch (c) {
1008          case 'P': list.push(parse(true, 1, true)[0] + '*'); break; // pointer
1009          case 'R': list.push(parse(true, 1, true)[0] + '&'); break; // reference
1010          case 'L': { // literal
1011            i++; // skip basic type
1012            var end = func.indexOf('E', i);
1013            var size = end - i;
1014            list.push(func.substr(i, size));
1015            i += size + 2; // size + 'EE'
1016            break;
1017          }
1018          case 'A': { // array
1019            var size = parseInt(func.substr(i));
1020            i += size.toString().length;
1021            if (func[i] !== '_') throw '?';
1022            i++; // skip _
1023            list.push(parse(true, 1, true)[0] + ' [' + size + ']');
1024            break;
1025          }
1026          case 'E': break paramLoop;
1027          default: ret += '?' + c; break paramLoop;
1028        }
1029      }
1030    }
1031    if (!allowVoid && list.length === 1 && list[0] === 'void') list = []; // avoid (void)
1032    if (rawList) {
1033      if (ret) {
1034        list.push(ret + '?');
1035      }
1036      return list;
1037    } else {
1038      return ret + flushList();
1039    }
1040  }
1041  try {
1042    // Special-case the entry point, since its name differs from other name mangling.
1043    if (func == 'Object._main' || func == '_main') {
1044      return 'main()';
1045    }
1046    if (typeof func === 'number') func = Pointer_stringify(func);
1047    if (func[0] !== '_') return func;
1048    if (func[1] !== '_') return func; // C function
1049    if (func[2] !== 'Z') return func;
1050    switch (func[3]) {
1051      case 'n': return 'operator new()';
1052      case 'd': return 'operator delete()';
1053    }
1054    return parse();
1055  } catch(e) {
1056    return func;
1057  }
1058}
1059
1060function demangleAll(text) {
1061  return text.replace(/__Z[\w\d_]+/g, function(x) { var y = demangle(x); return x === y ? x : (x + ' [' + y + ']') });
1062}
1063
1064function stackTrace() {
1065  var stack = new Error().stack;
1066  return stack ? demangleAll(stack) : '(no stack trace available)'; // Stack trace is not available at least on IE10 and Safari 6.
1067}
1068
1069// Memory management
1070
1071var PAGE_SIZE = 4096;
1072function alignMemoryPage(x) {
1073  return (x+4095)&-4096;
1074}
1075
1076var HEAP;
1077var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
1078
1079var STATIC_BASE = 0, STATICTOP = 0, staticSealed = false; // static area
1080var STACK_BASE = 0, STACKTOP = 0, STACK_MAX = 0; // stack area
1081var DYNAMIC_BASE = 0, DYNAMICTOP = 0; // dynamic area handled by sbrk
1082
1083function enlargeMemory() {
1084  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 ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.');
1085}
1086
1087var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880;
1088var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 134217728;
1089var FAST_MEMORY = Module['FAST_MEMORY'] || 2097152;
1090
1091var totalMemory = 4096;
1092while (totalMemory < TOTAL_MEMORY || totalMemory < 2*TOTAL_STACK) {
1093  if (totalMemory < 16*1024*1024) {
1094    totalMemory *= 2;
1095  } else {
1096    totalMemory += 16*1024*1024
1097  }
1098}
1099if (totalMemory !== TOTAL_MEMORY) {
1100  Module.printErr('increasing TOTAL_MEMORY to ' + totalMemory + ' to be more reasonable');
1101  TOTAL_MEMORY = totalMemory;
1102}
1103
1104// Initialize the runtime's memory
1105// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
1106assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']),
1107       'JS engine does not provide full typed array support');
1108
1109var buffer = new ArrayBuffer(TOTAL_MEMORY);
1110HEAP8 = new Int8Array(buffer);
1111HEAP16 = new Int16Array(buffer);
1112HEAP32 = new Int32Array(buffer);
1113HEAPU8 = new Uint8Array(buffer);
1114HEAPU16 = new Uint16Array(buffer);
1115HEAPU32 = new Uint32Array(buffer);
1116HEAPF32 = new Float32Array(buffer);
1117HEAPF64 = new Float64Array(buffer);
1118
1119// Endianness check (note: assumes compiler arch was little-endian)
1120HEAP32[0] = 255;
1121assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
1122
1123Module['HEAP'] = HEAP;
1124Module['HEAP8'] = HEAP8;
1125Module['HEAP16'] = HEAP16;
1126Module['HEAP32'] = HEAP32;
1127Module['HEAPU8'] = HEAPU8;
1128Module['HEAPU16'] = HEAPU16;
1129Module['HEAPU32'] = HEAPU32;
1130Module['HEAPF32'] = HEAPF32;
1131Module['HEAPF64'] = HEAPF64;
1132
1133function callRuntimeCallbacks(callbacks) {
1134  while(callbacks.length > 0) {
1135    var callback = callbacks.shift();
1136    if (typeof callback == 'function') {
1137      callback();
1138      continue;
1139    }
1140    var func = callback.func;
1141    if (typeof func === 'number') {
1142      if (callback.arg === undefined) {
1143        Runtime.dynCall('v', func);
1144      } else {
1145        Runtime.dynCall('vi', func, [callback.arg]);
1146      }
1147    } else {
1148      func(callback.arg === undefined ? null : callback.arg);
1149    }
1150  }
1151}
1152
1153var __ATPRERUN__  = []; // functions called before the runtime is initialized
1154var __ATINIT__    = []; // functions called during startup
1155var __ATMAIN__    = []; // functions called when main() is to be run
1156var __ATEXIT__    = []; // functions called during shutdown
1157var __ATPOSTRUN__ = []; // functions called after the runtime has exited
1158
1159var runtimeInitialized = false;
1160
1161function preRun() {
1162  // compatibility - merge in anything from Module['preRun'] at this time
1163  if (Module['preRun']) {
1164    if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
1165    while (Module['preRun'].length) {
1166      addOnPreRun(Module['preRun'].shift());
1167    }
1168  }
1169  callRuntimeCallbacks(__ATPRERUN__);
1170}
1171
1172function ensureInitRuntime() {
1173  if (runtimeInitialized) return;
1174  runtimeInitialized = true;
1175  callRuntimeCallbacks(__ATINIT__);
1176}
1177
1178function preMain() {
1179  callRuntimeCallbacks(__ATMAIN__);
1180}
1181
1182function exitRuntime() {
1183  callRuntimeCallbacks(__ATEXIT__);
1184}
1185
1186function postRun() {
1187  // compatibility - merge in anything from Module['postRun'] at this time
1188  if (Module['postRun']) {
1189    if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
1190    while (Module['postRun'].length) {
1191      addOnPostRun(Module['postRun'].shift());
1192    }
1193  }
1194  callRuntimeCallbacks(__ATPOSTRUN__);
1195}
1196
1197function addOnPreRun(cb) {
1198  __ATPRERUN__.unshift(cb);
1199}
1200Module['addOnPreRun'] = Module.addOnPreRun = addOnPreRun;
1201
1202function addOnInit(cb) {
1203  __ATINIT__.unshift(cb);
1204}
1205Module['addOnInit'] = Module.addOnInit = addOnInit;
1206
1207function addOnPreMain(cb) {
1208  __ATMAIN__.unshift(cb);
1209}
1210Module['addOnPreMain'] = Module.addOnPreMain = addOnPreMain;
1211
1212function addOnExit(cb) {
1213  __ATEXIT__.unshift(cb);
1214}
1215Module['addOnExit'] = Module.addOnExit = addOnExit;
1216
1217function addOnPostRun(cb) {
1218  __ATPOSTRUN__.unshift(cb);
1219}
1220Module['addOnPostRun'] = Module.addOnPostRun = addOnPostRun;
1221
1222// Tools
1223
1224// This processes a JS string into a C-line array of numbers, 0-terminated.
1225// For LLVM-originating strings, see parser.js:parseLLVMString function
1226function intArrayFromString(stringy, dontAddNull, length /* optional */) {
1227  var ret = (new Runtime.UTF8Processor()).processJSString(stringy);
1228  if (length) {
1229    ret.length = length;
1230  }
1231  if (!dontAddNull) {
1232    ret.push(0);
1233  }
1234  return ret;
1235}
1236Module['intArrayFromString'] = intArrayFromString;
1237
1238function intArrayToString(array) {
1239  var ret = [];
1240  for (var i = 0; i < array.length; i++) {
1241    var chr = array[i];
1242    if (chr > 0xFF) {
1243      chr &= 0xFF;
1244    }
1245    ret.push(String.fromCharCode(chr));
1246  }
1247  return ret.join('');
1248}
1249Module['intArrayToString'] = intArrayToString;
1250
1251// Write a Javascript array to somewhere in the heap
1252function writeStringToMemory(string, buffer, dontAddNull) {
1253  var array = intArrayFromString(string, dontAddNull);
1254  var i = 0;
1255  while (i < array.length) {
1256    var chr = array[i];
1257    HEAP8[(((buffer)+(i))|0)]=chr;
1258    i = i + 1;
1259  }
1260}
1261Module['writeStringToMemory'] = writeStringToMemory;
1262
1263function writeArrayToMemory(array, buffer) {
1264  for (var i = 0; i < array.length; i++) {
1265    HEAP8[(((buffer)+(i))|0)]=array[i];
1266  }
1267}
1268Module['writeArrayToMemory'] = writeArrayToMemory;
1269
1270function writeAsciiToMemory(str, buffer, dontAddNull) {
1271  for (var i = 0; i < str.length; i++) {
1272    HEAP8[(((buffer)+(i))|0)]=str.charCodeAt(i);
1273  }
1274  if (!dontAddNull) HEAP8[(((buffer)+(str.length))|0)]=0;
1275}
1276Module['writeAsciiToMemory'] = writeAsciiToMemory;
1277
1278function unSign(value, bits, ignore) {
1279  if (value >= 0) {
1280    return value;
1281  }
1282  return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
1283                    : Math.pow(2, bits)         + value;
1284}
1285function reSign(value, bits, ignore) {
1286  if (value <= 0) {
1287    return value;
1288  }
1289  var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
1290                        : Math.pow(2, bits-1);
1291  if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that
1292                                                       // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
1293                                                       // TODO: In i64 mode 1, resign the two parts separately and safely
1294    value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
1295  }
1296  return value;
1297}
1298
1299// check for imul support, and also for correctness ( https://bugs.webkit.org/show_bug.cgi?id=126345 )
1300if (!Math['imul'] || Math['imul'](0xffffffff, 5) !== -5) Math['imul'] = function imul(a, b) {
1301  var ah  = a >>> 16;
1302  var al = a & 0xffff;
1303  var bh  = b >>> 16;
1304  var bl = b & 0xffff;
1305  return (al*bl + ((ah*bl + al*bh) << 16))|0;
1306};
1307Math.imul = Math['imul'];
1308
1309
1310var Math_abs = Math.abs;
1311var Math_cos = Math.cos;
1312var Math_sin = Math.sin;
1313var Math_tan = Math.tan;
1314var Math_acos = Math.acos;
1315var Math_asin = Math.asin;
1316var Math_atan = Math.atan;
1317var Math_atan2 = Math.atan2;
1318var Math_exp = Math.exp;
1319var Math_log = Math.log;
1320var Math_sqrt = Math.sqrt;
1321var Math_ceil = Math.ceil;
1322var Math_floor = Math.floor;
1323var Math_pow = Math.pow;
1324var Math_imul = Math.imul;
1325var Math_fround = Math.fround;
1326var Math_min = Math.min;
1327
1328// A counter of dependencies for calling run(). If we need to
1329// do asynchronous work before running, increment this and
1330// decrement it. Incrementing must happen in a place like
1331// PRE_RUN_ADDITIONS (used by emcc to add file preloading).
1332// Note that you can add dependencies in preRun, even though
1333// it happens right before run - run will be postponed until
1334// the dependencies are met.
1335var runDependencies = 0;
1336var runDependencyWatcher = null;
1337var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
1338
1339function addRunDependency(id) {
1340  runDependencies++;
1341  if (Module['monitorRunDependencies']) {
1342    Module['monitorRunDependencies'](runDependencies);
1343  }
1344}
1345Module['addRunDependency'] = addRunDependency;
1346function removeRunDependency(id) {
1347  runDependencies--;
1348  if (Module['monitorRunDependencies']) {
1349    Module['monitorRunDependencies'](runDependencies);
1350  }
1351  if (runDependencies == 0) {
1352    if (runDependencyWatcher !== null) {
1353      clearInterval(runDependencyWatcher);
1354      runDependencyWatcher = null;
1355    }
1356    if (dependenciesFulfilled) {
1357      var callback = dependenciesFulfilled;
1358      dependenciesFulfilled = null;
1359      callback(); // can add another dependenciesFulfilled
1360    }
1361  }
1362}
1363Module['removeRunDependency'] = removeRunDependency;
1364
1365Module["preloadedImages"] = {}; // maps url to image data
1366Module["preloadedAudios"] = {}; // maps url to audio data
1367
1368
1369var memoryInitializer = null;
1370
1371// === Body ===
1372
1373
1374
1375
1376
1377STATIC_BASE = 8;
1378
1379STATICTOP = STATIC_BASE + Runtime.alignMemory(1155);
1380/* global initializers */ __ATINIT__.push();
1381
1382
1383/* memory initializer */ allocate([38,2,0,0,0,0,0,0,42,0,0,0,0,0,0,0,97,0,0,0,113,61,138,62,0,0,0,0,99,0,0,0,143,194,245,61,0,0,0,0,103,0,0,0,143,194,245,61,0,0,0,0,116,0,0,0,113,61,138,62,0,0,0,0,66,0,0,0,10,215,163,60,0,0,0,0,68,0,0,0,10,215,163,60,0,0,0,0,72,0,0,0,10,215,163,60,0,0,0,0,75,0,0,0,10,215,163,60,0,0,0,0,77,0,0,0,10,215,163,60,0,0,0,0,78,0,0,0,10,215,163,60,0,0,0,0,82,0,0,0,10,215,163,60,0,0,0,0,83,0,0,0,10,215,163,60,0,0,0,0,86,0,0,0,10,215,163,60,0,0,0,0,87,0,0,0,10,215,163,60,0,0,0,0,89,0,0,0,10,215,163,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,0,0,0,233,28,155,62,0,0,0,0,99,0,0,0,114,189,74,62,0,0,0,0,103,0,0,0,215,73,74,62,0,0,0,0,116,0,0,0,114,95,154,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,114,114,111,114,58,32,37,100,10,0,0,0,0,0,0,71,71,67,67,71,71,71,67,71,67,71,71,84,71,71,67,84,67,65,67,71,67,67,84,71,84,65,65,84,67,67,67,65,71,67,65,67,84,84,84,71,71,71,65,71,71,67,67,71,65,71,71,67,71,71,71,67,71,71,65,84,67,65,67,67,84,71,65,71,71,84,67,65,71,71,65,71,84,84,67,71,65,71,65,67,67,65,71,67,67,84,71,71,67,67,65,65,67,65,84,71,71,84,71,65,65,65,67,67,67,67,71,84,67,84,67,84,65,67,84,65,65,65,65,65,84,65,67,65,65,65,65,65,84,84,65,71,67,67,71,71,71,67,71,84,71,71,84,71,71,67,71,67,71,67,71,67,67,84,71,84,65,65,84,67,67,67,65,71,67,84,65,67,84,67,71,71,71,65,71,71,67,84,71,65,71,71,67,65,71,71,65,71,65,65,84,67,71,67,84,84,71,65,65,67,67,67,71,71,71,65,71,71,67,71,71,65,71,71,84,84,71,67,65,71,84,71,65,71,67,67,71,65,71,65,84,67,71,67,71,67,67,65,67,84,71,67,65,67,84,67,67,65,71,67,67,84,71,71,71,67,71,65,67,65,71,65,71,67,71,65,71,65,67,84,67,67,71,84,67,84,67,65,65,65,65,65,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,120,4,0,0,1,0,0,0,2,0,0,0,1,0,0,0,0,0,0,0,115,116,100,58,58,98,97,100,95,97,108,108,111,99,0,0,83,116,57,98,97,100,95,97,108,108,111,99,0,0,0,0,8,0,0,0,104,4,0,0,0,0,0,0,0,0,0,0], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE);
1384
1385
1386
1387
1388var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8);
1389
1390assert(tempDoublePtr % 8 == 0);
1391
1392function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much
1393
1394  HEAP8[tempDoublePtr] = HEAP8[ptr];
1395
1396  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
1397
1398  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
1399
1400  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
1401
1402}
1403
1404function copyTempDouble(ptr) {
1405
1406  HEAP8[tempDoublePtr] = HEAP8[ptr];
1407
1408  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
1409
1410  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
1411
1412  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
1413
1414  HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];
1415
1416  HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];
1417
1418  HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];
1419
1420  HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];
1421
1422}
1423
1424
1425
1426
1427  var ___errno_state=0;function ___setErrNo(value) {
1428      // For convenient setting and returning of errno.
1429      HEAP32[((___errno_state)>>2)]=value;
1430      return value;
1431    }
1432
1433  var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};function _sysconf(name) {
1434      // long sysconf(int name);
1435      // http://pubs.opengroup.org/onlinepubs/009695399/functions/sysconf.html
1436      switch(name) {
1437        case 30: return PAGE_SIZE;
1438        case 132:
1439        case 133:
1440        case 12:
1441        case 137:
1442        case 138:
1443        case 15:
1444        case 235:
1445        case 16:
1446        case 17:
1447        case 18:
1448        case 19:
1449        case 20:
1450        case 149:
1451        case 13:
1452        case 10:
1453        case 236:
1454        case 153:
1455        case 9:
1456        case 21:
1457        case 22:
1458        case 159:
1459        case 154:
1460        case 14:
1461        case 77:
1462        case 78:
1463        case 139:
1464        case 80:
1465        case 81:
1466        case 79:
1467        case 82:
1468        case 68:
1469        case 67:
1470        case 164:
1471        case 11:
1472        case 29:
1473        case 47:
1474        case 48:
1475        case 95:
1476        case 52:
1477        case 51:
1478        case 46:
1479          return 200809;
1480        case 27:
1481        case 246:
1482        case 127:
1483        case 128:
1484        case 23:
1485        case 24:
1486        case 160:
1487        case 161:
1488        case 181:
1489        case 182:
1490        case 242:
1491        case 183:
1492        case 184:
1493        case 243:
1494        case 244:
1495        case 245:
1496        case 165:
1497        case 178:
1498        case 179:
1499        case 49:
1500        case 50:
1501        case 168:
1502        case 169:
1503        case 175:
1504        case 170:
1505        case 171:
1506        case 172:
1507        case 97:
1508        case 76:
1509        case 32:
1510        case 173:
1511        case 35:
1512          return -1;
1513        case 176:
1514        case 177:
1515        case 7:
1516        case 155:
1517        case 8:
1518        case 157:
1519        case 125:
1520        case 126:
1521        case 92:
1522        case 93:
1523        case 129:
1524        case 130:
1525        case 131:
1526        case 94:
1527        case 91:
1528          return 1;
1529        case 74:
1530        case 60:
1531        case 69:
1532        case 70:
1533        case 4:
1534          return 1024;
1535        case 31:
1536        case 42:
1537        case 72:
1538          return 32;
1539        case 87:
1540        case 26:
1541        case 33:
1542          return 2147483647;
1543        case 34:
1544        case 1:
1545          return 47839;
1546        case 38:
1547        case 36:
1548          return 99;
1549        case 43:
1550        case 37:
1551          return 2048;
1552        case 0: return 2097152;
1553        case 3: return 65536;
1554        case 28: return 32768;
1555        case 44: return 32767;
1556        case 75: return 16384;
1557        case 39: return 1000;
1558        case 89: return 700;
1559        case 71: return 256;
1560        case 40: return 255;
1561        case 2: return 100;
1562        case 180: return 64;
1563        case 25: return 20;
1564        case 5: return 16;
1565        case 6: return 6;
1566        case 73: return 4;
1567        case 84: return 1;
1568      }
1569      ___setErrNo(ERRNO_CODES.EINVAL);
1570      return -1;
1571    }
1572
1573
1574  function __ZSt18uncaught_exceptionv() { // std::uncaught_exception()
1575      return !!__ZSt18uncaught_exceptionv.uncaught_exception;
1576    }
1577
1578
1579
1580  function ___cxa_is_number_type(type) {
1581      var isNumber = false;
1582      try { if (type == __ZTIi) isNumber = true } catch(e){}
1583      try { if (type == __ZTIj) isNumber = true } catch(e){}
1584      try { if (type == __ZTIl) isNumber = true } catch(e){}
1585      try { if (type == __ZTIm) isNumber = true } catch(e){}
1586      try { if (type == __ZTIx) isNumber = true } catch(e){}
1587      try { if (type == __ZTIy) isNumber = true } catch(e){}
1588      try { if (type == __ZTIf) isNumber = true } catch(e){}
1589      try { if (type == __ZTId) isNumber = true } catch(e){}
1590      try { if (type == __ZTIe) isNumber = true } catch(e){}
1591      try { if (type == __ZTIc) isNumber = true } catch(e){}
1592      try { if (type == __ZTIa) isNumber = true } catch(e){}
1593      try { if (type == __ZTIh) isNumber = true } catch(e){}
1594      try { if (type == __ZTIs) isNumber = true } catch(e){}
1595      try { if (type == __ZTIt) isNumber = true } catch(e){}
1596      return isNumber;
1597    }function ___cxa_does_inherit(definiteType, possibilityType, possibility) {
1598      if (possibility == 0) return false;
1599      if (possibilityType == 0 || possibilityType == definiteType)
1600        return true;
1601      var possibility_type_info;
1602      if (___cxa_is_number_type(possibilityType)) {
1603        possibility_type_info = possibilityType;
1604      } else {
1605        var possibility_type_infoAddr = HEAP32[((possibilityType)>>2)] - 8;
1606        possibility_type_info = HEAP32[((possibility_type_infoAddr)>>2)];
1607      }
1608      switch (possibility_type_info) {
1609      case 0: // possibility is a pointer
1610        // See if definite type is a pointer
1611        var definite_type_infoAddr = HEAP32[((definiteType)>>2)] - 8;
1612        var definite_type_info = HEAP32[((definite_type_infoAddr)>>2)];
1613        if (definite_type_info == 0) {
1614          // Also a pointer; compare base types of pointers
1615          var defPointerBaseAddr = definiteType+8;
1616          var defPointerBaseType = HEAP32[((defPointerBaseAddr)>>2)];
1617          var possPointerBaseAddr = possibilityType+8;
1618          var possPointerBaseType = HEAP32[((possPointerBaseAddr)>>2)];
1619          return ___cxa_does_inherit(defPointerBaseType, possPointerBaseType, possibility);
1620        } else
1621          return false; // one pointer and one non-pointer
1622      case 1: // class with no base class
1623        return false;
1624      case 2: // class with base class
1625        var parentTypeAddr = possibilityType + 8;
1626        var parentType = HEAP32[((parentTypeAddr)>>2)];
1627        return ___cxa_does_inherit(definiteType, parentType, possibility);
1628      default:
1629        return false; // some unencountered type
1630      }
1631    }
1632
1633
1634
1635  var ___cxa_last_thrown_exception=0;function ___resumeException(ptr) {
1636      if (!___cxa_last_thrown_exception) { ___cxa_last_thrown_exception = ptr; }
1637      throw ptr + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.";
1638    }
1639
1640  var ___cxa_exception_header_size=8;function ___cxa_find_matching_catch(thrown, throwntype) {
1641      if (thrown == -1) thrown = ___cxa_last_thrown_exception;
1642      header = thrown - ___cxa_exception_header_size;
1643      if (throwntype == -1) throwntype = HEAP32[((header)>>2)];
1644      var typeArray = Array.prototype.slice.call(arguments, 2);
1645
1646      // If throwntype is a pointer, this means a pointer has been
1647      // thrown. When a pointer is thrown, actually what's thrown
1648      // is a pointer to the pointer. We'll dereference it.
1649      if (throwntype != 0 && !___cxa_is_number_type(throwntype)) {
1650        var throwntypeInfoAddr= HEAP32[((throwntype)>>2)] - 8;
1651        var throwntypeInfo= HEAP32[((throwntypeInfoAddr)>>2)];
1652        if (throwntypeInfo == 0)
1653          thrown = HEAP32[((thrown)>>2)];
1654      }
1655      // The different catch blocks are denoted by different types.
1656      // Due to inheritance, those types may not precisely match the
1657      // type of the thrown object. Find one which matches, and
1658      // return the type of the catch block which should be called.
1659      for (var i = 0; i < typeArray.length; i++) {
1660        if (___cxa_does_inherit(typeArray[i], throwntype, thrown))
1661          return ((asm["setTempRet0"](typeArray[i]),thrown)|0);
1662      }
1663      // Shouldn't happen unless we have bogus data in typeArray
1664      // or encounter a type for which emscripten doesn't have suitable
1665      // typeinfo defined. Best-efforts match just in case.
1666      return ((asm["setTempRet0"](throwntype),thrown)|0);
1667    }function ___cxa_throw(ptr, type, destructor) {
1668      if (!___cxa_throw.initialized) {
1669        try {
1670          HEAP32[((__ZTVN10__cxxabiv119__pointer_type_infoE)>>2)]=0; // Workaround for libcxxabi integration bug
1671        } catch(e){}
1672        try {
1673          HEAP32[((__ZTVN10__cxxabiv117__class_type_infoE)>>2)]=1; // Workaround for libcxxabi integration bug
1674        } catch(e){}
1675        try {
1676          HEAP32[((__ZTVN10__cxxabiv120__si_class_type_infoE)>>2)]=2; // Workaround for libcxxabi integration bug
1677        } catch(e){}
1678        ___cxa_throw.initialized = true;
1679      }
1680      var header = ptr - ___cxa_exception_header_size;
1681      HEAP32[((header)>>2)]=type;
1682      HEAP32[(((header)+(4))>>2)]=destructor;
1683      ___cxa_last_thrown_exception = ptr;
1684      if (!("uncaught_exception" in __ZSt18uncaught_exceptionv)) {
1685        __ZSt18uncaught_exceptionv.uncaught_exception = 1;
1686      } else {
1687        __ZSt18uncaught_exceptionv.uncaught_exception++;
1688      }
1689      throw ptr + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.";
1690    }
1691
1692
1693  Module["_memset"] = _memset;
1694
1695  function _abort() {
1696      Module['abort']();
1697    }
1698
1699
1700
1701
1702
1703  var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can   access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"};
1704
1705  var PATH={splitPath:function (filename) {
1706        var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
1707        return splitPathRe.exec(filename).slice(1);
1708      },normalizeArray:function (parts, allowAboveRoot) {
1709        // if the path tries to go above the root, `up` ends up > 0
1710        var up = 0;
1711        for (var i = parts.length - 1; i >= 0; i--) {
1712          var last = parts[i];
1713          if (last === '.') {
1714            parts.splice(i, 1);
1715          } else if (last === '..') {
1716            parts.splice(i, 1);
1717            up++;
1718          } else if (up) {
1719            parts.splice(i, 1);
1720            up--;
1721          }
1722        }
1723        // if the path is allowed to go above the root, restore leading ..s
1724        if (allowAboveRoot) {
1725          for (; up--; up) {
1726            parts.unshift('..');
1727          }
1728        }
1729        return parts;
1730      },normalize:function (path) {
1731        var isAbsolute = path.charAt(0) === '/',
1732            trailingSlash = path.substr(-1) === '/';
1733        // Normalize the path
1734        path = PATH.normalizeArray(path.split('/').filter(function(p) {
1735          return !!p;
1736        }), !isAbsolute).join('/');
1737        if (!path && !isAbsolute) {
1738          path = '.';
1739        }
1740        if (path && trailingSlash) {
1741          path += '/';
1742        }
1743        return (isAbsolute ? '/' : '') + path;
1744      },dirname:function (path) {
1745        var result = PATH.splitPath(path),
1746            root = result[0],
1747            dir = result[1];
1748        if (!root && !dir) {
1749          // No dirname whatsoever
1750          return '.';
1751        }
1752        if (dir) {
1753          // It has a dirname, strip trailing slash
1754          dir = dir.substr(0, dir.length - 1);
1755        }
1756        return root + dir;
1757      },basename:function (path) {
1758        // EMSCRIPTEN return '/'' for '/', not an empty string
1759        if (path === '/') return '/';
1760        var lastSlash = path.lastIndexOf('/');
1761        if (lastSlash === -1) return path;
1762        return path.substr(lastSlash+1);
1763      },extname:function (path) {
1764        return PATH.splitPath(path)[3];
1765      },join:function () {
1766        var paths = Array.prototype.slice.call(arguments, 0);
1767        return PATH.normalize(paths.join('/'));
1768      },join2:function (l, r) {
1769        return PATH.normalize(l + '/' + r);
1770      },resolve:function () {
1771        var resolvedPath = '',
1772          resolvedAbsolute = false;
1773        for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
1774          var path = (i >= 0) ? arguments[i] : FS.cwd();
1775          // Skip empty and invalid entries
1776          if (typeof path !== 'string') {
1777            throw new TypeError('Arguments to path.resolve must be strings');
1778          } else if (!path) {
1779            continue;
1780          }
1781          resolvedPath = path + '/' + resolvedPath;
1782          resolvedAbsolute = path.charAt(0) === '/';
1783        }
1784        // At this point the path should be resolved to a full absolute path, but
1785        // handle relative paths to be safe (might happen when process.cwd() fails)
1786        resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) {
1787          return !!p;
1788        }), !resolvedAbsolute).join('/');
1789        return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
1790      },relative:function (from, to) {
1791        from = PATH.resolve(from).substr(1);
1792        to = PATH.resolve(to).substr(1);
1793        function trim(arr) {
1794          var start = 0;
1795          for (; start < arr.length; start++) {
1796            if (arr[start] !== '') break;
1797          }
1798          var end = arr.length - 1;
1799          for (; end >= 0; end--) {
1800            if (arr[end] !== '') break;
1801          }
1802          if (start > end) return [];
1803          return arr.slice(start, end - start + 1);
1804        }
1805        var fromParts = trim(from.split('/'));
1806        var toParts = trim(to.split('/'));
1807        var length = Math.min(fromParts.length, toParts.length);
1808        var samePartsLength = length;
1809        for (var i = 0; i < length; i++) {
1810          if (fromParts[i] !== toParts[i]) {
1811            samePartsLength = i;
1812            break;
1813          }
1814        }
1815        var outputParts = [];
1816        for (var i = samePartsLength; i < fromParts.length; i++) {
1817          outputParts.push('..');
1818        }
1819        outputParts = outputParts.concat(toParts.slice(samePartsLength));
1820        return outputParts.join('/');
1821      }};
1822
1823  var TTY={ttys:[],init:function () {
1824        // https://github.com/kripken/emscripten/pull/1555
1825        // if (ENVIRONMENT_IS_NODE) {
1826        //   // currently, FS.init does not distinguish if process.stdin is a file or TTY
1827        //   // device, it always assumes it's a TTY device. because of this, we're forcing
1828        //   // process.stdin to UTF8 encoding to at least make stdin reading compatible
1829        //   // with text files until FS.init can be refactored.
1830        //   process['stdin']['setEncoding']('utf8');
1831        // }
1832      },shutdown:function () {
1833        // https://github.com/kripken/emscripten/pull/1555
1834        // if (ENVIRONMENT_IS_NODE) {
1835        //   // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
1836        //   // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
1837        //   // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
1838        //   // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
1839        //   // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
1840        //   process['stdin']['pause']();
1841        // }
1842      },register:function (dev, ops) {
1843        TTY.ttys[dev] = { input: [], output: [], ops: ops };
1844        FS.registerDevice(dev, TTY.stream_ops);
1845      },stream_ops:{open:function (stream) {
1846          var tty = TTY.ttys[stream.node.rdev];
1847          if (!tty) {
1848            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
1849          }
1850          stream.tty = tty;
1851          stream.seekable = false;
1852        },close:function (stream) {
1853          // flush any pending line data
1854          if (stream.tty.output.length) {
1855            stream.tty.ops.put_char(stream.tty, 10);
1856          }
1857        },read:function (stream, buffer, offset, length, pos /* ignored */) {
1858          if (!stream.tty || !stream.tty.ops.get_char) {
1859            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
1860          }
1861          var bytesRead = 0;
1862          for (var i = 0; i < length; i++) {
1863            var result;
1864            try {
1865              result = stream.tty.ops.get_char(stream.tty);
1866            } catch (e) {
1867              throw new FS.ErrnoError(ERRNO_CODES.EIO);
1868            }
1869            if (result === undefined && bytesRead === 0) {
1870              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
1871            }
1872            if (result === null || result === undefined) break;
1873            bytesRead++;
1874            buffer[offset+i] = result;
1875          }
1876          if (bytesRead) {
1877            stream.node.timestamp = Date.now();
1878          }
1879          return bytesRead;
1880        },write:function (stream, buffer, offset, length, pos) {
1881          if (!stream.tty || !stream.tty.ops.put_char) {
1882            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
1883          }
1884          for (var i = 0; i < length; i++) {
1885            try {
1886              stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
1887            } catch (e) {
1888              throw new FS.ErrnoError(ERRNO_CODES.EIO);
1889            }
1890          }
1891          if (length) {
1892            stream.node.timestamp = Date.now();
1893          }
1894          return i;
1895        }},default_tty_ops:{get_char:function (tty) {
1896          if (!tty.input.length) {
1897            var result = null;
1898            if (ENVIRONMENT_IS_NODE) {
1899              result = process['stdin']['read']();
1900              if (!result) {
1901                if (process['stdin']['_readableState'] && process['stdin']['_readableState']['ended']) {
1902                  return null;  // EOF
1903                }
1904                return undefined;  // no data available
1905              }
1906            } else if (typeof window != 'undefined' &&
1907              typeof window.prompt == 'function') {
1908              // Browser.
1909              result = window.prompt('Input: ');  // returns null on cancel
1910              if (result !== null) {
1911                result += '\n';
1912              }
1913            } else if (typeof readline == 'function') {
1914              // Command line.
1915              result = readline();
1916              if (result !== null) {
1917                result += '\n';
1918              }
1919            }
1920            if (!result) {
1921              return null;
1922            }
1923            tty.input = intArrayFromString(result, true);
1924          }
1925          return tty.input.shift();
1926        },put_char:function (tty, val) {
1927          if (val === null || val === 10) {
1928            Module['print'](tty.output.join(''));
1929            tty.output = [];
1930          } else {
1931            tty.output.push(TTY.utf8.processCChar(val));
1932          }
1933        }},default_tty1_ops:{put_char:function (tty, val) {
1934          if (val === null || val === 10) {
1935            Module['printErr'](tty.output.join(''));
1936            tty.output = [];
1937          } else {
1938            tty.output.push(TTY.utf8.processCChar(val));
1939          }
1940        }}};
1941
1942  var MEMFS={ops_table:null,CONTENT_OWNING:1,CONTENT_FLEXIBLE:2,CONTENT_FIXED:3,mount:function (mount) {
1943        return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
1944      },createNode:function (parent, name, mode, dev) {
1945        if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
1946          // no supported
1947          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
1948        }
1949        if (!MEMFS.ops_table) {
1950          MEMFS.ops_table = {
1951            dir: {
1952              node: {
1953                getattr: MEMFS.node_ops.getattr,
1954                setattr: MEMFS.node_ops.setattr,
1955                lookup: MEMFS.node_ops.lookup,
1956                mknod: MEMFS.node_ops.mknod,
1957                rename: MEMFS.node_ops.rename,
1958                unlink: MEMFS.node_ops.unlink,
1959                rmdir: MEMFS.node_ops.rmdir,
1960                readdir: MEMFS.node_ops.readdir,
1961                symlink: MEMFS.node_ops.symlink
1962              },
1963              stream: {
1964                llseek: MEMFS.stream_ops.llseek
1965              }
1966            },
1967            file: {
1968              node: {
1969                getattr: MEMFS.node_ops.getattr,
1970                setattr: MEMFS.node_ops.setattr
1971              },
1972              stream: {
1973                llseek: MEMFS.stream_ops.llseek,
1974                read: MEMFS.stream_ops.read,
1975                write: MEMFS.stream_ops.write,
1976                allocate: MEMFS.stream_ops.allocate,
1977                mmap: MEMFS.stream_ops.mmap
1978              }
1979            },
1980            link: {
1981              node: {
1982                getattr: MEMFS.node_ops.getattr,
1983                setattr: MEMFS.node_ops.setattr,
1984                readlink: MEMFS.node_ops.readlink
1985              },
1986              stream: {}
1987            },
1988            chrdev: {
1989              node: {
1990                getattr: MEMFS.node_ops.getattr,
1991                setattr: MEMFS.node_ops.setattr
1992              },
1993              stream: FS.chrdev_stream_ops
1994            },
1995          };
1996        }
1997        var node = FS.createNode(parent, name, mode, dev);
1998        if (FS.isDir(node.mode)) {
1999          node.node_ops = MEMFS.ops_table.dir.node;
2000          node.stream_ops = MEMFS.ops_table.dir.stream;
2001          node.contents = {};
2002        } else if (FS.isFile(node.mode)) {
2003          node.node_ops = MEMFS.ops_table.file.node;
2004          node.stream_ops = MEMFS.ops_table.file.stream;
2005          node.contents = [];
2006          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
2007        } else if (FS.isLink(node.mode)) {
2008          node.node_ops = MEMFS.ops_table.link.node;
2009          node.stream_ops = MEMFS.ops_table.link.stream;
2010        } else if (FS.isChrdev(node.mode)) {
2011          node.node_ops = MEMFS.ops_table.chrdev.node;
2012          node.stream_ops = MEMFS.ops_table.chrdev.stream;
2013        }
2014        node.timestamp = Date.now();
2015        // add the new node to the parent
2016        if (parent) {
2017          parent.contents[name] = node;
2018        }
2019        return node;
2020      },ensureFlexible:function (node) {
2021        if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) {
2022          var contents = node.contents;
2023          node.contents = Array.prototype.slice.call(contents);
2024          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
2025        }
2026      },node_ops:{getattr:function (node) {
2027          var attr = {};
2028          // device numbers reuse inode numbers.
2029          attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
2030          attr.ino = node.id;
2031          attr.mode = node.mode;
2032          attr.nlink = 1;
2033          attr.uid = 0;
2034          attr.gid = 0;
2035          attr.rdev = node.rdev;
2036          if (FS.isDir(node.mode)) {
2037            attr.size = 4096;
2038          } else if (FS.isFile(node.mode)) {
2039            attr.size = node.contents.length;
2040          } else if (FS.isLink(node.mode)) {
2041            attr.size = node.link.length;
2042          } else {
2043            attr.size = 0;
2044          }
2045          attr.atime = new Date(node.timestamp);
2046          attr.mtime = new Date(node.timestamp);
2047          attr.ctime = new Date(node.timestamp);
2048          // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
2049          //       but this is not required by the standard.
2050          attr.blksize = 4096;
2051          attr.blocks = Math.ceil(attr.size / attr.blksize);
2052          return attr;
2053        },setattr:function (node, attr) {
2054          if (attr.mode !== undefined) {
2055            node.mode = attr.mode;
2056          }
2057          if (attr.timestamp !== undefined) {
2058            node.timestamp = attr.timestamp;
2059          }
2060          if (attr.size !== undefined) {
2061            MEMFS.ensureFlexible(node);
2062            var contents = node.contents;
2063            if (attr.size < contents.length) contents.length = attr.size;
2064            else while (attr.size > contents.length) contents.push(0);
2065          }
2066        },lookup:function (parent, name) {
2067          throw FS.genericErrors[ERRNO_CODES.ENOENT];
2068        },mknod:function (parent, name, mode, dev) {
2069          return MEMFS.createNode(parent, name, mode, dev);
2070        },rename:function (old_node, new_dir, new_name) {
2071          // if we're overwriting a directory at new_name, make sure it's empty.
2072          if (FS.isDir(old_node.mode)) {
2073            var new_node;
2074            try {
2075              new_node = FS.lookupNode(new_dir, new_name);
2076            } catch (e) {
2077            }
2078            if (new_node) {
2079              for (var i in new_node.contents) {
2080                throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
2081              }
2082            }
2083          }
2084          // do the internal rewiring
2085          delete old_node.parent.contents[old_node.name];
2086          old_node.name = new_name;
2087          new_dir.contents[new_name] = old_node;
2088          old_node.parent = new_dir;
2089        },unlink:function (parent, name) {
2090          delete parent.contents[name];
2091        },rmdir:function (parent, name) {
2092          var node = FS.lookupNode(parent, name);
2093          for (var i in node.contents) {
2094            throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
2095          }
2096          delete parent.contents[name];
2097        },readdir:function (node) {
2098          var entries = ['.', '..']
2099          for (var key in node.contents) {
2100            if (!node.contents.hasOwnProperty(key)) {
2101              continue;
2102            }
2103            entries.push(key);
2104          }
2105          return entries;
2106        },symlink:function (parent, newname, oldpath) {
2107          var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
2108          node.link = oldpath;
2109          return node;
2110        },readlink:function (node) {
2111          if (!FS.isLink(node.mode)) {
2112            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
2113          }
2114          return node.link;
2115        }},stream_ops:{read:function (stream, buffer, offset, length, position) {
2116          var contents = stream.node.contents;
2117          if (position >= contents.length)
2118            return 0;
2119          var size = Math.min(contents.length - position, length);
2120          assert(size >= 0);
2121          if (size > 8 && contents.subarray) { // non-trivial, and typed array
2122            buffer.set(contents.subarray(position, position + size), offset);
2123          } else
2124          {
2125            for (var i = 0; i < size; i++) {
2126              buffer[offset + i] = contents[position + i];
2127            }
2128          }
2129          return size;
2130        },write:function (stream, buffer, offset, length, position, canOwn) {
2131          var node = stream.node;
2132          node.timestamp = Date.now();
2133          var contents = node.contents;
2134          if (length && contents.length === 0 && position === 0 && buffer.subarray) {
2135            // just replace it with the new data
2136            if (canOwn && offset === 0) {
2137              node.contents = buffer; // this could be a subarray of Emscripten HEAP, or allocated from some other source.
2138              node.contentMode = (buffer.buffer === HEAP8.buffer) ? MEMFS.CONTENT_OWNING : MEMFS.CONTENT_FIXED;
2139            } else {
2140              node.contents = new Uint8Array(buffer.subarray(offset, offset+length));
2141              node.contentMode = MEMFS.CONTENT_FIXED;
2142            }
2143            return length;
2144          }
2145          MEMFS.ensureFlexible(node);
2146          var contents = node.contents;
2147          while (contents.length < position) contents.push(0);
2148          for (var i = 0; i < length; i++) {
2149            contents[position + i] = buffer[offset + i];
2150          }
2151          return length;
2152        },llseek:function (stream, offset, whence) {
2153          var position = offset;
2154          if (whence === 1) {  // SEEK_CUR.
2155            position += stream.position;
2156          } else if (whence === 2) {  // SEEK_END.
2157            if (FS.isFile(stream.node.mode)) {
2158              position += stream.node.contents.length;
2159            }
2160          }
2161          if (position < 0) {
2162            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
2163          }
2164          stream.ungotten = [];
2165          stream.position = position;
2166          return position;
2167        },allocate:function (stream, offset, length) {
2168          MEMFS.ensureFlexible(stream.node);
2169          var contents = stream.node.contents;
2170          var limit = offset + length;
2171          while (limit > contents.length) contents.push(0);
2172        },mmap:function (stream, buffer, offset, length, position, prot, flags) {
2173          if (!FS.isFile(stream.node.mode)) {
2174            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
2175          }
2176          var ptr;
2177          var allocated;
2178          var contents = stream.node.contents;
2179          // Only make a new copy when MAP_PRIVATE is specified.
2180          if ( !(flags & 2) &&
2181                (contents.buffer === buffer || contents.buffer === buffer.buffer) ) {
2182            // We can't emulate MAP_SHARED when the file is not backed by the buffer
2183            // we're mapping to (e.g. the HEAP buffer).
2184            allocated = false;
2185            ptr = contents.byteOffset;
2186          } else {
2187            // Try to avoid unnecessary slices.
2188            if (position > 0 || position + length < contents.length) {
2189              if (contents.subarray) {
2190                contents = contents.subarray(position, position + length);
2191              } else {
2192                contents = Array.prototype.slice.call(contents, position, position + length);
2193              }
2194            }
2195            allocated = true;
2196            ptr = _malloc(length);
2197            if (!ptr) {
2198              throw new FS.ErrnoError(ERRNO_CODES.ENOMEM);
2199            }
2200            buffer.set(contents, ptr);
2201          }
2202          return { ptr: ptr, allocated: allocated };
2203        }}};
2204
2205  var IDBFS={dbs:{},indexedDB:function () {
2206        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
2207      },DB_VERSION:21,DB_STORE_NAME:"FILE_DATA",mount:function (mount) {
2208        // reuse all of the core MEMFS functionality
2209        return MEMFS.mount.apply(null, arguments);
2210      },syncfs:function (mount, populate, callback) {
2211        IDBFS.getLocalSet(mount, function(err, local) {
2212          if (err) return callback(err);
2213
2214          IDBFS.getRemoteSet(mount, function(err, remote) {
2215            if (err) return callback(err);
2216
2217            var src = populate ? remote : local;
2218            var dst = populate ? local : remote;
2219
2220            IDBFS.reconcile(src, dst, callback);
2221          });
2222        });
2223      },getDB:function (name, callback) {
2224        // check the cache first
2225        var db = IDBFS.dbs[name];
2226        if (db) {
2227          return callback(null, db);
2228        }
2229
2230        var req;
2231        try {
2232          req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION);
2233        } catch (e) {
2234          return callback(e);
2235        }
2236        req.onupgradeneeded = function(e) {
2237          var db = e.target.result;
2238          var transaction = e.target.transaction;
2239
2240          var fileStore;
2241
2242          if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) {
2243            fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME);
2244          } else {
2245            fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME);
2246          }
2247
2248          fileStore.createIndex('timestamp', 'timestamp', { unique: false });
2249        };
2250        req.onsuccess = function() {
2251          db = req.result;
2252
2253          // add to the cache
2254          IDBFS.dbs[name] = db;
2255          callback(null, db);
2256        };
2257        req.onerror = function() {
2258          callback(this.error);
2259        };
2260      },getLocalSet:function (mount, callback) {
2261        var entries = {};
2262
2263        function isRealDir(p) {
2264          return p !== '.' && p !== '..';
2265        };
2266        function toAbsolute(root) {
2267          return function(p) {
2268            return PATH.join2(root, p);
2269          }
2270        };
2271
2272        var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint));
2273
2274        while (check.length) {
2275          var path = check.pop();
2276          var stat;
2277
2278          try {
2279            stat = FS.stat(path);
2280          } catch (e) {
2281            return callback(e);
2282          }
2283
2284          if (FS.isDir(stat.mode)) {
2285            check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
2286          }
2287
2288          entries[path] = { timestamp: stat.mtime };
2289        }
2290
2291        return callback(null, { type: 'local', entries: entries });
2292      },getRemoteSet:function (mount, callback) {
2293        var entries = {};
2294
2295        IDBFS.getDB(mount.mountpoint, function(err, db) {
2296          if (err) return callback(err);
2297
2298          var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readonly');
2299          transaction.onerror = function() { callback(this.error); };
2300
2301          var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
2302          var index = store.index('timestamp');
2303
2304          index.openKeyCursor().onsuccess = function(event) {
2305            var cursor = event.target.result;
2306
2307            if (!cursor) {
2308              return callback(null, { type: 'remote', db: db, entries: entries });
2309            }
2310
2311            entries[cursor.primaryKey] = { timestamp: cursor.key };
2312
2313            cursor.continue();
2314          };
2315        });
2316      },loadLocalEntry:function (path, callback) {
2317        var stat, node;
2318
2319        try {
2320          var lookup = FS.lookupPath(path);
2321          node = lookup.node;
2322          stat = FS.stat(path);
2323        } catch (e) {
2324          return callback(e);
2325        }
2326
2327        if (FS.isDir(stat.mode)) {
2328          return callback(null, { timestamp: stat.mtime, mode: stat.mode });
2329        } else if (FS.isFile(stat.mode)) {
2330          return callback(null, { timestamp: stat.mtime, mode: stat.mode, contents: node.contents });
2331        } else {
2332          return callback(new Error('node type not supported'));
2333        }
2334      },storeLocalEntry:function (path, entry, callback) {
2335        try {
2336          if (FS.isDir(entry.mode)) {
2337            FS.mkdir(path, entry.mode);
2338          } else if (FS.isFile(entry.mode)) {
2339            FS.writeFile(path, entry.contents, { encoding: 'binary', canOwn: true });
2340          } else {
2341            return callback(new Error('node type not supported'));
2342          }
2343
2344          FS.utime(path, entry.timestamp, entry.timestamp);
2345        } catch (e) {
2346          return callback(e);
2347        }
2348
2349        callback(null);
2350      },removeLocalEntry:function (path, callback) {
2351        try {
2352          var lookup = FS.lookupPath(path);
2353          var stat = FS.stat(path);
2354
2355          if (FS.isDir(stat.mode)) {
2356            FS.rmdir(path);
2357          } else if (FS.isFile(stat.mode)) {
2358            FS.unlink(path);
2359          }
2360        } catch (e) {
2361          return callback(e);
2362        }
2363
2364        callback(null);
2365      },loadRemoteEntry:function (store, path, callback) {
2366        var req = store.get(path);
2367        req.onsuccess = function(event) { callback(null, event.target.result); };
2368        req.onerror = function() { callback(this.error); };
2369      },storeRemoteEntry:function (store, path, entry, callback) {
2370        var req = store.put(entry, path);
2371        req.onsuccess = function() { callback(null); };
2372        req.onerror = function() { callback(this.error); };
2373      },removeRemoteEntry:function (store, path, callback) {
2374        var req = store.delete(path);
2375        req.onsuccess = function() { callback(null); };
2376        req.onerror = function() { callback(this.error); };
2377      },reconcile:function (src, dst, callback) {
2378        var total = 0;
2379
2380        var create = [];
2381        Object.keys(src.entries).forEach(function (key) {
2382          var e = src.entries[key];
2383          var e2 = dst.entries[key];
2384          if (!e2 || e.timestamp > e2.timestamp) {
2385            create.push(key);
2386            total++;
2387          }
2388        });
2389
2390        var remove = [];
2391        Object.keys(dst.entries).forEach(function (key) {
2392          var e = dst.entries[key];
2393          var e2 = src.entries[key];
2394          if (!e2) {
2395            remove.push(key);
2396            total++;
2397          }
2398        });
2399
2400        if (!total) {
2401          return callback(null);
2402        }
2403
2404        var errored = false;
2405        var completed = 0;
2406        var db = src.type === 'remote' ? src.db : dst.db;
2407        var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite');
2408        var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
2409
2410        function done(err) {
2411          if (err) {
2412            if (!done.errored) {
2413              done.errored = true;
2414              return callback(err);
2415            }
2416            return;
2417          }
2418          if (++completed >= total) {
2419            return callback(null);
2420          }
2421        };
2422
2423        transaction.onerror = function() { done(this.error); };
2424
2425        // sort paths in ascending order so directory entries are created
2426        // before the files inside them
2427        create.sort().forEach(function (path) {
2428          if (dst.type === 'local') {
2429            IDBFS.loadRemoteEntry(store, path, function (err, entry) {
2430              if (err) return done(err);
2431              IDBFS.storeLocalEntry(path, entry, done);
2432            });
2433          } else {
2434            IDBFS.loadLocalEntry(path, function (err, entry) {
2435              if (err) return done(err);
2436              IDBFS.storeRemoteEntry(store, path, entry, done);
2437            });
2438          }
2439        });
2440
2441        // sort paths in descending order so files are deleted before their
2442        // parent directories
2443        remove.sort().reverse().forEach(function(path) {
2444          if (dst.type === 'local') {
2445            IDBFS.removeLocalEntry(path, done);
2446          } else {
2447            IDBFS.removeRemoteEntry(store, path, done);
2448          }
2449        });
2450      }};
2451
2452  var NODEFS={isWindows:false,staticInit:function () {
2453        NODEFS.isWindows = !!process.platform.match(/^win/);
2454      },mount:function (mount) {
2455        assert(ENVIRONMENT_IS_NODE);
2456        return NODEFS.createNode(null, '/', NODEFS.getMode(mount.opts.root), 0);
2457      },createNode:function (parent, name, mode, dev) {
2458        if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) {
2459          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
2460        }
2461        var node = FS.createNode(parent, name, mode);
2462        node.node_ops = NODEFS.node_ops;
2463        node.stream_ops = NODEFS.stream_ops;
2464        return node;
2465      },getMode:function (path) {
2466        var stat;
2467        try {
2468          stat = fs.lstatSync(path);
2469          if (NODEFS.isWindows) {
2470            // On Windows, directories return permission bits 'rw-rw-rw-', even though they have 'rwxrwxrwx', so
2471            // propagate write bits to execute bits.
2472            stat.mode = stat.mode | ((stat.mode & 146) >> 1);
2473          }
2474        } catch (e) {
2475          if (!e.code) throw e;
2476          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2477        }
2478        return stat.mode;
2479      },realPath:function (node) {
2480        var parts = [];
2481        while (node.parent !== node) {
2482          parts.push(node.name);
2483          node = node.parent;
2484        }
2485        parts.push(node.mount.opts.root);
2486        parts.reverse();
2487        return PATH.join.apply(null, parts);
2488      },flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:function (flags) {
2489        if (flags in NODEFS.flagsToPermissionStringMap) {
2490          return NODEFS.flagsToPermissionStringMap[flags];
2491        } else {
2492          return flags;
2493        }
2494      },node_ops:{getattr:function (node) {
2495          var path = NODEFS.realPath(node);
2496          var stat;
2497          try {
2498            stat = fs.lstatSync(path);
2499          } catch (e) {
2500            if (!e.code) throw e;
2501            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2502          }
2503          // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake them with default blksize of 4096.
2504          // See http://support.microsoft.com/kb/140365
2505          if (NODEFS.isWindows && !stat.blksize) {
2506            stat.blksize = 4096;
2507          }
2508          if (NODEFS.isWindows && !stat.blocks) {
2509            stat.blocks = (stat.size+stat.blksize-1)/stat.blksize|0;
2510          }
2511          return {
2512            dev: stat.dev,
2513            ino: stat.ino,
2514            mode: stat.mode,
2515            nlink: stat.nlink,
2516            uid: stat.uid,
2517            gid: stat.gid,
2518            rdev: stat.rdev,
2519            size: stat.size,
2520            atime: stat.atime,
2521            mtime: stat.mtime,
2522            ctime: stat.ctime,
2523            blksize: stat.blksize,
2524            blocks: stat.blocks
2525          };
2526        },setattr:function (node, attr) {
2527          var path = NODEFS.realPath(node);
2528          try {
2529            if (attr.mode !== undefined) {
2530              fs.chmodSync(path, attr.mode);
2531              // update the common node structure mode as well
2532              node.mode = attr.mode;
2533            }
2534            if (attr.timestamp !== undefined) {
2535              var date = new Date(attr.timestamp);
2536              fs.utimesSync(path, date, date);
2537            }
2538            if (attr.size !== undefined) {
2539              fs.truncateSync(path, attr.size);
2540            }
2541          } catch (e) {
2542            if (!e.code) throw e;
2543            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2544          }
2545        },lookup:function (parent, name) {
2546          var path = PATH.join2(NODEFS.realPath(parent), name);
2547          var mode = NODEFS.getMode(path);
2548          return NODEFS.createNode(parent, name, mode);
2549        },mknod:function (parent, name, mode, dev) {
2550          var node = NODEFS.createNode(parent, name, mode, dev);
2551          // create the backing node for this in the fs root as well
2552          var path = NODEFS.realPath(node);
2553          try {
2554            if (FS.isDir(node.mode)) {
2555              fs.mkdirSync(path, node.mode);
2556            } else {
2557              fs.writeFileSync(path, '', { mode: node.mode });
2558            }
2559          } catch (e) {
2560            if (!e.code) throw e;
2561            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2562          }
2563          return node;
2564        },rename:function (oldNode, newDir, newName) {
2565          var oldPath = NODEFS.realPath(oldNode);
2566          var newPath = PATH.join2(NODEFS.realPath(newDir), newName);
2567          try {
2568            fs.renameSync(oldPath, newPath);
2569          } catch (e) {
2570            if (!e.code) throw e;
2571            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2572          }
2573        },unlink:function (parent, name) {
2574          var path = PATH.join2(NODEFS.realPath(parent), name);
2575          try {
2576            fs.unlinkSync(path);
2577          } catch (e) {
2578            if (!e.code) throw e;
2579            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2580          }
2581        },rmdir:function (parent, name) {
2582          var path = PATH.join2(NODEFS.realPath(parent), name);
2583          try {
2584            fs.rmdirSync(path);
2585          } catch (e) {
2586            if (!e.code) throw e;
2587            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2588          }
2589        },readdir:function (node) {
2590          var path = NODEFS.realPath(node);
2591          try {
2592            return fs.readdirSync(path);
2593          } catch (e) {
2594            if (!e.code) throw e;
2595            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2596          }
2597        },symlink:function (parent, newName, oldPath) {
2598          var newPath = PATH.join2(NODEFS.realPath(parent), newName);
2599          try {
2600            fs.symlinkSync(oldPath, newPath);
2601          } catch (e) {
2602            if (!e.code) throw e;
2603            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2604          }
2605        },readlink:function (node) {
2606          var path = NODEFS.realPath(node);
2607          try {
2608            return fs.readlinkSync(path);
2609          } catch (e) {
2610            if (!e.code) throw e;
2611            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2612          }
2613        }},stream_ops:{open:function (stream) {
2614          var path = NODEFS.realPath(stream.node);
2615          try {
2616            if (FS.isFile(stream.node.mode)) {
2617              stream.nfd = fs.openSync(path, NODEFS.flagsToPermissionString(stream.flags));
2618            }
2619          } catch (e) {
2620            if (!e.code) throw e;
2621            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2622          }
2623        },close:function (stream) {
2624          try {
2625            if (FS.isFile(stream.node.mode) && stream.nfd) {
2626              fs.closeSync(stream.nfd);
2627            }
2628          } catch (e) {
2629            if (!e.code) throw e;
2630            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2631          }
2632        },read:function (stream, buffer, offset, length, position) {
2633          // FIXME this is terrible.
2634          var nbuffer = new Buffer(length);
2635          var res;
2636          try {
2637            res = fs.readSync(stream.nfd, nbuffer, 0, length, position);
2638          } catch (e) {
2639            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2640          }
2641          if (res > 0) {
2642            for (var i = 0; i < res; i++) {
2643              buffer[offset + i] = nbuffer[i];
2644            }
2645          }
2646          return res;
2647        },write:function (stream, buffer, offset, length, position) {
2648          // FIXME this is terrible.
2649          var nbuffer = new Buffer(buffer.subarray(offset, offset + length));
2650          var res;
2651          try {
2652            res = fs.writeSync(stream.nfd, nbuffer, 0, length, position);
2653          } catch (e) {
2654            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2655          }
2656          return res;
2657        },llseek:function (stream, offset, whence) {
2658          var position = offset;
2659          if (whence === 1) {  // SEEK_CUR.
2660            position += stream.position;
2661          } else if (whence === 2) {  // SEEK_END.
2662            if (FS.isFile(stream.node.mode)) {
2663              try {
2664                var stat = fs.fstatSync(stream.nfd);
2665                position += stat.size;
2666              } catch (e) {
2667                throw new FS.ErrnoError(ERRNO_CODES[e.code]);
2668              }
2669            }
2670          }
2671
2672          if (position < 0) {
2673            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
2674          }
2675
2676          stream.position = position;
2677          return position;
2678        }}};
2679
2680  var _stdin=allocate(1, "i32*", ALLOC_STATIC);
2681
2682  var _stdout=allocate(1, "i32*", ALLOC_STATIC);
2683
2684  var _stderr=allocate(1, "i32*", ALLOC_STATIC);
2685
2686  function _fflush(stream) {
2687      // int fflush(FILE *stream);
2688      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fflush.html
2689      // we don't currently perform any user-space buffering of data
2690    }var FS={root:null,mounts:[],devices:[null],streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},handleFSError:function (e) {
2691        if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace();
2692        return ___setErrNo(e.errno);
2693      },lookupPath:function (path, opts) {
2694        path = PATH.resolve(FS.cwd(), path);
2695        opts = opts || {};
2696
2697        var defaults = {
2698          follow_mount: true,
2699          recurse_count: 0
2700        };
2701        for (var key in defaults) {
2702          if (opts[key] === undefined) {
2703            opts[key] = defaults[key];
2704          }
2705        }
2706
2707        if (opts.recurse_count > 8) {  // max recursive lookup of 8
2708          throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
2709        }
2710
2711        // split the path
2712        var parts = PATH.normalizeArray(path.split('/').filter(function(p) {
2713          return !!p;
2714        }), false);
2715
2716        // start at the root
2717        var current = FS.root;
2718        var current_path = '/';
2719
2720        for (var i = 0; i < parts.length; i++) {
2721          var islast = (i === parts.length-1);
2722          if (islast && opts.parent) {
2723            // stop resolving
2724            break;
2725          }
2726
2727          current = FS.lookupNode(current, parts[i]);
2728          current_path = PATH.join2(current_path, parts[i]);
2729
2730          // jump to the mount's root node if this is a mountpoint
2731          if (FS.isMountpoint(current)) {
2732            if (!islast || (islast && opts.follow_mount)) {
2733              current = current.mounted.root;
2734            }
2735          }
2736
2737          // by default, lookupPath will not follow a symlink if it is the final path component.
2738          // setting opts.follow = true will override this behavior.
2739          if (!islast || opts.follow) {
2740            var count = 0;
2741            while (FS.isLink(current.mode)) {
2742              var link = FS.readlink(current_path);
2743              current_path = PATH.resolve(PATH.dirname(current_path), link);
2744
2745              var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });
2746              current = lookup.node;
2747
2748              if (count++ > 40) {  // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
2749                throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
2750              }
2751            }
2752          }
2753        }
2754
2755        return { path: current_path, node: current };
2756      },getPath:function (node) {
2757        var path;
2758        while (true) {
2759          if (FS.isRoot(node)) {
2760            var mount = node.mount.mountpoint;
2761            if (!path) return mount;
2762            return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
2763          }
2764          path = path ? node.name + '/' + path : node.name;
2765          node = node.parent;
2766        }
2767      },hashName:function (parentid, name) {
2768        var hash = 0;
2769
2770
2771        for (var i = 0; i < name.length; i++) {
2772          hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
2773        }
2774        return ((parentid + hash) >>> 0) % FS.nameTable.length;
2775      },hashAddNode:function (node) {
2776        var hash = FS.hashName(node.parent.id, node.name);
2777        node.name_next = FS.nameTable[hash];
2778        FS.nameTable[hash] = node;
2779      },hashRemoveNode:function (node) {
2780        var hash = FS.hashName(node.parent.id, node.name);
2781        if (FS.nameTable[hash] === node) {
2782          FS.nameTable[hash] = node.name_next;
2783        } else {
2784          var current = FS.nameTable[hash];
2785          while (current) {
2786            if (current.name_next === node) {
2787              current.name_next = node.name_next;
2788              break;
2789            }
2790            current = current.name_next;
2791          }
2792        }
2793      },lookupNode:function (parent, name) {
2794        var err = FS.mayLookup(parent);
2795        if (err) {
2796          throw new FS.ErrnoError(err);
2797        }
2798        var hash = FS.hashName(parent.id, name);
2799        for (var node = FS.nameTable[hash]; node; node = node.name_next) {
2800          var nodeName = node.name;
2801          if (node.parent.id === parent.id && nodeName === name) {
2802            return node;
2803          }
2804        }
2805        // if we failed to find it in the cache, call into the VFS
2806        return FS.lookup(parent, name);
2807      },createNode:function (parent, name, mode, rdev) {
2808        if (!FS.FSNode) {
2809          FS.FSNode = function(parent, name, mode, rdev) {
2810            if (!parent) {
2811              parent = this;  // root node sets parent to itself
2812            }
2813            this.parent = parent;
2814            this.mount = parent.mount;
2815            this.mounted = null;
2816            this.id = FS.nextInode++;
2817            this.name = name;
2818            this.mode = mode;
2819            this.node_ops = {};
2820            this.stream_ops = {};
2821            this.rdev = rdev;
2822          };
2823
2824          FS.FSNode.prototype = {};
2825
2826          // compatibility
2827          var readMode = 292 | 73;
2828          var writeMode = 146;
2829
2830          // NOTE we must use Object.defineProperties instead of individual calls to
2831          // Object.defineProperty in order to make closure compiler happy
2832          Object.defineProperties(FS.FSNode.prototype, {
2833            read: {
2834              get: function() { return (this.mode & readMode) === readMode; },
2835              set: function(val) { val ? this.mode |= readMode : this.mode &= ~readMode; }
2836            },
2837            write: {
2838              get: function() { return (this.mode & writeMode) === writeMode; },
2839              set: function(val) { val ? this.mode |= writeMode : this.mode &= ~writeMode; }
2840            },
2841            isFolder: {
2842              get: function() { return FS.isDir(this.mode); },
2843            },
2844            isDevice: {
2845              get: function() { return FS.isChrdev(this.mode); },
2846            },
2847          });
2848        }
2849
2850        var node = new FS.FSNode(parent, name, mode, rdev);
2851
2852        FS.hashAddNode(node);
2853
2854        return node;
2855      },destroyNode:function (node) {
2856        FS.hashRemoveNode(node);
2857      },isRoot:function (node) {
2858        return node === node.parent;
2859      },isMountpoint:function (node) {
2860        return !!node.mounted;
2861      },isFile:function (mode) {
2862        return (mode & 61440) === 32768;
2863      },isDir:function (mode) {
2864        return (mode & 61440) === 16384;
2865      },isLink:function (mode) {
2866        return (mode & 61440) === 40960;
2867      },isChrdev:function (mode) {
2868        return (mode & 61440) === 8192;
2869      },isBlkdev:function (mode) {
2870        return (mode & 61440) === 24576;
2871      },isFIFO:function (mode) {
2872        return (mode & 61440) === 4096;
2873      },isSocket:function (mode) {
2874        return (mode & 49152) === 49152;
2875      },flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function (str) {
2876        var flags = FS.flagModes[str];
2877        if (typeof flags === 'undefined') {
2878          throw new Error('Unknown file open mode: ' + str);
2879        }
2880        return flags;
2881      },flagsToPermissionString:function (flag) {
2882        var accmode = flag & 2097155;
2883        var perms = ['r', 'w', 'rw'][accmode];
2884        if ((flag & 512)) {
2885          perms += 'w';
2886        }
2887        return perms;
2888      },nodePermissions:function (node, perms) {
2889        if (FS.ignorePermissions) {
2890          return 0;
2891        }
2892        // return 0 if any user, group or owner bits are set.
2893        if (perms.indexOf('r') !== -1 && !(node.mode & 292)) {
2894          return ERRNO_CODES.EACCES;
2895        } else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) {
2896          return ERRNO_CODES.EACCES;
2897        } else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) {
2898          return ERRNO_CODES.EACCES;
2899        }
2900        return 0;
2901      },mayLookup:function (dir) {
2902        return FS.nodePermissions(dir, 'x');
2903      },mayCreate:function (dir, name) {
2904        try {
2905          var node = FS.lookupNode(dir, name);
2906          return ERRNO_CODES.EEXIST;
2907        } catch (e) {
2908        }
2909        return FS.nodePermissions(dir, 'wx');
2910      },mayDelete:function (dir, name, isdir) {
2911        var node;
2912        try {
2913          node = FS.lookupNode(dir, name);
2914        } catch (e) {
2915          return e.errno;
2916        }
2917        var err = FS.nodePermissions(dir, 'wx');
2918        if (err) {
2919          return err;
2920        }
2921        if (isdir) {
2922          if (!FS.isDir(node.mode)) {
2923            return ERRNO_CODES.ENOTDIR;
2924          }
2925          if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
2926            return ERRNO_CODES.EBUSY;
2927          }
2928        } else {
2929          if (FS.isDir(node.mode)) {
2930            return ERRNO_CODES.EISDIR;
2931          }
2932        }
2933        return 0;
2934      },mayOpen:function (node, flags) {
2935        if (!node) {
2936          return ERRNO_CODES.ENOENT;
2937        }
2938        if (FS.isLink(node.mode)) {
2939          return ERRNO_CODES.ELOOP;
2940        } else if (FS.isDir(node.mode)) {
2941          if ((flags & 2097155) !== 0 ||  // opening for write
2942              (flags & 512)) {
2943            return ERRNO_CODES.EISDIR;
2944          }
2945        }
2946        return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
2947      },MAX_OPEN_FDS:4096,nextfd:function (fd_start, fd_end) {
2948        fd_start = fd_start || 0;
2949        fd_end = fd_end || FS.MAX_OPEN_FDS;
2950        for (var fd = fd_start; fd <= fd_end; fd++) {
2951          if (!FS.streams[fd]) {
2952            return fd;
2953          }
2954        }
2955        throw new FS.ErrnoError(ERRNO_CODES.EMFILE);
2956      },getStream:function (fd) {
2957        return FS.streams[fd];
2958      },createStream:function (stream, fd_start, fd_end) {
2959        if (!FS.FSStream) {
2960          FS.FSStream = function(){};
2961          FS.FSStream.prototype = {};
2962          // compatibility
2963          Object.defineProperties(FS.FSStream.prototype, {
2964            object: {
2965              get: function() { return this.node; },
2966              set: function(val) { this.node = val; }
2967            },
2968            isRead: {
2969              get: function() { return (this.flags & 2097155) !== 1; }
2970            },
2971            isWrite: {
2972              get: function() { return (this.flags & 2097155) !== 0; }
2973            },
2974            isAppend: {
2975              get: function() { return (this.flags & 1024); }
2976            }
2977          });
2978        }
2979        if (0) {
2980          // reuse the object
2981          stream.__proto__ = FS.FSStream.prototype;
2982        } else {
2983          var newStream = new FS.FSStream();
2984          for (var p in stream) {
2985            newStream[p] = stream[p];
2986          }
2987          stream = newStream;
2988        }
2989        var fd = FS.nextfd(fd_start, fd_end);
2990        stream.fd = fd;
2991        FS.streams[fd] = stream;
2992        return stream;
2993      },closeStream:function (fd) {
2994        FS.streams[fd] = null;
2995      },getStreamFromPtr:function (ptr) {
2996        return FS.streams[ptr - 1];
2997      },getPtrForStream:function (stream) {
2998        return stream ? stream.fd + 1 : 0;
2999      },chrdev_stream_ops:{open:function (stream) {
3000          var device = FS.getDevice(stream.node.rdev);
3001          // override node's stream ops with the device's
3002          stream.stream_ops = device.stream_ops;
3003          // forward the open call
3004          if (stream.stream_ops.open) {
3005            stream.stream_ops.open(stream);
3006          }
3007        },llseek:function () {
3008          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
3009        }},major:function (dev) {
3010        return ((dev) >> 8);
3011      },minor:function (dev) {
3012        return ((dev) & 0xff);
3013      },makedev:function (ma, mi) {
3014        return ((ma) << 8 | (mi));
3015      },registerDevice:function (dev, ops) {
3016        FS.devices[dev] = { stream_ops: ops };
3017      },getDevice:function (dev) {
3018        return FS.devices[dev];
3019      },getMounts:function (mount) {
3020        var mounts = [];
3021        var check = [mount];
3022
3023        while (check.length) {
3024          var m = check.pop();
3025
3026          mounts.push(m);
3027
3028          check.push.apply(check, m.mounts);
3029        }
3030
3031        return mounts;
3032      },syncfs:function (populate, callback) {
3033        if (typeof(populate) === 'function') {
3034          callback = populate;
3035          populate = false;
3036        }
3037
3038        var mounts = FS.getMounts(FS.root.mount);
3039        var completed = 0;
3040
3041        function done(err) {
3042          if (err) {
3043            if (!done.errored) {
3044              done.errored = true;
3045              return callback(err);
3046            }
3047            return;
3048          }
3049          if (++completed >= mounts.length) {
3050            callback(null);
3051          }
3052        };
3053
3054        // sync all mounts
3055        mounts.forEach(function (mount) {
3056          if (!mount.type.syncfs) {
3057            return done(null);
3058          }
3059          mount.type.syncfs(mount, populate, done);
3060        });
3061      },mount:function (type, opts, mountpoint) {
3062        var root = mountpoint === '/';
3063        var pseudo = !mountpoint;
3064        var node;
3065
3066        if (root && FS.root) {
3067          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
3068        } else if (!root && !pseudo) {
3069          var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
3070
3071          mountpoint = lookup.path;  // use the absolute path
3072          node = lookup.node;
3073
3074          if (FS.isMountpoint(node)) {
3075            throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
3076          }
3077
3078          if (!FS.isDir(node.mode)) {
3079            throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
3080          }
3081        }
3082
3083        var mount = {
3084          type: type,
3085          opts: opts,
3086          mountpoint: mountpoint,
3087          mounts: []
3088        };
3089
3090        // create a root node for the fs
3091        var mountRoot = type.mount(mount);
3092        mountRoot.mount = mount;
3093        mount.root = mountRoot;
3094
3095        if (root) {
3096          FS.root = mountRoot;
3097        } else if (node) {
3098          // set as a mountpoint
3099          node.mounted = mount;
3100
3101          // add the new mount to the current mount's children
3102          if (node.mount) {
3103            node.mount.mounts.push(mount);
3104          }
3105        }
3106
3107        return mountRoot;
3108      },unmount:function (mountpoint) {
3109        var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
3110
3111        if (!FS.isMountpoint(lookup.node)) {
3112          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3113        }
3114
3115        // destroy the nodes for this mount, and all its child mounts
3116        var node = lookup.node;
3117        var mount = node.mounted;
3118        var mounts = FS.getMounts(mount);
3119
3120        Object.keys(FS.nameTable).forEach(function (hash) {
3121          var current = FS.nameTable[hash];
3122
3123          while (current) {
3124            var next = current.name_next;
3125
3126            if (mounts.indexOf(current.mount) !== -1) {
3127              FS.destroyNode(current);
3128            }
3129
3130            current = next;
3131          }
3132        });
3133
3134        // no longer a mountpoint
3135        node.mounted = null;
3136
3137        // remove this mount from the child mounts
3138        var idx = node.mount.mounts.indexOf(mount);
3139        assert(idx !== -1);
3140        node.mount.mounts.splice(idx, 1);
3141      },lookup:function (parent, name) {
3142        return parent.node_ops.lookup(parent, name);
3143      },mknod:function (path, mode, dev) {
3144        var lookup = FS.lookupPath(path, { parent: true });
3145        var parent = lookup.node;
3146        var name = PATH.basename(path);
3147        var err = FS.mayCreate(parent, name);
3148        if (err) {
3149          throw new FS.ErrnoError(err);
3150        }
3151        if (!parent.node_ops.mknod) {
3152          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3153        }
3154        return parent.node_ops.mknod(parent, name, mode, dev);
3155      },create:function (path, mode) {
3156        mode = mode !== undefined ? mode : 438 /* 0666 */;
3157        mode &= 4095;
3158        mode |= 32768;
3159        return FS.mknod(path, mode, 0);
3160      },mkdir:function (path, mode) {
3161        mode = mode !== undefined ? mode : 511 /* 0777 */;
3162        mode &= 511 | 512;
3163        mode |= 16384;
3164        return FS.mknod(path, mode, 0);
3165      },mkdev:function (path, mode, dev) {
3166        if (typeof(dev) === 'undefined') {
3167          dev = mode;
3168          mode = 438 /* 0666 */;
3169        }
3170        mode |= 8192;
3171        return FS.mknod(path, mode, dev);
3172      },symlink:function (oldpath, newpath) {
3173        var lookup = FS.lookupPath(newpath, { parent: true });
3174        var parent = lookup.node;
3175        var newname = PATH.basename(newpath);
3176        var err = FS.mayCreate(parent, newname);
3177        if (err) {
3178          throw new FS.ErrnoError(err);
3179        }
3180        if (!parent.node_ops.symlink) {
3181          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3182        }
3183        return parent.node_ops.symlink(parent, newname, oldpath);
3184      },rename:function (old_path, new_path) {
3185        var old_dirname = PATH.dirname(old_path);
3186        var new_dirname = PATH.dirname(new_path);
3187        var old_name = PATH.basename(old_path);
3188        var new_name = PATH.basename(new_path);
3189        // parents must exist
3190        var lookup, old_dir, new_dir;
3191        try {
3192          lookup = FS.lookupPath(old_path, { parent: true });
3193          old_dir = lookup.node;
3194          lookup = FS.lookupPath(new_path, { parent: true });
3195          new_dir = lookup.node;
3196        } catch (e) {
3197          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
3198        }
3199        // need to be part of the same mount
3200        if (old_dir.mount !== new_dir.mount) {
3201          throw new FS.ErrnoError(ERRNO_CODES.EXDEV);
3202        }
3203        // source must exist
3204        var old_node = FS.lookupNode(old_dir, old_name);
3205        // old path should not be an ancestor of the new path
3206        var relative = PATH.relative(old_path, new_dirname);
3207        if (relative.charAt(0) !== '.') {
3208          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3209        }
3210        // new path should not be an ancestor of the old path
3211        relative = PATH.relative(new_path, old_dirname);
3212        if (relative.charAt(0) !== '.') {
3213          throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
3214        }
3215        // see if the new path already exists
3216        var new_node;
3217        try {
3218          new_node = FS.lookupNode(new_dir, new_name);
3219        } catch (e) {
3220          // not fatal
3221        }
3222        // early out if nothing needs to change
3223        if (old_node === new_node) {
3224          return;
3225        }
3226        // we'll need to delete the old entry
3227        var isdir = FS.isDir(old_node.mode);
3228        var err = FS.mayDelete(old_dir, old_name, isdir);
3229        if (err) {
3230          throw new FS.ErrnoError(err);
3231        }
3232        // need delete permissions if we'll be overwriting.
3233        // need create permissions if new doesn't already exist.
3234        err = new_node ?
3235          FS.mayDelete(new_dir, new_name, isdir) :
3236          FS.mayCreate(new_dir, new_name);
3237        if (err) {
3238          throw new FS.ErrnoError(err);
3239        }
3240        if (!old_dir.node_ops.rename) {
3241          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3242        }
3243        if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
3244          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
3245        }
3246        // if we are going to change the parent, check write permissions
3247        if (new_dir !== old_dir) {
3248          err = FS.nodePermissions(old_dir, 'w');
3249          if (err) {
3250            throw new FS.ErrnoError(err);
3251          }
3252        }
3253        // remove the node from the lookup hash
3254        FS.hashRemoveNode(old_node);
3255        // do the underlying fs rename
3256        try {
3257          old_dir.node_ops.rename(old_node, new_dir, new_name);
3258        } catch (e) {
3259          throw e;
3260        } finally {
3261          // add the node back to the hash (in case node_ops.rename
3262          // changed its name)
3263          FS.hashAddNode(old_node);
3264        }
3265      },rmdir:function (path) {
3266        var lookup = FS.lookupPath(path, { parent: true });
3267        var parent = lookup.node;
3268        var name = PATH.basename(path);
3269        var node = FS.lookupNode(parent, name);
3270        var err = FS.mayDelete(parent, name, true);
3271        if (err) {
3272          throw new FS.ErrnoError(err);
3273        }
3274        if (!parent.node_ops.rmdir) {
3275          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3276        }
3277        if (FS.isMountpoint(node)) {
3278          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
3279        }
3280        parent.node_ops.rmdir(parent, name);
3281        FS.destroyNode(node);
3282      },readdir:function (path) {
3283        var lookup = FS.lookupPath(path, { follow: true });
3284        var node = lookup.node;
3285        if (!node.node_ops.readdir) {
3286          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
3287        }
3288        return node.node_ops.readdir(node);
3289      },unlink:function (path) {
3290        var lookup = FS.lookupPath(path, { parent: true });
3291        var parent = lookup.node;
3292        var name = PATH.basename(path);
3293        var node = FS.lookupNode(parent, name);
3294        var err = FS.mayDelete(parent, name, false);
3295        if (err) {
3296          // POSIX says unlink should set EPERM, not EISDIR
3297          if (err === ERRNO_CODES.EISDIR) err = ERRNO_CODES.EPERM;
3298          throw new FS.ErrnoError(err);
3299        }
3300        if (!parent.node_ops.unlink) {
3301          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3302        }
3303        if (FS.isMountpoint(node)) {
3304          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
3305        }
3306        parent.node_ops.unlink(parent, name);
3307        FS.destroyNode(node);
3308      },readlink:function (path) {
3309        var lookup = FS.lookupPath(path);
3310        var link = lookup.node;
3311        if (!link.node_ops.readlink) {
3312          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3313        }
3314        return link.node_ops.readlink(link);
3315      },stat:function (path, dontFollow) {
3316        var lookup = FS.lookupPath(path, { follow: !dontFollow });
3317        var node = lookup.node;
3318        if (!node.node_ops.getattr) {
3319          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3320        }
3321        return node.node_ops.getattr(node);
3322      },lstat:function (path) {
3323        return FS.stat(path, true);
3324      },chmod:function (path, mode, dontFollow) {
3325        var node;
3326        if (typeof path === 'string') {
3327          var lookup = FS.lookupPath(path, { follow: !dontFollow });
3328          node = lookup.node;
3329        } else {
3330          node = path;
3331        }
3332        if (!node.node_ops.setattr) {
3333          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3334        }
3335        node.node_ops.setattr(node, {
3336          mode: (mode & 4095) | (node.mode & ~4095),
3337          timestamp: Date.now()
3338        });
3339      },lchmod:function (path, mode) {
3340        FS.chmod(path, mode, true);
3341      },fchmod:function (fd, mode) {
3342        var stream = FS.getStream(fd);
3343        if (!stream) {
3344          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3345        }
3346        FS.chmod(stream.node, mode);
3347      },chown:function (path, uid, gid, dontFollow) {
3348        var node;
3349        if (typeof path === 'string') {
3350          var lookup = FS.lookupPath(path, { follow: !dontFollow });
3351          node = lookup.node;
3352        } else {
3353          node = path;
3354        }
3355        if (!node.node_ops.setattr) {
3356          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3357        }
3358        node.node_ops.setattr(node, {
3359          timestamp: Date.now()
3360          // we ignore the uid / gid for now
3361        });
3362      },lchown:function (path, uid, gid) {
3363        FS.chown(path, uid, gid, true);
3364      },fchown:function (fd, uid, gid) {
3365        var stream = FS.getStream(fd);
3366        if (!stream) {
3367          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3368        }
3369        FS.chown(stream.node, uid, gid);
3370      },truncate:function (path, len) {
3371        if (len < 0) {
3372          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3373        }
3374        var node;
3375        if (typeof path === 'string') {
3376          var lookup = FS.lookupPath(path, { follow: true });
3377          node = lookup.node;
3378        } else {
3379          node = path;
3380        }
3381        if (!node.node_ops.setattr) {
3382          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
3383        }
3384        if (FS.isDir(node.mode)) {
3385          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
3386        }
3387        if (!FS.isFile(node.mode)) {
3388          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3389        }
3390        var err = FS.nodePermissions(node, 'w');
3391        if (err) {
3392          throw new FS.ErrnoError(err);
3393        }
3394        node.node_ops.setattr(node, {
3395          size: len,
3396          timestamp: Date.now()
3397        });
3398      },ftruncate:function (fd, len) {
3399        var stream = FS.getStream(fd);
3400        if (!stream) {
3401          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3402        }
3403        if ((stream.flags & 2097155) === 0) {
3404          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3405        }
3406        FS.truncate(stream.node, len);
3407      },utime:function (path, atime, mtime) {
3408        var lookup = FS.lookupPath(path, { follow: true });
3409        var node = lookup.node;
3410        node.node_ops.setattr(node, {
3411          timestamp: Math.max(atime, mtime)
3412        });
3413      },open:function (path, flags, mode, fd_start, fd_end) {
3414        flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
3415        mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode;
3416        if ((flags & 64)) {
3417          mode = (mode & 4095) | 32768;
3418        } else {
3419          mode = 0;
3420        }
3421        var node;
3422        if (typeof path === 'object') {
3423          node = path;
3424        } else {
3425          path = PATH.normalize(path);
3426          try {
3427            var lookup = FS.lookupPath(path, {
3428              follow: !(flags & 131072)
3429            });
3430            node = lookup.node;
3431          } catch (e) {
3432            // ignore
3433          }
3434        }
3435        // perhaps we need to create the node
3436        if ((flags & 64)) {
3437          if (node) {
3438            // if O_CREAT and O_EXCL are set, error out if the node already exists
3439            if ((flags & 128)) {
3440              throw new FS.ErrnoError(ERRNO_CODES.EEXIST);
3441            }
3442          } else {
3443            // node doesn't exist, try to create it
3444            node = FS.mknod(path, mode, 0);
3445          }
3446        }
3447        if (!node) {
3448          throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
3449        }
3450        // can't truncate a device
3451        if (FS.isChrdev(node.mode)) {
3452          flags &= ~512;
3453        }
3454        // check permissions
3455        var err = FS.mayOpen(node, flags);
3456        if (err) {
3457          throw new FS.ErrnoError(err);
3458        }
3459        // do truncation if necessary
3460        if ((flags & 512)) {
3461          FS.truncate(node, 0);
3462        }
3463        // we've already handled these, don't pass down to the underlying vfs
3464        flags &= ~(128 | 512);
3465
3466        // register the stream with the filesystem
3467        var stream = FS.createStream({
3468          node: node,
3469          path: FS.getPath(node),  // we want the absolute path to the node
3470          flags: flags,
3471          seekable: true,
3472          position: 0,
3473          stream_ops: node.stream_ops,
3474          // used by the file family libc calls (fopen, fwrite, ferror, etc.)
3475          ungotten: [],
3476          error: false
3477        }, fd_start, fd_end);
3478        // call the new stream's open function
3479        if (stream.stream_ops.open) {
3480          stream.stream_ops.open(stream);
3481        }
3482        if (Module['logReadFiles'] && !(flags & 1)) {
3483          if (!FS.readFiles) FS.readFiles = {};
3484          if (!(path in FS.readFiles)) {
3485            FS.readFiles[path] = 1;
3486            Module['printErr']('read file: ' + path);
3487          }
3488        }
3489        return stream;
3490      },close:function (stream) {
3491        try {
3492          if (stream.stream_ops.close) {
3493            stream.stream_ops.close(stream);
3494          }
3495        } catch (e) {
3496          throw e;
3497        } finally {
3498          FS.closeStream(stream.fd);
3499        }
3500      },llseek:function (stream, offset, whence) {
3501        if (!stream.seekable || !stream.stream_ops.llseek) {
3502          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
3503        }
3504        return stream.stream_ops.llseek(stream, offset, whence);
3505      },read:function (stream, buffer, offset, length, position) {
3506        if (length < 0 || position < 0) {
3507          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3508        }
3509        if ((stream.flags & 2097155) === 1) {
3510          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3511        }
3512        if (FS.isDir(stream.node.mode)) {
3513          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
3514        }
3515        if (!stream.stream_ops.read) {
3516          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3517        }
3518        var seeking = true;
3519        if (typeof position === 'undefined') {
3520          position = stream.position;
3521          seeking = false;
3522        } else if (!stream.seekable) {
3523          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
3524        }
3525        var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
3526        if (!seeking) stream.position += bytesRead;
3527        return bytesRead;
3528      },write:function (stream, buffer, offset, length, position, canOwn) {
3529        if (length < 0 || position < 0) {
3530          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3531        }
3532        if ((stream.flags & 2097155) === 0) {
3533          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3534        }
3535        if (FS.isDir(stream.node.mode)) {
3536          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
3537        }
3538        if (!stream.stream_ops.write) {
3539          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3540        }
3541        var seeking = true;
3542        if (typeof position === 'undefined') {
3543          position = stream.position;
3544          seeking = false;
3545        } else if (!stream.seekable) {
3546          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
3547        }
3548        if (stream.flags & 1024) {
3549          // seek to the end before writing in append mode
3550          FS.llseek(stream, 0, 2);
3551        }
3552        var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
3553        if (!seeking) stream.position += bytesWritten;
3554        return bytesWritten;
3555      },allocate:function (stream, offset, length) {
3556        if (offset < 0 || length <= 0) {
3557          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
3558        }
3559        if ((stream.flags & 2097155) === 0) {
3560          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
3561        }
3562        if (!FS.isFile(stream.node.mode) && !FS.isDir(node.mode)) {
3563          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
3564        }
3565        if (!stream.stream_ops.allocate) {
3566          throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
3567        }
3568        stream.stream_ops.allocate(stream, offset, length);
3569      },mmap:function (stream, buffer, offset, length, position, prot, flags) {
3570        // TODO if PROT is PROT_WRITE, make sure we have write access
3571        if ((stream.flags & 2097155) === 1) {
3572          throw new FS.ErrnoError(ERRNO_CODES.EACCES);
3573        }
3574        if (!stream.stream_ops.mmap) {
3575          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
3576        }
3577        return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags);
3578      },ioctl:function (stream, cmd, arg) {
3579        if (!stream.stream_ops.ioctl) {
3580          throw new FS.ErrnoError(ERRNO_CODES.ENOTTY);
3581        }
3582        return stream.stream_ops.ioctl(stream, cmd, arg);
3583      },readFile:function (path, opts) {
3584        opts = opts || {};
3585        opts.flags = opts.flags || 'r';
3586        opts.encoding = opts.encoding || 'binary';
3587        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
3588          throw new Error('Invalid encoding type "' + opts.encoding + '"');
3589        }
3590        var ret;
3591        var stream = FS.open(path, opts.flags);
3592        var stat = FS.stat(path);
3593        var length = stat.size;
3594        var buf = new Uint8Array(length);
3595        FS.read(stream, buf, 0, length, 0);
3596        if (opts.encoding === 'utf8') {
3597          ret = '';
3598          var utf8 = new Runtime.UTF8Processor();
3599          for (var i = 0; i < length; i++) {
3600            ret += utf8.processCChar(buf[i]);
3601          }
3602        } else if (opts.encoding === 'binary') {
3603          ret = buf;
3604        }
3605        FS.close(stream);
3606        return ret;
3607      },writeFile:function (path, data, opts) {
3608        opts = opts || {};
3609        opts.flags = opts.flags || 'w';
3610        opts.encoding = opts.encoding || 'utf8';
3611        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
3612          throw new Error('Invalid encoding type "' + opts.encoding + '"');
3613        }
3614        var stream = FS.open(path, opts.flags, opts.mode);
3615        if (opts.encoding === 'utf8') {
3616          var utf8 = new Runtime.UTF8Processor();
3617          var buf = new Uint8Array(utf8.processJSString(data));
3618          FS.write(stream, buf, 0, buf.length, 0, opts.canOwn);
3619        } else if (opts.encoding === 'binary') {
3620          FS.write(stream, data, 0, data.length, 0, opts.canOwn);
3621        }
3622        FS.close(stream);
3623      },cwd:function () {
3624        return FS.currentPath;
3625      },chdir:function (path) {
3626        var lookup = FS.lookupPath(path, { follow: true });
3627        if (!FS.isDir(lookup.node.mode)) {
3628          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
3629        }
3630        var err = FS.nodePermissions(lookup.node, 'x');
3631        if (err) {
3632          throw new FS.ErrnoError(err);
3633        }
3634        FS.currentPath = lookup.path;
3635      },createDefaultDirectories:function () {
3636        FS.mkdir('/tmp');
3637      },createDefaultDevices:function () {
3638        // create /dev
3639        FS.mkdir('/dev');
3640        // setup /dev/null
3641        FS.registerDevice(FS.makedev(1, 3), {
3642          read: function() { return 0; },
3643          write: function() { return 0; }
3644        });
3645        FS.mkdev('/dev/null', FS.makedev(1, 3));
3646        // setup /dev/tty and /dev/tty1
3647        // stderr needs to print output using Module['printErr']
3648        // so we register a second tty just for it.
3649        TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
3650        TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
3651        FS.mkdev('/dev/tty', FS.makedev(5, 0));
3652        FS.mkdev('/dev/tty1', FS.makedev(6, 0));
3653        // we're not going to emulate the actual shm device,
3654        // just create the tmp dirs that reside in it commonly
3655        FS.mkdir('/dev/shm');
3656        FS.mkdir('/dev/shm/tmp');
3657      },createStandardStreams:function () {
3658        // TODO deprecate the old functionality of a single
3659        // input / output callback and that utilizes FS.createDevice
3660        // and instead require a unique set of stream ops
3661
3662        // by default, we symlink the standard streams to the
3663        // default tty devices. however, if the standard streams
3664        // have been overwritten we create a unique device for
3665        // them instead.
3666        if (Module['stdin']) {
3667          FS.createDevice('/dev', 'stdin', Module['stdin']);
3668        } else {
3669          FS.symlink('/dev/tty', '/dev/stdin');
3670        }
3671        if (Module['stdout']) {
3672          FS.createDevice('/dev', 'stdout', null, Module['stdout']);
3673        } else {
3674          FS.symlink('/dev/tty', '/dev/stdout');
3675        }
3676        if (Module['stderr']) {
3677          FS.createDevice('/dev', 'stderr', null, Module['stderr']);
3678        } else {
3679          FS.symlink('/dev/tty1', '/dev/stderr');
3680        }
3681
3682        // open default streams for the stdin, stdout and stderr devices
3683        var stdin = FS.open('/dev/stdin', 'r');
3684        HEAP32[((_stdin)>>2)]=FS.getPtrForStream(stdin);
3685        assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
3686
3687        var stdout = FS.open('/dev/stdout', 'w');
3688        HEAP32[((_stdout)>>2)]=FS.getPtrForStream(stdout);
3689        assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
3690
3691        var stderr = FS.open('/dev/stderr', 'w');
3692        HEAP32[((_stderr)>>2)]=FS.getPtrForStream(stderr);
3693        assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
3694      },ensureErrnoError:function () {
3695        if (FS.ErrnoError) return;
3696        FS.ErrnoError = function ErrnoError(errno) {
3697          this.errno = errno;
3698          for (var key in ERRNO_CODES) {
3699            if (ERRNO_CODES[key] === errno) {
3700              this.code = key;
3701              break;
3702            }
3703          }
3704          this.message = ERRNO_MESSAGES[errno];
3705        };
3706        FS.ErrnoError.prototype = new Error();
3707        FS.ErrnoError.prototype.constructor = FS.ErrnoError;
3708        // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
3709        [ERRNO_CODES.ENOENT].forEach(function(code) {
3710          FS.genericErrors[code] = new FS.ErrnoError(code);
3711          FS.genericErrors[code].stack = '<generic error, no stack>';
3712        });
3713      },staticInit:function () {
3714        FS.ensureErrnoError();
3715
3716        FS.nameTable = new Array(4096);
3717
3718        FS.mount(MEMFS, {}, '/');
3719
3720        FS.createDefaultDirectories();
3721        FS.createDefaultDevices();
3722      },init:function (input, output, error) {
3723        assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
3724        FS.init.initialized = true;
3725
3726        FS.ensureErrnoError();
3727
3728        // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
3729        Module['stdin'] = input || Module['stdin'];
3730        Module['stdout'] = output || Module['stdout'];
3731        Module['stderr'] = error || Module['stderr'];
3732
3733        FS.createStandardStreams();
3734      },quit:function () {
3735        FS.init.initialized = false;
3736        for (var i = 0; i < FS.streams.length; i++) {
3737          var stream = FS.streams[i];
3738          if (!stream) {
3739            continue;
3740          }
3741          FS.close(stream);
3742        }
3743      },getMode:function (canRead, canWrite) {
3744        var mode = 0;
3745        if (canRead) mode |= 292 | 73;
3746        if (canWrite) mode |= 146;
3747        return mode;
3748      },joinPath:function (parts, forceRelative) {
3749        var path = PATH.join.apply(null, parts);
3750        if (forceRelative && path[0] == '/') path = path.substr(1);
3751        return path;
3752      },absolutePath:function (relative, base) {
3753        return PATH.resolve(base, relative);
3754      },standardizePath:function (path) {
3755        return PATH.normalize(path);
3756      },findObject:function (path, dontResolveLastLink) {
3757        var ret = FS.analyzePath(path, dontResolveLastLink);
3758        if (ret.exists) {
3759          return ret.object;
3760        } else {
3761          ___setErrNo(ret.error);
3762          return null;
3763        }
3764      },analyzePath:function (path, dontResolveLastLink) {
3765        // operate from within the context of the symlink's target
3766        try {
3767          var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
3768          path = lookup.path;
3769        } catch (e) {
3770        }
3771        var ret = {
3772          isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
3773          parentExists: false, parentPath: null, parentObject: null
3774        };
3775        try {
3776          var lookup = FS.lookupPath(path, { parent: true });
3777          ret.parentExists = true;
3778          ret.parentPath = lookup.path;
3779          ret.parentObject = lookup.node;
3780          ret.name = PATH.basename(path);
3781          lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
3782          ret.exists = true;
3783          ret.path = lookup.path;
3784          ret.object = lookup.node;
3785          ret.name = lookup.node.name;
3786          ret.isRoot = lookup.path === '/';
3787        } catch (e) {
3788          ret.error = e.errno;
3789        };
3790        return ret;
3791      },createFolder:function (parent, name, canRead, canWrite) {
3792        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
3793        var mode = FS.getMode(canRead, canWrite);
3794        return FS.mkdir(path, mode);
3795      },createPath:function (parent, path, canRead, canWrite) {
3796        parent = typeof parent === 'string' ? parent : FS.getPath(parent);
3797        var parts = path.split('/').reverse();
3798        while (parts.length) {
3799          var part = parts.pop();
3800          if (!part) continue;
3801          var current = PATH.join2(parent, part);
3802          try {
3803            FS.mkdir(current);
3804          } catch (e) {
3805            // ignore EEXIST
3806          }
3807          parent = current;
3808        }
3809        return current;
3810      },createFile:function (parent, name, properties, canRead, canWrite) {
3811        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
3812        var mode = FS.getMode(canRead, canWrite);
3813        return FS.create(path, mode);
3814      },createDataFile:function (parent, name, data, canRead, canWrite, canOwn) {
3815        var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent;
3816        var mode = FS.getMode(canRead, canWrite);
3817        var node = FS.create(path, mode);
3818        if (data) {
3819          if (typeof data === 'string') {
3820            var arr = new Array(data.length);
3821            for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
3822            data = arr;
3823          }
3824          // make sure we can write to the file
3825          FS.chmod(node, mode | 146);
3826          var stream = FS.open(node, 'w');
3827          FS.write(stream, data, 0, data.length, 0, canOwn);
3828          FS.close(stream);
3829          FS.chmod(node, mode);
3830        }
3831        return node;
3832      },createDevice:function (parent, name, input, output) {
3833        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
3834        var mode = FS.getMode(!!input, !!output);
3835        if (!FS.createDevice.major) FS.createDevice.major = 64;
3836        var dev = FS.makedev(FS.createDevice.major++, 0);
3837        // Create a fake device that a set of stream ops to emulate
3838        // the old behavior.
3839        FS.registerDevice(dev, {
3840          open: function(stream) {
3841            stream.seekable = false;
3842          },
3843          close: function(stream) {
3844            // flush any pending line data
3845            if (output && output.buffer && output.buffer.length) {
3846              output(10);
3847            }
3848          },
3849          read: function(stream, buffer, offset, length, pos /* ignored */) {
3850            var bytesRead = 0;
3851            for (var i = 0; i < length; i++) {
3852              var result;
3853              try {
3854                result = input();
3855              } catch (e) {
3856                throw new FS.ErrnoError(ERRNO_CODES.EIO);
3857              }
3858              if (result === undefined && bytesRead === 0) {
3859                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
3860              }
3861              if (result === null || result === undefined) break;
3862              bytesRead++;
3863              buffer[offset+i] = result;
3864            }
3865            if (bytesRead) {
3866              stream.node.timestamp = Date.now();
3867            }
3868            return bytesRead;
3869          },
3870          write: function(stream, buffer, offset, length, pos) {
3871            for (var i = 0; i < length; i++) {
3872              try {
3873                output(buffer[offset+i]);
3874              } catch (e) {
3875                throw new FS.ErrnoError(ERRNO_CODES.EIO);
3876              }
3877            }
3878            if (length) {
3879              stream.node.timestamp = Date.now();
3880            }
3881            return i;
3882          }
3883        });
3884        return FS.mkdev(path, mode, dev);
3885      },createLink:function (parent, name, target, canRead, canWrite) {
3886        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
3887        return FS.symlink(target, path);
3888      },forceLoadFile:function (obj) {
3889        if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
3890        var success = true;
3891        if (typeof XMLHttpRequest !== 'undefined') {
3892          throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
3893        } else if (Module['read']) {
3894          // Command-line.
3895          try {
3896            // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
3897            //          read() will try to parse UTF8.
3898            obj.contents = intArrayFromString(Module['read'](obj.url), true);
3899          } catch (e) {
3900            success = false;
3901          }
3902        } else {
3903          throw new Error('Cannot load without read() or XMLHttpRequest.');
3904        }
3905        if (!success) ___setErrNo(ERRNO_CODES.EIO);
3906        return success;
3907      },createLazyFile:function (parent, name, url, canRead, canWrite) {
3908        // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
3909        function LazyUint8Array() {
3910          this.lengthKnown = false;
3911          this.chunks = []; // Loaded chunks. Index is the chunk number
3912        }
3913        LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) {
3914          if (idx > this.length-1 || idx < 0) {
3915            return undefined;
3916          }
3917          var chunkOffset = idx % this.chunkSize;
3918          var chunkNum = Math.floor(idx / this.chunkSize);
3919          return this.getter(chunkNum)[chunkOffset];
3920        }
3921        LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
3922          this.getter = getter;
3923        }
3924        LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
3925            // Find length
3926            var xhr = new XMLHttpRequest();
3927            xhr.open('HEAD', url, false);
3928            xhr.send(null);
3929            if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
3930            var datalength = Number(xhr.getResponseHeader("Content-length"));
3931            var header;
3932            var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
3933            var chunkSize = 1024*1024; // Chunk size in bytes
3934
3935            if (!hasByteServing) chunkSize = datalength;
3936
3937            // Function to get a range from the remote URL.
3938            var doXHR = (function(from, to) {
3939              if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
3940              if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
3941
3942              // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
3943              var xhr = new XMLHttpRequest();
3944              xhr.open('GET', url, false);
3945              if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
3946
3947              // Some hints to the browser that we want binary data.
3948              if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';
3949              if (xhr.overrideMimeType) {
3950                xhr.overrideMimeType('text/plain; charset=x-user-defined');
3951              }
3952
3953              xhr.send(null);
3954              if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
3955              if (xhr.response !== undefined) {
3956                return new Uint8Array(xhr.response || []);
3957              } else {
3958                return intArrayFromString(xhr.responseText || '', true);
3959              }
3960            });
3961            var lazyArray = this;
3962            lazyArray.setDataGetter(function(chunkNum) {
3963              var start = chunkNum * chunkSize;
3964              var end = (chunkNum+1) * chunkSize - 1; // including this byte
3965              end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
3966              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") {
3967                lazyArray.chunks[chunkNum] = doXHR(start, end);
3968              }
3969              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!");
3970              return lazyArray.chunks[chunkNum];
3971            });
3972
3973            this._length = datalength;
3974            this._chunkSize = chunkSize;
3975            this.lengthKnown = true;
3976        }
3977        if (typeof XMLHttpRequest !== 'undefined') {
3978          if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
3979          var lazyArray = new LazyUint8Array();
3980          Object.defineProperty(lazyArray, "length", {
3981              get: function() {
3982                  if(!this.lengthKnown) {
3983                      this.cacheLength();
3984                  }
3985                  return this._length;
3986              }
3987          });
3988          Object.defineProperty(lazyArray, "chunkSize", {
3989              get: function() {
3990                  if(!this.lengthKnown) {
3991                      this.cacheLength();
3992                  }
3993                  return this._chunkSize;
3994              }
3995          });
3996
3997          var properties = { isDevice: false, contents: lazyArray };
3998        } else {
3999          var properties = { isDevice: false, url: url };
4000        }
4001
4002        var node = FS.createFile(parent, name, properties, canRead, canWrite);
4003        // This is a total hack, but I want to get this lazy file code out of the
4004        // core of MEMFS. If we want to keep this lazy file concept I feel it should
4005        // be its own thin LAZYFS proxying calls to MEMFS.
4006        if (properties.contents) {
4007          node.contents = properties.contents;
4008        } else if (properties.url) {
4009          node.contents = null;
4010          node.url = properties.url;
4011        }
4012        // override each stream op with one that tries to force load the lazy file first
4013        var stream_ops = {};
4014        var keys = Object.keys(node.stream_ops);
4015        keys.forEach(function(key) {
4016          var fn = node.stream_ops[key];
4017          stream_ops[key] = function forceLoadLazyFile() {
4018            if (!FS.forceLoadFile(node)) {
4019              throw new FS.ErrnoError(ERRNO_CODES.EIO);
4020            }
4021            return fn.apply(null, arguments);
4022          };
4023        });
4024        // use a custom read function
4025        stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) {
4026          if (!FS.forceLoadFile(node)) {
4027            throw new FS.ErrnoError(ERRNO_CODES.EIO);
4028          }
4029          var contents = stream.node.contents;
4030          if (position >= contents.length)
4031            return 0;
4032          var size = Math.min(contents.length - position, length);
4033          assert(size >= 0);
4034          if (contents.slice) { // normal array
4035            for (var i = 0; i < size; i++) {
4036              buffer[offset + i] = contents[position + i];
4037            }
4038          } else {
4039            for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
4040              buffer[offset + i] = contents.get(position + i);
4041            }
4042          }
4043          return size;
4044        };
4045        node.stream_ops = stream_ops;
4046        return node;
4047      },createPreloadedFile:function (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn) {
4048        Browser.init();
4049        // TODO we should allow people to just pass in a complete filename instead
4050        // of parent and name being that we just join them anyways
4051        var fullname = name ? PATH.resolve(PATH.join2(parent, name)) : parent;
4052        function processData(byteArray) {
4053          function finish(byteArray) {
4054            if (!dontCreateFile) {
4055              FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
4056            }
4057            if (onload) onload();
4058            removeRunDependency('cp ' + fullname);
4059          }
4060          var handled = false;
4061          Module['preloadPlugins'].forEach(function(plugin) {
4062            if (handled) return;
4063            if (plugin['canHandle'](fullname)) {
4064              plugin['handle'](byteArray, fullname, finish, function() {
4065                if (onerror) onerror();
4066                removeRunDependency('cp ' + fullname);
4067              });
4068              handled = true;
4069            }
4070          });
4071          if (!handled) finish(byteArray);
4072        }
4073        addRunDependency('cp ' + fullname);
4074        if (typeof url == 'string') {
4075          Browser.asyncLoad(url, function(byteArray) {
4076            processData(byteArray);
4077          }, onerror);
4078        } else {
4079          processData(url);
4080        }
4081      },indexedDB:function () {
4082        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
4083      },DB_NAME:function () {
4084        return 'EM_FS_' + window.location.pathname;
4085      },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function (paths, onload, onerror) {
4086        onload = onload || function(){};
4087        onerror = onerror || function(){};
4088        var indexedDB = FS.indexedDB();
4089        try {
4090          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
4091        } catch (e) {
4092          return onerror(e);
4093        }
4094        openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {
4095          console.log('creating db');
4096          var db = openRequest.result;
4097          db.createObjectStore(FS.DB_STORE_NAME);
4098        };
4099        openRequest.onsuccess = function openRequest_onsuccess() {
4100          var db = openRequest.result;
4101          var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
4102          var files = transaction.objectStore(FS.DB_STORE_NAME);
4103          var ok = 0, fail = 0, total = paths.length;
4104          function finish() {
4105            if (fail == 0) onload(); else onerror();
4106          }
4107          paths.forEach(function(path) {
4108            var putRequest = files.put(FS.analyzePath(path).object.contents, path);
4109            putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() };
4110            putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() };
4111          });
4112          transaction.onerror = onerror;
4113        };
4114        openRequest.onerror = onerror;
4115      },loadFilesFromDB:function (paths, onload, onerror) {
4116        onload = onload || function(){};
4117        onerror = onerror || function(){};
4118        var indexedDB = FS.indexedDB();
4119        try {
4120          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
4121        } catch (e) {
4122          return onerror(e);
4123        }
4124        openRequest.onupgradeneeded = onerror; // no database to load from
4125        openRequest.onsuccess = function openRequest_onsuccess() {
4126          var db = openRequest.result;
4127          try {
4128            var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
4129          } catch(e) {
4130            onerror(e);
4131            return;
4132          }
4133          var files = transaction.objectStore(FS.DB_STORE_NAME);
4134          var ok = 0, fail = 0, total = paths.length;
4135          function finish() {
4136            if (fail == 0) onload(); else onerror();
4137          }
4138          paths.forEach(function(path) {
4139            var getRequest = files.get(path);
4140            getRequest.onsuccess = function getRequest_onsuccess() {
4141              if (FS.analyzePath(path).exists) {
4142                FS.unlink(path);
4143              }
4144              FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
4145              ok++;
4146              if (ok + fail == total) finish();
4147            };
4148            getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() };
4149          });
4150          transaction.onerror = onerror;
4151        };
4152        openRequest.onerror = onerror;
4153      }};
4154
4155
4156
4157
4158  function _mkport() { throw 'TODO' }var SOCKFS={mount:function (mount) {
4159        return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
4160      },createSocket:function (family, type, protocol) {
4161        var streaming = type == 1;
4162        if (protocol) {
4163          assert(streaming == (protocol == 6)); // if SOCK_STREAM, must be tcp
4164        }
4165
4166        // create our internal socket structure
4167        var sock = {
4168          family: family,
4169          type: type,
4170          protocol: protocol,
4171          server: null,
4172          peers: {},
4173          pending: [],
4174          recv_queue: [],
4175          sock_ops: SOCKFS.websocket_sock_ops
4176        };
4177
4178        // create the filesystem node to store the socket structure
4179        var name = SOCKFS.nextname();
4180        var node = FS.createNode(SOCKFS.root, name, 49152, 0);
4181        node.sock = sock;
4182
4183        // and the wrapping stream that enables library functions such
4184        // as read and write to indirectly interact with the socket
4185        var stream = FS.createStream({
4186          path: name,
4187          node: node,
4188          flags: FS.modeStringToFlags('r+'),
4189          seekable: false,
4190          stream_ops: SOCKFS.stream_ops
4191        });
4192
4193        // map the new stream to the socket structure (sockets have a 1:1
4194        // relationship with a stream)
4195        sock.stream = stream;
4196
4197        return sock;
4198      },getSocket:function (fd) {
4199        var stream = FS.getStream(fd);
4200        if (!stream || !FS.isSocket(stream.node.mode)) {
4201          return null;
4202        }
4203        return stream.node.sock;
4204      },stream_ops:{poll:function (stream) {
4205          var sock = stream.node.sock;
4206          return sock.sock_ops.poll(sock);
4207        },ioctl:function (stream, request, varargs) {
4208          var sock = stream.node.sock;
4209          return sock.sock_ops.ioctl(sock, request, varargs);
4210        },read:function (stream, buffer, offset, length, position /* ignored */) {
4211          var sock = stream.node.sock;
4212          var msg = sock.sock_ops.recvmsg(sock, length);
4213          if (!msg) {
4214            // socket is closed
4215            return 0;
4216          }
4217          buffer.set(msg.buffer, offset);
4218          return msg.buffer.length;
4219        },write:function (stream, buffer, offset, length, position /* ignored */) {
4220          var sock = stream.node.sock;
4221          return sock.sock_ops.sendmsg(sock, buffer, offset, length);
4222        },close:function (stream) {
4223          var sock = stream.node.sock;
4224          sock.sock_ops.close(sock);
4225        }},nextname:function () {
4226        if (!SOCKFS.nextname.current) {
4227          SOCKFS.nextname.current = 0;
4228        }
4229        return 'socket[' + (SOCKFS.nextname.current++) + ']';
4230      },websocket_sock_ops:{createPeer:function (sock, addr, port) {
4231          var ws;
4232
4233          if (typeof addr === 'object') {
4234            ws = addr;
4235            addr = null;
4236            port = null;
4237          }
4238
4239          if (ws) {
4240            // for sockets that've already connected (e.g. we're the server)
4241            // we can inspect the _socket property for the address
4242            if (ws._socket) {
4243              addr = ws._socket.remoteAddress;
4244              port = ws._socket.remotePort;
4245            }
4246            // if we're just now initializing a connection to the remote,
4247            // inspect the url property
4248            else {
4249              var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
4250              if (!result) {
4251                throw new Error('WebSocket URL must be in the format ws(s)://address:port');
4252              }
4253              addr = result[1];
4254              port = parseInt(result[2], 10);
4255            }
4256          } else {
4257            // create the actual websocket object and connect
4258            try {
4259              // runtimeConfig gets set to true if WebSocket runtime configuration is available.
4260              var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket']));
4261
4262              // The default value is 'ws://' the replace is needed because the compiler replaces "//" comments with '#'
4263              // comments without checking context, so we'd end up with ws:#, the replace swaps the "#" for "//" again.
4264              var url = 'ws:#'.replace('#', '//');
4265
4266              if (runtimeConfig) {
4267                if ('string' === typeof Module['websocket']['url']) {
4268                  url = Module['websocket']['url']; // Fetch runtime WebSocket URL config.
4269                }
4270              }
4271
4272              if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it.
4273                url = url + addr + ':' + port;
4274              }
4275
4276              // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set.
4277              var subProtocols = 'binary'; // The default value is 'binary'
4278
4279              if (runtimeConfig) {
4280                if ('string' === typeof Module['websocket']['subprotocol']) {
4281                  subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config.
4282                }
4283              }
4284
4285              // The regex trims the string (removes spaces at the beginning and end, then splits the string by
4286              // <any space>,<any space> into an Array. Whitespace removal is important for Websockify and ws.
4287              subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */);
4288
4289              // The node ws library API for specifying optional subprotocol is slightly different than the browser's.
4290              var opts = ENVIRONMENT_IS_NODE ? {'protocol': subProtocols.toString()} : subProtocols;
4291
4292              // If node we use the ws library.
4293              var WebSocket = ENVIRONMENT_IS_NODE ? require('ws') : window['WebSocket'];
4294              ws = new WebSocket(url, opts);
4295              ws.binaryType = 'arraybuffer';
4296            } catch (e) {
4297              throw new FS.ErrnoError(ERRNO_CODES.EHOSTUNREACH);
4298            }
4299          }
4300
4301
4302          var peer = {
4303            addr: addr,
4304            port: port,
4305            socket: ws,
4306            dgram_send_queue: []
4307          };
4308
4309          SOCKFS.websocket_sock_ops.addPeer(sock, peer);
4310          SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
4311
4312          // if this is a bound dgram socket, send the port number first to allow
4313          // us to override the ephemeral port reported to us by remotePort on the
4314          // remote end.
4315          if (sock.type === 2 && typeof sock.sport !== 'undefined') {
4316            peer.dgram_send_queue.push(new Uint8Array([
4317                255, 255, 255, 255,
4318                'p'.charCodeAt(0), 'o'.charCodeAt(0), 'r'.charCodeAt(0), 't'.charCodeAt(0),
4319                ((sock.sport & 0xff00) >> 8) , (sock.sport & 0xff)
4320            ]));
4321          }
4322
4323          return peer;
4324        },getPeer:function (sock, addr, port) {
4325          return sock.peers[addr + ':' + port];
4326        },addPeer:function (sock, peer) {
4327          sock.peers[peer.addr + ':' + peer.port] = peer;
4328        },removePeer:function (sock, peer) {
4329          delete sock.peers[peer.addr + ':' + peer.port];
4330        },handlePeerEvents:function (sock, peer) {
4331          var first = true;
4332
4333          var handleOpen = function () {
4334            try {
4335              var queued = peer.dgram_send_queue.shift();
4336              while (queued) {
4337                peer.socket.send(queued);
4338                queued = peer.dgram_send_queue.shift();
4339              }
4340            } catch (e) {
4341              // not much we can do here in the way of proper error handling as we've already
4342              // lied and said this data was sent. shut it down.
4343              peer.socket.close();
4344            }
4345          };
4346
4347          function handleMessage(data) {
4348            assert(typeof data !== 'string' && data.byteLength !== undefined);  // must receive an ArrayBuffer
4349            data = new Uint8Array(data);  // make a typed array view on the array buffer
4350
4351
4352            // if this is the port message, override the peer's port with it
4353            var wasfirst = first;
4354            first = false;
4355            if (wasfirst &&
4356                data.length === 10 &&
4357                data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 &&
4358                data[4] === 'p'.charCodeAt(0) && data[5] === 'o'.charCodeAt(0) && data[6] === 'r'.charCodeAt(0) && data[7] === 't'.charCodeAt(0)) {
4359              // update the peer's port and it's key in the peer map
4360              var newport = ((data[8] << 8) | data[9]);
4361              SOCKFS.websocket_sock_ops.removePeer(sock, peer);
4362              peer.port = newport;
4363              SOCKFS.websocket_sock_ops.addPeer(sock, peer);
4364              return;
4365            }
4366
4367            sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data });
4368          };
4369
4370          if (ENVIRONMENT_IS_NODE) {
4371            peer.socket.on('open', handleOpen);
4372            peer.socket.on('message', function(data, flags) {
4373              if (!flags.binary) {
4374                return;
4375              }
4376              handleMessage((new Uint8Array(data)).buffer);  // copy from node Buffer -> ArrayBuffer
4377            });
4378            peer.socket.on('error', function() {
4379              // don't throw
4380            });
4381          } else {
4382            peer.socket.onopen = handleOpen;
4383            peer.socket.onmessage = function peer_socket_onmessage(event) {
4384              handleMessage(event.data);
4385            };
4386          }
4387        },poll:function (sock) {
4388          if (sock.type === 1 && sock.server) {
4389            // listen sockets should only say they're available for reading
4390            // if there are pending clients.
4391            return sock.pending.length ? (64 | 1) : 0;
4392          }
4393
4394          var mask = 0;
4395          var dest = sock.type === 1 ?  // we only care about the socket state for connection-based sockets
4396            SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) :
4397            null;
4398
4399          if (sock.recv_queue.length ||
4400              !dest ||  // connection-less sockets are always ready to read
4401              (dest && dest.socket.readyState === dest.socket.CLOSING) ||
4402              (dest && dest.socket.readyState === dest.socket.CLOSED)) {  // let recv return 0 once closed
4403            mask |= (64 | 1);
4404          }
4405
4406          if (!dest ||  // connection-less sockets are always ready to write
4407              (dest && dest.socket.readyState === dest.socket.OPEN)) {
4408            mask |= 4;
4409          }
4410
4411          if ((dest && dest.socket.readyState === dest.socket.CLOSING) ||
4412              (dest && dest.socket.readyState === dest.socket.CLOSED)) {
4413            mask |= 16;
4414          }
4415
4416          return mask;
4417        },ioctl:function (sock, request, arg) {
4418          switch (request) {
4419            case 21531:
4420              var bytes = 0;
4421              if (sock.recv_queue.length) {
4422                bytes = sock.recv_queue[0].data.length;
4423              }
4424              HEAP32[((arg)>>2)]=bytes;
4425              return 0;
4426            default:
4427              return ERRNO_CODES.EINVAL;
4428          }
4429        },close:function (sock) {
4430          // if we've spawned a listen server, close it
4431          if (sock.server) {
4432            try {
4433              sock.server.close();
4434            } catch (e) {
4435            }
4436            sock.server = null;
4437          }
4438          // close any peer connections
4439          var peers = Object.keys(sock.peers);
4440          for (var i = 0; i < peers.length; i++) {
4441            var peer = sock.peers[peers[i]];
4442            try {
4443              peer.socket.close();
4444            } catch (e) {
4445            }
4446            SOCKFS.websocket_sock_ops.removePeer(sock, peer);
4447          }
4448          return 0;
4449        },bind:function (sock, addr, port) {
4450          if (typeof sock.saddr !== 'undefined' || typeof sock.sport !== 'undefined') {
4451            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already bound
4452          }
4453          sock.saddr = addr;
4454          sock.sport = port || _mkport();
4455          // in order to emulate dgram sockets, we need to launch a listen server when
4456          // binding on a connection-less socket
4457          // note: this is only required on the server side
4458          if (sock.type === 2) {
4459            // close the existing server if it exists
4460            if (sock.server) {
4461              sock.server.close();
4462              sock.server = null;
4463            }
4464            // swallow error operation not supported error that occurs when binding in the
4465            // browser where this isn't supported
4466            try {
4467              sock.sock_ops.listen(sock, 0);
4468            } catch (e) {
4469              if (!(e instanceof FS.ErrnoError)) throw e;
4470              if (e.errno !== ERRNO_CODES.EOPNOTSUPP) throw e;
4471            }
4472          }
4473        },connect:function (sock, addr, port) {
4474          if (sock.server) {
4475            throw new FS.ErrnoError(ERRNO_CODS.EOPNOTSUPP);
4476          }
4477
4478          // TODO autobind
4479          // if (!sock.addr && sock.type == 2) {
4480          // }
4481
4482          // early out if we're already connected / in the middle of connecting
4483          if (typeof sock.daddr !== 'undefined' && typeof sock.dport !== 'undefined') {
4484            var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
4485            if (dest) {
4486              if (dest.socket.readyState === dest.socket.CONNECTING) {
4487                throw new FS.ErrnoError(ERRNO_CODES.EALREADY);
4488              } else {
4489                throw new FS.ErrnoError(ERRNO_CODES.EISCONN);
4490              }
4491            }
4492          }
4493
4494          // add the socket to our peer list and set our
4495          // destination address / port to match
4496          var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
4497          sock.daddr = peer.addr;
4498          sock.dport = peer.port;
4499
4500          // always "fail" in non-blocking mode
4501          throw new FS.ErrnoError(ERRNO_CODES.EINPROGRESS);
4502        },listen:function (sock, backlog) {
4503          if (!ENVIRONMENT_IS_NODE) {
4504            throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
4505          }
4506          if (sock.server) {
4507             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already listening
4508          }
4509          var WebSocketServer = require('ws').Server;
4510          var host = sock.saddr;
4511          sock.server = new WebSocketServer({
4512            host: host,
4513            port: sock.sport
4514            // TODO support backlog
4515          });
4516
4517          sock.server.on('connection', function(ws) {
4518            if (sock.type === 1) {
4519              var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol);
4520
4521              // create a peer on the new socket
4522              var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws);
4523              newsock.daddr = peer.addr;
4524              newsock.dport = peer.port;
4525
4526              // push to queue for accept to pick up
4527              sock.pending.push(newsock);
4528            } else {
4529              // create a peer on the listen socket so calling sendto
4530              // with the listen socket and an address will resolve
4531              // to the correct client
4532              SOCKFS.websocket_sock_ops.createPeer(sock, ws);
4533            }
4534          });
4535          sock.server.on('closed', function() {
4536            sock.server = null;
4537          });
4538          sock.server.on('error', function() {
4539            // don't throw
4540          });
4541        },accept:function (listensock) {
4542          if (!listensock.server) {
4543            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
4544          }
4545          var newsock = listensock.pending.shift();
4546          newsock.stream.flags = listensock.stream.flags;
4547          return newsock;
4548        },getname:function (sock, peer) {
4549          var addr, port;
4550          if (peer) {
4551            if (sock.daddr === undefined || sock.dport === undefined) {
4552              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
4553            }
4554            addr = sock.daddr;
4555            port = sock.dport;
4556          } else {
4557            // TODO saddr and sport will be set for bind()'d UDP sockets, but what
4558            // should we be returning for TCP sockets that've been connect()'d?
4559            addr = sock.saddr || 0;
4560            port = sock.sport || 0;
4561          }
4562          return { addr: addr, port: port };
4563        },sendmsg:function (sock, buffer, offset, length, addr, port) {
4564          if (sock.type === 2) {
4565            // connection-less sockets will honor the message address,
4566            // and otherwise fall back to the bound destination address
4567            if (addr === undefined || port === undefined) {
4568              addr = sock.daddr;
4569              port = sock.dport;
4570            }
4571            // if there was no address to fall back to, error out
4572            if (addr === undefined || port === undefined) {
4573              throw new FS.ErrnoError(ERRNO_CODES.EDESTADDRREQ);
4574            }
4575          } else {
4576            // connection-based sockets will only use the bound
4577            addr = sock.daddr;
4578            port = sock.dport;
4579          }
4580
4581          // find the peer for the destination address
4582          var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
4583
4584          // early out if not connected with a connection-based socket
4585          if (sock.type === 1) {
4586            if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
4587              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
4588            } else if (dest.socket.readyState === dest.socket.CONNECTING) {
4589              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
4590            }
4591          }
4592
4593          // create a copy of the incoming data to send, as the WebSocket API
4594          // doesn't work entirely with an ArrayBufferView, it'll just send
4595          // the entire underlying buffer
4596          var data;
4597          if (buffer instanceof Array || buffer instanceof ArrayBuffer) {
4598            data = buffer.slice(offset, offset + length);
4599          } else {  // ArrayBufferView
4600            data = buffer.buffer.slice(buffer.byteOffset + offset, buffer.byteOffset + offset + length);
4601          }
4602
4603          // if we're emulating a connection-less dgram socket and don't have
4604          // a cached connection, queue the buffer to send upon connect and
4605          // lie, saying the data was sent now.
4606          if (sock.type === 2) {
4607            if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
4608              // if we're not connected, open a new connection
4609              if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
4610                dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
4611              }
4612              dest.dgram_send_queue.push(data);
4613              return length;
4614            }
4615          }
4616
4617          try {
4618            // send the actual data
4619            dest.socket.send(data);
4620            return length;
4621          } catch (e) {
4622            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
4623          }
4624        },recvmsg:function (sock, length) {
4625          // http://pubs.opengroup.org/onlinepubs/7908799/xns/recvmsg.html
4626          if (sock.type === 1 && sock.server) {
4627            // tcp servers should not be recv()'ing on the listen socket
4628            throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
4629          }
4630
4631          var queued = sock.recv_queue.shift();
4632          if (!queued) {
4633            if (sock.type === 1) {
4634              var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
4635
4636              if (!dest) {
4637                // if we have a destination address but are not connected, error out
4638                throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
4639              }
4640              else if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
4641                // return null if the socket has closed
4642                return null;
4643              }
4644              else {
4645                // else, our socket is in a valid state but truly has nothing available
4646                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
4647              }
4648            } else {
4649              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
4650            }
4651          }
4652
4653          // queued.data will be an ArrayBuffer if it's unadulterated, but if it's
4654          // requeued TCP data it'll be an ArrayBufferView
4655          var queuedLength = queued.data.byteLength || queued.data.length;
4656          var queuedOffset = queued.data.byteOffset || 0;
4657          var queuedBuffer = queued.data.buffer || queued.data;
4658          var bytesRead = Math.min(length, queuedLength);
4659          var res = {
4660            buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead),
4661            addr: queued.addr,
4662            port: queued.port
4663          };
4664
4665
4666          // push back any unread data for TCP connections
4667          if (sock.type === 1 && bytesRead < queuedLength) {
4668            var bytesRemaining = queuedLength - bytesRead;
4669            queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining);
4670            sock.recv_queue.unshift(queued);
4671          }
4672
4673          return res;
4674        }}};function _send(fd, buf, len, flags) {
4675      var sock = SOCKFS.getSocket(fd);
4676      if (!sock) {
4677        ___setErrNo(ERRNO_CODES.EBADF);
4678        return -1;
4679      }
4680      // TODO honor flags
4681      return _write(fd, buf, len);
4682    }
4683
4684  function _pwrite(fildes, buf, nbyte, offset) {
4685      // ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
4686      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
4687      var stream = FS.getStream(fildes);
4688      if (!stream) {
4689        ___setErrNo(ERRNO_CODES.EBADF);
4690        return -1;
4691      }
4692      try {
4693        var slab = HEAP8;
4694        return FS.write(stream, slab, buf, nbyte, offset);
4695      } catch (e) {
4696        FS.handleFSError(e);
4697        return -1;
4698      }
4699    }function _write(fildes, buf, nbyte) {
4700      // ssize_t write(int fildes, const void *buf, size_t nbyte);
4701      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
4702      var stream = FS.getStream(fildes);
4703      if (!stream) {
4704        ___setErrNo(ERRNO_CODES.EBADF);
4705        return -1;
4706      }
4707
4708
4709      try {
4710        var slab = HEAP8;
4711        return FS.write(stream, slab, buf, nbyte);
4712      } catch (e) {
4713        FS.handleFSError(e);
4714        return -1;
4715      }
4716    }
4717
4718  function _fileno(stream) {
4719      // int fileno(FILE *stream);
4720      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html
4721      stream = FS.getStreamFromPtr(stream);
4722      if (!stream) return -1;
4723      return stream.fd;
4724    }function _fwrite(ptr, size, nitems, stream) {
4725      // size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
4726      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html
4727      var bytesToWrite = nitems * size;
4728      if (bytesToWrite == 0) return 0;
4729      var fd = _fileno(stream);
4730      var bytesWritten = _write(fd, ptr, bytesToWrite);
4731      if (bytesWritten == -1) {
4732        var streamObj = FS.getStreamFromPtr(stream);
4733        if (streamObj) streamObj.error = true;
4734        return 0;
4735      } else {
4736        return Math.floor(bytesWritten / size);
4737      }
4738    }
4739
4740
4741
4742  Module["_strlen"] = _strlen;
4743
4744  function __reallyNegative(x) {
4745      return x < 0 || (x === 0 && (1/x) === -Infinity);
4746    }function __formatString(format, varargs) {
4747      var textIndex = format;
4748      var argIndex = 0;
4749      function getNextArg(type) {
4750        // NOTE: Explicitly ignoring type safety. Otherwise this fails:
4751        //       int x = 4; printf("%c\n", (char)x);
4752        var ret;
4753        if (type === 'double') {
4754          ret = HEAPF64[(((varargs)+(argIndex))>>3)];
4755        } else if (type == 'i64') {
4756          ret = [HEAP32[(((varargs)+(argIndex))>>2)],
4757                 HEAP32[(((varargs)+(argIndex+4))>>2)]];
4758
4759        } else {
4760          type = 'i32'; // varargs are always i32, i64, or double
4761          ret = HEAP32[(((varargs)+(argIndex))>>2)];
4762        }
4763        argIndex += Runtime.getNativeFieldSize(type);
4764        return ret;
4765      }
4766
4767      var ret = [];
4768      var curr, next, currArg;
4769      while(1) {
4770        var startTextIndex = textIndex;
4771        curr = HEAP8[(textIndex)];
4772        if (curr === 0) break;
4773        next = HEAP8[((textIndex+1)|0)];
4774        if (curr == 37) {
4775          // Handle flags.
4776          var flagAlwaysSigned = false;
4777          var flagLeftAlign = false;
4778          var flagAlternative = false;
4779          var flagZeroPad = false;
4780          var flagPadSign = false;
4781          flagsLoop: while (1) {
4782            switch (next) {
4783              case 43:
4784                flagAlwaysSigned = true;
4785                break;
4786              case 45:
4787                flagLeftAlign = true;
4788                break;
4789              case 35:
4790                flagAlternative = true;
4791                break;
4792              case 48:
4793                if (flagZeroPad) {
4794                  break flagsLoop;
4795                } else {
4796                  flagZeroPad = true;
4797                  break;
4798                }
4799              case 32:
4800                flagPadSign = true;
4801                break;
4802              default:
4803                break flagsLoop;
4804            }
4805            textIndex++;
4806            next = HEAP8[((textIndex+1)|0)];
4807          }
4808
4809          // Handle width.
4810          var width = 0;
4811          if (next == 42) {
4812            width = getNextArg('i32');
4813            textIndex++;
4814            next = HEAP8[((textIndex+1)|0)];
4815          } else {
4816            while (next >= 48 && next <= 57) {
4817              width = width * 10 + (next - 48);
4818              textIndex++;
4819              next = HEAP8[((textIndex+1)|0)];
4820            }
4821          }
4822
4823          // Handle precision.
4824          var precisionSet = false, precision = -1;
4825          if (next == 46) {
4826            precision = 0;
4827            precisionSet = true;
4828            textIndex++;
4829            next = HEAP8[((textIndex+1)|0)];
4830            if (next == 42) {
4831              precision = getNextArg('i32');
4832              textIndex++;
4833            } else {
4834              while(1) {
4835                var precisionChr = HEAP8[((textIndex+1)|0)];
4836                if (precisionChr < 48 ||
4837                    precisionChr > 57) break;
4838                precision = precision * 10 + (precisionChr - 48);
4839                textIndex++;
4840              }
4841            }
4842            next = HEAP8[((textIndex+1)|0)];
4843          }
4844          if (precision < 0) {
4845            precision = 6; // Standard default.
4846            precisionSet = false;
4847          }
4848
4849          // Handle integer sizes. WARNING: These assume a 32-bit architecture!
4850          var argSize;
4851          switch (String.fromCharCode(next)) {
4852            case 'h':
4853              var nextNext = HEAP8[((textIndex+2)|0)];
4854              if (nextNext == 104) {
4855                textIndex++;
4856                argSize = 1; // char (actually i32 in varargs)
4857              } else {
4858                argSize = 2; // short (actually i32 in varargs)
4859              }
4860              break;
4861            case 'l':
4862              var nextNext = HEAP8[((textIndex+2)|0)];
4863              if (nextNext == 108) {
4864                textIndex++;
4865                argSize = 8; // long long
4866              } else {
4867                argSize = 4; // long
4868              }
4869              break;
4870            case 'L': // long long
4871            case 'q': // int64_t
4872            case 'j': // intmax_t
4873              argSize = 8;
4874              break;
4875            case 'z': // size_t
4876            case 't': // ptrdiff_t
4877            case 'I': // signed ptrdiff_t or unsigned size_t
4878              argSize = 4;
4879              break;
4880            default:
4881              argSize = null;
4882          }
4883          if (argSize) textIndex++;
4884          next = HEAP8[((textIndex+1)|0)];
4885
4886          // Handle type specifier.
4887          switch (String.fromCharCode(next)) {
4888            case 'd': case 'i': case 'u': case 'o': case 'x': case 'X': case 'p': {
4889              // Integer.
4890              var signed = next == 100 || next == 105;
4891              argSize = argSize || 4;
4892              var currArg = getNextArg('i' + (argSize * 8));
4893              var argText;
4894              // Flatten i64-1 [low, high] into a (slightly rounded) double
4895              if (argSize == 8) {
4896                currArg = Runtime.makeBigInt(currArg[0], currArg[1], next == 117);
4897              }
4898              // Truncate to requested size.
4899              if (argSize <= 4) {
4900                var limit = Math.pow(256, argSize) - 1;
4901                currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8);
4902              }
4903              // Format the number.
4904              var currAbsArg = Math.abs(currArg);
4905              var prefix = '';
4906              if (next == 100 || next == 105) {
4907                argText = reSign(currArg, 8 * argSize, 1).toString(10);
4908              } else if (next == 117) {
4909                argText = unSign(currArg, 8 * argSize, 1).toString(10);
4910                currArg = Math.abs(currArg);
4911              } else if (next == 111) {
4912                argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8);
4913              } else if (next == 120 || next == 88) {
4914                prefix = (flagAlternative && currArg != 0) ? '0x' : '';
4915                if (currArg < 0) {
4916                  // Represent negative numbers in hex as 2's complement.
4917                  currArg = -currArg;
4918                  argText = (currAbsArg - 1).toString(16);
4919                  var buffer = [];
4920                  for (var i = 0; i < argText.length; i++) {
4921                    buffer.push((0xF - parseInt(argText[i], 16)).toString(16));
4922                  }
4923                  argText = buffer.join('');
4924                  while (argText.length < argSize * 2) argText = 'f' + argText;
4925                } else {
4926                  argText = currAbsArg.toString(16);
4927                }
4928                if (next == 88) {
4929                  prefix = prefix.toUpperCase();
4930                  argText = argText.toUpperCase();
4931                }
4932              } else if (next == 112) {
4933                if (currAbsArg === 0) {
4934                  argText = '(nil)';
4935                } else {
4936                  prefix = '0x';
4937                  argText = currAbsArg.toString(16);
4938                }
4939              }
4940              if (precisionSet) {
4941                while (argText.length < precision) {
4942                  argText = '0' + argText;
4943                }
4944              }
4945
4946              // Add sign if needed
4947              if (currArg >= 0) {
4948                if (flagAlwaysSigned) {
4949                  prefix = '+' + prefix;
4950                } else if (flagPadSign) {
4951                  prefix = ' ' + prefix;
4952                }
4953              }
4954
4955              // Move sign to prefix so we zero-pad after the sign
4956              if (argText.charAt(0) == '-') {
4957                prefix = '-' + prefix;
4958                argText = argText.substr(1);
4959              }
4960
4961              // Add padding.
4962              while (prefix.length + argText.length < width) {
4963                if (flagLeftAlign) {
4964                  argText += ' ';
4965                } else {
4966                  if (flagZeroPad) {
4967                    argText = '0' + argText;
4968                  } else {
4969                    prefix = ' ' + prefix;
4970                  }
4971                }
4972              }
4973
4974              // Insert the result into the buffer.
4975              argText = prefix + argText;
4976              argText.split('').forEach(function(chr) {
4977                ret.push(chr.charCodeAt(0));
4978              });
4979              break;
4980            }
4981            case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': {
4982              // Float.
4983              var currArg = getNextArg('double');
4984              var argText;
4985              if (isNaN(currArg)) {
4986                argText = 'nan';
4987                flagZeroPad = false;
4988              } else if (!isFinite(currArg)) {
4989                argText = (currArg < 0 ? '-' : '') + 'inf';
4990                flagZeroPad = false;
4991              } else {
4992                var isGeneral = false;
4993                var effectivePrecision = Math.min(precision, 20);
4994
4995                // Convert g/G to f/F or e/E, as per:
4996                // http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
4997                if (next == 103 || next == 71) {
4998                  isGeneral = true;
4999                  precision = precision || 1;
5000                  var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10);
5001                  if (precision > exponent && exponent >= -4) {
5002                    next = ((next == 103) ? 'f' : 'F').charCodeAt(0);
5003                    precision -= exponent + 1;
5004                  } else {
5005                    next = ((next == 103) ? 'e' : 'E').charCodeAt(0);
5006                    precision--;
5007                  }
5008                  effectivePrecision = Math.min(precision, 20);
5009                }
5010
5011                if (next == 101 || next == 69) {
5012                  argText = currArg.toExponential(effectivePrecision);
5013                  // Make sure the exponent has at least 2 digits.
5014                  if (/[eE][-+]\d$/.test(argText)) {
5015                    argText = argText.slice(0, -1) + '0' + argText.slice(-1);
5016                  }
5017                } else if (next == 102 || next == 70) {
5018                  argText = currArg.toFixed(effectivePrecision);
5019                  if (currArg === 0 && __reallyNegative(currArg)) {
5020                    argText = '-' + argText;
5021                  }
5022                }
5023
5024                var parts = argText.split('e');
5025                if (isGeneral && !flagAlternative) {
5026                  // Discard trailing zeros and periods.
5027                  while (parts[0].length > 1 && parts[0].indexOf('.') != -1 &&
5028                         (parts[0].slice(-1) == '0' || parts[0].slice(-1) == '.')) {
5029                    parts[0] = parts[0].slice(0, -1);
5030                  }
5031                } else {
5032                  // Make sure we have a period in alternative mode.
5033                  if (flagAlternative && argText.indexOf('.') == -1) parts[0] += '.';
5034                  // Zero pad until required precision.
5035                  while (precision > effectivePrecision++) parts[0] += '0';
5036                }
5037                argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : '');
5038
5039                // Capitalize 'E' if needed.
5040                if (next == 69) argText = argText.toUpperCase();
5041
5042                // Add sign.
5043                if (currArg >= 0) {
5044                  if (flagAlwaysSigned) {
5045                    argText = '+' + argText;
5046                  } else if (flagPadSign) {
5047                    argText = ' ' + argText;
5048                  }
5049                }
5050              }
5051
5052              // Add padding.
5053              while (argText.length < width) {
5054                if (flagLeftAlign) {
5055                  argText += ' ';
5056                } else {
5057                  if (flagZeroPad && (argText[0] == '-' || argText[0] == '+')) {
5058                    argText = argText[0] + '0' + argText.slice(1);
5059                  } else {
5060                    argText = (flagZeroPad ? '0' : ' ') + argText;
5061                  }
5062                }
5063              }
5064
5065              // Adjust case.
5066              if (next < 97) argText = argText.toUpperCase();
5067
5068              // Insert the result into the buffer.
5069              argText.split('').forEach(function(chr) {
5070                ret.push(chr.charCodeAt(0));
5071              });
5072              break;
5073            }
5074            case 's': {
5075              // String.
5076              var arg = getNextArg('i8*');
5077              var argLength = arg ? _strlen(arg) : '(null)'.length;
5078              if (precisionSet) argLength = Math.min(argLength, precision);
5079              if (!flagLeftAlign) {
5080                while (argLength < width--) {
5081                  ret.push(32);
5082                }
5083              }
5084              if (arg) {
5085                for (var i = 0; i < argLength; i++) {
5086                  ret.push(HEAPU8[((arg++)|0)]);
5087                }
5088              } else {
5089                ret = ret.concat(intArrayFromString('(null)'.substr(0, argLength), true));
5090              }
5091              if (flagLeftAlign) {
5092                while (argLength < width--) {
5093                  ret.push(32);
5094                }
5095              }
5096              break;
5097            }
5098            case 'c': {
5099              // Character.
5100              if (flagLeftAlign) ret.push(getNextArg('i8'));
5101              while (--width > 0) {
5102                ret.push(32);
5103              }
5104              if (!flagLeftAlign) ret.push(getNextArg('i8'));
5105              break;
5106            }
5107            case 'n': {
5108              // Write the length written so far to the next parameter.
5109              var ptr = getNextArg('i32*');
5110              HEAP32[((ptr)>>2)]=ret.length;
5111              break;
5112            }
5113            case '%': {
5114              // Literal percent sign.
5115              ret.push(curr);
5116              break;
5117            }
5118            default: {
5119              // Unknown specifiers remain untouched.
5120              for (var i = startTextIndex; i < textIndex + 2; i++) {
5121                ret.push(HEAP8[(i)]);
5122              }
5123            }
5124          }
5125          textIndex += 2;
5126          // TODO: Support a/A (hex float) and m (last error) specifiers.
5127          // TODO: Support %1${specifier} for arg selection.
5128        } else {
5129          ret.push(curr);
5130          textIndex += 1;
5131        }
5132      }
5133      return ret;
5134    }function _fprintf(stream, format, varargs) {
5135      // int fprintf(FILE *restrict stream, const char *restrict format, ...);
5136      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
5137      var result = __formatString(format, varargs);
5138      var stack = Runtime.stackSave();
5139      var ret = _fwrite(allocate(result, 'i8', ALLOC_STACK), 1, result.length, stream);
5140      Runtime.stackRestore(stack);
5141      return ret;
5142    }function _printf(format, varargs) {
5143      // int printf(const char *restrict format, ...);
5144      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
5145      var stdout = HEAP32[((_stdout)>>2)];
5146      return _fprintf(stdout, format, varargs);
5147    }
5148
5149
5150
5151  function _emscripten_memcpy_big(dest, src, num) {
5152      HEAPU8.set(HEAPU8.subarray(src, src+num), dest);
5153      return dest;
5154    }
5155  Module["_memcpy"] = _memcpy;
5156
5157
5158  function _fputs(s, stream) {
5159      // int fputs(const char *restrict s, FILE *restrict stream);
5160      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fputs.html
5161      var fd = _fileno(stream);
5162      return _write(fd, s, _strlen(s));
5163    }
5164
5165  function _fputc(c, stream) {
5166      // int fputc(int c, FILE *stream);
5167      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fputc.html
5168      var chr = unSign(c & 0xFF);
5169      HEAP8[((_fputc.ret)|0)]=chr;
5170      var fd = _fileno(stream);
5171      var ret = _write(fd, _fputc.ret, 1);
5172      if (ret == -1) {
5173        var streamObj = FS.getStreamFromPtr(stream);
5174        if (streamObj) streamObj.error = true;
5175        return -1;
5176      } else {
5177        return chr;
5178      }
5179    }function _puts(s) {
5180      // int puts(const char *s);
5181      // http://pubs.opengroup.org/onlinepubs/000095399/functions/puts.html
5182      // NOTE: puts() always writes an extra newline.
5183      var stdout = HEAP32[((_stdout)>>2)];
5184      var ret = _fputs(s, stdout);
5185      if (ret < 0) {
5186        return ret;
5187      } else {
5188        var newlineRet = _fputc(10, stdout);
5189        return (newlineRet < 0) ? -1 : ret + 1;
5190      }
5191    }
5192
5193  function _sbrk(bytes) {
5194      // Implement a Linux-like 'memory area' for our 'process'.
5195      // Changes the size of the memory area by |bytes|; returns the
5196      // address of the previous top ('break') of the memory area
5197      // We control the "dynamic" memory - DYNAMIC_BASE to DYNAMICTOP
5198      var self = _sbrk;
5199      if (!self.called) {
5200        DYNAMICTOP = alignMemoryPage(DYNAMICTOP); // make sure we start out aligned
5201        self.called = true;
5202        assert(Runtime.dynamicAlloc);
5203        self.alloc = Runtime.dynamicAlloc;
5204        Runtime.dynamicAlloc = function() { abort('cannot dynamically allocate, sbrk now has control') };
5205      }
5206      var ret = DYNAMICTOP;
5207      if (bytes != 0) self.alloc(bytes);
5208      return ret;  // Previous break location.
5209    }
5210
5211  function ___errno_location() {
5212      return ___errno_state;
5213    }
5214
5215  function __ZNSt9exceptionD2Ev() {}
5216
5217  var Browser={mainLoop:{scheduler:null,method:"",shouldPause:false,paused:false,queue:[],pause:function () {
5218          Browser.mainLoop.shouldPause = true;
5219        },resume:function () {
5220          if (Browser.mainLoop.paused) {
5221            Browser.mainLoop.paused = false;
5222            Browser.mainLoop.scheduler();
5223          }
5224          Browser.mainLoop.shouldPause = false;
5225        },updateStatus:function () {
5226          if (Module['setStatus']) {
5227            var message = Module['statusMessage'] || 'Please wait...';
5228            var remaining = Browser.mainLoop.remainingBlockers;
5229            var expected = Browser.mainLoop.expectedBlockers;
5230            if (remaining) {
5231              if (remaining < expected) {
5232                Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')');
5233              } else {
5234                Module['setStatus'](message);
5235              }
5236            } else {
5237              Module['setStatus']('');
5238            }
5239          }
5240        }},isFullScreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function () {
5241        if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers
5242
5243        if (Browser.initted || ENVIRONMENT_IS_WORKER) return;
5244        Browser.initted = true;
5245
5246        try {
5247          new Blob();
5248          Browser.hasBlobConstructor = true;
5249        } catch(e) {
5250          Browser.hasBlobConstructor = false;
5251          console.log("warning: no blob constructor, cannot create blobs with mimetypes");
5252        }
5253        Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null));
5254        Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined;
5255        if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') {
5256          console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");
5257          Module.noImageDecoding = true;
5258        }
5259
5260        // Support for plugins that can process preloaded files. You can add more of these to
5261        // your app by creating and appending to Module.preloadPlugins.
5262        //
5263        // Each plugin is asked if it can handle a file based on the file's name. If it can,
5264        // it is given the file's raw data. When it is done, it calls a callback with the file's
5265        // (possibly modified) data. For example, a plugin might decompress a file, or it
5266        // might create some side data structure for use later (like an Image element, etc.).
5267
5268        var imagePlugin = {};
5269        imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
5270          return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name);
5271        };
5272        imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
5273          var b = null;
5274          if (Browser.hasBlobConstructor) {
5275            try {
5276              b = new Blob([byteArray], { type: Browser.getMimetype(name) });
5277              if (b.size !== byteArray.length) { // Safari bug #118630
5278                // Safari's Blob can only take an ArrayBuffer
5279                b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
5280              }
5281            } catch(e) {
5282              Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder');
5283            }
5284          }
5285          if (!b) {
5286            var bb = new Browser.BlobBuilder();
5287            bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range
5288            b = bb.getBlob();
5289          }
5290          var url = Browser.URLObject.createObjectURL(b);
5291          var img = new Image();
5292          img.onload = function img_onload() {
5293            assert(img.complete, 'Image ' + name + ' could not be decoded');
5294            var canvas = document.createElement('canvas');
5295            canvas.width = img.width;
5296            canvas.height = img.height;
5297            var ctx = canvas.getContext('2d');
5298            ctx.drawImage(img, 0, 0);
5299            Module["preloadedImages"][name] = canvas;
5300            Browser.URLObject.revokeObjectURL(url);
5301            if (onload) onload(byteArray);
5302          };
5303          img.onerror = function img_onerror(event) {
5304            console.log('Image ' + url + ' could not be decoded');
5305            if (onerror) onerror();
5306          };
5307          img.src = url;
5308        };
5309        Module['preloadPlugins'].push(imagePlugin);
5310
5311        var audioPlugin = {};
5312        audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
5313          return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
5314        };
5315        audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
5316          var done = false;
5317          function finish(audio) {
5318            if (done) return;
5319            done = true;
5320            Module["preloadedAudios"][name] = audio;
5321            if (onload) onload(byteArray);
5322          }
5323          function fail() {
5324            if (done) return;
5325            done = true;
5326            Module["preloadedAudios"][name] = new Audio(); // empty shim
5327            if (onerror) onerror();
5328          }
5329          if (Browser.hasBlobConstructor) {
5330            try {
5331              var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
5332            } catch(e) {
5333              return fail();
5334            }
5335            var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this!
5336            var audio = new Audio();
5337            audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926
5338            audio.onerror = function audio_onerror(event) {
5339              if (done) return;
5340              console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach');
5341              function encode64(data) {
5342                var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
5343                var PAD = '=';
5344                var ret = '';
5345                var leftchar = 0;
5346                var leftbits = 0;
5347                for (var i = 0; i < data.length; i++) {
5348                  leftchar = (leftchar << 8) | data[i];
5349                  leftbits += 8;
5350                  while (leftbits >= 6) {
5351                    var curr = (leftchar >> (leftbits-6)) & 0x3f;
5352                    leftbits -= 6;
5353                    ret += BASE[curr];
5354                  }
5355                }
5356                if (leftbits == 2) {
5357                  ret += BASE[(leftchar&3) << 4];
5358                  ret += PAD + PAD;
5359                } else if (leftbits == 4) {
5360                  ret += BASE[(leftchar&0xf) << 2];
5361                  ret += PAD;
5362                }
5363                return ret;
5364              }
5365              audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);
5366              finish(audio); // we don't wait for confirmation this worked - but it's worth trying
5367            };
5368            audio.src = url;
5369            // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
5370            Browser.safeSetTimeout(function() {
5371              finish(audio); // try to use it even though it is not necessarily ready to play
5372            }, 10000);
5373          } else {
5374            return fail();
5375          }
5376        };
5377        Module['preloadPlugins'].push(audioPlugin);
5378
5379        // Canvas event setup
5380
5381        var canvas = Module['canvas'];
5382
5383        // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
5384        // Module['forcedAspectRatio'] = 4 / 3;
5385
5386        canvas.requestPointerLock = canvas['requestPointerLock'] ||
5387                                    canvas['mozRequestPointerLock'] ||
5388                                    canvas['webkitRequestPointerLock'] ||
5389                                    canvas['msRequestPointerLock'] ||
5390                                    function(){};
5391        canvas.exitPointerLock = document['exitPointerLock'] ||
5392                                 document['mozExitPointerLock'] ||
5393                                 document['webkitExitPointerLock'] ||
5394                                 document['msExitPointerLock'] ||
5395                                 function(){}; // no-op if function does not exist
5396        canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
5397
5398        function pointerLockChange() {
5399          Browser.pointerLock = document['pointerLockElement'] === canvas ||
5400                                document['mozPointerLockElement'] === canvas ||
5401                                document['webkitPointerLockElement'] === canvas ||
5402                                document['msPointerLockElement'] === canvas;
5403        }
5404
5405        document.addEventListener('pointerlockchange', pointerLockChange, false);
5406        document.addEventListener('mozpointerlockchange', pointerLockChange, false);
5407        document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
5408        document.addEventListener('mspointerlockchange', pointerLockChange, false);
5409
5410        if (Module['elementPointerLock']) {
5411          canvas.addEventListener("click", function(ev) {
5412            if (!Browser.pointerLock && canvas.requestPointerLock) {
5413              canvas.requestPointerLock();
5414              ev.preventDefault();
5415            }
5416          }, false);
5417        }
5418      },createContext:function (canvas, useWebGL, setInModule, webGLContextAttributes) {
5419        var ctx;
5420        var errorInfo = '?';
5421        function onContextCreationError(event) {
5422          errorInfo = event.statusMessage || errorInfo;
5423        }
5424        try {
5425          if (useWebGL) {
5426            var contextAttributes = {
5427              antialias: false,
5428              alpha: false
5429            };
5430
5431            if (webGLContextAttributes) {
5432              for (var attribute in webGLContextAttributes) {
5433                contextAttributes[attribute] = webGLContextAttributes[attribute];
5434              }
5435            }
5436
5437
5438            canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false);
5439            try {
5440              ['experimental-webgl', 'webgl'].some(function(webglId) {
5441                return ctx = canvas.getContext(webglId, contextAttributes);
5442              });
5443            } finally {
5444              canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false);
5445            }
5446          } else {
5447            ctx = canvas.getContext('2d');
5448          }
5449          if (!ctx) throw ':(';
5450        } catch (e) {
5451          Module.print('Could not create canvas: ' + [errorInfo, e]);
5452          return null;
5453        }
5454        if (useWebGL) {
5455          // Set the background of the WebGL canvas to black
5456          canvas.style.backgroundColor = "black";
5457
5458          // Warn on context loss
5459          canvas.addEventListener('webglcontextlost', function(event) {
5460            alert('WebGL context lost. You will need to reload the page.');
5461          }, false);
5462        }
5463        if (setInModule) {
5464          GLctx = Module.ctx = ctx;
5465          Module.useWebGL = useWebGL;
5466          Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });
5467          Browser.init();
5468        }
5469        return ctx;
5470      },destroyContext:function (canvas, useWebGL, setInModule) {},fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:function (lockPointer, resizeCanvas) {
5471        Browser.lockPointer = lockPointer;
5472        Browser.resizeCanvas = resizeCanvas;
5473        if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true;
5474        if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false;
5475
5476        var canvas = Module['canvas'];
5477        function fullScreenChange() {
5478          Browser.isFullScreen = false;
5479          var canvasContainer = canvas.parentNode;
5480          if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
5481               document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
5482               document['fullScreenElement'] || document['fullscreenElement'] ||
5483               document['msFullScreenElement'] || document['msFullscreenElement'] ||
5484               document['webkitCurrentFullScreenElement']) === canvasContainer) {
5485            canvas.cancelFullScreen = document['cancelFullScreen'] ||
5486                                      document['mozCancelFullScreen'] ||
5487                                      document['webkitCancelFullScreen'] ||
5488                                      document['msExitFullscreen'] ||
5489                                      document['exitFullscreen'] ||
5490                                      function() {};
5491            canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document);
5492            if (Browser.lockPointer) canvas.requestPointerLock();
5493            Browser.isFullScreen = true;
5494            if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize();
5495          } else {
5496
5497            // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
5498            canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
5499            canvasContainer.parentNode.removeChild(canvasContainer);
5500
5501            if (Browser.resizeCanvas) Browser.setWindowedCanvasSize();
5502          }
5503          if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen);
5504          Browser.updateCanvasDimensions(canvas);
5505        }
5506
5507        if (!Browser.fullScreenHandlersInstalled) {
5508          Browser.fullScreenHandlersInstalled = true;
5509          document.addEventListener('fullscreenchange', fullScreenChange, false);
5510          document.addEventListener('mozfullscreenchange', fullScreenChange, false);
5511          document.addEventListener('webkitfullscreenchange', fullScreenChange, false);
5512          document.addEventListener('MSFullscreenChange', fullScreenChange, false);
5513        }
5514
5515        // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root
5516        var canvasContainer = document.createElement("div");
5517        canvas.parentNode.insertBefore(canvasContainer, canvas);
5518        canvasContainer.appendChild(canvas);
5519
5520        // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
5521        canvasContainer.requestFullScreen = canvasContainer['requestFullScreen'] ||
5522                                            canvasContainer['mozRequestFullScreen'] ||
5523                                            canvasContainer['msRequestFullscreen'] ||
5524                                           (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null);
5525        canvasContainer.requestFullScreen();
5526      },requestAnimationFrame:function requestAnimationFrame(func) {
5527        if (typeof window === 'undefined') { // Provide fallback to setTimeout if window is undefined (e.g. in Node.js)
5528          setTimeout(func, 1000/60);
5529        } else {
5530          if (!window.requestAnimationFrame) {
5531            window.requestAnimationFrame = window['requestAnimationFrame'] ||
5532                                           window['mozRequestAnimationFrame'] ||
5533                                           window['webkitRequestAnimationFrame'] ||
5534                                           window['msRequestAnimationFrame'] ||
5535                                           window['oRequestAnimationFrame'] ||
5536                                           window['setTimeout'];
5537          }
5538          window.requestAnimationFrame(func);
5539        }
5540      },safeCallback:function (func) {
5541        return function() {
5542          if (!ABORT) return func.apply(null, arguments);
5543        };
5544      },safeRequestAnimationFrame:function (func) {
5545        return Browser.requestAnimationFrame(function() {
5546          if (!ABORT) func();
5547        });
5548      },safeSetTimeout:function (func, timeout) {
5549        return setTimeout(function() {
5550          if (!ABORT) func();
5551        }, timeout);
5552      },safeSetInterval:function (func, timeout) {
5553        return setInterval(function() {
5554          if (!ABORT) func();
5555        }, timeout);
5556      },getMimetype:function (name) {
5557        return {
5558          'jpg': 'image/jpeg',
5559          'jpeg': 'image/jpeg',
5560          'png': 'image/png',
5561          'bmp': 'image/bmp',
5562          'ogg': 'audio/ogg',
5563          'wav': 'audio/wav',
5564          'mp3': 'audio/mpeg'
5565        }[name.substr(name.lastIndexOf('.')+1)];
5566      },getUserMedia:function (func) {
5567        if(!window.getUserMedia) {
5568          window.getUserMedia = navigator['getUserMedia'] ||
5569                                navigator['mozGetUserMedia'];
5570        }
5571        window.getUserMedia(func);
5572      },getMovementX:function (event) {
5573        return event['movementX'] ||
5574               event['mozMovementX'] ||
5575               event['webkitMovementX'] ||
5576               0;
5577      },getMovementY:function (event) {
5578        return event['movementY'] ||
5579               event['mozMovementY'] ||
5580               event['webkitMovementY'] ||
5581               0;
5582      },getMouseWheelDelta:function (event) {
5583        return Math.max(-1, Math.min(1, event.type === 'DOMMouseScroll' ? event.detail : -event.wheelDelta));
5584      },mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,calculateMouseEvent:function (event) { // event should be mousemove, mousedown or mouseup
5585        if (Browser.pointerLock) {
5586          // When the pointer is locked, calculate the coordinates
5587          // based on the movement of the mouse.
5588          // Workaround for Firefox bug 764498
5589          if (event.type != 'mousemove' &&
5590              ('mozMovementX' in event)) {
5591            Browser.mouseMovementX = Browser.mouseMovementY = 0;
5592          } else {
5593            Browser.mouseMovementX = Browser.getMovementX(event);
5594            Browser.mouseMovementY = Browser.getMovementY(event);
5595          }
5596
5597          // check if SDL is available
5598          if (typeof SDL != "undefined") {
5599            Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
5600            Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;
5601          } else {
5602            // just add the mouse delta to the current absolut mouse position
5603            // FIXME: ideally this should be clamped against the canvas size and zero
5604            Browser.mouseX += Browser.mouseMovementX;
5605            Browser.mouseY += Browser.mouseMovementY;
5606          }
5607        } else {
5608          // Otherwise, calculate the movement based on the changes
5609          // in the coordinates.
5610          var rect = Module["canvas"].getBoundingClientRect();
5611          var x, y;
5612
5613          // Neither .scrollX or .pageXOffset are defined in a spec, but
5614          // we prefer .scrollX because it is currently in a spec draft.
5615          // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
5616          var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset);
5617          var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset);
5618          if (event.type == 'touchstart' ||
5619              event.type == 'touchend' ||
5620              event.type == 'touchmove') {
5621            var t = event.touches.item(0);
5622            if (t) {
5623              x = t.pageX - (scrollX + rect.left);
5624              y = t.pageY - (scrollY + rect.top);
5625            } else {
5626              return;
5627            }
5628          } else {
5629            x = event.pageX - (scrollX + rect.left);
5630            y = event.pageY - (scrollY + rect.top);
5631          }
5632
5633          // the canvas might be CSS-scaled compared to its backbuffer;
5634          // SDL-using content will want mouse coordinates in terms
5635          // of backbuffer units.
5636          var cw = Module["canvas"].width;
5637          var ch = Module["canvas"].height;
5638          x = x * (cw / rect.width);
5639          y = y * (ch / rect.height);
5640
5641          Browser.mouseMovementX = x - Browser.mouseX;
5642          Browser.mouseMovementY = y - Browser.mouseY;
5643          Browser.mouseX = x;
5644          Browser.mouseY = y;
5645        }
5646      },xhrLoad:function (url, onload, onerror) {
5647        var xhr = new XMLHttpRequest();
5648        xhr.open('GET', url, true);
5649        xhr.responseType = 'arraybuffer';
5650        xhr.onload = function xhr_onload() {
5651          if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
5652            onload(xhr.response);
5653          } else {
5654            onerror();
5655          }
5656        };
5657        xhr.onerror = onerror;
5658        xhr.send(null);
5659      },asyncLoad:function (url, onload, onerror, noRunDep) {
5660        Browser.xhrLoad(url, function(arrayBuffer) {
5661          assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
5662          onload(new Uint8Array(arrayBuffer));
5663          if (!noRunDep) removeRunDependency('al ' + url);
5664        }, function(event) {
5665          if (onerror) {
5666            onerror();
5667          } else {
5668            throw 'Loading data file "' + url + '" failed.';
5669          }
5670        });
5671        if (!noRunDep) addRunDependency('al ' + url);
5672      },resizeListeners:[],updateResizeListeners:function () {
5673        var canvas = Module['canvas'];
5674        Browser.resizeListeners.forEach(function(listener) {
5675          listener(canvas.width, canvas.height);
5676        });
5677      },setCanvasSize:function (width, height, noUpdates) {
5678        var canvas = Module['canvas'];
5679        Browser.updateCanvasDimensions(canvas, width, height);
5680        if (!noUpdates) Browser.updateResizeListeners();
5681      },windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:function () {
5682        // check if SDL is available
5683        if (typeof SDL != "undefined") {
5684          var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
5685          flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
5686          HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
5687        }
5688        Browser.updateResizeListeners();
5689      },setWindowedCanvasSize:function () {
5690        // check if SDL is available
5691        if (typeof SDL != "undefined") {
5692          var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
5693          flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
5694          HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
5695        }
5696        Browser.updateResizeListeners();
5697      },updateCanvasDimensions:function (canvas, wNative, hNative) {
5698        if (wNative && hNative) {
5699          canvas.widthNative = wNative;
5700          canvas.heightNative = hNative;
5701        } else {
5702          wNative = canvas.widthNative;
5703          hNative = canvas.heightNative;
5704        }
5705        var w = wNative;
5706        var h = hNative;
5707        if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
5708          if (w/h < Module['forcedAspectRatio']) {
5709            w = Math.round(h * Module['forcedAspectRatio']);
5710          } else {
5711            h = Math.round(w / Module['forcedAspectRatio']);
5712          }
5713        }
5714        if (((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
5715             document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
5716             document['fullScreenElement'] || document['fullscreenElement'] ||
5717             document['msFullScreenElement'] || document['msFullscreenElement'] ||
5718             document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
5719           var factor = Math.min(screen.width / w, screen.height / h);
5720           w = Math.round(w * factor);
5721           h = Math.round(h * factor);
5722        }
5723        if (Browser.resizeCanvas) {
5724          if (canvas.width  != w) canvas.width  = w;
5725          if (canvas.height != h) canvas.height = h;
5726          if (typeof canvas.style != 'undefined') {
5727            canvas.style.removeProperty( "width");
5728            canvas.style.removeProperty("height");
5729          }
5730        } else {
5731          if (canvas.width  != wNative) canvas.width  = wNative;
5732          if (canvas.height != hNative) canvas.height = hNative;
5733          if (typeof canvas.style != 'undefined') {
5734            if (w != wNative || h != hNative) {
5735              canvas.style.setProperty( "width", w + "px", "important");
5736              canvas.style.setProperty("height", h + "px", "important");
5737            } else {
5738              canvas.style.removeProperty( "width");
5739              canvas.style.removeProperty("height");
5740            }
5741          }
5742        }
5743      }};
5744
5745  function _time(ptr) {
5746      var ret = Math.floor(Date.now()/1000);
5747      if (ptr) {
5748        HEAP32[((ptr)>>2)]=ret;
5749      }
5750      return ret;
5751    }
5752
5753
5754  function _malloc(bytes) {
5755      /* Over-allocate to make sure it is byte-aligned by 8.
5756       * This will leak memory, but this is only the dummy
5757       * implementation (replaced by dlmalloc normally) so
5758       * not an issue.
5759       */
5760      var ptr = Runtime.dynamicAlloc(bytes + 8);
5761      return (ptr+8) & 0xFFFFFFF8;
5762    }
5763  Module["_malloc"] = _malloc;function ___cxa_allocate_exception(size) {
5764      var ptr = _malloc(size + ___cxa_exception_header_size);
5765      return ptr + ___cxa_exception_header_size;
5766    }
5767
5768  var __ZTISt9exception=allocate([allocate([1,0,0,0,0,0,0], "i8", ALLOC_STATIC)+8, 0], "i32", ALLOC_STATIC);
5769
5770  function __ZTVN10__cxxabiv120__si_class_type_infoE() {
5771  Module['printErr']('missing function: _ZTVN10__cxxabiv120__si_class_type_infoE'); abort(-1);
5772  }
5773___errno_state = Runtime.staticAlloc(4); HEAP32[((___errno_state)>>2)]=0;
5774FS.staticInit();__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });__ATEXIT__.push({ func: function() { FS.quit() } });Module["FS_createFolder"] = FS.createFolder;Module["FS_createPath"] = FS.createPath;Module["FS_createDataFile"] = FS.createDataFile;Module["FS_createPreloadedFile"] = FS.createPreloadedFile;Module["FS_createLazyFile"] = FS.createLazyFile;Module["FS_createLink"] = FS.createLink;Module["FS_createDevice"] = FS.createDevice;
5775__ATINIT__.unshift({ func: function() { TTY.init() } });__ATEXIT__.push({ func: function() { TTY.shutdown() } });TTY.utf8 = new Runtime.UTF8Processor();
5776if (ENVIRONMENT_IS_NODE) { var fs = require("fs"); NODEFS.staticInit(); }
5777__ATINIT__.push({ func: function() { SOCKFS.root = FS.mount(SOCKFS, {}, null); } });
5778_fputc.ret = allocate([0], "i8", ALLOC_STATIC);
5779Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) };
5780  Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };
5781  Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };
5782  Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };
5783  Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() };
5784  Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }
5785STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP);
5786
5787staticSealed = true; // seal the static portion of memory
5788
5789STACK_MAX = STACK_BASE + 5242880;
5790
5791DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);
5792
5793assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack");
5794
5795
5796var Math_min = Math.min;
5797function invoke_ii(index,a1) {
5798  try {
5799    return Module["dynCall_ii"](index,a1);
5800  } catch(e) {
5801    if (typeof e !== 'number' && e !== 'longjmp') throw e;
5802    asm["setThrew"](1, 0);
5803  }
5804}
5805
5806function invoke_vi(index,a1) {
5807  try {
5808    Module["dynCall_vi"](index,a1);
5809  } catch(e) {
5810    if (typeof e !== 'number' && e !== 'longjmp') throw e;
5811    asm["setThrew"](1, 0);
5812  }
5813}
5814
5815function invoke_v(index) {
5816  try {
5817    Module["dynCall_v"](index);
5818  } catch(e) {
5819    if (typeof e !== 'number' && e !== 'longjmp') throw e;
5820    asm["setThrew"](1, 0);
5821  }
5822}
5823
5824function asmPrintInt(x, y) {
5825  Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack);
5826}
5827function asmPrintFloat(x, y) {
5828  Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack);
5829}
5830// EMSCRIPTEN_START_ASM
5831var asm = Wasm.instantiateModuleFromAsm((function Module(global, env, buffer) {
5832  'use asm';
5833  var HEAP8 = new global.Int8Array(buffer);
5834  var HEAP16 = new global.Int16Array(buffer);
5835  var HEAP32 = new global.Int32Array(buffer);
5836  var HEAPU8 = new global.Uint8Array(buffer);
5837  var HEAPU16 = new global.Uint16Array(buffer);
5838  var HEAPU32 = new global.Uint32Array(buffer);
5839  var HEAPF32 = new global.Float32Array(buffer);
5840  var HEAPF64 = new global.Float64Array(buffer);
5841
5842  var STACKTOP=env.STACKTOP|0;
5843  var STACK_MAX=env.STACK_MAX|0;
5844  var tempDoublePtr=env.tempDoublePtr|0;
5845  var ABORT=env.ABORT|0;
5846  var __ZTISt9exception=env.__ZTISt9exception|0;
5847  var __ZTVN10__cxxabiv120__si_class_type_infoE=env.__ZTVN10__cxxabiv120__si_class_type_infoE|0;
5848
5849  var __THREW__ = 0;
5850  var threwValue = 0;
5851  var setjmpId = 0;
5852  var undef = 0;
5853  var nan = +env.NaN, inf = +env.Infinity;
5854  var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
5855
5856  var tempRet0 = 0;
5857  var tempRet1 = 0;
5858  var tempRet2 = 0;
5859  var tempRet3 = 0;
5860  var tempRet4 = 0;
5861  var tempRet5 = 0;
5862  var tempRet6 = 0;
5863  var tempRet7 = 0;
5864  var tempRet8 = 0;
5865  var tempRet9 = 0;
5866  var Math_floor=global.Math.floor;
5867  var Math_abs=global.Math.abs;
5868  var Math_sqrt=global.Math.sqrt;
5869  var Math_pow=global.Math.pow;
5870  var Math_cos=global.Math.cos;
5871  var Math_sin=global.Math.sin;
5872  var Math_tan=global.Math.tan;
5873  var Math_acos=global.Math.acos;
5874  var Math_asin=global.Math.asin;
5875  var Math_atan=global.Math.atan;
5876  var Math_atan2=global.Math.atan2;
5877  var Math_exp=global.Math.exp;
5878  var Math_log=global.Math.log;
5879  var Math_ceil=global.Math.ceil;
5880  var Math_imul=global.Math.imul;
5881  var abort=env.abort;
5882  var assert=env.assert;
5883  var asmPrintInt=env.asmPrintInt;
5884  var asmPrintFloat=env.asmPrintFloat;
5885  var Math_min=env.min;
5886  var invoke_ii=env.invoke_ii;
5887  var invoke_vi=env.invoke_vi;
5888  var invoke_v=env.invoke_v;
5889  var _send=env._send;
5890  var ___setErrNo=env.___setErrNo;
5891  var ___cxa_is_number_type=env.___cxa_is_number_type;
5892  var ___cxa_allocate_exception=env.___cxa_allocate_exception;
5893  var ___cxa_find_matching_catch=env.___cxa_find_matching_catch;
5894  var _fflush=env._fflush;
5895  var _time=env._time;
5896  var _pwrite=env._pwrite;
5897  var __reallyNegative=env.__reallyNegative;
5898  var _sbrk=env._sbrk;
5899  var _emscripten_memcpy_big=env._emscripten_memcpy_big;
5900  var _fileno=env._fileno;
5901  var ___resumeException=env.___resumeException;
5902  var __ZSt18uncaught_exceptionv=env.__ZSt18uncaught_exceptionv;
5903  var _sysconf=env._sysconf;
5904  var _puts=env._puts;
5905  var _mkport=env._mkport;
5906  var _write=env._write;
5907  var ___errno_location=env.___errno_location;
5908  var __ZNSt9exceptionD2Ev=env.__ZNSt9exceptionD2Ev;
5909  var _fputc=env._fputc;
5910  var ___cxa_throw=env.___cxa_throw;
5911  var _abort=env._abort;
5912  var _fwrite=env._fwrite;
5913  var ___cxa_does_inherit=env.___cxa_does_inherit;
5914  var _fprintf=env._fprintf;
5915  var __formatString=env.__formatString;
5916  var _fputs=env._fputs;
5917  var _printf=env._printf;
5918  var tempFloat = 0.0;
5919
5920// EMSCRIPTEN_START_FUNCS
5921function _malloc(i12) {
5922 i12 = i12 | 0;
5923 var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0;
5924 i1 = STACKTOP;
5925 do {
5926  if (i12 >>> 0 < 245) {
5927   if (i12 >>> 0 < 11) {
5928    i12 = 16;
5929   } else {
5930    i12 = i12 + 11 & -8;
5931   }
5932   i20 = i12 >>> 3;
5933   i18 = HEAP32[146] | 0;
5934   i21 = i18 >>> i20;
5935   if ((i21 & 3 | 0) != 0) {
5936    i6 = (i21 & 1 ^ 1) + i20 | 0;
5937    i5 = i6 << 1;
5938    i3 = 624 + (i5 << 2) | 0;
5939    i5 = 624 + (i5 + 2 << 2) | 0;
5940    i7 = HEAP32[i5 >> 2] | 0;
5941    i2 = i7 + 8 | 0;
5942    i4 = HEAP32[i2 >> 2] | 0;
5943    do {
5944     if ((i3 | 0) != (i4 | 0)) {
5945      if (i4 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
5946       _abort();
5947      }
5948      i8 = i4 + 12 | 0;
5949      if ((HEAP32[i8 >> 2] | 0) == (i7 | 0)) {
5950       HEAP32[i8 >> 2] = i3;
5951       HEAP32[i5 >> 2] = i4;
5952       break;
5953      } else {
5954       _abort();
5955      }
5956     } else {
5957      HEAP32[146] = i18 & ~(1 << i6);
5958     }
5959    } while (0);
5960    i32 = i6 << 3;
5961    HEAP32[i7 + 4 >> 2] = i32 | 3;
5962    i32 = i7 + (i32 | 4) | 0;
5963    HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
5964    i32 = i2;
5965    STACKTOP = i1;
5966    return i32 | 0;
5967   }
5968   if (i12 >>> 0 > (HEAP32[592 >> 2] | 0) >>> 0) {
5969    if ((i21 | 0) != 0) {
5970     i7 = 2 << i20;
5971     i7 = i21 << i20 & (i7 | 0 - i7);
5972     i7 = (i7 & 0 - i7) + -1 | 0;
5973     i2 = i7 >>> 12 & 16;
5974     i7 = i7 >>> i2;
5975     i6 = i7 >>> 5 & 8;
5976     i7 = i7 >>> i6;
5977     i5 = i7 >>> 2 & 4;
5978     i7 = i7 >>> i5;
5979     i4 = i7 >>> 1 & 2;
5980     i7 = i7 >>> i4;
5981     i3 = i7 >>> 1 & 1;
5982     i3 = (i6 | i2 | i5 | i4 | i3) + (i7 >>> i3) | 0;
5983     i7 = i3 << 1;
5984     i4 = 624 + (i7 << 2) | 0;
5985     i7 = 624 + (i7 + 2 << 2) | 0;
5986     i5 = HEAP32[i7 >> 2] | 0;
5987     i2 = i5 + 8 | 0;
5988     i6 = HEAP32[i2 >> 2] | 0;
5989     do {
5990      if ((i4 | 0) != (i6 | 0)) {
5991       if (i6 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
5992        _abort();
5993       }
5994       i8 = i6 + 12 | 0;
5995       if ((HEAP32[i8 >> 2] | 0) == (i5 | 0)) {
5996        HEAP32[i8 >> 2] = i4;
5997        HEAP32[i7 >> 2] = i6;
5998        break;
5999       } else {
6000        _abort();
6001       }
6002      } else {
6003       HEAP32[146] = i18 & ~(1 << i3);
6004      }
6005     } while (0);
6006     i6 = i3 << 3;
6007     i4 = i6 - i12 | 0;
6008     HEAP32[i5 + 4 >> 2] = i12 | 3;
6009     i3 = i5 + i12 | 0;
6010     HEAP32[i5 + (i12 | 4) >> 2] = i4 | 1;
6011     HEAP32[i5 + i6 >> 2] = i4;
6012     i6 = HEAP32[592 >> 2] | 0;
6013     if ((i6 | 0) != 0) {
6014      i5 = HEAP32[604 >> 2] | 0;
6015      i8 = i6 >>> 3;
6016      i9 = i8 << 1;
6017      i6 = 624 + (i9 << 2) | 0;
6018      i7 = HEAP32[146] | 0;
6019      i8 = 1 << i8;
6020      if ((i7 & i8 | 0) != 0) {
6021       i7 = 624 + (i9 + 2 << 2) | 0;
6022       i8 = HEAP32[i7 >> 2] | 0;
6023       if (i8 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6024        _abort();
6025       } else {
6026        i28 = i7;
6027        i27 = i8;
6028       }
6029      } else {
6030       HEAP32[146] = i7 | i8;
6031       i28 = 624 + (i9 + 2 << 2) | 0;
6032       i27 = i6;
6033      }
6034      HEAP32[i28 >> 2] = i5;
6035      HEAP32[i27 + 12 >> 2] = i5;
6036      HEAP32[i5 + 8 >> 2] = i27;
6037      HEAP32[i5 + 12 >> 2] = i6;
6038     }
6039     HEAP32[592 >> 2] = i4;
6040     HEAP32[604 >> 2] = i3;
6041     i32 = i2;
6042     STACKTOP = i1;
6043     return i32 | 0;
6044    }
6045    i18 = HEAP32[588 >> 2] | 0;
6046    if ((i18 | 0) != 0) {
6047     i2 = (i18 & 0 - i18) + -1 | 0;
6048     i31 = i2 >>> 12 & 16;
6049     i2 = i2 >>> i31;
6050     i30 = i2 >>> 5 & 8;
6051     i2 = i2 >>> i30;
6052     i32 = i2 >>> 2 & 4;
6053     i2 = i2 >>> i32;
6054     i6 = i2 >>> 1 & 2;
6055     i2 = i2 >>> i6;
6056     i3 = i2 >>> 1 & 1;
6057     i3 = HEAP32[888 + ((i30 | i31 | i32 | i6 | i3) + (i2 >>> i3) << 2) >> 2] | 0;
6058     i2 = (HEAP32[i3 + 4 >> 2] & -8) - i12 | 0;
6059     i6 = i3;
6060     while (1) {
6061      i5 = HEAP32[i6 + 16 >> 2] | 0;
6062      if ((i5 | 0) == 0) {
6063       i5 = HEAP32[i6 + 20 >> 2] | 0;
6064       if ((i5 | 0) == 0) {
6065        break;
6066       }
6067      }
6068      i6 = (HEAP32[i5 + 4 >> 2] & -8) - i12 | 0;
6069      i4 = i6 >>> 0 < i2 >>> 0;
6070      i2 = i4 ? i6 : i2;
6071      i6 = i5;
6072      i3 = i4 ? i5 : i3;
6073     }
6074     i6 = HEAP32[600 >> 2] | 0;
6075     if (i3 >>> 0 < i6 >>> 0) {
6076      _abort();
6077     }
6078     i4 = i3 + i12 | 0;
6079     if (!(i3 >>> 0 < i4 >>> 0)) {
6080      _abort();
6081     }
6082     i5 = HEAP32[i3 + 24 >> 2] | 0;
6083     i7 = HEAP32[i3 + 12 >> 2] | 0;
6084     do {
6085      if ((i7 | 0) == (i3 | 0)) {
6086       i8 = i3 + 20 | 0;
6087       i7 = HEAP32[i8 >> 2] | 0;
6088       if ((i7 | 0) == 0) {
6089        i8 = i3 + 16 | 0;
6090        i7 = HEAP32[i8 >> 2] | 0;
6091        if ((i7 | 0) == 0) {
6092         i26 = 0;
6093         break;
6094        }
6095       }
6096       while (1) {
6097        i10 = i7 + 20 | 0;
6098        i9 = HEAP32[i10 >> 2] | 0;
6099        if ((i9 | 0) != 0) {
6100         i7 = i9;
6101         i8 = i10;
6102         continue;
6103        }
6104        i10 = i7 + 16 | 0;
6105        i9 = HEAP32[i10 >> 2] | 0;
6106        if ((i9 | 0) == 0) {
6107         break;
6108        } else {
6109         i7 = i9;
6110         i8 = i10;
6111        }
6112       }
6113       if (i8 >>> 0 < i6 >>> 0) {
6114        _abort();
6115       } else {
6116        HEAP32[i8 >> 2] = 0;
6117        i26 = i7;
6118        break;
6119       }
6120      } else {
6121       i8 = HEAP32[i3 + 8 >> 2] | 0;
6122       if (i8 >>> 0 < i6 >>> 0) {
6123        _abort();
6124       }
6125       i6 = i8 + 12 | 0;
6126       if ((HEAP32[i6 >> 2] | 0) != (i3 | 0)) {
6127        _abort();
6128       }
6129       i9 = i7 + 8 | 0;
6130       if ((HEAP32[i9 >> 2] | 0) == (i3 | 0)) {
6131        HEAP32[i6 >> 2] = i7;
6132        HEAP32[i9 >> 2] = i8;
6133        i26 = i7;
6134        break;
6135       } else {
6136        _abort();
6137       }
6138      }
6139     } while (0);
6140     do {
6141      if ((i5 | 0) != 0) {
6142       i7 = HEAP32[i3 + 28 >> 2] | 0;
6143       i6 = 888 + (i7 << 2) | 0;
6144       if ((i3 | 0) == (HEAP32[i6 >> 2] | 0)) {
6145        HEAP32[i6 >> 2] = i26;
6146        if ((i26 | 0) == 0) {
6147         HEAP32[588 >> 2] = HEAP32[588 >> 2] & ~(1 << i7);
6148         break;
6149        }
6150       } else {
6151        if (i5 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6152         _abort();
6153        }
6154        i6 = i5 + 16 | 0;
6155        if ((HEAP32[i6 >> 2] | 0) == (i3 | 0)) {
6156         HEAP32[i6 >> 2] = i26;
6157        } else {
6158         HEAP32[i5 + 20 >> 2] = i26;
6159        }
6160        if ((i26 | 0) == 0) {
6161         break;
6162        }
6163       }
6164       if (i26 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6165        _abort();
6166       }
6167       HEAP32[i26 + 24 >> 2] = i5;
6168       i5 = HEAP32[i3 + 16 >> 2] | 0;
6169       do {
6170        if ((i5 | 0) != 0) {
6171         if (i5 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6172          _abort();
6173         } else {
6174          HEAP32[i26 + 16 >> 2] = i5;
6175          HEAP32[i5 + 24 >> 2] = i26;
6176          break;
6177         }
6178        }
6179       } while (0);
6180       i5 = HEAP32[i3 + 20 >> 2] | 0;
6181       if ((i5 | 0) != 0) {
6182        if (i5 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6183         _abort();
6184        } else {
6185         HEAP32[i26 + 20 >> 2] = i5;
6186         HEAP32[i5 + 24 >> 2] = i26;
6187         break;
6188        }
6189       }
6190      }
6191     } while (0);
6192     if (i2 >>> 0 < 16) {
6193      i32 = i2 + i12 | 0;
6194      HEAP32[i3 + 4 >> 2] = i32 | 3;
6195      i32 = i3 + (i32 + 4) | 0;
6196      HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
6197     } else {
6198      HEAP32[i3 + 4 >> 2] = i12 | 3;
6199      HEAP32[i3 + (i12 | 4) >> 2] = i2 | 1;
6200      HEAP32[i3 + (i2 + i12) >> 2] = i2;
6201      i6 = HEAP32[592 >> 2] | 0;
6202      if ((i6 | 0) != 0) {
6203       i5 = HEAP32[604 >> 2] | 0;
6204       i8 = i6 >>> 3;
6205       i9 = i8 << 1;
6206       i6 = 624 + (i9 << 2) | 0;
6207       i7 = HEAP32[146] | 0;
6208       i8 = 1 << i8;
6209       if ((i7 & i8 | 0) != 0) {
6210        i7 = 624 + (i9 + 2 << 2) | 0;
6211        i8 = HEAP32[i7 >> 2] | 0;
6212        if (i8 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6213         _abort();
6214        } else {
6215         i25 = i7;
6216         i24 = i8;
6217        }
6218       } else {
6219        HEAP32[146] = i7 | i8;
6220        i25 = 624 + (i9 + 2 << 2) | 0;
6221        i24 = i6;
6222       }
6223       HEAP32[i25 >> 2] = i5;
6224       HEAP32[i24 + 12 >> 2] = i5;
6225       HEAP32[i5 + 8 >> 2] = i24;
6226       HEAP32[i5 + 12 >> 2] = i6;
6227      }
6228      HEAP32[592 >> 2] = i2;
6229      HEAP32[604 >> 2] = i4;
6230     }
6231     i32 = i3 + 8 | 0;
6232     STACKTOP = i1;
6233     return i32 | 0;
6234    }
6235   }
6236  } else {
6237   if (!(i12 >>> 0 > 4294967231)) {
6238    i24 = i12 + 11 | 0;
6239    i12 = i24 & -8;
6240    i26 = HEAP32[588 >> 2] | 0;
6241    if ((i26 | 0) != 0) {
6242     i25 = 0 - i12 | 0;
6243     i24 = i24 >>> 8;
6244     if ((i24 | 0) != 0) {
6245      if (i12 >>> 0 > 16777215) {
6246       i27 = 31;
6247      } else {
6248       i31 = (i24 + 1048320 | 0) >>> 16 & 8;
6249       i32 = i24 << i31;
6250       i30 = (i32 + 520192 | 0) >>> 16 & 4;
6251       i32 = i32 << i30;
6252       i27 = (i32 + 245760 | 0) >>> 16 & 2;
6253       i27 = 14 - (i30 | i31 | i27) + (i32 << i27 >>> 15) | 0;
6254       i27 = i12 >>> (i27 + 7 | 0) & 1 | i27 << 1;
6255      }
6256     } else {
6257      i27 = 0;
6258     }
6259     i30 = HEAP32[888 + (i27 << 2) >> 2] | 0;
6260     L126 : do {
6261      if ((i30 | 0) == 0) {
6262       i29 = 0;
6263       i24 = 0;
6264      } else {
6265       if ((i27 | 0) == 31) {
6266        i24 = 0;
6267       } else {
6268        i24 = 25 - (i27 >>> 1) | 0;
6269       }
6270       i29 = 0;
6271       i28 = i12 << i24;
6272       i24 = 0;
6273       while (1) {
6274        i32 = HEAP32[i30 + 4 >> 2] & -8;
6275        i31 = i32 - i12 | 0;
6276        if (i31 >>> 0 < i25 >>> 0) {
6277         if ((i32 | 0) == (i12 | 0)) {
6278          i25 = i31;
6279          i29 = i30;
6280          i24 = i30;
6281          break L126;
6282         } else {
6283          i25 = i31;
6284          i24 = i30;
6285         }
6286        }
6287        i31 = HEAP32[i30 + 20 >> 2] | 0;
6288        i30 = HEAP32[i30 + (i28 >>> 31 << 2) + 16 >> 2] | 0;
6289        i29 = (i31 | 0) == 0 | (i31 | 0) == (i30 | 0) ? i29 : i31;
6290        if ((i30 | 0) == 0) {
6291         break;
6292        } else {
6293         i28 = i28 << 1;
6294        }
6295       }
6296      }
6297     } while (0);
6298     if ((i29 | 0) == 0 & (i24 | 0) == 0) {
6299      i32 = 2 << i27;
6300      i26 = i26 & (i32 | 0 - i32);
6301      if ((i26 | 0) == 0) {
6302       break;
6303      }
6304      i32 = (i26 & 0 - i26) + -1 | 0;
6305      i28 = i32 >>> 12 & 16;
6306      i32 = i32 >>> i28;
6307      i27 = i32 >>> 5 & 8;
6308      i32 = i32 >>> i27;
6309      i30 = i32 >>> 2 & 4;
6310      i32 = i32 >>> i30;
6311      i31 = i32 >>> 1 & 2;
6312      i32 = i32 >>> i31;
6313      i29 = i32 >>> 1 & 1;
6314      i29 = HEAP32[888 + ((i27 | i28 | i30 | i31 | i29) + (i32 >>> i29) << 2) >> 2] | 0;
6315     }
6316     if ((i29 | 0) != 0) {
6317      while (1) {
6318       i27 = (HEAP32[i29 + 4 >> 2] & -8) - i12 | 0;
6319       i26 = i27 >>> 0 < i25 >>> 0;
6320       i25 = i26 ? i27 : i25;
6321       i24 = i26 ? i29 : i24;
6322       i26 = HEAP32[i29 + 16 >> 2] | 0;
6323       if ((i26 | 0) != 0) {
6324        i29 = i26;
6325        continue;
6326       }
6327       i29 = HEAP32[i29 + 20 >> 2] | 0;
6328       if ((i29 | 0) == 0) {
6329        break;
6330       }
6331      }
6332     }
6333     if ((i24 | 0) != 0 ? i25 >>> 0 < ((HEAP32[592 >> 2] | 0) - i12 | 0) >>> 0 : 0) {
6334      i4 = HEAP32[600 >> 2] | 0;
6335      if (i24 >>> 0 < i4 >>> 0) {
6336       _abort();
6337      }
6338      i2 = i24 + i12 | 0;
6339      if (!(i24 >>> 0 < i2 >>> 0)) {
6340       _abort();
6341      }
6342      i3 = HEAP32[i24 + 24 >> 2] | 0;
6343      i6 = HEAP32[i24 + 12 >> 2] | 0;
6344      do {
6345       if ((i6 | 0) == (i24 | 0)) {
6346        i6 = i24 + 20 | 0;
6347        i5 = HEAP32[i6 >> 2] | 0;
6348        if ((i5 | 0) == 0) {
6349         i6 = i24 + 16 | 0;
6350         i5 = HEAP32[i6 >> 2] | 0;
6351         if ((i5 | 0) == 0) {
6352          i22 = 0;
6353          break;
6354         }
6355        }
6356        while (1) {
6357         i8 = i5 + 20 | 0;
6358         i7 = HEAP32[i8 >> 2] | 0;
6359         if ((i7 | 0) != 0) {
6360          i5 = i7;
6361          i6 = i8;
6362          continue;
6363         }
6364         i7 = i5 + 16 | 0;
6365         i8 = HEAP32[i7 >> 2] | 0;
6366         if ((i8 | 0) == 0) {
6367          break;
6368         } else {
6369          i5 = i8;
6370          i6 = i7;
6371         }
6372        }
6373        if (i6 >>> 0 < i4 >>> 0) {
6374         _abort();
6375        } else {
6376         HEAP32[i6 >> 2] = 0;
6377         i22 = i5;
6378         break;
6379        }
6380       } else {
6381        i5 = HEAP32[i24 + 8 >> 2] | 0;
6382        if (i5 >>> 0 < i4 >>> 0) {
6383         _abort();
6384        }
6385        i7 = i5 + 12 | 0;
6386        if ((HEAP32[i7 >> 2] | 0) != (i24 | 0)) {
6387         _abort();
6388        }
6389        i4 = i6 + 8 | 0;
6390        if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
6391         HEAP32[i7 >> 2] = i6;
6392         HEAP32[i4 >> 2] = i5;
6393         i22 = i6;
6394         break;
6395        } else {
6396         _abort();
6397        }
6398       }
6399      } while (0);
6400      do {
6401       if ((i3 | 0) != 0) {
6402        i4 = HEAP32[i24 + 28 >> 2] | 0;
6403        i5 = 888 + (i4 << 2) | 0;
6404        if ((i24 | 0) == (HEAP32[i5 >> 2] | 0)) {
6405         HEAP32[i5 >> 2] = i22;
6406         if ((i22 | 0) == 0) {
6407          HEAP32[588 >> 2] = HEAP32[588 >> 2] & ~(1 << i4);
6408          break;
6409         }
6410        } else {
6411         if (i3 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6412          _abort();
6413         }
6414         i4 = i3 + 16 | 0;
6415         if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
6416          HEAP32[i4 >> 2] = i22;
6417         } else {
6418          HEAP32[i3 + 20 >> 2] = i22;
6419         }
6420         if ((i22 | 0) == 0) {
6421          break;
6422         }
6423        }
6424        if (i22 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6425         _abort();
6426        }
6427        HEAP32[i22 + 24 >> 2] = i3;
6428        i3 = HEAP32[i24 + 16 >> 2] | 0;
6429        do {
6430         if ((i3 | 0) != 0) {
6431          if (i3 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6432           _abort();
6433          } else {
6434           HEAP32[i22 + 16 >> 2] = i3;
6435           HEAP32[i3 + 24 >> 2] = i22;
6436           break;
6437          }
6438         }
6439        } while (0);
6440        i3 = HEAP32[i24 + 20 >> 2] | 0;
6441        if ((i3 | 0) != 0) {
6442         if (i3 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6443          _abort();
6444         } else {
6445          HEAP32[i22 + 20 >> 2] = i3;
6446          HEAP32[i3 + 24 >> 2] = i22;
6447          break;
6448         }
6449        }
6450       }
6451      } while (0);
6452      L204 : do {
6453       if (!(i25 >>> 0 < 16)) {
6454        HEAP32[i24 + 4 >> 2] = i12 | 3;
6455        HEAP32[i24 + (i12 | 4) >> 2] = i25 | 1;
6456        HEAP32[i24 + (i25 + i12) >> 2] = i25;
6457        i4 = i25 >>> 3;
6458        if (i25 >>> 0 < 256) {
6459         i6 = i4 << 1;
6460         i3 = 624 + (i6 << 2) | 0;
6461         i5 = HEAP32[146] | 0;
6462         i4 = 1 << i4;
6463         if ((i5 & i4 | 0) != 0) {
6464          i5 = 624 + (i6 + 2 << 2) | 0;
6465          i4 = HEAP32[i5 >> 2] | 0;
6466          if (i4 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6467           _abort();
6468          } else {
6469           i21 = i5;
6470           i20 = i4;
6471          }
6472         } else {
6473          HEAP32[146] = i5 | i4;
6474          i21 = 624 + (i6 + 2 << 2) | 0;
6475          i20 = i3;
6476         }
6477         HEAP32[i21 >> 2] = i2;
6478         HEAP32[i20 + 12 >> 2] = i2;
6479         HEAP32[i24 + (i12 + 8) >> 2] = i20;
6480         HEAP32[i24 + (i12 + 12) >> 2] = i3;
6481         break;
6482        }
6483        i3 = i25 >>> 8;
6484        if ((i3 | 0) != 0) {
6485         if (i25 >>> 0 > 16777215) {
6486          i3 = 31;
6487         } else {
6488          i31 = (i3 + 1048320 | 0) >>> 16 & 8;
6489          i32 = i3 << i31;
6490          i30 = (i32 + 520192 | 0) >>> 16 & 4;
6491          i32 = i32 << i30;
6492          i3 = (i32 + 245760 | 0) >>> 16 & 2;
6493          i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
6494          i3 = i25 >>> (i3 + 7 | 0) & 1 | i3 << 1;
6495         }
6496        } else {
6497         i3 = 0;
6498        }
6499        i6 = 888 + (i3 << 2) | 0;
6500        HEAP32[i24 + (i12 + 28) >> 2] = i3;
6501        HEAP32[i24 + (i12 + 20) >> 2] = 0;
6502        HEAP32[i24 + (i12 + 16) >> 2] = 0;
6503        i4 = HEAP32[588 >> 2] | 0;
6504        i5 = 1 << i3;
6505        if ((i4 & i5 | 0) == 0) {
6506         HEAP32[588 >> 2] = i4 | i5;
6507         HEAP32[i6 >> 2] = i2;
6508         HEAP32[i24 + (i12 + 24) >> 2] = i6;
6509         HEAP32[i24 + (i12 + 12) >> 2] = i2;
6510         HEAP32[i24 + (i12 + 8) >> 2] = i2;
6511         break;
6512        }
6513        i4 = HEAP32[i6 >> 2] | 0;
6514        if ((i3 | 0) == 31) {
6515         i3 = 0;
6516        } else {
6517         i3 = 25 - (i3 >>> 1) | 0;
6518        }
6519        L225 : do {
6520         if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i25 | 0)) {
6521          i3 = i25 << i3;
6522          while (1) {
6523           i6 = i4 + (i3 >>> 31 << 2) + 16 | 0;
6524           i5 = HEAP32[i6 >> 2] | 0;
6525           if ((i5 | 0) == 0) {
6526            break;
6527           }
6528           if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i25 | 0)) {
6529            i18 = i5;
6530            break L225;
6531           } else {
6532            i3 = i3 << 1;
6533            i4 = i5;
6534           }
6535          }
6536          if (i6 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6537           _abort();
6538          } else {
6539           HEAP32[i6 >> 2] = i2;
6540           HEAP32[i24 + (i12 + 24) >> 2] = i4;
6541           HEAP32[i24 + (i12 + 12) >> 2] = i2;
6542           HEAP32[i24 + (i12 + 8) >> 2] = i2;
6543           break L204;
6544          }
6545         } else {
6546          i18 = i4;
6547         }
6548        } while (0);
6549        i4 = i18 + 8 | 0;
6550        i3 = HEAP32[i4 >> 2] | 0;
6551        i5 = HEAP32[600 >> 2] | 0;
6552        if (i18 >>> 0 < i5 >>> 0) {
6553         _abort();
6554        }
6555        if (i3 >>> 0 < i5 >>> 0) {
6556         _abort();
6557        } else {
6558         HEAP32[i3 + 12 >> 2] = i2;
6559         HEAP32[i4 >> 2] = i2;
6560         HEAP32[i24 + (i12 + 8) >> 2] = i3;
6561         HEAP32[i24 + (i12 + 12) >> 2] = i18;
6562         HEAP32[i24 + (i12 + 24) >> 2] = 0;
6563         break;
6564        }
6565       } else {
6566        i32 = i25 + i12 | 0;
6567        HEAP32[i24 + 4 >> 2] = i32 | 3;
6568        i32 = i24 + (i32 + 4) | 0;
6569        HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
6570       }
6571      } while (0);
6572      i32 = i24 + 8 | 0;
6573      STACKTOP = i1;
6574      return i32 | 0;
6575     }
6576    }
6577   } else {
6578    i12 = -1;
6579   }
6580  }
6581 } while (0);
6582 i18 = HEAP32[592 >> 2] | 0;
6583 if (!(i12 >>> 0 > i18 >>> 0)) {
6584  i3 = i18 - i12 | 0;
6585  i2 = HEAP32[604 >> 2] | 0;
6586  if (i3 >>> 0 > 15) {
6587   HEAP32[604 >> 2] = i2 + i12;
6588   HEAP32[592 >> 2] = i3;
6589   HEAP32[i2 + (i12 + 4) >> 2] = i3 | 1;
6590   HEAP32[i2 + i18 >> 2] = i3;
6591   HEAP32[i2 + 4 >> 2] = i12 | 3;
6592  } else {
6593   HEAP32[592 >> 2] = 0;
6594   HEAP32[604 >> 2] = 0;
6595   HEAP32[i2 + 4 >> 2] = i18 | 3;
6596   i32 = i2 + (i18 + 4) | 0;
6597   HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
6598  }
6599  i32 = i2 + 8 | 0;
6600  STACKTOP = i1;
6601  return i32 | 0;
6602 }
6603 i18 = HEAP32[596 >> 2] | 0;
6604 if (i12 >>> 0 < i18 >>> 0) {
6605  i31 = i18 - i12 | 0;
6606  HEAP32[596 >> 2] = i31;
6607  i32 = HEAP32[608 >> 2] | 0;
6608  HEAP32[608 >> 2] = i32 + i12;
6609  HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
6610  HEAP32[i32 + 4 >> 2] = i12 | 3;
6611  i32 = i32 + 8 | 0;
6612  STACKTOP = i1;
6613  return i32 | 0;
6614 }
6615 do {
6616  if ((HEAP32[264] | 0) == 0) {
6617   i18 = _sysconf(30) | 0;
6618   if ((i18 + -1 & i18 | 0) == 0) {
6619    HEAP32[1064 >> 2] = i18;
6620    HEAP32[1060 >> 2] = i18;
6621    HEAP32[1068 >> 2] = -1;
6622    HEAP32[1072 >> 2] = -1;
6623    HEAP32[1076 >> 2] = 0;
6624    HEAP32[1028 >> 2] = 0;
6625    HEAP32[264] = (_time(0) | 0) & -16 ^ 1431655768;
6626    break;
6627   } else {
6628    _abort();
6629   }
6630  }
6631 } while (0);
6632 i20 = i12 + 48 | 0;
6633 i25 = HEAP32[1064 >> 2] | 0;
6634 i21 = i12 + 47 | 0;
6635 i22 = i25 + i21 | 0;
6636 i25 = 0 - i25 | 0;
6637 i18 = i22 & i25;
6638 if (!(i18 >>> 0 > i12 >>> 0)) {
6639  i32 = 0;
6640  STACKTOP = i1;
6641  return i32 | 0;
6642 }
6643 i24 = HEAP32[1024 >> 2] | 0;
6644 if ((i24 | 0) != 0 ? (i31 = HEAP32[1016 >> 2] | 0, i32 = i31 + i18 | 0, i32 >>> 0 <= i31 >>> 0 | i32 >>> 0 > i24 >>> 0) : 0) {
6645  i32 = 0;
6646  STACKTOP = i1;
6647  return i32 | 0;
6648 }
6649 L269 : do {
6650  if ((HEAP32[1028 >> 2] & 4 | 0) == 0) {
6651   i26 = HEAP32[608 >> 2] | 0;
6652   L271 : do {
6653    if ((i26 | 0) != 0) {
6654     i24 = 1032 | 0;
6655     while (1) {
6656      i27 = HEAP32[i24 >> 2] | 0;
6657      if (!(i27 >>> 0 > i26 >>> 0) ? (i23 = i24 + 4 | 0, (i27 + (HEAP32[i23 >> 2] | 0) | 0) >>> 0 > i26 >>> 0) : 0) {
6658       break;
6659      }
6660      i24 = HEAP32[i24 + 8 >> 2] | 0;
6661      if ((i24 | 0) == 0) {
6662       i13 = 182;
6663       break L271;
6664      }
6665     }
6666     if ((i24 | 0) != 0) {
6667      i25 = i22 - (HEAP32[596 >> 2] | 0) & i25;
6668      if (i25 >>> 0 < 2147483647) {
6669       i13 = _sbrk(i25 | 0) | 0;
6670       i26 = (i13 | 0) == ((HEAP32[i24 >> 2] | 0) + (HEAP32[i23 >> 2] | 0) | 0);
6671       i22 = i13;
6672       i24 = i25;
6673       i23 = i26 ? i13 : -1;
6674       i25 = i26 ? i25 : 0;
6675       i13 = 191;
6676      } else {
6677       i25 = 0;
6678      }
6679     } else {
6680      i13 = 182;
6681     }
6682    } else {
6683     i13 = 182;
6684    }
6685   } while (0);
6686   do {
6687    if ((i13 | 0) == 182) {
6688     i23 = _sbrk(0) | 0;
6689     if ((i23 | 0) != (-1 | 0)) {
6690      i24 = i23;
6691      i22 = HEAP32[1060 >> 2] | 0;
6692      i25 = i22 + -1 | 0;
6693      if ((i25 & i24 | 0) == 0) {
6694       i25 = i18;
6695      } else {
6696       i25 = i18 - i24 + (i25 + i24 & 0 - i22) | 0;
6697      }
6698      i24 = HEAP32[1016 >> 2] | 0;
6699      i26 = i24 + i25 | 0;
6700      if (i25 >>> 0 > i12 >>> 0 & i25 >>> 0 < 2147483647) {
6701       i22 = HEAP32[1024 >> 2] | 0;
6702       if ((i22 | 0) != 0 ? i26 >>> 0 <= i24 >>> 0 | i26 >>> 0 > i22 >>> 0 : 0) {
6703        i25 = 0;
6704        break;
6705       }
6706       i22 = _sbrk(i25 | 0) | 0;
6707       i13 = (i22 | 0) == (i23 | 0);
6708       i24 = i25;
6709       i23 = i13 ? i23 : -1;
6710       i25 = i13 ? i25 : 0;
6711       i13 = 191;
6712      } else {
6713       i25 = 0;
6714      }
6715     } else {
6716      i25 = 0;
6717     }
6718    }
6719   } while (0);
6720   L291 : do {
6721    if ((i13 | 0) == 191) {
6722     i13 = 0 - i24 | 0;
6723     if ((i23 | 0) != (-1 | 0)) {
6724      i17 = i23;
6725      i14 = i25;
6726      i13 = 202;
6727      break L269;
6728     }
6729     do {
6730      if ((i22 | 0) != (-1 | 0) & i24 >>> 0 < 2147483647 & i24 >>> 0 < i20 >>> 0 ? (i19 = HEAP32[1064 >> 2] | 0, i19 = i21 - i24 + i19 & 0 - i19, i19 >>> 0 < 2147483647) : 0) {
6731       if ((_sbrk(i19 | 0) | 0) == (-1 | 0)) {
6732        _sbrk(i13 | 0) | 0;
6733        break L291;
6734       } else {
6735        i24 = i19 + i24 | 0;
6736        break;
6737       }
6738      }
6739     } while (0);
6740     if ((i22 | 0) != (-1 | 0)) {
6741      i17 = i22;
6742      i14 = i24;
6743      i13 = 202;
6744      break L269;
6745     }
6746    }
6747   } while (0);
6748   HEAP32[1028 >> 2] = HEAP32[1028 >> 2] | 4;
6749   i13 = 199;
6750  } else {
6751   i25 = 0;
6752   i13 = 199;
6753  }
6754 } while (0);
6755 if ((((i13 | 0) == 199 ? i18 >>> 0 < 2147483647 : 0) ? (i17 = _sbrk(i18 | 0) | 0, i16 = _sbrk(0) | 0, (i16 | 0) != (-1 | 0) & (i17 | 0) != (-1 | 0) & i17 >>> 0 < i16 >>> 0) : 0) ? (i15 = i16 - i17 | 0, i14 = i15 >>> 0 > (i12 + 40 | 0) >>> 0, i14) : 0) {
6756  i14 = i14 ? i15 : i25;
6757  i13 = 202;
6758 }
6759 if ((i13 | 0) == 202) {
6760  i15 = (HEAP32[1016 >> 2] | 0) + i14 | 0;
6761  HEAP32[1016 >> 2] = i15;
6762  if (i15 >>> 0 > (HEAP32[1020 >> 2] | 0) >>> 0) {
6763   HEAP32[1020 >> 2] = i15;
6764  }
6765  i15 = HEAP32[608 >> 2] | 0;
6766  L311 : do {
6767   if ((i15 | 0) != 0) {
6768    i21 = 1032 | 0;
6769    while (1) {
6770     i16 = HEAP32[i21 >> 2] | 0;
6771     i19 = i21 + 4 | 0;
6772     i20 = HEAP32[i19 >> 2] | 0;
6773     if ((i17 | 0) == (i16 + i20 | 0)) {
6774      i13 = 214;
6775      break;
6776     }
6777     i18 = HEAP32[i21 + 8 >> 2] | 0;
6778     if ((i18 | 0) == 0) {
6779      break;
6780     } else {
6781      i21 = i18;
6782     }
6783    }
6784    if (((i13 | 0) == 214 ? (HEAP32[i21 + 12 >> 2] & 8 | 0) == 0 : 0) ? i15 >>> 0 >= i16 >>> 0 & i15 >>> 0 < i17 >>> 0 : 0) {
6785     HEAP32[i19 >> 2] = i20 + i14;
6786     i2 = (HEAP32[596 >> 2] | 0) + i14 | 0;
6787     i3 = i15 + 8 | 0;
6788     if ((i3 & 7 | 0) == 0) {
6789      i3 = 0;
6790     } else {
6791      i3 = 0 - i3 & 7;
6792     }
6793     i32 = i2 - i3 | 0;
6794     HEAP32[608 >> 2] = i15 + i3;
6795     HEAP32[596 >> 2] = i32;
6796     HEAP32[i15 + (i3 + 4) >> 2] = i32 | 1;
6797     HEAP32[i15 + (i2 + 4) >> 2] = 40;
6798     HEAP32[612 >> 2] = HEAP32[1072 >> 2];
6799     break;
6800    }
6801    if (i17 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6802     HEAP32[600 >> 2] = i17;
6803    }
6804    i19 = i17 + i14 | 0;
6805    i16 = 1032 | 0;
6806    while (1) {
6807     if ((HEAP32[i16 >> 2] | 0) == (i19 | 0)) {
6808      i13 = 224;
6809      break;
6810     }
6811     i18 = HEAP32[i16 + 8 >> 2] | 0;
6812     if ((i18 | 0) == 0) {
6813      break;
6814     } else {
6815      i16 = i18;
6816     }
6817    }
6818    if ((i13 | 0) == 224 ? (HEAP32[i16 + 12 >> 2] & 8 | 0) == 0 : 0) {
6819     HEAP32[i16 >> 2] = i17;
6820     i6 = i16 + 4 | 0;
6821     HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + i14;
6822     i6 = i17 + 8 | 0;
6823     if ((i6 & 7 | 0) == 0) {
6824      i6 = 0;
6825     } else {
6826      i6 = 0 - i6 & 7;
6827     }
6828     i7 = i17 + (i14 + 8) | 0;
6829     if ((i7 & 7 | 0) == 0) {
6830      i13 = 0;
6831     } else {
6832      i13 = 0 - i7 & 7;
6833     }
6834     i15 = i17 + (i13 + i14) | 0;
6835     i8 = i6 + i12 | 0;
6836     i7 = i17 + i8 | 0;
6837     i10 = i15 - (i17 + i6) - i12 | 0;
6838     HEAP32[i17 + (i6 + 4) >> 2] = i12 | 3;
6839     L348 : do {
6840      if ((i15 | 0) != (HEAP32[608 >> 2] | 0)) {
6841       if ((i15 | 0) == (HEAP32[604 >> 2] | 0)) {
6842        i32 = (HEAP32[592 >> 2] | 0) + i10 | 0;
6843        HEAP32[592 >> 2] = i32;
6844        HEAP32[604 >> 2] = i7;
6845        HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
6846        HEAP32[i17 + (i32 + i8) >> 2] = i32;
6847        break;
6848       }
6849       i12 = i14 + 4 | 0;
6850       i18 = HEAP32[i17 + (i12 + i13) >> 2] | 0;
6851       if ((i18 & 3 | 0) == 1) {
6852        i11 = i18 & -8;
6853        i16 = i18 >>> 3;
6854        do {
6855         if (!(i18 >>> 0 < 256)) {
6856          i9 = HEAP32[i17 + ((i13 | 24) + i14) >> 2] | 0;
6857          i19 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
6858          do {
6859           if ((i19 | 0) == (i15 | 0)) {
6860            i19 = i13 | 16;
6861            i18 = i17 + (i12 + i19) | 0;
6862            i16 = HEAP32[i18 >> 2] | 0;
6863            if ((i16 | 0) == 0) {
6864             i18 = i17 + (i19 + i14) | 0;
6865             i16 = HEAP32[i18 >> 2] | 0;
6866             if ((i16 | 0) == 0) {
6867              i5 = 0;
6868              break;
6869             }
6870            }
6871            while (1) {
6872             i20 = i16 + 20 | 0;
6873             i19 = HEAP32[i20 >> 2] | 0;
6874             if ((i19 | 0) != 0) {
6875              i16 = i19;
6876              i18 = i20;
6877              continue;
6878             }
6879             i19 = i16 + 16 | 0;
6880             i20 = HEAP32[i19 >> 2] | 0;
6881             if ((i20 | 0) == 0) {
6882              break;
6883             } else {
6884              i16 = i20;
6885              i18 = i19;
6886             }
6887            }
6888            if (i18 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6889             _abort();
6890            } else {
6891             HEAP32[i18 >> 2] = 0;
6892             i5 = i16;
6893             break;
6894            }
6895           } else {
6896            i18 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
6897            if (i18 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6898             _abort();
6899            }
6900            i16 = i18 + 12 | 0;
6901            if ((HEAP32[i16 >> 2] | 0) != (i15 | 0)) {
6902             _abort();
6903            }
6904            i20 = i19 + 8 | 0;
6905            if ((HEAP32[i20 >> 2] | 0) == (i15 | 0)) {
6906             HEAP32[i16 >> 2] = i19;
6907             HEAP32[i20 >> 2] = i18;
6908             i5 = i19;
6909             break;
6910            } else {
6911             _abort();
6912            }
6913           }
6914          } while (0);
6915          if ((i9 | 0) != 0) {
6916           i16 = HEAP32[i17 + (i14 + 28 + i13) >> 2] | 0;
6917           i18 = 888 + (i16 << 2) | 0;
6918           if ((i15 | 0) == (HEAP32[i18 >> 2] | 0)) {
6919            HEAP32[i18 >> 2] = i5;
6920            if ((i5 | 0) == 0) {
6921             HEAP32[588 >> 2] = HEAP32[588 >> 2] & ~(1 << i16);
6922             break;
6923            }
6924           } else {
6925            if (i9 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6926             _abort();
6927            }
6928            i16 = i9 + 16 | 0;
6929            if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
6930             HEAP32[i16 >> 2] = i5;
6931            } else {
6932             HEAP32[i9 + 20 >> 2] = i5;
6933            }
6934            if ((i5 | 0) == 0) {
6935             break;
6936            }
6937           }
6938           if (i5 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6939            _abort();
6940           }
6941           HEAP32[i5 + 24 >> 2] = i9;
6942           i15 = i13 | 16;
6943           i9 = HEAP32[i17 + (i15 + i14) >> 2] | 0;
6944           do {
6945            if ((i9 | 0) != 0) {
6946             if (i9 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6947              _abort();
6948             } else {
6949              HEAP32[i5 + 16 >> 2] = i9;
6950              HEAP32[i9 + 24 >> 2] = i5;
6951              break;
6952             }
6953            }
6954           } while (0);
6955           i9 = HEAP32[i17 + (i12 + i15) >> 2] | 0;
6956           if ((i9 | 0) != 0) {
6957            if (i9 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6958             _abort();
6959            } else {
6960             HEAP32[i5 + 20 >> 2] = i9;
6961             HEAP32[i9 + 24 >> 2] = i5;
6962             break;
6963            }
6964           }
6965          }
6966         } else {
6967          i5 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
6968          i12 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
6969          i18 = 624 + (i16 << 1 << 2) | 0;
6970          if ((i5 | 0) != (i18 | 0)) {
6971           if (i5 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6972            _abort();
6973           }
6974           if ((HEAP32[i5 + 12 >> 2] | 0) != (i15 | 0)) {
6975            _abort();
6976           }
6977          }
6978          if ((i12 | 0) == (i5 | 0)) {
6979           HEAP32[146] = HEAP32[146] & ~(1 << i16);
6980           break;
6981          }
6982          if ((i12 | 0) != (i18 | 0)) {
6983           if (i12 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
6984            _abort();
6985           }
6986           i16 = i12 + 8 | 0;
6987           if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
6988            i9 = i16;
6989           } else {
6990            _abort();
6991           }
6992          } else {
6993           i9 = i12 + 8 | 0;
6994          }
6995          HEAP32[i5 + 12 >> 2] = i12;
6996          HEAP32[i9 >> 2] = i5;
6997         }
6998        } while (0);
6999        i15 = i17 + ((i11 | i13) + i14) | 0;
7000        i10 = i11 + i10 | 0;
7001       }
7002       i5 = i15 + 4 | 0;
7003       HEAP32[i5 >> 2] = HEAP32[i5 >> 2] & -2;
7004       HEAP32[i17 + (i8 + 4) >> 2] = i10 | 1;
7005       HEAP32[i17 + (i10 + i8) >> 2] = i10;
7006       i5 = i10 >>> 3;
7007       if (i10 >>> 0 < 256) {
7008        i10 = i5 << 1;
7009        i2 = 624 + (i10 << 2) | 0;
7010        i9 = HEAP32[146] | 0;
7011        i5 = 1 << i5;
7012        if ((i9 & i5 | 0) != 0) {
7013         i9 = 624 + (i10 + 2 << 2) | 0;
7014         i5 = HEAP32[i9 >> 2] | 0;
7015         if (i5 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7016          _abort();
7017         } else {
7018          i3 = i9;
7019          i4 = i5;
7020         }
7021        } else {
7022         HEAP32[146] = i9 | i5;
7023         i3 = 624 + (i10 + 2 << 2) | 0;
7024         i4 = i2;
7025        }
7026        HEAP32[i3 >> 2] = i7;
7027        HEAP32[i4 + 12 >> 2] = i7;
7028        HEAP32[i17 + (i8 + 8) >> 2] = i4;
7029        HEAP32[i17 + (i8 + 12) >> 2] = i2;
7030        break;
7031       }
7032       i3 = i10 >>> 8;
7033       if ((i3 | 0) != 0) {
7034        if (i10 >>> 0 > 16777215) {
7035         i3 = 31;
7036        } else {
7037         i31 = (i3 + 1048320 | 0) >>> 16 & 8;
7038         i32 = i3 << i31;
7039         i30 = (i32 + 520192 | 0) >>> 16 & 4;
7040         i32 = i32 << i30;
7041         i3 = (i32 + 245760 | 0) >>> 16 & 2;
7042         i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
7043         i3 = i10 >>> (i3 + 7 | 0) & 1 | i3 << 1;
7044        }
7045       } else {
7046        i3 = 0;
7047       }
7048       i4 = 888 + (i3 << 2) | 0;
7049       HEAP32[i17 + (i8 + 28) >> 2] = i3;
7050       HEAP32[i17 + (i8 + 20) >> 2] = 0;
7051       HEAP32[i17 + (i8 + 16) >> 2] = 0;
7052       i9 = HEAP32[588 >> 2] | 0;
7053       i5 = 1 << i3;
7054       if ((i9 & i5 | 0) == 0) {
7055        HEAP32[588 >> 2] = i9 | i5;
7056        HEAP32[i4 >> 2] = i7;
7057        HEAP32[i17 + (i8 + 24) >> 2] = i4;
7058        HEAP32[i17 + (i8 + 12) >> 2] = i7;
7059        HEAP32[i17 + (i8 + 8) >> 2] = i7;
7060        break;
7061       }
7062       i4 = HEAP32[i4 >> 2] | 0;
7063       if ((i3 | 0) == 31) {
7064        i3 = 0;
7065       } else {
7066        i3 = 25 - (i3 >>> 1) | 0;
7067       }
7068       L444 : do {
7069        if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i10 | 0)) {
7070         i3 = i10 << i3;
7071         while (1) {
7072          i5 = i4 + (i3 >>> 31 << 2) + 16 | 0;
7073          i9 = HEAP32[i5 >> 2] | 0;
7074          if ((i9 | 0) == 0) {
7075           break;
7076          }
7077          if ((HEAP32[i9 + 4 >> 2] & -8 | 0) == (i10 | 0)) {
7078           i2 = i9;
7079           break L444;
7080          } else {
7081           i3 = i3 << 1;
7082           i4 = i9;
7083          }
7084         }
7085         if (i5 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7086          _abort();
7087         } else {
7088          HEAP32[i5 >> 2] = i7;
7089          HEAP32[i17 + (i8 + 24) >> 2] = i4;
7090          HEAP32[i17 + (i8 + 12) >> 2] = i7;
7091          HEAP32[i17 + (i8 + 8) >> 2] = i7;
7092          break L348;
7093         }
7094        } else {
7095         i2 = i4;
7096        }
7097       } while (0);
7098       i4 = i2 + 8 | 0;
7099       i3 = HEAP32[i4 >> 2] | 0;
7100       i5 = HEAP32[600 >> 2] | 0;
7101       if (i2 >>> 0 < i5 >>> 0) {
7102        _abort();
7103       }
7104       if (i3 >>> 0 < i5 >>> 0) {
7105        _abort();
7106       } else {
7107        HEAP32[i3 + 12 >> 2] = i7;
7108        HEAP32[i4 >> 2] = i7;
7109        HEAP32[i17 + (i8 + 8) >> 2] = i3;
7110        HEAP32[i17 + (i8 + 12) >> 2] = i2;
7111        HEAP32[i17 + (i8 + 24) >> 2] = 0;
7112        break;
7113       }
7114      } else {
7115       i32 = (HEAP32[596 >> 2] | 0) + i10 | 0;
7116       HEAP32[596 >> 2] = i32;
7117       HEAP32[608 >> 2] = i7;
7118       HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
7119      }
7120     } while (0);
7121     i32 = i17 + (i6 | 8) | 0;
7122     STACKTOP = i1;
7123     return i32 | 0;
7124    }
7125    i3 = 1032 | 0;
7126    while (1) {
7127     i2 = HEAP32[i3 >> 2] | 0;
7128     if (!(i2 >>> 0 > i15 >>> 0) ? (i11 = HEAP32[i3 + 4 >> 2] | 0, i10 = i2 + i11 | 0, i10 >>> 0 > i15 >>> 0) : 0) {
7129      break;
7130     }
7131     i3 = HEAP32[i3 + 8 >> 2] | 0;
7132    }
7133    i3 = i2 + (i11 + -39) | 0;
7134    if ((i3 & 7 | 0) == 0) {
7135     i3 = 0;
7136    } else {
7137     i3 = 0 - i3 & 7;
7138    }
7139    i2 = i2 + (i11 + -47 + i3) | 0;
7140    i2 = i2 >>> 0 < (i15 + 16 | 0) >>> 0 ? i15 : i2;
7141    i3 = i2 + 8 | 0;
7142    i4 = i17 + 8 | 0;
7143    if ((i4 & 7 | 0) == 0) {
7144     i4 = 0;
7145    } else {
7146     i4 = 0 - i4 & 7;
7147    }
7148    i32 = i14 + -40 - i4 | 0;
7149    HEAP32[608 >> 2] = i17 + i4;
7150    HEAP32[596 >> 2] = i32;
7151    HEAP32[i17 + (i4 + 4) >> 2] = i32 | 1;
7152    HEAP32[i17 + (i14 + -36) >> 2] = 40;
7153    HEAP32[612 >> 2] = HEAP32[1072 >> 2];
7154    HEAP32[i2 + 4 >> 2] = 27;
7155    HEAP32[i3 + 0 >> 2] = HEAP32[1032 >> 2];
7156    HEAP32[i3 + 4 >> 2] = HEAP32[1036 >> 2];
7157    HEAP32[i3 + 8 >> 2] = HEAP32[1040 >> 2];
7158    HEAP32[i3 + 12 >> 2] = HEAP32[1044 >> 2];
7159    HEAP32[1032 >> 2] = i17;
7160    HEAP32[1036 >> 2] = i14;
7161    HEAP32[1044 >> 2] = 0;
7162    HEAP32[1040 >> 2] = i3;
7163    i4 = i2 + 28 | 0;
7164    HEAP32[i4 >> 2] = 7;
7165    if ((i2 + 32 | 0) >>> 0 < i10 >>> 0) {
7166     while (1) {
7167      i3 = i4 + 4 | 0;
7168      HEAP32[i3 >> 2] = 7;
7169      if ((i4 + 8 | 0) >>> 0 < i10 >>> 0) {
7170       i4 = i3;
7171      } else {
7172       break;
7173      }
7174     }
7175    }
7176    if ((i2 | 0) != (i15 | 0)) {
7177     i2 = i2 - i15 | 0;
7178     i3 = i15 + (i2 + 4) | 0;
7179     HEAP32[i3 >> 2] = HEAP32[i3 >> 2] & -2;
7180     HEAP32[i15 + 4 >> 2] = i2 | 1;
7181     HEAP32[i15 + i2 >> 2] = i2;
7182     i3 = i2 >>> 3;
7183     if (i2 >>> 0 < 256) {
7184      i4 = i3 << 1;
7185      i2 = 624 + (i4 << 2) | 0;
7186      i5 = HEAP32[146] | 0;
7187      i3 = 1 << i3;
7188      if ((i5 & i3 | 0) != 0) {
7189       i4 = 624 + (i4 + 2 << 2) | 0;
7190       i3 = HEAP32[i4 >> 2] | 0;
7191       if (i3 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7192        _abort();
7193       } else {
7194        i7 = i4;
7195        i8 = i3;
7196       }
7197      } else {
7198       HEAP32[146] = i5 | i3;
7199       i7 = 624 + (i4 + 2 << 2) | 0;
7200       i8 = i2;
7201      }
7202      HEAP32[i7 >> 2] = i15;
7203      HEAP32[i8 + 12 >> 2] = i15;
7204      HEAP32[i15 + 8 >> 2] = i8;
7205      HEAP32[i15 + 12 >> 2] = i2;
7206      break;
7207     }
7208     i3 = i2 >>> 8;
7209     if ((i3 | 0) != 0) {
7210      if (i2 >>> 0 > 16777215) {
7211       i3 = 31;
7212      } else {
7213       i31 = (i3 + 1048320 | 0) >>> 16 & 8;
7214       i32 = i3 << i31;
7215       i30 = (i32 + 520192 | 0) >>> 16 & 4;
7216       i32 = i32 << i30;
7217       i3 = (i32 + 245760 | 0) >>> 16 & 2;
7218       i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
7219       i3 = i2 >>> (i3 + 7 | 0) & 1 | i3 << 1;
7220      }
7221     } else {
7222      i3 = 0;
7223     }
7224     i7 = 888 + (i3 << 2) | 0;
7225     HEAP32[i15 + 28 >> 2] = i3;
7226     HEAP32[i15 + 20 >> 2] = 0;
7227     HEAP32[i15 + 16 >> 2] = 0;
7228     i4 = HEAP32[588 >> 2] | 0;
7229     i5 = 1 << i3;
7230     if ((i4 & i5 | 0) == 0) {
7231      HEAP32[588 >> 2] = i4 | i5;
7232      HEAP32[i7 >> 2] = i15;
7233      HEAP32[i15 + 24 >> 2] = i7;
7234      HEAP32[i15 + 12 >> 2] = i15;
7235      HEAP32[i15 + 8 >> 2] = i15;
7236      break;
7237     }
7238     i4 = HEAP32[i7 >> 2] | 0;
7239     if ((i3 | 0) == 31) {
7240      i3 = 0;
7241     } else {
7242      i3 = 25 - (i3 >>> 1) | 0;
7243     }
7244     L499 : do {
7245      if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i2 | 0)) {
7246       i3 = i2 << i3;
7247       while (1) {
7248        i7 = i4 + (i3 >>> 31 << 2) + 16 | 0;
7249        i5 = HEAP32[i7 >> 2] | 0;
7250        if ((i5 | 0) == 0) {
7251         break;
7252        }
7253        if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i2 | 0)) {
7254         i6 = i5;
7255         break L499;
7256        } else {
7257         i3 = i3 << 1;
7258         i4 = i5;
7259        }
7260       }
7261       if (i7 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7262        _abort();
7263       } else {
7264        HEAP32[i7 >> 2] = i15;
7265        HEAP32[i15 + 24 >> 2] = i4;
7266        HEAP32[i15 + 12 >> 2] = i15;
7267        HEAP32[i15 + 8 >> 2] = i15;
7268        break L311;
7269       }
7270      } else {
7271       i6 = i4;
7272      }
7273     } while (0);
7274     i4 = i6 + 8 | 0;
7275     i3 = HEAP32[i4 >> 2] | 0;
7276     i2 = HEAP32[600 >> 2] | 0;
7277     if (i6 >>> 0 < i2 >>> 0) {
7278      _abort();
7279     }
7280     if (i3 >>> 0 < i2 >>> 0) {
7281      _abort();
7282     } else {
7283      HEAP32[i3 + 12 >> 2] = i15;
7284      HEAP32[i4 >> 2] = i15;
7285      HEAP32[i15 + 8 >> 2] = i3;
7286      HEAP32[i15 + 12 >> 2] = i6;
7287      HEAP32[i15 + 24 >> 2] = 0;
7288      break;
7289     }
7290    }
7291   } else {
7292    i32 = HEAP32[600 >> 2] | 0;
7293    if ((i32 | 0) == 0 | i17 >>> 0 < i32 >>> 0) {
7294     HEAP32[600 >> 2] = i17;
7295    }
7296    HEAP32[1032 >> 2] = i17;
7297    HEAP32[1036 >> 2] = i14;
7298    HEAP32[1044 >> 2] = 0;
7299    HEAP32[620 >> 2] = HEAP32[264];
7300    HEAP32[616 >> 2] = -1;
7301    i2 = 0;
7302    do {
7303     i32 = i2 << 1;
7304     i31 = 624 + (i32 << 2) | 0;
7305     HEAP32[624 + (i32 + 3 << 2) >> 2] = i31;
7306     HEAP32[624 + (i32 + 2 << 2) >> 2] = i31;
7307     i2 = i2 + 1 | 0;
7308    } while ((i2 | 0) != 32);
7309    i2 = i17 + 8 | 0;
7310    if ((i2 & 7 | 0) == 0) {
7311     i2 = 0;
7312    } else {
7313     i2 = 0 - i2 & 7;
7314    }
7315    i32 = i14 + -40 - i2 | 0;
7316    HEAP32[608 >> 2] = i17 + i2;
7317    HEAP32[596 >> 2] = i32;
7318    HEAP32[i17 + (i2 + 4) >> 2] = i32 | 1;
7319    HEAP32[i17 + (i14 + -36) >> 2] = 40;
7320    HEAP32[612 >> 2] = HEAP32[1072 >> 2];
7321   }
7322  } while (0);
7323  i2 = HEAP32[596 >> 2] | 0;
7324  if (i2 >>> 0 > i12 >>> 0) {
7325   i31 = i2 - i12 | 0;
7326   HEAP32[596 >> 2] = i31;
7327   i32 = HEAP32[608 >> 2] | 0;
7328   HEAP32[608 >> 2] = i32 + i12;
7329   HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
7330   HEAP32[i32 + 4 >> 2] = i12 | 3;
7331   i32 = i32 + 8 | 0;
7332   STACKTOP = i1;
7333   return i32 | 0;
7334  }
7335 }
7336 HEAP32[(___errno_location() | 0) >> 2] = 12;
7337 i32 = 0;
7338 STACKTOP = i1;
7339 return i32 | 0;
7340}
7341function _free(i7) {
7342 i7 = i7 | 0;
7343 var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0;
7344 i1 = STACKTOP;
7345 if ((i7 | 0) == 0) {
7346  STACKTOP = i1;
7347  return;
7348 }
7349 i15 = i7 + -8 | 0;
7350 i16 = HEAP32[600 >> 2] | 0;
7351 if (i15 >>> 0 < i16 >>> 0) {
7352  _abort();
7353 }
7354 i13 = HEAP32[i7 + -4 >> 2] | 0;
7355 i12 = i13 & 3;
7356 if ((i12 | 0) == 1) {
7357  _abort();
7358 }
7359 i8 = i13 & -8;
7360 i6 = i7 + (i8 + -8) | 0;
7361 do {
7362  if ((i13 & 1 | 0) == 0) {
7363   i19 = HEAP32[i15 >> 2] | 0;
7364   if ((i12 | 0) == 0) {
7365    STACKTOP = i1;
7366    return;
7367   }
7368   i15 = -8 - i19 | 0;
7369   i13 = i7 + i15 | 0;
7370   i12 = i19 + i8 | 0;
7371   if (i13 >>> 0 < i16 >>> 0) {
7372    _abort();
7373   }
7374   if ((i13 | 0) == (HEAP32[604 >> 2] | 0)) {
7375    i2 = i7 + (i8 + -4) | 0;
7376    if ((HEAP32[i2 >> 2] & 3 | 0) != 3) {
7377     i2 = i13;
7378     i11 = i12;
7379     break;
7380    }
7381    HEAP32[592 >> 2] = i12;
7382    HEAP32[i2 >> 2] = HEAP32[i2 >> 2] & -2;
7383    HEAP32[i7 + (i15 + 4) >> 2] = i12 | 1;
7384    HEAP32[i6 >> 2] = i12;
7385    STACKTOP = i1;
7386    return;
7387   }
7388   i18 = i19 >>> 3;
7389   if (i19 >>> 0 < 256) {
7390    i2 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
7391    i11 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
7392    i14 = 624 + (i18 << 1 << 2) | 0;
7393    if ((i2 | 0) != (i14 | 0)) {
7394     if (i2 >>> 0 < i16 >>> 0) {
7395      _abort();
7396     }
7397     if ((HEAP32[i2 + 12 >> 2] | 0) != (i13 | 0)) {
7398      _abort();
7399     }
7400    }
7401    if ((i11 | 0) == (i2 | 0)) {
7402     HEAP32[146] = HEAP32[146] & ~(1 << i18);
7403     i2 = i13;
7404     i11 = i12;
7405     break;
7406    }
7407    if ((i11 | 0) != (i14 | 0)) {
7408     if (i11 >>> 0 < i16 >>> 0) {
7409      _abort();
7410     }
7411     i14 = i11 + 8 | 0;
7412     if ((HEAP32[i14 >> 2] | 0) == (i13 | 0)) {
7413      i17 = i14;
7414     } else {
7415      _abort();
7416     }
7417    } else {
7418     i17 = i11 + 8 | 0;
7419    }
7420    HEAP32[i2 + 12 >> 2] = i11;
7421    HEAP32[i17 >> 2] = i2;
7422    i2 = i13;
7423    i11 = i12;
7424    break;
7425   }
7426   i17 = HEAP32[i7 + (i15 + 24) >> 2] | 0;
7427   i18 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
7428   do {
7429    if ((i18 | 0) == (i13 | 0)) {
7430     i19 = i7 + (i15 + 20) | 0;
7431     i18 = HEAP32[i19 >> 2] | 0;
7432     if ((i18 | 0) == 0) {
7433      i19 = i7 + (i15 + 16) | 0;
7434      i18 = HEAP32[i19 >> 2] | 0;
7435      if ((i18 | 0) == 0) {
7436       i14 = 0;
7437       break;
7438      }
7439     }
7440     while (1) {
7441      i21 = i18 + 20 | 0;
7442      i20 = HEAP32[i21 >> 2] | 0;
7443      if ((i20 | 0) != 0) {
7444       i18 = i20;
7445       i19 = i21;
7446       continue;
7447      }
7448      i20 = i18 + 16 | 0;
7449      i21 = HEAP32[i20 >> 2] | 0;
7450      if ((i21 | 0) == 0) {
7451       break;
7452      } else {
7453       i18 = i21;
7454       i19 = i20;
7455      }
7456     }
7457     if (i19 >>> 0 < i16 >>> 0) {
7458      _abort();
7459     } else {
7460      HEAP32[i19 >> 2] = 0;
7461      i14 = i18;
7462      break;
7463     }
7464    } else {
7465     i19 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
7466     if (i19 >>> 0 < i16 >>> 0) {
7467      _abort();
7468     }
7469     i16 = i19 + 12 | 0;
7470     if ((HEAP32[i16 >> 2] | 0) != (i13 | 0)) {
7471      _abort();
7472     }
7473     i20 = i18 + 8 | 0;
7474     if ((HEAP32[i20 >> 2] | 0) == (i13 | 0)) {
7475      HEAP32[i16 >> 2] = i18;
7476      HEAP32[i20 >> 2] = i19;
7477      i14 = i18;
7478      break;
7479     } else {
7480      _abort();
7481     }
7482    }
7483   } while (0);
7484   if ((i17 | 0) != 0) {
7485    i18 = HEAP32[i7 + (i15 + 28) >> 2] | 0;
7486    i16 = 888 + (i18 << 2) | 0;
7487    if ((i13 | 0) == (HEAP32[i16 >> 2] | 0)) {
7488     HEAP32[i16 >> 2] = i14;
7489     if ((i14 | 0) == 0) {
7490      HEAP32[588 >> 2] = HEAP32[588 >> 2] & ~(1 << i18);
7491      i2 = i13;
7492      i11 = i12;
7493      break;
7494     }
7495    } else {
7496     if (i17 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7497      _abort();
7498     }
7499     i16 = i17 + 16 | 0;
7500     if ((HEAP32[i16 >> 2] | 0) == (i13 | 0)) {
7501      HEAP32[i16 >> 2] = i14;
7502     } else {
7503      HEAP32[i17 + 20 >> 2] = i14;
7504     }
7505     if ((i14 | 0) == 0) {
7506      i2 = i13;
7507      i11 = i12;
7508      break;
7509     }
7510    }
7511    if (i14 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7512     _abort();
7513    }
7514    HEAP32[i14 + 24 >> 2] = i17;
7515    i16 = HEAP32[i7 + (i15 + 16) >> 2] | 0;
7516    do {
7517     if ((i16 | 0) != 0) {
7518      if (i16 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7519       _abort();
7520      } else {
7521       HEAP32[i14 + 16 >> 2] = i16;
7522       HEAP32[i16 + 24 >> 2] = i14;
7523       break;
7524      }
7525     }
7526    } while (0);
7527    i15 = HEAP32[i7 + (i15 + 20) >> 2] | 0;
7528    if ((i15 | 0) != 0) {
7529     if (i15 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7530      _abort();
7531     } else {
7532      HEAP32[i14 + 20 >> 2] = i15;
7533      HEAP32[i15 + 24 >> 2] = i14;
7534      i2 = i13;
7535      i11 = i12;
7536      break;
7537     }
7538    } else {
7539     i2 = i13;
7540     i11 = i12;
7541    }
7542   } else {
7543    i2 = i13;
7544    i11 = i12;
7545   }
7546  } else {
7547   i2 = i15;
7548   i11 = i8;
7549  }
7550 } while (0);
7551 if (!(i2 >>> 0 < i6 >>> 0)) {
7552  _abort();
7553 }
7554 i12 = i7 + (i8 + -4) | 0;
7555 i13 = HEAP32[i12 >> 2] | 0;
7556 if ((i13 & 1 | 0) == 0) {
7557  _abort();
7558 }
7559 if ((i13 & 2 | 0) == 0) {
7560  if ((i6 | 0) == (HEAP32[608 >> 2] | 0)) {
7561   i21 = (HEAP32[596 >> 2] | 0) + i11 | 0;
7562   HEAP32[596 >> 2] = i21;
7563   HEAP32[608 >> 2] = i2;
7564   HEAP32[i2 + 4 >> 2] = i21 | 1;
7565   if ((i2 | 0) != (HEAP32[604 >> 2] | 0)) {
7566    STACKTOP = i1;
7567    return;
7568   }
7569   HEAP32[604 >> 2] = 0;
7570   HEAP32[592 >> 2] = 0;
7571   STACKTOP = i1;
7572   return;
7573  }
7574  if ((i6 | 0) == (HEAP32[604 >> 2] | 0)) {
7575   i21 = (HEAP32[592 >> 2] | 0) + i11 | 0;
7576   HEAP32[592 >> 2] = i21;
7577   HEAP32[604 >> 2] = i2;
7578   HEAP32[i2 + 4 >> 2] = i21 | 1;
7579   HEAP32[i2 + i21 >> 2] = i21;
7580   STACKTOP = i1;
7581   return;
7582  }
7583  i11 = (i13 & -8) + i11 | 0;
7584  i12 = i13 >>> 3;
7585  do {
7586   if (!(i13 >>> 0 < 256)) {
7587    i10 = HEAP32[i7 + (i8 + 16) >> 2] | 0;
7588    i15 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
7589    do {
7590     if ((i15 | 0) == (i6 | 0)) {
7591      i13 = i7 + (i8 + 12) | 0;
7592      i12 = HEAP32[i13 >> 2] | 0;
7593      if ((i12 | 0) == 0) {
7594       i13 = i7 + (i8 + 8) | 0;
7595       i12 = HEAP32[i13 >> 2] | 0;
7596       if ((i12 | 0) == 0) {
7597        i9 = 0;
7598        break;
7599       }
7600      }
7601      while (1) {
7602       i14 = i12 + 20 | 0;
7603       i15 = HEAP32[i14 >> 2] | 0;
7604       if ((i15 | 0) != 0) {
7605        i12 = i15;
7606        i13 = i14;
7607        continue;
7608       }
7609       i14 = i12 + 16 | 0;
7610       i15 = HEAP32[i14 >> 2] | 0;
7611       if ((i15 | 0) == 0) {
7612        break;
7613       } else {
7614        i12 = i15;
7615        i13 = i14;
7616       }
7617      }
7618      if (i13 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7619       _abort();
7620      } else {
7621       HEAP32[i13 >> 2] = 0;
7622       i9 = i12;
7623       break;
7624      }
7625     } else {
7626      i13 = HEAP32[i7 + i8 >> 2] | 0;
7627      if (i13 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7628       _abort();
7629      }
7630      i14 = i13 + 12 | 0;
7631      if ((HEAP32[i14 >> 2] | 0) != (i6 | 0)) {
7632       _abort();
7633      }
7634      i12 = i15 + 8 | 0;
7635      if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
7636       HEAP32[i14 >> 2] = i15;
7637       HEAP32[i12 >> 2] = i13;
7638       i9 = i15;
7639       break;
7640      } else {
7641       _abort();
7642      }
7643     }
7644    } while (0);
7645    if ((i10 | 0) != 0) {
7646     i12 = HEAP32[i7 + (i8 + 20) >> 2] | 0;
7647     i13 = 888 + (i12 << 2) | 0;
7648     if ((i6 | 0) == (HEAP32[i13 >> 2] | 0)) {
7649      HEAP32[i13 >> 2] = i9;
7650      if ((i9 | 0) == 0) {
7651       HEAP32[588 >> 2] = HEAP32[588 >> 2] & ~(1 << i12);
7652       break;
7653      }
7654     } else {
7655      if (i10 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7656       _abort();
7657      }
7658      i12 = i10 + 16 | 0;
7659      if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
7660       HEAP32[i12 >> 2] = i9;
7661      } else {
7662       HEAP32[i10 + 20 >> 2] = i9;
7663      }
7664      if ((i9 | 0) == 0) {
7665       break;
7666      }
7667     }
7668     if (i9 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7669      _abort();
7670     }
7671     HEAP32[i9 + 24 >> 2] = i10;
7672     i6 = HEAP32[i7 + (i8 + 8) >> 2] | 0;
7673     do {
7674      if ((i6 | 0) != 0) {
7675       if (i6 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7676        _abort();
7677       } else {
7678        HEAP32[i9 + 16 >> 2] = i6;
7679        HEAP32[i6 + 24 >> 2] = i9;
7680        break;
7681       }
7682      }
7683     } while (0);
7684     i6 = HEAP32[i7 + (i8 + 12) >> 2] | 0;
7685     if ((i6 | 0) != 0) {
7686      if (i6 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7687       _abort();
7688      } else {
7689       HEAP32[i9 + 20 >> 2] = i6;
7690       HEAP32[i6 + 24 >> 2] = i9;
7691       break;
7692      }
7693     }
7694    }
7695   } else {
7696    i9 = HEAP32[i7 + i8 >> 2] | 0;
7697    i7 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
7698    i8 = 624 + (i12 << 1 << 2) | 0;
7699    if ((i9 | 0) != (i8 | 0)) {
7700     if (i9 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7701      _abort();
7702     }
7703     if ((HEAP32[i9 + 12 >> 2] | 0) != (i6 | 0)) {
7704      _abort();
7705     }
7706    }
7707    if ((i7 | 0) == (i9 | 0)) {
7708     HEAP32[146] = HEAP32[146] & ~(1 << i12);
7709     break;
7710    }
7711    if ((i7 | 0) != (i8 | 0)) {
7712     if (i7 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7713      _abort();
7714     }
7715     i8 = i7 + 8 | 0;
7716     if ((HEAP32[i8 >> 2] | 0) == (i6 | 0)) {
7717      i10 = i8;
7718     } else {
7719      _abort();
7720     }
7721    } else {
7722     i10 = i7 + 8 | 0;
7723    }
7724    HEAP32[i9 + 12 >> 2] = i7;
7725    HEAP32[i10 >> 2] = i9;
7726   }
7727  } while (0);
7728  HEAP32[i2 + 4 >> 2] = i11 | 1;
7729  HEAP32[i2 + i11 >> 2] = i11;
7730  if ((i2 | 0) == (HEAP32[604 >> 2] | 0)) {
7731   HEAP32[592 >> 2] = i11;
7732   STACKTOP = i1;
7733   return;
7734  }
7735 } else {
7736  HEAP32[i12 >> 2] = i13 & -2;
7737  HEAP32[i2 + 4 >> 2] = i11 | 1;
7738  HEAP32[i2 + i11 >> 2] = i11;
7739 }
7740 i6 = i11 >>> 3;
7741 if (i11 >>> 0 < 256) {
7742  i7 = i6 << 1;
7743  i3 = 624 + (i7 << 2) | 0;
7744  i8 = HEAP32[146] | 0;
7745  i6 = 1 << i6;
7746  if ((i8 & i6 | 0) != 0) {
7747   i6 = 624 + (i7 + 2 << 2) | 0;
7748   i7 = HEAP32[i6 >> 2] | 0;
7749   if (i7 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7750    _abort();
7751   } else {
7752    i4 = i6;
7753    i5 = i7;
7754   }
7755  } else {
7756   HEAP32[146] = i8 | i6;
7757   i4 = 624 + (i7 + 2 << 2) | 0;
7758   i5 = i3;
7759  }
7760  HEAP32[i4 >> 2] = i2;
7761  HEAP32[i5 + 12 >> 2] = i2;
7762  HEAP32[i2 + 8 >> 2] = i5;
7763  HEAP32[i2 + 12 >> 2] = i3;
7764  STACKTOP = i1;
7765  return;
7766 }
7767 i4 = i11 >>> 8;
7768 if ((i4 | 0) != 0) {
7769  if (i11 >>> 0 > 16777215) {
7770   i4 = 31;
7771  } else {
7772   i20 = (i4 + 1048320 | 0) >>> 16 & 8;
7773   i21 = i4 << i20;
7774   i19 = (i21 + 520192 | 0) >>> 16 & 4;
7775   i21 = i21 << i19;
7776   i4 = (i21 + 245760 | 0) >>> 16 & 2;
7777   i4 = 14 - (i19 | i20 | i4) + (i21 << i4 >>> 15) | 0;
7778   i4 = i11 >>> (i4 + 7 | 0) & 1 | i4 << 1;
7779  }
7780 } else {
7781  i4 = 0;
7782 }
7783 i5 = 888 + (i4 << 2) | 0;
7784 HEAP32[i2 + 28 >> 2] = i4;
7785 HEAP32[i2 + 20 >> 2] = 0;
7786 HEAP32[i2 + 16 >> 2] = 0;
7787 i7 = HEAP32[588 >> 2] | 0;
7788 i6 = 1 << i4;
7789 L199 : do {
7790  if ((i7 & i6 | 0) != 0) {
7791   i5 = HEAP32[i5 >> 2] | 0;
7792   if ((i4 | 0) == 31) {
7793    i4 = 0;
7794   } else {
7795    i4 = 25 - (i4 >>> 1) | 0;
7796   }
7797   L204 : do {
7798    if ((HEAP32[i5 + 4 >> 2] & -8 | 0) != (i11 | 0)) {
7799     i4 = i11 << i4;
7800     i7 = i5;
7801     while (1) {
7802      i6 = i7 + (i4 >>> 31 << 2) + 16 | 0;
7803      i5 = HEAP32[i6 >> 2] | 0;
7804      if ((i5 | 0) == 0) {
7805       break;
7806      }
7807      if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i11 | 0)) {
7808       i3 = i5;
7809       break L204;
7810      } else {
7811       i4 = i4 << 1;
7812       i7 = i5;
7813      }
7814     }
7815     if (i6 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
7816      _abort();
7817     } else {
7818      HEAP32[i6 >> 2] = i2;
7819      HEAP32[i2 + 24 >> 2] = i7;
7820      HEAP32[i2 + 12 >> 2] = i2;
7821      HEAP32[i2 + 8 >> 2] = i2;
7822      break L199;
7823     }
7824    } else {
7825     i3 = i5;
7826    }
7827   } while (0);
7828   i5 = i3 + 8 | 0;
7829   i4 = HEAP32[i5 >> 2] | 0;
7830   i6 = HEAP32[600 >> 2] | 0;
7831   if (i3 >>> 0 < i6 >>> 0) {
7832    _abort();
7833   }
7834   if (i4 >>> 0 < i6 >>> 0) {
7835    _abort();
7836   } else {
7837    HEAP32[i4 + 12 >> 2] = i2;
7838    HEAP32[i5 >> 2] = i2;
7839    HEAP32[i2 + 8 >> 2] = i4;
7840    HEAP32[i2 + 12 >> 2] = i3;
7841    HEAP32[i2 + 24 >> 2] = 0;
7842    break;
7843   }
7844  } else {
7845   HEAP32[588 >> 2] = i7 | i6;
7846   HEAP32[i5 >> 2] = i2;
7847   HEAP32[i2 + 24 >> 2] = i5;
7848   HEAP32[i2 + 12 >> 2] = i2;
7849   HEAP32[i2 + 8 >> 2] = i2;
7850  }
7851 } while (0);
7852 i21 = (HEAP32[616 >> 2] | 0) + -1 | 0;
7853 HEAP32[616 >> 2] = i21;
7854 if ((i21 | 0) == 0) {
7855  i2 = 1040 | 0;
7856 } else {
7857  STACKTOP = i1;
7858  return;
7859 }
7860 while (1) {
7861  i2 = HEAP32[i2 >> 2] | 0;
7862  if ((i2 | 0) == 0) {
7863   break;
7864  } else {
7865   i2 = i2 + 8 | 0;
7866  }
7867 }
7868 HEAP32[616 >> 2] = -1;
7869 STACKTOP = i1;
7870 return;
7871}
7872function _main(i7, i8) {
7873 i7 = i7 | 0;
7874 i8 = i8 | 0;
7875 var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, d9 = 0.0, d10 = 0.0;
7876 i2 = STACKTOP;
7877 STACKTOP = STACKTOP + 4272 | 0;
7878 i3 = i2;
7879 i5 = i2 + 4248 | 0;
7880 i4 = i2 + 2128 | 0;
7881 i1 = i2 + 8 | 0;
7882 L1 : do {
7883  if ((i7 | 0) > 1) {
7884   i7 = HEAP8[HEAP32[i8 + 4 >> 2] | 0] | 0;
7885   switch (i7 | 0) {
7886   case 50:
7887    {
7888     i3 = 95e5;
7889     break L1;
7890    }
7891   case 51:
7892    {
7893     i6 = 4;
7894     break L1;
7895    }
7896   case 52:
7897    {
7898     i3 = 95e6;
7899     break L1;
7900    }
7901   case 53:
7902    {
7903     i3 = 19e7;
7904     break L1;
7905    }
7906   case 49:
7907    {
7908     i3 = 95e4;
7909     break L1;
7910    }
7911   case 48:
7912    {
7913     i8 = 0;
7914     STACKTOP = i2;
7915     return i8 | 0;
7916    }
7917   default:
7918    {
7919     HEAP32[i3 >> 2] = i7 + -48;
7920     _printf(280, i3 | 0) | 0;
7921     i8 = -1;
7922     STACKTOP = i2;
7923     return i8 | 0;
7924    }
7925   }
7926  } else {
7927   i6 = 4;
7928  }
7929 } while (0);
7930 if ((i6 | 0) == 4) {
7931  i3 = 19e6;
7932 }
7933 HEAP32[i5 + 8 >> 2] = 0;
7934 HEAP32[i5 + 4 >> 2] = 287;
7935 i8 = __Znaj(347) | 0;
7936 HEAP32[i5 >> 2] = i8;
7937 _memcpy(i8 | 0, 296, 287) | 0;
7938 i8 = i8 + 287 | 0;
7939 i7 = 296 | 0;
7940 i6 = i8 + 60 | 0;
7941 do {
7942  HEAP8[i8] = HEAP8[i7] | 0;
7943  i8 = i8 + 1 | 0;
7944  i7 = i7 + 1 | 0;
7945 } while ((i8 | 0) < (i6 | 0));
7946 i7 = i3 << 1;
7947 while (1) {
7948  i6 = i7 >>> 0 < 60 ? i7 : 60;
7949  __ZN14RotatingString5writeEj(i5, i6);
7950  if ((i7 | 0) == (i6 | 0)) {
7951   break;
7952  } else {
7953   i7 = i7 - i6 | 0;
7954  }
7955 }
7956 i5 = HEAP32[i5 >> 2] | 0;
7957 if ((i5 | 0) != 0) {
7958  __ZdaPv(i5);
7959 }
7960 if ((HEAP32[6] | 0) == 0) {
7961  i6 = 24;
7962  i5 = 0;
7963 } else {
7964  i5 = 24;
7965  d9 = 0.0;
7966  while (1) {
7967   i6 = i5 + 4 | 0;
7968   d9 = d9 + +HEAPF32[i6 >> 2];
7969   d10 = d9 < 1.0 ? d9 : 1.0;
7970   HEAPF32[i6 >> 2] = d10;
7971   HEAP32[i5 + 8 >> 2] = ~~(d10 * 512.0) >>> 0;
7972   i5 = i5 + 12 | 0;
7973   if ((HEAP32[i5 >> 2] | 0) == 0) {
7974    i6 = 24;
7975    i5 = 0;
7976    break;
7977   }
7978  }
7979 }
7980 do {
7981  while (1) {
7982   i8 = HEAP32[i6 + 8 >> 2] | 0;
7983   if (i5 >>> 0 > i8 >>> 0 & (i8 | 0) != 0) {
7984    i6 = i6 + 12 | 0;
7985   } else {
7986    break;
7987   }
7988  }
7989  HEAP32[i4 + (i5 << 2) >> 2] = i6;
7990  i5 = i5 + 1 | 0;
7991 } while ((i5 | 0) != 513);
7992 HEAP32[i4 + 2116 >> 2] = 0;
7993 __Z9makeFastaI10RandomizedEvPKcS2_jRT_(0, 0, i3 * 3 | 0, i4);
7994 if ((HEAP32[54] | 0) == 0) {
7995  i5 = 216;
7996  i4 = 0;
7997 } else {
7998  i5 = 216;
7999  d9 = 0.0;
8000  while (1) {
8001   i4 = i5 + 4 | 0;
8002   d9 = d9 + +HEAPF32[i4 >> 2];
8003   d10 = d9 < 1.0 ? d9 : 1.0;
8004   HEAPF32[i4 >> 2] = d10;
8005   HEAP32[i5 + 8 >> 2] = ~~(d10 * 512.0) >>> 0;
8006   i5 = i5 + 12 | 0;
8007   if ((HEAP32[i5 >> 2] | 0) == 0) {
8008    i5 = 216;
8009    i4 = 0;
8010    break;
8011   }
8012  }
8013 }
8014 do {
8015  while (1) {
8016   i8 = HEAP32[i5 + 8 >> 2] | 0;
8017   if (i4 >>> 0 > i8 >>> 0 & (i8 | 0) != 0) {
8018    i5 = i5 + 12 | 0;
8019   } else {
8020    break;
8021   }
8022  }
8023  HEAP32[i1 + (i4 << 2) >> 2] = i5;
8024  i4 = i4 + 1 | 0;
8025 } while ((i4 | 0) != 513);
8026 HEAP32[i1 + 2116 >> 2] = 0;
8027 __Z9makeFastaI10RandomizedEvPKcS2_jRT_(0, 0, i3 * 5 | 0, i1);
8028 i8 = 0;
8029 STACKTOP = i2;
8030 return i8 | 0;
8031}
8032function __Z9makeFastaI10RandomizedEvPKcS2_jRT_(i3, i2, i6, i1) {
8033 i3 = i3 | 0;
8034 i2 = i2 | 0;
8035 i6 = i6 | 0;
8036 i1 = i1 | 0;
8037 var i4 = 0, i5 = 0, i7 = 0, d8 = 0.0, i9 = 0;
8038 i2 = STACKTOP;
8039 if ((i6 | 0) == 0) {
8040  STACKTOP = i2;
8041  return;
8042 }
8043 i4 = i1 + 2116 | 0;
8044 i3 = i1 + 2052 | 0;
8045 while (1) {
8046  i5 = i6 >>> 0 < 60 ? i6 : 60;
8047  if ((i5 | 0) != 0) {
8048   i7 = 0;
8049   do {
8050    i9 = ((((HEAP32[4] | 0) * 3877 | 0) + 29573 | 0) >>> 0) % 139968 | 0;
8051    HEAP32[4] = i9;
8052    d8 = +(i9 >>> 0) / 139968.0;
8053    i9 = HEAP32[i1 + (~~(d8 * 512.0) >>> 0 << 2) >> 2] | 0;
8054    while (1) {
8055     if (+HEAPF32[i9 + 4 >> 2] < d8) {
8056      i9 = i9 + 12 | 0;
8057     } else {
8058      break;
8059     }
8060    }
8061    HEAP8[i1 + i7 + 2052 | 0] = HEAP32[i9 >> 2];
8062    i7 = i7 + 1 | 0;
8063   } while ((i7 | 0) != (i5 | 0));
8064  }
8065  HEAP8[i1 + i5 + 2052 | 0] = 10;
8066  i9 = i5 + 1 | 0;
8067  HEAP8[i1 + i9 + 2052 | 0] = 0;
8068  HEAP32[i4 >> 2] = i9;
8069  i9 = _strlen(i3 | 0) | 0;
8070  i7 = HEAP32[2] | 0;
8071  if ((i9 | 0) > (i7 | 0)) {
8072   if ((i7 | 0) > 0) {
8073    HEAP8[i1 + i7 + 2052 | 0] = 0;
8074    _puts(i3 | 0) | 0;
8075    HEAP8[i1 + (HEAP32[2] | 0) + 2052 | 0] = 122;
8076    HEAP32[2] = 0;
8077   }
8078  } else {
8079   _puts(i3 | 0) | 0;
8080   HEAP32[2] = (HEAP32[2] | 0) - i9;
8081  }
8082  if ((i6 | 0) == (i5 | 0)) {
8083   break;
8084  } else {
8085   i6 = i6 - i5 | 0;
8086  }
8087 }
8088 STACKTOP = i2;
8089 return;
8090}
8091function __ZN14RotatingString5writeEj(i3, i4) {
8092 i3 = i3 | 0;
8093 i4 = i4 | 0;
8094 var i1 = 0, i2 = 0, i5 = 0, i6 = 0, i7 = 0;
8095 i1 = STACKTOP;
8096 i5 = __Znaj(i4 + 2 | 0) | 0;
8097 i2 = i3 + 8 | 0;
8098 _memcpy(i5 | 0, (HEAP32[i3 >> 2] | 0) + (HEAP32[i2 >> 2] | 0) | 0, i4 | 0) | 0;
8099 HEAP8[i5 + i4 | 0] = 0;
8100 i7 = _strlen(i5 | 0) | 0;
8101 i6 = HEAP32[2] | 0;
8102 if ((i7 | 0) > (i6 | 0)) {
8103  if ((i6 | 0) > 0) {
8104   HEAP8[i5 + i6 | 0] = 0;
8105   _puts(i5 | 0) | 0;
8106   HEAP32[2] = 0;
8107   i6 = 6;
8108  } else {
8109   i6 = 5;
8110  }
8111 } else {
8112  _puts(i5 | 0) | 0;
8113  HEAP32[2] = (HEAP32[2] | 0) - i7;
8114  i6 = 5;
8115 }
8116 if ((i6 | 0) == 5 ? (i5 | 0) != 0 : 0) {
8117  i6 = 6;
8118 }
8119 if ((i6 | 0) == 6) {
8120  __ZdlPv(i5);
8121 }
8122 i4 = (HEAP32[i2 >> 2] | 0) + i4 | 0;
8123 HEAP32[i2 >> 2] = i4;
8124 i3 = HEAP32[i3 + 4 >> 2] | 0;
8125 if (!(i4 >>> 0 > i3 >>> 0)) {
8126  STACKTOP = i1;
8127  return;
8128 }
8129 HEAP32[i2 >> 2] = i4 - i3;
8130 STACKTOP = i1;
8131 return;
8132}
8133function _memcpy(i3, i2, i1) {
8134 i3 = i3 | 0;
8135 i2 = i2 | 0;
8136 i1 = i1 | 0;
8137 var i4 = 0;
8138 if ((i1 | 0) >= 4096) return _emscripten_memcpy_big(i3 | 0, i2 | 0, i1 | 0) | 0;
8139 i4 = i3 | 0;
8140 if ((i3 & 3) == (i2 & 3)) {
8141  while (i3 & 3) {
8142   if ((i1 | 0) == 0) return i4 | 0;
8143   HEAP8[i3] = HEAP8[i2] | 0;
8144   i3 = i3 + 1 | 0;
8145   i2 = i2 + 1 | 0;
8146   i1 = i1 - 1 | 0;
8147  }
8148  while ((i1 | 0) >= 4) {
8149   HEAP32[i3 >> 2] = HEAP32[i2 >> 2];
8150   i3 = i3 + 4 | 0;
8151   i2 = i2 + 4 | 0;
8152   i1 = i1 - 4 | 0;
8153  }
8154 }
8155 while ((i1 | 0) > 0) {
8156  HEAP8[i3] = HEAP8[i2] | 0;
8157  i3 = i3 + 1 | 0;
8158  i2 = i2 + 1 | 0;
8159  i1 = i1 - 1 | 0;
8160 }
8161 return i4 | 0;
8162}
8163function _memset(i1, i4, i3) {
8164 i1 = i1 | 0;
8165 i4 = i4 | 0;
8166 i3 = i3 | 0;
8167 var i2 = 0, i5 = 0, i6 = 0, i7 = 0;
8168 i2 = i1 + i3 | 0;
8169 if ((i3 | 0) >= 20) {
8170  i4 = i4 & 255;
8171  i7 = i1 & 3;
8172  i6 = i4 | i4 << 8 | i4 << 16 | i4 << 24;
8173  i5 = i2 & ~3;
8174  if (i7) {
8175   i7 = i1 + 4 - i7 | 0;
8176   while ((i1 | 0) < (i7 | 0)) {
8177    HEAP8[i1] = i4;
8178    i1 = i1 + 1 | 0;
8179   }
8180  }
8181  while ((i1 | 0) < (i5 | 0)) {
8182   HEAP32[i1 >> 2] = i6;
8183   i1 = i1 + 4 | 0;
8184  }
8185 }
8186 while ((i1 | 0) < (i2 | 0)) {
8187  HEAP8[i1] = i4;
8188  i1 = i1 + 1 | 0;
8189 }
8190 return i1 - i3 | 0;
8191}
8192function __Znwj(i2) {
8193 i2 = i2 | 0;
8194 var i1 = 0, i3 = 0;
8195 i1 = STACKTOP;
8196 i2 = (i2 | 0) == 0 ? 1 : i2;
8197 while (1) {
8198  i3 = _malloc(i2) | 0;
8199  if ((i3 | 0) != 0) {
8200   i2 = 6;
8201   break;
8202  }
8203  i3 = HEAP32[270] | 0;
8204  HEAP32[270] = i3 + 0;
8205  if ((i3 | 0) == 0) {
8206   i2 = 5;
8207   break;
8208  }
8209  FUNCTION_TABLE_v[i3 & 0]();
8210 }
8211 if ((i2 | 0) == 5) {
8212  i3 = ___cxa_allocate_exception(4) | 0;
8213  HEAP32[i3 >> 2] = 1096;
8214  ___cxa_throw(i3 | 0, 1144, 1);
8215 } else if ((i2 | 0) == 6) {
8216  STACKTOP = i1;
8217  return i3 | 0;
8218 }
8219 return 0;
8220}
8221function copyTempDouble(i1) {
8222 i1 = i1 | 0;
8223 HEAP8[tempDoublePtr] = HEAP8[i1];
8224 HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
8225 HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
8226 HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
8227 HEAP8[tempDoublePtr + 4 | 0] = HEAP8[i1 + 4 | 0];
8228 HEAP8[tempDoublePtr + 5 | 0] = HEAP8[i1 + 5 | 0];
8229 HEAP8[tempDoublePtr + 6 | 0] = HEAP8[i1 + 6 | 0];
8230 HEAP8[tempDoublePtr + 7 | 0] = HEAP8[i1 + 7 | 0];
8231}
8232function copyTempFloat(i1) {
8233 i1 = i1 | 0;
8234 HEAP8[tempDoublePtr] = HEAP8[i1];
8235 HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
8236 HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
8237 HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
8238}
8239function __ZNSt9bad_allocD0Ev(i1) {
8240 i1 = i1 | 0;
8241 var i2 = 0;
8242 i2 = STACKTOP;
8243 __ZNSt9exceptionD2Ev(i1 | 0);
8244 __ZdlPv(i1);
8245 STACKTOP = i2;
8246 return;
8247}
8248function stackAlloc(i1) {
8249 i1 = i1 | 0;
8250 var i2 = 0;
8251 i2 = STACKTOP;
8252 STACKTOP = STACKTOP + i1 | 0;
8253 STACKTOP = STACKTOP + 7 & -8;
8254 return i2 | 0;
8255}
8256function __ZNSt9bad_allocD2Ev(i1) {
8257 i1 = i1 | 0;
8258 var i2 = 0;
8259 i2 = STACKTOP;
8260 __ZNSt9exceptionD2Ev(i1 | 0);
8261 STACKTOP = i2;
8262 return;
8263}
8264function __ZdlPv(i1) {
8265 i1 = i1 | 0;
8266 var i2 = 0;
8267 i2 = STACKTOP;
8268 if ((i1 | 0) != 0) {
8269  _free(i1);
8270 }
8271 STACKTOP = i2;
8272 return;
8273}
8274function _strlen(i1) {
8275 i1 = i1 | 0;
8276 var i2 = 0;
8277 i2 = i1;
8278 while (HEAP8[i2] | 0) {
8279  i2 = i2 + 1 | 0;
8280 }
8281 return i2 - i1 | 0;
8282}
8283function setThrew(i1, i2) {
8284 i1 = i1 | 0;
8285 i2 = i2 | 0;
8286 if ((__THREW__ | 0) == 0) {
8287  __THREW__ = i1;
8288  threwValue = i2;
8289 }
8290}
8291function __Znaj(i1) {
8292 i1 = i1 | 0;
8293 var i2 = 0;
8294 i2 = STACKTOP;
8295 i1 = __Znwj(i1) | 0;
8296 STACKTOP = i2;
8297 return i1 | 0;
8298}
8299function runPostSets() {
8300 HEAP32[286] = __ZTVN10__cxxabiv120__si_class_type_infoE;
8301 HEAP32[288] = __ZTISt9exception;
8302}
8303function dynCall_ii(i2, i1) {
8304 i2 = i2 | 0;
8305 i1 = i1 | 0;
8306 return FUNCTION_TABLE_ii[i2 & 1](i1 | 0) | 0;
8307}
8308function __ZdaPv(i1) {
8309 i1 = i1 | 0;
8310 var i2 = 0;
8311 i2 = STACKTOP;
8312 __ZdlPv(i1);
8313 STACKTOP = i2;
8314 return;
8315}
8316function dynCall_vi(i2, i1) {
8317 i2 = i2 | 0;
8318 i1 = i1 | 0;
8319 FUNCTION_TABLE_vi[i2 & 3](i1 | 0);
8320}
8321function dynCall_v(i1) {
8322 i1 = i1 | 0;
8323 FUNCTION_TABLE_v[i1 & 0]();
8324}
8325function __ZNKSt9bad_alloc4whatEv(i1) {
8326 i1 = i1 | 0;
8327 return 1112;
8328}
8329function stackRestore(i1) {
8330 i1 = i1 | 0;
8331 STACKTOP = i1;
8332}
8333function setTempRet9(i1) {
8334 i1 = i1 | 0;
8335 tempRet9 = i1;
8336}
8337function setTempRet8(i1) {
8338 i1 = i1 | 0;
8339 tempRet8 = i1;
8340}
8341function setTempRet7(i1) {
8342 i1 = i1 | 0;
8343 tempRet7 = i1;
8344}
8345function setTempRet6(i1) {
8346 i1 = i1 | 0;
8347 tempRet6 = i1;
8348}
8349function setTempRet5(i1) {
8350 i1 = i1 | 0;
8351 tempRet5 = i1;
8352}
8353function setTempRet4(i1) {
8354 i1 = i1 | 0;
8355 tempRet4 = i1;
8356}
8357function setTempRet3(i1) {
8358 i1 = i1 | 0;
8359 tempRet3 = i1;
8360}
8361function setTempRet2(i1) {
8362 i1 = i1 | 0;
8363 tempRet2 = i1;
8364}
8365function setTempRet1(i1) {
8366 i1 = i1 | 0;
8367 tempRet1 = i1;
8368}
8369function setTempRet0(i1) {
8370 i1 = i1 | 0;
8371 tempRet0 = i1;
8372}
8373function b0(i1) {
8374 i1 = i1 | 0;
8375 abort(0);
8376 return 0;
8377}
8378function stackSave() {
8379 return STACKTOP | 0;
8380}
8381function b1(i1) {
8382 i1 = i1 | 0;
8383 abort(1);
8384}
8385function b2() {
8386 abort(2);
8387}
8388
8389// EMSCRIPTEN_END_FUNCS
8390  var FUNCTION_TABLE_ii = [b0,__ZNKSt9bad_alloc4whatEv];
8391  var FUNCTION_TABLE_vi = [b1,__ZNSt9bad_allocD2Ev,__ZNSt9bad_allocD0Ev,b1];
8392  var FUNCTION_TABLE_v = [b2];
8393
8394  return { _strlen: _strlen, _free: _free, _main: _main, _memset: _memset, _malloc: _malloc, _memcpy: _memcpy, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, setThrew: setThrew, setTempRet0: setTempRet0, setTempRet1: setTempRet1, setTempRet2: setTempRet2, setTempRet3: setTempRet3, setTempRet4: setTempRet4, setTempRet5: setTempRet5, setTempRet6: setTempRet6, setTempRet7: setTempRet7, setTempRet8: setTempRet8, setTempRet9: setTempRet9, dynCall_ii: dynCall_ii, dynCall_vi: dynCall_vi, dynCall_v: dynCall_v };
8395}).toString(),
8396// EMSCRIPTEN_END_ASM
8397{ "Math": Math, "Int8Array": Int8Array, "Int16Array": Int16Array, "Int32Array": Int32Array, "Uint8Array": Uint8Array, "Uint16Array": Uint16Array, "Uint32Array": Uint32Array, "Float32Array": Float32Array, "Float64Array": Float64Array, "abort": abort, "assert": assert, "asmPrintInt": asmPrintInt, "asmPrintFloat": asmPrintFloat, "min": Math_min, "invoke_ii": invoke_ii, "invoke_vi": invoke_vi, "invoke_v": invoke_v, "_send": _send, "___setErrNo": ___setErrNo, "___cxa_is_number_type": ___cxa_is_number_type, "___cxa_allocate_exception": ___cxa_allocate_exception, "___cxa_find_matching_catch": ___cxa_find_matching_catch, "_fflush": _fflush, "_time": _time, "_pwrite": _pwrite, "__reallyNegative": __reallyNegative, "_sbrk": _sbrk, "_emscripten_memcpy_big": _emscripten_memcpy_big, "_fileno": _fileno, "___resumeException": ___resumeException, "__ZSt18uncaught_exceptionv": __ZSt18uncaught_exceptionv, "_sysconf": _sysconf, "_puts": _puts, "_mkport": _mkport, "_write": _write, "___errno_location": ___errno_location, "__ZNSt9exceptionD2Ev": __ZNSt9exceptionD2Ev, "_fputc": _fputc, "___cxa_throw": ___cxa_throw, "_abort": _abort, "_fwrite": _fwrite, "___cxa_does_inherit": ___cxa_does_inherit, "_fprintf": _fprintf, "__formatString": __formatString, "_fputs": _fputs, "_printf": _printf, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "NaN": NaN, "Infinity": Infinity, "__ZTISt9exception": __ZTISt9exception, "__ZTVN10__cxxabiv120__si_class_type_infoE": __ZTVN10__cxxabiv120__si_class_type_infoE }, buffer);
8398var _strlen = Module["_strlen"] = asm["_strlen"];
8399var _free = Module["_free"] = asm["_free"];
8400var _main = Module["_main"] = asm["_main"];
8401var _memset = Module["_memset"] = asm["_memset"];
8402var _malloc = Module["_malloc"] = asm["_malloc"];
8403var _memcpy = Module["_memcpy"] = asm["_memcpy"];
8404var runPostSets = Module["runPostSets"] = asm["runPostSets"];
8405var dynCall_ii = Module["dynCall_ii"] = asm["dynCall_ii"];
8406var dynCall_vi = Module["dynCall_vi"] = asm["dynCall_vi"];
8407var dynCall_v = Module["dynCall_v"] = asm["dynCall_v"];
8408
8409Runtime.stackAlloc = function(size) { return asm['stackAlloc'](size) };
8410Runtime.stackSave = function() { return asm['stackSave']() };
8411Runtime.stackRestore = function(top) { asm['stackRestore'](top) };
8412
8413
8414// Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included
8415var i64Math = null;
8416
8417// === Auto-generated postamble setup entry stuff ===
8418
8419if (memoryInitializer) {
8420  if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
8421    var data = Module['readBinary'](memoryInitializer);
8422    HEAPU8.set(data, STATIC_BASE);
8423  } else {
8424    addRunDependency('memory initializer');
8425    Browser.asyncLoad(memoryInitializer, function(data) {
8426      HEAPU8.set(data, STATIC_BASE);
8427      removeRunDependency('memory initializer');
8428    }, function(data) {
8429      throw 'could not load memory initializer ' + memoryInitializer;
8430    });
8431  }
8432}
8433
8434function ExitStatus(status) {
8435  this.name = "ExitStatus";
8436  this.message = "Program terminated with exit(" + status + ")";
8437  this.status = status;
8438};
8439ExitStatus.prototype = new Error();
8440ExitStatus.prototype.constructor = ExitStatus;
8441
8442var initialStackTop;
8443var preloadStartTime = null;
8444var calledMain = false;
8445
8446dependenciesFulfilled = function runCaller() {
8447  // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
8448  if (!Module['calledRun'] && shouldRunNow) run([].concat(Module["arguments"]));
8449  if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
8450}
8451
8452Module['callMain'] = Module.callMain = function callMain(args) {
8453  assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)');
8454  assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
8455
8456  args = args || [];
8457
8458  ensureInitRuntime();
8459
8460  var argc = args.length+1;
8461  function pad() {
8462    for (var i = 0; i < 4-1; i++) {
8463      argv.push(0);
8464    }
8465  }
8466  var argv = [allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_NORMAL) ];
8467  pad();
8468  for (var i = 0; i < argc-1; i = i + 1) {
8469    argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL));
8470    pad();
8471  }
8472  argv.push(0);
8473  argv = allocate(argv, 'i32', ALLOC_NORMAL);
8474
8475  initialStackTop = STACKTOP;
8476
8477  try {
8478
8479    var ret = Module['_main'](argc, argv, 0);
8480
8481
8482    // if we're not running an evented main loop, it's time to exit
8483    if (!Module['noExitRuntime']) {
8484      exit(ret);
8485    }
8486  }
8487  catch(e) {
8488    if (e instanceof ExitStatus) {
8489      // exit() throws this once it's done to make sure execution
8490      // has been stopped completely
8491      return;
8492    } else if (e == 'SimulateInfiniteLoop') {
8493      // running an evented main loop, don't immediately exit
8494      Module['noExitRuntime'] = true;
8495      return;
8496    } else {
8497      if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]);
8498      throw e;
8499    }
8500  } finally {
8501    calledMain = true;
8502  }
8503}
8504
8505
8506
8507
8508function run(args) {
8509  args = args || Module['arguments'];
8510
8511  if (preloadStartTime === null) preloadStartTime = Date.now();
8512
8513  if (runDependencies > 0) {
8514    Module.printErr('run() called, but dependencies remain, so not running');
8515    return;
8516  }
8517
8518  preRun();
8519
8520  if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
8521  if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame
8522
8523  function doRun() {
8524    if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening
8525    Module['calledRun'] = true;
8526
8527    ensureInitRuntime();
8528
8529    preMain();
8530
8531    if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
8532      Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms');
8533    }
8534
8535    if (Module['_main'] && shouldRunNow) {
8536      Module['callMain'](args);
8537    }
8538
8539    postRun();
8540  }
8541
8542  if (Module['setStatus']) {
8543    Module['setStatus']('Running...');
8544    setTimeout(function() {
8545      setTimeout(function() {
8546        Module['setStatus']('');
8547      }, 1);
8548      if (!ABORT) doRun();
8549    }, 1);
8550  } else {
8551    doRun();
8552  }
8553}
8554Module['run'] = Module.run = run;
8555
8556function exit(status) {
8557  ABORT = true;
8558  EXITSTATUS = status;
8559  STACKTOP = initialStackTop;
8560
8561  // exit the runtime
8562  exitRuntime();
8563
8564  // TODO We should handle this differently based on environment.
8565  // In the browser, the best we can do is throw an exception
8566  // to halt execution, but in node we could process.exit and
8567  // I'd imagine SM shell would have something equivalent.
8568  // This would let us set a proper exit status (which
8569  // would be great for checking test exit statuses).
8570  // https://github.com/kripken/emscripten/issues/1371
8571
8572  // throw an exception to halt the current execution
8573  throw new ExitStatus(status);
8574}
8575Module['exit'] = Module.exit = exit;
8576
8577function abort(text) {
8578  if (text) {
8579    Module.print(text);
8580    Module.printErr(text);
8581  }
8582
8583  ABORT = true;
8584  EXITSTATUS = 1;
8585
8586  var extra = '\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.';
8587
8588  throw 'abort() at ' + stackTrace() + extra;
8589}
8590Module['abort'] = Module.abort = abort;
8591
8592// {{PRE_RUN_ADDITIONS}}
8593
8594if (Module['preInit']) {
8595  if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
8596  while (Module['preInit'].length > 0) {
8597    Module['preInit'].pop()();
8598  }
8599}
8600
8601// shouldRunNow refers to calling main(), not run().
8602var shouldRunNow = true;
8603if (Module['noInitialRun']) {
8604  shouldRunNow = false;
8605}
8606
8607
8608run([].concat(Module["arguments"]));
8609