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