Created
August 15, 2013 20:00
-
-
Save pszturmaj/6244266 to your computer and use it in GitHub Desktop.
LDC2 + Emscripten + SDL + std.algorithms's sort & map
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en-us"> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
<title>Emscripten-Generated Code</title> | |
<style> | |
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; } | |
textarea.emscripten { font-family: monospace; width: 80%; } | |
div.emscripten { text-align: center; } | |
div.emscripten_border { border: 1px solid black; } | |
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */ | |
canvas.emscripten { border: 0px none; } | |
</style> | |
</head> | |
<body> | |
<hr/> | |
<div class="emscripten" id="status">Downloading...</div> | |
<div class="emscripten"> | |
<progress value="0" max="100" id="progress" hidden=1></progress> | |
</div> | |
<div class="emscripten_border"> | |
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas> | |
</div> | |
<hr/> | |
<div class="emscripten"> | |
<input type="checkbox" id="resize">Resize canvas | |
<input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer | |
| |
<input type="button" value="Fullscreen" onclick="Module.requestFullScreen(document.getElementById('pointerLock').checked, | |
document.getElementById('resize').checked)"> | |
</div> | |
<hr/> | |
<textarea class="emscripten" id="output" rows="8"></textarea> | |
<hr> | |
<script type='text/javascript'> | |
// connect to canvas | |
var Module = { | |
preRun: [], | |
postRun: [], | |
print: (function() { | |
var element = document.getElementById('output'); | |
element.value = ''; // clear browser cache | |
return function(text) { | |
text = Array.prototype.slice.call(arguments).join(' '); | |
// These replacements are necessary if you render to raw HTML | |
//text = text.replace(/&/g, "&"); | |
//text = text.replace(/</g, "<"); | |
//text = text.replace(/>/g, ">"); | |
//text = text.replace('\n', '<br>', 'g'); | |
element.value += text + "\n"; | |
element.scrollTop = 99999; // focus on bottom | |
}; | |
})(), | |
printErr: function(text) { | |
text = Array.prototype.slice.call(arguments).join(' '); | |
if (0) { // XXX disabled for safety typeof dump == 'function') { | |
dump(text + '\n'); // fast, straight to the real console | |
} else { | |
console.log(text); | |
} | |
}, | |
canvas: document.getElementById('canvas'), | |
setStatus: function(text) { | |
if (Module.setStatus.interval) clearInterval(Module.setStatus.interval); | |
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); | |
var statusElement = document.getElementById('status'); | |
var progressElement = document.getElementById('progress'); | |
if (m) { | |
text = m[1]; | |
progressElement.value = parseInt(m[2])*100; | |
progressElement.max = parseInt(m[4])*100; | |
progressElement.hidden = false; | |
} else { | |
progressElement.value = null; | |
progressElement.max = null; | |
progressElement.hidden = true; | |
} | |
statusElement.innerHTML = text; | |
}, | |
totalDependencies: 0, | |
monitorRunDependencies: function(left) { | |
this.totalDependencies = Math.max(this.totalDependencies, left); | |
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.'); | |
} | |
}; | |
Module.setStatus('Downloading...'); | |
</script> | |
<script type='text/javascript'>// Note: For maximum-speed code, see "Optimizing Code" on the Emscripten wiki, https://github.com/kripken/emscripten/wiki/Optimizing-Code | |
// Note: Some Emscripten settings may limit the speed of the generated code. | |
// The Module object: Our interface to the outside world. We import | |
// and export values on it, and do the work to get that through | |
// closure compiler if necessary. There are various ways Module can be used: | |
// 1. Not defined. We create it here | |
// 2. A function parameter, function(Module) { ..generated code.. } | |
// 3. pre-run appended it, var Module = {}; ..generated code.. | |
// 4. External script tag defines var Module. | |
// We need to do an eval in order to handle the closure compiler | |
// case, where this code here is minified but Module was defined | |
// elsewhere (e.g. case 4 above). We also need to check if Module | |
// already exists (e.g. case 3 above). | |
// Note that if you want to run closure, and also to use Module | |
// after the generated code, you will need to define var Module = {}; | |
// before the code. Then that object will be used in the code, and you | |
// can continue to use Module afterwards as well. | |
var Module; | |
if (!Module) Module = eval('(function() { try { return Module || {} } catch(e) { return {} } })()'); | |
// Sometimes an existing Module object exists with properties | |
// meant to overwrite the default module functionality. Here | |
// we collect those properties and reapply _after_ we configure | |
// the current environment's defaults to avoid having to be so | |
// defensive during initialization. | |
var moduleOverrides = {}; | |
for (var key in Module) { | |
if (Module.hasOwnProperty(key)) { | |
moduleOverrides[key] = Module[key]; | |
} | |
} | |
// The environment setup code below is customized to use Module. | |
// *** Environment setup code *** | |
var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function'; | |
var ENVIRONMENT_IS_WEB = typeof window === 'object'; | |
var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function'; | |
var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; | |
if (ENVIRONMENT_IS_NODE) { | |
// Expose functionality in the same simple way that the shells work | |
// Note that we pollute the global namespace here, otherwise we break in node | |
Module['print'] = function(x) { | |
process['stdout'].write(x + '\n'); | |
}; | |
Module['printErr'] = function(x) { | |
process['stderr'].write(x + '\n'); | |
}; | |
var nodeFS = require('fs'); | |
var nodePath = require('path'); | |
Module['read'] = function(filename, binary) { | |
filename = nodePath['normalize'](filename); | |
var ret = nodeFS['readFileSync'](filename); | |
// The path is absolute if the normalized version is the same as the resolved. | |
if (!ret && filename != nodePath['resolve'](filename)) { | |
filename = path.join(__dirname, '..', 'src', filename); | |
ret = nodeFS['readFileSync'](filename); | |
} | |
if (ret && !binary) ret = ret.toString(); | |
return ret; | |
}; | |
Module['readBinary'] = function(filename) { return Module['read'](filename, true) }; | |
Module['load'] = function(f) { | |
globalEval(read(f)); | |
}; | |
Module['arguments'] = process['argv'].slice(2); | |
module.exports = Module; | |
} | |
else if (ENVIRONMENT_IS_SHELL) { | |
Module['print'] = print; | |
if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm | |
Module['read'] = read; | |
Module['readBinary'] = function(f) { | |
return read(f, 'binary'); | |
}; | |
if (typeof scriptArgs != 'undefined') { | |
Module['arguments'] = scriptArgs; | |
} else if (typeof arguments != 'undefined') { | |
Module['arguments'] = arguments; | |
} | |
this['Module'] = Module; | |
} | |
else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { | |
Module['read'] = function(url) { | |
var xhr = new XMLHttpRequest(); | |
xhr.open('GET', url, false); | |
xhr.send(null); | |
return xhr.responseText; | |
}; | |
if (typeof arguments != 'undefined') { | |
Module['arguments'] = arguments; | |
} | |
if (ENVIRONMENT_IS_WEB) { | |
Module['print'] = function(x) { | |
console.log(x); | |
}; | |
Module['printErr'] = function(x) { | |
console.log(x); | |
}; | |
this['Module'] = Module; | |
} else if (ENVIRONMENT_IS_WORKER) { | |
// We can do very little here... | |
var TRY_USE_DUMP = false; | |
Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) { | |
dump(x); | |
}) : (function(x) { | |
// self.postMessage(x); // enable this if you want stdout to be sent as messages | |
})); | |
Module['load'] = importScripts; | |
} | |
} | |
else { | |
// Unreachable because SHELL is dependant on the others | |
throw 'Unknown runtime environment. Where are we?'; | |
} | |
function globalEval(x) { | |
eval.call(null, x); | |
} | |
if (!Module['load'] == 'undefined' && Module['read']) { | |
Module['load'] = function(f) { | |
globalEval(Module['read'](f)); | |
}; | |
} | |
if (!Module['print']) { | |
Module['print'] = function(){}; | |
} | |
if (!Module['printErr']) { | |
Module['printErr'] = Module['print']; | |
} | |
if (!Module['arguments']) { | |
Module['arguments'] = []; | |
} | |
// *** Environment setup code *** | |
// Closure helpers | |
Module.print = Module['print']; | |
Module.printErr = Module['printErr']; | |
// Callbacks | |
Module['preRun'] = []; | |
Module['postRun'] = []; | |
// Merge back in the overrides | |
for (var key in moduleOverrides) { | |
if (moduleOverrides.hasOwnProperty(key)) { | |
Module[key] = moduleOverrides[key]; | |
} | |
} | |
// === Auto-generated preamble library stuff === | |
//======================================== | |
// Runtime code shared with compiler | |
//======================================== | |
var Runtime = { | |
stackSave: function () { | |
return STACKTOP; | |
}, | |
stackRestore: function (stackTop) { | |
STACKTOP = stackTop; | |
}, | |
forceAlign: function (target, quantum) { | |
quantum = quantum || 4; | |
if (quantum == 1) return target; | |
if (isNumber(target) && isNumber(quantum)) { | |
return Math.ceil(target/quantum)*quantum; | |
} else if (isNumber(quantum) && isPowerOfTwo(quantum)) { | |
var logg = log2(quantum); | |
return '((((' +target + ')+' + (quantum-1) + ')>>' + logg + ')<<' + logg + ')'; | |
} | |
return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum; | |
}, | |
isNumberType: function (type) { | |
return type in Runtime.INT_TYPES || type in Runtime.FLOAT_TYPES; | |
}, | |
isPointerType: function isPointerType(type) { | |
return type[type.length-1] == '*'; | |
}, | |
isStructType: function isStructType(type) { | |
if (isPointerType(type)) return false; | |
if (isArrayType(type)) return true; | |
if (/<?{ ?[^}]* ?}>?/.test(type)) return true; // { i32, i8 } etc. - anonymous struct types | |
// See comment in isStructPointerType() | |
return type[0] == '%'; | |
}, | |
INT_TYPES: {"i1":0,"i8":0,"i16":0,"i32":0,"i64":0}, | |
FLOAT_TYPES: {"float":0,"double":0}, | |
or64: function (x, y) { | |
var l = (x | 0) | (y | 0); | |
var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296; | |
return l + h; | |
}, | |
and64: function (x, y) { | |
var l = (x | 0) & (y | 0); | |
var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296; | |
return l + h; | |
}, | |
xor64: function (x, y) { | |
var l = (x | 0) ^ (y | 0); | |
var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296; | |
return l + h; | |
}, | |
getNativeTypeSize: function (type, quantumSize) { | |
if (Runtime.QUANTUM_SIZE == 1) return 1; | |
var size = { | |
'%i1': 1, | |
'%i8': 1, | |
'%i16': 2, | |
'%i32': 4, | |
'%i64': 8, | |
"%float": 4, | |
"%double": 8 | |
}['%'+type]; // add '%' since float and double confuse Closure compiler as keys, and also spidermonkey as a compiler will remove 's from '_i8' etc | |
if (!size) { | |
if (type.charAt(type.length-1) == '*') { | |
size = Runtime.QUANTUM_SIZE; // A pointer | |
} else if (type[0] == 'i') { | |
var bits = parseInt(type.substr(1)); | |
assert(bits % 8 == 0); | |
size = bits/8; | |
} | |
} | |
return size; | |
}, | |
getNativeFieldSize: function (type) { | |
return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE); | |
}, | |
dedup: function dedup(items, ident) { | |
var seen = {}; | |
if (ident) { | |
return items.filter(function(item) { | |
if (seen[item[ident]]) return false; | |
seen[item[ident]] = true; | |
return true; | |
}); | |
} else { | |
return items.filter(function(item) { | |
if (seen[item]) return false; | |
seen[item] = true; | |
return true; | |
}); | |
} | |
}, | |
set: function set() { | |
var args = typeof arguments[0] === 'object' ? arguments[0] : arguments; | |
var ret = {}; | |
for (var i = 0; i < args.length; i++) { | |
ret[args[i]] = 0; | |
} | |
return ret; | |
}, | |
STACK_ALIGN: 8, | |
getAlignSize: function (type, size, vararg) { | |
// we align i64s and doubles on 64-bit boundaries, unlike x86 | |
if (type == 'i64' || type == 'double' || vararg) return 8; | |
if (!type) return Math.min(size, 8); // align structures internally to 64 bits | |
return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE); | |
}, | |
calculateStructAlignment: function calculateStructAlignment(type) { | |
type.flatSize = 0; | |
type.alignSize = 0; | |
var diffs = []; | |
var prev = -1; | |
var index = 0; | |
type.flatIndexes = type.fields.map(function(field) { | |
index++; | |
var size, alignSize; | |
if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) { | |
size = Runtime.getNativeTypeSize(field); // pack char; char; in structs, also char[X]s. | |
alignSize = Runtime.getAlignSize(field, size); | |
} else if (Runtime.isStructType(field)) { | |
if (field[1] === '0') { | |
// this is [0 x something]. When inside another structure like here, it must be at the end, | |
// and it adds no size | |
// XXX this happens in java-nbody for example... assert(index === type.fields.length, 'zero-length in the middle!'); | |
size = 0; | |
alignSize = type.alignSize || QUANTUM_SIZE; | |
} else { | |
size = Types.types[field].flatSize; | |
alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize); | |
} | |
} else if (field[0] == 'b') { | |
// bN, large number field, like a [N x i8] | |
size = field.substr(1)|0; | |
alignSize = 1; | |
} else { | |
throw 'Unclear type in struct: ' + field + ', in ' + type.name_ + ' :: ' + dump(Types.types[type.name_]); | |
} | |
if (type.packed) alignSize = 1; | |
type.alignSize = Math.max(type.alignSize, alignSize); | |
var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory | |
type.flatSize = curr + size; | |
if (prev >= 0) { | |
diffs.push(curr-prev); | |
} | |
prev = curr; | |
return curr; | |
}); | |
type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize); | |
if (diffs.length == 0) { | |
type.flatFactor = type.flatSize; | |
} else if (Runtime.dedup(diffs).length == 1) { | |
type.flatFactor = diffs[0]; | |
} | |
type.needsFlattening = (type.flatFactor != 1); | |
return type.flatIndexes; | |
}, | |
generateStructInfo: function (struct, typeName, offset) { | |
var type, alignment; | |
if (typeName) { | |
offset = offset || 0; | |
type = (typeof Types === 'undefined' ? Runtime.typeInfo : Types.types)[typeName]; | |
if (!type) return null; | |
if (type.fields.length != struct.length) { | |
printErr('Number of named fields must match the type for ' + typeName + ': possibly duplicate struct names. Cannot return structInfo'); | |
return null; | |
} | |
alignment = type.flatIndexes; | |
} else { | |
var type = { fields: struct.map(function(item) { return item[0] }) }; | |
alignment = Runtime.calculateStructAlignment(type); | |
} | |
var ret = { | |
__size__: type.flatSize | |
}; | |
if (typeName) { | |
struct.forEach(function(item, i) { | |
if (typeof item === 'string') { | |
ret[item] = alignment[i] + offset; | |
} else { | |
// embedded struct | |
var key; | |
for (var k in item) key = k; | |
ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]); | |
} | |
}); | |
} else { | |
struct.forEach(function(item, i) { | |
ret[item[1]] = alignment[i]; | |
}); | |
} | |
return ret; | |
}, | |
dynCall: function (sig, ptr, args) { | |
if (args && args.length) { | |
if (!args.splice) args = Array.prototype.slice.call(args); | |
args.splice(0, 0, ptr); | |
return Module['dynCall_' + sig].apply(null, args); | |
} else { | |
return Module['dynCall_' + sig].call(null, ptr); | |
} | |
}, | |
functionPointers: [], | |
addFunction: function (func) { | |
for (var i = 0; i < Runtime.functionPointers.length; i++) { | |
if (!Runtime.functionPointers[i]) { | |
Runtime.functionPointers[i] = func; | |
return 2 + 2*i; | |
} | |
} | |
throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.'; | |
}, | |
removeFunction: function (index) { | |
Runtime.functionPointers[(index-2)/2] = null; | |
}, | |
warnOnce: function (text) { | |
if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {}; | |
if (!Runtime.warnOnce.shown[text]) { | |
Runtime.warnOnce.shown[text] = 1; | |
Module.printErr(text); | |
} | |
}, | |
funcWrappers: {}, | |
getFuncWrapper: function (func, sig) { | |
assert(sig); | |
if (!Runtime.funcWrappers[func]) { | |
Runtime.funcWrappers[func] = function() { | |
return Runtime.dynCall(sig, func, arguments); | |
}; | |
} | |
return Runtime.funcWrappers[func]; | |
}, | |
UTF8Processor: function () { | |
var buffer = []; | |
var needed = 0; | |
this.processCChar = function (code) { | |
code = code & 0xff; | |
if (needed) { | |
buffer.push(code); | |
needed--; | |
} | |
if (buffer.length == 0) { | |
if (code < 128) return String.fromCharCode(code); | |
buffer.push(code); | |
if (code > 191 && code < 224) { | |
needed = 1; | |
} else { | |
needed = 2; | |
} | |
return ''; | |
} | |
if (needed > 0) return ''; | |
var c1 = buffer[0]; | |
var c2 = buffer[1]; | |
var c3 = buffer[2]; | |
var ret; | |
if (c1 > 191 && c1 < 224) { | |
ret = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63)); | |
} else { | |
ret = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); | |
} | |
buffer.length = 0; | |
return ret; | |
} | |
this.processJSString = function(string) { | |
string = unescape(encodeURIComponent(string)); | |
var ret = []; | |
for (var i = 0; i < string.length; i++) { | |
ret.push(string.charCodeAt(i)); | |
} | |
return ret; | |
} | |
}, | |
stackAlloc: function (size) { var ret = STACKTOP;STACKTOP = (STACKTOP + size)|0;STACKTOP = ((((STACKTOP)+7)>>3)<<3); return ret; }, | |
staticAlloc: function (size) { var ret = STATICTOP;STATICTOP = (STATICTOP + size)|0;STATICTOP = ((((STATICTOP)+7)>>3)<<3); return ret; }, | |
dynamicAlloc: function (size) { var ret = DYNAMICTOP;DYNAMICTOP = (DYNAMICTOP + size)|0;DYNAMICTOP = ((((DYNAMICTOP)+7)>>3)<<3); if (DYNAMICTOP >= TOTAL_MEMORY) enlargeMemory();; return ret; }, | |
alignMemory: function (size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 8))*(quantum ? quantum : 8); return ret; }, | |
makeBigInt: function (low,high,unsigned) { var ret = (unsigned ? ((+(((low)>>>(0))))+((+(((high)>>>(0))))*(+(4294967296)))) : ((+(((low)>>>(0))))+((+(((high)|(0))))*(+(4294967296))))); return ret; }, | |
GLOBAL_BASE: 8, | |
QUANTUM_SIZE: 4, | |
__dummy__: 0 | |
} | |
//======================================== | |
// Runtime essentials | |
//======================================== | |
var __THREW__ = 0; // Used in checking for thrown exceptions. | |
var ABORT = false; // whether we are quitting the application. no code should run after this. set in exit() and abort() | |
var EXITSTATUS = 0; | |
var undef = 0; | |
// tempInt is used for 32-bit signed values or smaller. tempBigInt is used | |
// for 32-bit unsigned values or more than 32 bits. TODO: audit all uses of tempInt | |
var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD; | |
var tempI64, tempI64b; | |
var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9; | |
function assert(condition, text) { | |
if (!condition) { | |
abort('Assertion failed: ' + text); | |
} | |
} | |
var globalScope = this; | |
// C calling interface. A convenient way to call C functions (in C files, or | |
// defined with extern "C"). | |
// | |
// Note: LLVM optimizations can inline and remove functions, after which you will not be | |
// able to call them. Closure can also do so. To avoid that, add your function to | |
// the exports using something like | |
// | |
// -s EXPORTED_FUNCTIONS='["_main", "_myfunc"]' | |
// | |
// @param ident The name of the C function (note that C++ functions will be name-mangled - use extern "C") | |
// @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and | |
// 'array' for JavaScript arrays and typed arrays; note that arrays are 8-bit). | |
// @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, | |
// except that 'array' is not possible (there is no way for us to know the length of the array) | |
// @param args An array of the arguments to the function, as native JS values (as in returnType) | |
// Note that string arguments will be stored on the stack (the JS string will become a C string on the stack). | |
// @return The return value, as a native JS value (as in returnType) | |
function ccall(ident, returnType, argTypes, args) { | |
return ccallFunc(getCFunc(ident), returnType, argTypes, args); | |
} | |
Module["ccall"] = ccall; | |
// Returns the C function with a specified identifier (for C++, you need to do manual name mangling) | |
function getCFunc(ident) { | |
try { | |
var func = Module['_' + ident]; // closure exported function | |
if (!func) func = eval('_' + ident); // explicit lookup | |
} catch(e) { | |
} | |
assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)'); | |
return func; | |
} | |
// Internal function that does a C call using a function, not an identifier | |
function ccallFunc(func, returnType, argTypes, args) { | |
var stack = 0; | |
function toC(value, type) { | |
if (type == 'string') { | |
if (value === null || value === undefined || value === 0) return 0; // null string | |
if (!stack) stack = Runtime.stackSave(); | |
var ret = Runtime.stackAlloc(value.length+1); | |
writeStringToMemory(value, ret); | |
return ret; | |
} else if (type == 'array') { | |
if (!stack) stack = Runtime.stackSave(); | |
var ret = Runtime.stackAlloc(value.length); | |
writeArrayToMemory(value, ret); | |
return ret; | |
} | |
return value; | |
} | |
function fromC(value, type) { | |
if (type == 'string') { | |
return Pointer_stringify(value); | |
} | |
assert(type != 'array'); | |
return value; | |
} | |
var i = 0; | |
var cArgs = args ? args.map(function(arg) { | |
return toC(arg, argTypes[i++]); | |
}) : []; | |
var ret = fromC(func.apply(null, cArgs), returnType); | |
if (stack) Runtime.stackRestore(stack); | |
return ret; | |
} | |
// Returns a native JS wrapper for a C function. This is similar to ccall, but | |
// returns a function you can call repeatedly in a normal way. For example: | |
// | |
// var my_function = cwrap('my_c_function', 'number', ['number', 'number']); | |
// alert(my_function(5, 22)); | |
// alert(my_function(99, 12)); | |
// | |
function cwrap(ident, returnType, argTypes) { | |
var func = getCFunc(ident); | |
return function() { | |
return ccallFunc(func, returnType, argTypes, Array.prototype.slice.call(arguments)); | |
} | |
} | |
Module["cwrap"] = cwrap; | |
// Sets a value in memory in a dynamic way at run-time. Uses the | |
// type data. This is the same as makeSetValue, except that | |
// makeSetValue is done at compile-time and generates the needed | |
// code then, whereas this function picks the right code at | |
// run-time. | |
// Note that setValue and getValue only do *aligned* writes and reads! | |
// Note that ccall uses JS types as for defining types, while setValue and | |
// getValue need LLVM types ('i8', 'i32') - this is a lower-level operation | |
function setValue(ptr, value, type, noSafe) { | |
type = type || 'i8'; | |
if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit | |
switch(type) { | |
case 'i1': HEAP8[(ptr)]=value; break; | |
case 'i8': HEAP8[(ptr)]=value; break; | |
case 'i16': HEAP16[((ptr)>>1)]=value; break; | |
case 'i32': HEAP32[((ptr)>>2)]=value; break; | |
case 'i64': (tempI64 = [value>>>0,((Math.min((+(Math.floor((value)/(+(4294967296))))), (+(4294967295))))|0)>>>0],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break; | |
case 'float': HEAPF32[((ptr)>>2)]=value; break; | |
case 'double': HEAPF64[((ptr)>>3)]=value; break; | |
default: abort('invalid type for setValue: ' + type); | |
} | |
} | |
Module['setValue'] = setValue; | |
// Parallel to setValue. | |
function getValue(ptr, type, noSafe) { | |
type = type || 'i8'; | |
if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit | |
switch(type) { | |
case 'i1': return HEAP8[(ptr)]; | |
case 'i8': return HEAP8[(ptr)]; | |
case 'i16': return HEAP16[((ptr)>>1)]; | |
case 'i32': return HEAP32[((ptr)>>2)]; | |
case 'i64': return HEAP32[((ptr)>>2)]; | |
case 'float': return HEAPF32[((ptr)>>2)]; | |
case 'double': return HEAPF64[((ptr)>>3)]; | |
default: abort('invalid type for setValue: ' + type); | |
} | |
return null; | |
} | |
Module['getValue'] = getValue; | |
var ALLOC_NORMAL = 0; // Tries to use _malloc() | |
var ALLOC_STACK = 1; // Lives for the duration of the current function call | |
var ALLOC_STATIC = 2; // Cannot be freed | |
var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk | |
var ALLOC_NONE = 4; // Do not allocate | |
Module['ALLOC_NORMAL'] = ALLOC_NORMAL; | |
Module['ALLOC_STACK'] = ALLOC_STACK; | |
Module['ALLOC_STATIC'] = ALLOC_STATIC; | |
Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC; | |
Module['ALLOC_NONE'] = ALLOC_NONE; | |
// allocate(): This is for internal use. You can use it yourself as well, but the interface | |
// is a little tricky (see docs right below). The reason is that it is optimized | |
// for multiple syntaxes to save space in generated code. So you should | |
// normally not use allocate(), and instead allocate memory using _malloc(), | |
// initialize it with setValue(), and so forth. | |
// @slab: An array of data, or a number. If a number, then the size of the block to allocate, | |
// in *bytes* (note that this is sometimes confusing: the next parameter does not | |
// affect this!) | |
// @types: Either an array of types, one for each byte (or 0 if no type at that position), | |
// or a single type which is used for the entire block. This only matters if there | |
// is initial data - if @slab is a number, then this does not matter at all and is | |
// ignored. | |
// @allocator: How to allocate memory, see ALLOC_* | |
function allocate(slab, types, allocator, ptr) { | |
var zeroinit, size; | |
if (typeof slab === 'number') { | |
zeroinit = true; | |
size = slab; | |
} else { | |
zeroinit = false; | |
size = slab.length; | |
} | |
var singleType = typeof types === 'string' ? types : null; | |
var ret; | |
if (allocator == ALLOC_NONE) { | |
ret = ptr; | |
} else { | |
ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc, Runtime.dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length)); | |
} | |
if (zeroinit) { | |
var ptr = ret, stop; | |
assert((ret & 3) == 0); | |
stop = ret + (size & ~3); | |
for (; ptr < stop; ptr += 4) { | |
HEAP32[((ptr)>>2)]=0; | |
} | |
stop = ret + size; | |
while (ptr < stop) { | |
HEAP8[((ptr++)|0)]=0; | |
} | |
return ret; | |
} | |
if (singleType === 'i8') { | |
if (slab.subarray || slab.slice) { | |
HEAPU8.set(slab, ret); | |
} else { | |
HEAPU8.set(new Uint8Array(slab), ret); | |
} | |
return ret; | |
} | |
var i = 0, type, typeSize, previousType; | |
while (i < size) { | |
var curr = slab[i]; | |
if (typeof curr === 'function') { | |
curr = Runtime.getFunctionIndex(curr); | |
} | |
type = singleType || types[i]; | |
if (type === 0) { | |
i++; | |
continue; | |
} | |
if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later | |
setValue(ret+i, curr, type); | |
// no need to look up size unless type changes, so cache it | |
if (previousType !== type) { | |
typeSize = Runtime.getNativeTypeSize(type); | |
previousType = type; | |
} | |
i += typeSize; | |
} | |
return ret; | |
} | |
Module['allocate'] = allocate; | |
function Pointer_stringify(ptr, /* optional */ length) { | |
// Find the length, and check for UTF while doing so | |
var hasUtf = false; | |
var t; | |
var i = 0; | |
while (1) { | |
t = HEAPU8[(((ptr)+(i))|0)]; | |
if (t >= 128) hasUtf = true; | |
else if (t == 0 && !length) break; | |
i++; | |
if (length && i == length) break; | |
} | |
if (!length) length = i; | |
var ret = ''; | |
if (!hasUtf) { | |
var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack | |
var curr; | |
while (length > 0) { | |
curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK))); | |
ret = ret ? ret + curr : curr; | |
ptr += MAX_CHUNK; | |
length -= MAX_CHUNK; | |
} | |
return ret; | |
} | |
var utf8 = new Runtime.UTF8Processor(); | |
for (i = 0; i < length; i++) { | |
t = HEAPU8[(((ptr)+(i))|0)]; | |
ret += utf8.processCChar(t); | |
} | |
return ret; | |
} | |
Module['Pointer_stringify'] = Pointer_stringify; | |
// Memory management | |
var PAGE_SIZE = 4096; | |
function alignMemoryPage(x) { | |
return ((x+4095)>>12)<<12; | |
} | |
var HEAP; | |
var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64; | |
var STATIC_BASE = 0, STATICTOP = 0, staticSealed = false; // static area | |
var STACK_BASE = 0, STACKTOP = 0, STACK_MAX = 0; // stack area | |
var DYNAMIC_BASE = 0, DYNAMICTOP = 0; // dynamic area handled by sbrk | |
function enlargeMemory() { | |
abort('Cannot enlarge memory arrays in asm.js. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value, or (2) set Module.TOTAL_MEMORY before the program runs.'); | |
} | |
var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880; | |
var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 16777216; | |
var FAST_MEMORY = Module['FAST_MEMORY'] || 2097152; | |
// Initialize the runtime's memory | |
// check for full engine support (use string 'subarray' to avoid closure compiler confusion) | |
assert(!!Int32Array && !!Float64Array && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']), | |
'Cannot fallback to non-typed array case: Code is too specialized'); | |
var buffer = new ArrayBuffer(TOTAL_MEMORY); | |
HEAP8 = new Int8Array(buffer); | |
HEAP16 = new Int16Array(buffer); | |
HEAP32 = new Int32Array(buffer); | |
HEAPU8 = new Uint8Array(buffer); | |
HEAPU16 = new Uint16Array(buffer); | |
HEAPU32 = new Uint32Array(buffer); | |
HEAPF32 = new Float32Array(buffer); | |
HEAPF64 = new Float64Array(buffer); | |
// Endianness check (note: assumes compiler arch was little-endian) | |
HEAP32[0] = 255; | |
assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system'); | |
Module['HEAP'] = HEAP; | |
Module['HEAP8'] = HEAP8; | |
Module['HEAP16'] = HEAP16; | |
Module['HEAP32'] = HEAP32; | |
Module['HEAPU8'] = HEAPU8; | |
Module['HEAPU16'] = HEAPU16; | |
Module['HEAPU32'] = HEAPU32; | |
Module['HEAPF32'] = HEAPF32; | |
Module['HEAPF64'] = HEAPF64; | |
function callRuntimeCallbacks(callbacks) { | |
while(callbacks.length > 0) { | |
var callback = callbacks.shift(); | |
if (typeof callback == 'function') { | |
callback(); | |
continue; | |
} | |
var func = callback.func; | |
if (typeof func === 'number') { | |
if (callback.arg === undefined) { | |
Runtime.dynCall('v', func); | |
} else { | |
Runtime.dynCall('vi', func, [callback.arg]); | |
} | |
} else { | |
func(callback.arg === undefined ? null : callback.arg); | |
} | |
} | |
} | |
var __ATPRERUN__ = []; // functions called before the runtime is initialized | |
var __ATINIT__ = []; // functions called during startup | |
var __ATMAIN__ = []; // functions called when main() is to be run | |
var __ATEXIT__ = []; // functions called during shutdown | |
var __ATPOSTRUN__ = []; // functions called after the runtime has exited | |
var runtimeInitialized = false; | |
function preRun() { | |
// compatibility - merge in anything from Module['preRun'] at this time | |
if (Module['preRun']) { | |
if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']]; | |
while (Module['preRun'].length) { | |
addOnPreRun(Module['preRun'].shift()); | |
} | |
} | |
callRuntimeCallbacks(__ATPRERUN__); | |
} | |
function ensureInitRuntime() { | |
if (runtimeInitialized) return; | |
runtimeInitialized = true; | |
callRuntimeCallbacks(__ATINIT__); | |
} | |
function preMain() { | |
callRuntimeCallbacks(__ATMAIN__); | |
} | |
function exitRuntime() { | |
callRuntimeCallbacks(__ATEXIT__); | |
} | |
function postRun() { | |
// compatibility - merge in anything from Module['postRun'] at this time | |
if (Module['postRun']) { | |
if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']]; | |
while (Module['postRun'].length) { | |
addOnPostRun(Module['postRun'].shift()); | |
} | |
} | |
callRuntimeCallbacks(__ATPOSTRUN__); | |
} | |
function addOnPreRun(cb) { | |
__ATPRERUN__.unshift(cb); | |
} | |
Module['addOnPreRun'] = Module.addOnPreRun = addOnPreRun; | |
function addOnInit(cb) { | |
__ATINIT__.unshift(cb); | |
} | |
Module['addOnInit'] = Module.addOnInit = addOnInit; | |
function addOnPreMain(cb) { | |
__ATMAIN__.unshift(cb); | |
} | |
Module['addOnPreMain'] = Module.addOnPreMain = addOnPreMain; | |
function addOnExit(cb) { | |
__ATEXIT__.unshift(cb); | |
} | |
Module['addOnExit'] = Module.addOnExit = addOnExit; | |
function addOnPostRun(cb) { | |
__ATPOSTRUN__.unshift(cb); | |
} | |
Module['addOnPostRun'] = Module.addOnPostRun = addOnPostRun; | |
// Tools | |
// This processes a JS string into a C-line array of numbers, 0-terminated. | |
// For LLVM-originating strings, see parser.js:parseLLVMString function | |
function intArrayFromString(stringy, dontAddNull, length /* optional */) { | |
var ret = (new Runtime.UTF8Processor()).processJSString(stringy); | |
if (length) { | |
ret.length = length; | |
} | |
if (!dontAddNull) { | |
ret.push(0); | |
} | |
return ret; | |
} | |
Module['intArrayFromString'] = intArrayFromString; | |
function intArrayToString(array) { | |
var ret = []; | |
for (var i = 0; i < array.length; i++) { | |
var chr = array[i]; | |
if (chr > 0xFF) { | |
chr &= 0xFF; | |
} | |
ret.push(String.fromCharCode(chr)); | |
} | |
return ret.join(''); | |
} | |
Module['intArrayToString'] = intArrayToString; | |
// Write a Javascript array to somewhere in the heap | |
function writeStringToMemory(string, buffer, dontAddNull) { | |
var array = intArrayFromString(string, dontAddNull); | |
var i = 0; | |
while (i < array.length) { | |
var chr = array[i]; | |
HEAP8[(((buffer)+(i))|0)]=chr | |
i = i + 1; | |
} | |
} | |
Module['writeStringToMemory'] = writeStringToMemory; | |
function writeArrayToMemory(array, buffer) { | |
for (var i = 0; i < array.length; i++) { | |
HEAP8[(((buffer)+(i))|0)]=array[i]; | |
} | |
} | |
Module['writeArrayToMemory'] = writeArrayToMemory; | |
function unSign(value, bits, ignore, sig) { | |
if (value >= 0) { | |
return value; | |
} | |
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 | |
: Math.pow(2, bits) + value; | |
} | |
function reSign(value, bits, ignore, sig) { | |
if (value <= 0) { | |
return value; | |
} | |
var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32 | |
: Math.pow(2, bits-1); | |
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 | |
// but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors | |
// TODO: In i64 mode 1, resign the two parts separately and safely | |
value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts | |
} | |
return value; | |
} | |
if (!Math['imul']) Math['imul'] = function(a, b) { | |
var ah = a >>> 16; | |
var al = a & 0xffff; | |
var bh = b >>> 16; | |
var bl = b & 0xffff; | |
return (al*bl + ((ah*bl + al*bh) << 16))|0; | |
}; | |
Math.imul = Math['imul']; | |
// A counter of dependencies for calling run(). If we need to | |
// do asynchronous work before running, increment this and | |
// decrement it. Incrementing must happen in a place like | |
// PRE_RUN_ADDITIONS (used by emcc to add file preloading). | |
// Note that you can add dependencies in preRun, even though | |
// it happens right before run - run will be postponed until | |
// the dependencies are met. | |
var runDependencies = 0; | |
var runDependencyTracking = {}; | |
var calledInit = false, calledRun = false; | |
var runDependencyWatcher = null; | |
function addRunDependency(id) { | |
runDependencies++; | |
if (Module['monitorRunDependencies']) { | |
Module['monitorRunDependencies'](runDependencies); | |
} | |
if (id) { | |
assert(!runDependencyTracking[id]); | |
runDependencyTracking[id] = 1; | |
} else { | |
Module.printErr('warning: run dependency added without ID'); | |
} | |
} | |
Module['addRunDependency'] = addRunDependency; | |
function removeRunDependency(id) { | |
runDependencies--; | |
if (Module['monitorRunDependencies']) { | |
Module['monitorRunDependencies'](runDependencies); | |
} | |
if (id) { | |
assert(runDependencyTracking[id]); | |
delete runDependencyTracking[id]; | |
} else { | |
Module.printErr('warning: run dependency removed without ID'); | |
} | |
if (runDependencies == 0) { | |
if (runDependencyWatcher !== null) { | |
clearInterval(runDependencyWatcher); | |
runDependencyWatcher = null; | |
} | |
// If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false) | |
if (!calledRun && shouldRunNow) run(); | |
} | |
} | |
Module['removeRunDependency'] = removeRunDependency; | |
Module["preloadedImages"] = {}; // maps url to image data | |
Module["preloadedAudios"] = {}; // maps url to audio data | |
function loadMemoryInitializer(filename) { | |
function applyData(data) { | |
HEAPU8.set(data, STATIC_BASE); | |
} | |
// always do this asynchronously, to keep shell and web as similar as possible | |
addOnPreRun(function() { | |
if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) { | |
applyData(Module['readBinary'](filename)); | |
} else { | |
Browser.asyncLoad(filename, function(data) { | |
applyData(data); | |
}, function(data) { | |
throw 'could not load memory initializer ' + filename; | |
}); | |
} | |
}); | |
} | |
// === Body === | |
STATIC_BASE = 8; | |
STATICTOP = STATIC_BASE + 2816; | |
var __Dmodule_ref; | |
var __D9Exception7__ClassZ; | |
var __D9Exception6__vtblZ; | |
var __D9Exception6__initZ; | |
var __D3std9algorithm12__ModuleInfoZ; | |
var __D3std6format15FormatException7__ClassZ; | |
var __D3std6format15FormatException6__vtblZ; | |
var __D3std6format15FormatException6__initZ; | |
var __D3std6format12__ModuleInfoZ; | |
var __D3std5stdio12__ModuleInfoZ; | |
var __D3std5array12__ModuleInfoZ; | |
var __D3std4conv21ConvOverflowException7__ClassZ; | |
var __D3std4conv21ConvOverflowException6__vtblZ; | |
var __D3std4conv21ConvOverflowException6__initZ; | |
var __D3std4conv13ConvException7__ClassZ; | |
var __D3std4conv13ConvException6__vtblZ; | |
var __D3std4conv13ConvException6__initZ; | |
var __D3std3utf12__ModuleInfoZ; | |
var __D3std3utf12UTFException7__ClassZ; | |
var __D3std3utf12UTFException6__vtblZ; | |
var __D3std3utf12UTFException6__initZ; | |
var __D3SDL12__ModuleInfoZ; | |
var __D15TypeInfo_Struct6__vtblZ; | |
var __D14TypeInfo_Const6__vtblZ; | |
var __D14TypeInfo_Array6__vtblZ; | |
var __D12TypeInfo_Aya6__initZ; | |
var __D11TypeInfo_Ai6__initZ; | |
var __D10TypeInfo_a6__initZ; | |
/* global initializers */ __ATINIT__.push({ func: function() { runPostSets() } },{ func: function() { __D3sdl16__moduleinfoCtorZ() } },{ func: function() { __GLOBAL__I_a() } }); | |
/* memory initializer */ allocate([47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,102,111,114,109,97,116,46,100,0,0,0,0,0,0,0,73,110,99,111,114,114,101,99,116,32,102,111,114,109,97,116,32,115,112,101,99,105,102,105,101,114,58,32,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,102,111,114,109,97,116,46,100,0,0,0,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,102,111,114,109,97,116,46,100,0,0,0,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,102,111,114,109,97,116,46,100,0,0,0,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,102,111,114,109,97,116,46,100,0,0,0,0,0,0,0,73,110,99,111,114,114,101,99,116,32,102,111,114,109,97,116,32,115,112,101,99,105,102,105,101,114,58,32,37,0,0,0,110,117,108,108,32,116,104,105,115,0,0,0,0,0,0,0,110,117,108,108,32,116,104,105,115,0,0,0,0,0,0,0,110,117,108,108,32,116,104,105,115,0,0,0,0,0,0,0,110,117,108,108,32,116,104,105,115,0,0,0,0,0,0,0,110,117,108,108,32,116,104,105,115,0,0,0,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,102,111,114,109,97,116,46,100,0,0,0,0,0,0,0,110,117,108,108,32,116,104,105,115,0,0,0,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,97,114,114,97,121,46,100,0,0,0,0,0,0,0,0,32,97,110,100,32,0,0,0,65,116,116,101,109,112,116,101,100,32,116,111,32,100,101,99,111,100,101,32,112,97,115,116,32,116,104,101,32,101,110,100,32,111,102,32,97,32,115,116,114,105,110,103,0,0,0,0,73,110,118,97,108,105,100,32,85,84,70,45,56,32,115,101,113,117,101,110,99,101,0,0,32,105,110,32,112,111,115,105,116,105,111,110,115,32,0,0,65,116,116,101,109,112,116,101,100,32,116,111,32,100,101,99,111,100,101,32,112,97,115,116,32,116,104,101,32,101,110,100,32,111,102,32,97,32,115,116,114,105,110,103,0,0,0,0,73,110,99,111,114,114,101,99,116,32,102,111,114,109,97,116,32,115,112,101,99,105,102,105,101,114,58,32,37,0,0,0,32,97,110,100,32,98,61,0,80,114,101,100,105,99,97,116,101,32,102,111,114,32,105,115,83,111,114,116,101,100,32,105,115,32,110,111,116,32,97,110,116,105,115,121,109,109,101,116,114,105,99,46,32,66,111,116,104,32,112,114,101,100,40,97,44,32,98,41,32,97,110,100,32,112,114,101,100,40,98,44,32,97,41,32,97,114,101,32,116,114,117,101,32,102,111,114,32,97,61,0,0,0,0,0,110,117,108,108,32,116,104,105,115,0,0,0,0,0,0,0,110,117,108,108,32,116,104,105,115,0,0,0,0,0,0,0,105,110,116,101,103,114,97,108,0,0,0,0,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,99,111,110,118,46,100,0,67,111,110,118,101,114,115,105,111,110,32,112,111,115,105,116,105,118,101,32,111,118,101,114,102,108,111,119,0,0,0,0,105,110,116,101,103,114,97,108,0,0,0,0,0,0,0,0,65,116,116,101,109,112,116,105,110,103,32,116,111,32,112,111,112,70,114,111,110,116,40,41,32,112,97,115,116,32,116,104,101,32,101,110,100,32,111,102,32,97,110,32,97,114,114,97,121,32,111,102,32,99,111,110,115,116,40,99,104,97,114,41,0,0,0,0,0,0,0,0,65,116,116,101,109,112,116,105,110,103,32,116,111,32,102,101,116,99,104,32,116,104,101,32,102,114,111,110,116,32,111,102,32,97,110,32,101,109,112,116,121,32,97,114,114,97,121,32,111,102,32,99,111,110,115,116,40,99,104,97,114,41,0,0,36,32,101,120,112,101,99,116,101,100,0,0,0,0,0,0,36,32,101,120,112,101,99,116,101,100,0,0,0,0,0,0,73,110,99,111,114,114,101,99,116,32,102,111,114,109,97,116,32,115,112,101,99,105,102,105,101,114,32,37,0,0,0,0,36,32,101,120,112,101,99,116,101,100,0,0,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,102,111,114,109,97,116,46,100,0,0,0,0,0,0,0,65,116,116,101,109,112,116,105,110,103,32,116,111,32,112,111,112,70,114,111,110,116,40,41,32,112,97,115,116,32,116,104,101,32,101,110,100,32,111,102,32,97,110,32,97,114,114,97,121,32,111,102,32,105,110,116,0,0,0,0,0,0,0,0,65,116,116,101,109,112,116,105,110,103,32,116,111,32,102,101,116,99,104,32,116,104,101,32,102,114,111,110,116,32,111,102,32,97,110,32,101,109,112,116,121,32,97,114,114,97,121,32,111,102,32,105,110,116,0,0,46,46,46,0,0,0,0,0,46,32,65,99,116,117,97,108,32,114,101,115,117,108,116,32,105,115,58,32,0,0,0,0,105,110,116,91,93,0,0,0,70,97,105,108,101,100,32,116,111,32,115,111,114,116,32,114,97,110,103,101,32,111,102,32,116,121,112,101,32,0,0,0,105,58,32,37,100,10,0,0,115,116,100,46,97,114,114,97,121,46,65,112,112,101,110,100,101,114,33,40,115,116,114,105,110,103,41,46,65,112,112,101,110,100,101,114,46,68,97,116,97,0,0,0,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,117,116,102,46,100,0,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,97,108,103,111,114,105,116,104,109,46,100,0,0,0,0,110,117,108,108,32,116,104,105,115,0,0,0,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,102,111,114,109,97,116,46,100,0,0,0,0,0,0,0,73,110,99,111,114,114,101,99,116,32,102,111,114,109,97,116,32,115,112,101,99,105,102,105,101,114,32,102,111,114,32,114,97,110,103,101,58,32,37,0,93,0,0,0,0,0,0,0,44,32,0,0,0,0,0,0,91,0,0,0,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,102,111,114,109,97,116,46,100,0,0,0,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,99,111,110,118,46,100,0,79,118,101,114,102,108,111,119,32,105,110,32,105,110,116,101,103,114,97,108,32,99,111,110,118,101,114,115,105,111,110,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,99,111,110,118,46,100,0,67,111,110,118,101,114,115,105,111,110,32,112,111,115,105,116,105,118,101,32,111,118,101,114,102,108,111,119,0,0,0,0,32,119,104,101,110,32,99,111,110,118,101,114,116,105,110,103,32,102,114,111,109,32,116,121,112,101,32,99,111,110,115,116,40,99,104,97,114,41,91,93,32,116,111,32,116,121,112,101,32,117,105,110,116,0,0,0,85,110,101,120,112,101,99,116,101,100,32,0,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,99,111,110,118,46,100,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,99,111,110,118,46,100,0,79,118,101,114,102,108,111,119,32,105,110,32,105,110,116,101,103,114,97,108,32,99,111,110,118,101,114,115,105,111,110,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,102,111,114,109,97,116,46,100,0,0,0,0,0,0,0,39,0,0,0,0,0,0,0,39,0,0,0,0,0,0,0,101,110,100,32,111,102,32,105,110,112,117,116,0,0,0,0,32,119,104,101,110,32,99,111,110,118,101,114,116,105,110,103,32,102,114,111,109,32,116,121,112,101,32,99,111,110,115,116,40,99,104,97,114,41,91,93,32,116,111,32,116,121,112,101,32,105,110,116,0,0,0,0,85,110,101,120,112,101,99,116,101,100,32,0,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,99,111,110,118,46,100,0,47,117,115,114,47,108,111,99,97,108,47,105,110,99,108,117,100,101,47,100,47,115,116,100,47,99,111,110,118,46,100,0,79,118,101,114,102,108,111,119,32,105,110,32,105,110,116,101,103,114,97,108,32,99,111,110,118,101,114,115,105,111,110,0,0,0,0,0,0,0,0,0,41,0,0,0,32,5,0,0,12,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,120,86,52,18,0,0,0,0,0,0,0,0,254,255,255,127,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,128,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,115,100,108,0,0,0,0,0,0,0,0,0,184,8,0,0,0,0,0,0,0,0,0,0,240,8,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) | |
var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8); | |
assert(tempDoublePtr % 8 == 0); | |
function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much | |
HEAP8[tempDoublePtr] = HEAP8[ptr]; | |
HEAP8[tempDoublePtr+1] = HEAP8[ptr+1]; | |
HEAP8[tempDoublePtr+2] = HEAP8[ptr+2]; | |
HEAP8[tempDoublePtr+3] = HEAP8[ptr+3]; | |
} | |
function copyTempDouble(ptr) { | |
HEAP8[tempDoublePtr] = HEAP8[ptr]; | |
HEAP8[tempDoublePtr+1] = HEAP8[ptr+1]; | |
HEAP8[tempDoublePtr+2] = HEAP8[ptr+2]; | |
HEAP8[tempDoublePtr+3] = HEAP8[ptr+3]; | |
HEAP8[tempDoublePtr+4] = HEAP8[ptr+4]; | |
HEAP8[tempDoublePtr+5] = HEAP8[ptr+5]; | |
HEAP8[tempDoublePtr+6] = HEAP8[ptr+6]; | |
HEAP8[tempDoublePtr+7] = HEAP8[ptr+7]; | |
} | |
function _emscripten_set_main_loop(func, fps, simulateInfiniteLoop) { | |
Module['noExitRuntime'] = true; | |
Browser.mainLoop.runner = function() { | |
if (ABORT) return; | |
if (Browser.mainLoop.queue.length > 0) { | |
var start = Date.now(); | |
var blocker = Browser.mainLoop.queue.shift(); | |
blocker.func(blocker.arg); | |
if (Browser.mainLoop.remainingBlockers) { | |
var remaining = Browser.mainLoop.remainingBlockers; | |
var next = remaining%1 == 0 ? remaining-1 : Math.floor(remaining); | |
if (blocker.counted) { | |
Browser.mainLoop.remainingBlockers = next; | |
} else { | |
// not counted, but move the progress along a tiny bit | |
next = next + 0.5; // do not steal all the next one's progress | |
Browser.mainLoop.remainingBlockers = (8*remaining + next)/9; | |
} | |
} | |
console.log('main loop blocker "' + blocker.name + '" took ' + (Date.now() - start) + ' ms'); //, left: ' + Browser.mainLoop.remainingBlockers); | |
Browser.mainLoop.updateStatus(); | |
setTimeout(Browser.mainLoop.runner, 0); | |
return; | |
} | |
if (Browser.mainLoop.shouldPause) { | |
// catch pauses from non-main loop sources | |
Browser.mainLoop.paused = true; | |
Browser.mainLoop.shouldPause = false; | |
return; | |
} | |
if (Module['preMainLoop']) { | |
Module['preMainLoop'](); | |
} | |
Runtime.dynCall('v', func); | |
if (Module['postMainLoop']) { | |
Module['postMainLoop'](); | |
} | |
if (Browser.mainLoop.shouldPause) { | |
// catch pauses from the main loop itself | |
Browser.mainLoop.paused = true; | |
Browser.mainLoop.shouldPause = false; | |
return; | |
} | |
Browser.mainLoop.scheduler(); | |
} | |
if (fps && fps > 0) { | |
Browser.mainLoop.scheduler = function() { | |
setTimeout(Browser.mainLoop.runner, 1000/fps); // doing this each time means that on exception, we stop | |
} | |
} else { | |
Browser.mainLoop.scheduler = function() { | |
Browser.requestAnimationFrame(Browser.mainLoop.runner); | |
} | |
} | |
Browser.mainLoop.scheduler(); | |
if (simulateInfiniteLoop) { | |
throw 'SimulateInfiniteLoop'; | |
} | |
} | |
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:35,EIDRM:36,ECHRNG:37,EL2NSYNC:38,EL3HLT:39,EL3RST:40,ELNRNG:41,EUNATCH:42,ENOCSI:43,EL2HLT:44,EDEADLK:45,ENOLCK:46,EBADE:50,EBADR:51,EXFULL:52,ENOANO:53,EBADRQC:54,EBADSLT:55,EDEADLOCK:56,EBFONT:57,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:74,EDOTDOT:76,EBADMSG:77,ENOTUNIQ:80,EBADFD:81,EREMCHG:82,ELIBACC:83,ELIBBAD:84,ELIBSCN:85,ELIBMAX:86,ELIBEXEC:87,ENOSYS:88,ENOTEMPTY:90,ENAMETOOLONG:91,ELOOP:92,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:106,EPROTOTYPE:107,ENOTSOCK:108,ENOPROTOOPT:109,ESHUTDOWN:110,ECONNREFUSED:111,EADDRINUSE:112,ECONNABORTED:113,ENETUNREACH:114,ENETDOWN:115,ETIMEDOUT:116,EHOSTDOWN:117,EHOSTUNREACH:118,EINPROGRESS:119,EALREADY:120,EDESTADDRREQ:121,EMSGSIZE:122,EPROTONOSUPPORT:123,ESOCKTNOSUPPORT:124,EADDRNOTAVAIL:125,ENETRESET:126,EISCONN:127,ENOTCONN:128,ETOOMANYREFS:129,EUSERS:131,EDQUOT:132,ESTALE:133,ENOTSUP:134,ENOMEDIUM:135,EILSEQ:138,EOVERFLOW:139,ECANCELED:140,ENOTRECOVERABLE:141,EOWNERDEAD:142,ESTRPIPE:143}; | |
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:"No message of desired type",36:"Identifier removed",37:"Channel number out of range",38:"Level 2 not synchronized",39:"Level 3 halted",40:"Level 3 reset",41:"Link number out of range",42:"Protocol driver not attached",43:"No CSI structure available",44:"Level 2 halted",45:"Deadlock condition",46:"No record locks available",50:"Invalid exchange",51:"Invalid request descriptor",52:"Exchange full",53:"No anode",54:"Invalid request code",55:"Invalid slot",56:"File locking deadlock error",57:"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",74:"Multihop attempted",76:"Cross mount point (not really error)",77:"Trying to read unreadable message",80:"Given log. name not unique",81:"f.d. invalid for this operation",82:"Remote address changed",83:"Can access a needed shared lib",84:"Accessing a corrupted shared lib",85:".lib section in a.out corrupted",86:"Attempting to link in too many libs",87:"Attempting to exec a shared library",88:"Function not implemented",90:"Directory not empty",91:"File or path name too long",92:"Too many symbolic links",95:"Operation not supported on transport endpoint",96:"Protocol family not supported",104:"Connection reset by peer",105:"No buffer space available",106:"Address family not supported by protocol family",107:"Protocol wrong type for socket",108:"Socket operation on non-socket",109:"Protocol not available",110:"Can't send after socket shutdown",111:"Connection refused",112:"Address already in use",113:"Connection aborted",114:"Network is unreachable",115:"Network interface is not configured",116:"Connection timed out",117:"Host is down",118:"Host is unreachable",119:"Connection already in progress",120:"Socket already connected",121:"Destination address required",122:"Message too long",123:"Unknown protocol",124:"Socket type not supported",125:"Address not available",126:"Connection reset by network",127:"Socket is already connected",128:"Socket is not connected",129:"Too many references",131:"Too many users",132:"Quota exceeded",133:"Stale file handle",134:"Not supported",135:"No medium (in tape drive)",138:"Illegal byte sequence",139:"Value too large for defined data type",140:"Operation canceled",141:"State not recoverable",142:"Previous owner died",143:"Streams pipe error"}; | |
var ___errno_state=0;function ___setErrNo(value) { | |
// For convenient setting and returning of errno. | |
HEAP32[((___errno_state)>>2)]=value | |
return value; | |
} | |
var VFS=undefined; | |
var PATH={splitPath:function (filename) { | |
var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; | |
return splitPathRe.exec(filename).slice(1); | |
},normalizeArray:function (parts, allowAboveRoot) { | |
// if the path tries to go above the root, `up` ends up > 0 | |
var up = 0; | |
for (var i = parts.length - 1; i >= 0; i--) { | |
var last = parts[i]; | |
if (last === '.') { | |
parts.splice(i, 1); | |
} else if (last === '..') { | |
parts.splice(i, 1); | |
up++; | |
} else if (up) { | |
parts.splice(i, 1); | |
up--; | |
} | |
} | |
// if the path is allowed to go above the root, restore leading ..s | |
if (allowAboveRoot) { | |
for (; up--; up) { | |
parts.unshift('..'); | |
} | |
} | |
return parts; | |
},normalize:function (path) { | |
var isAbsolute = path.charAt(0) === '/', | |
trailingSlash = path.substr(-1) === '/'; | |
// Normalize the path | |
path = PATH.normalizeArray(path.split('/').filter(function(p) { | |
return !!p; | |
}), !isAbsolute).join('/'); | |
if (!path && !isAbsolute) { | |
path = '.'; | |
} | |
if (path && trailingSlash) { | |
path += '/'; | |
} | |
return (isAbsolute ? '/' : '') + path; | |
},dirname:function (path) { | |
var result = PATH.splitPath(path), | |
root = result[0], | |
dir = result[1]; | |
if (!root && !dir) { | |
// No dirname whatsoever | |
return '.'; | |
} | |
if (dir) { | |
// It has a dirname, strip trailing slash | |
dir = dir.substr(0, dir.length - 1); | |
} | |
return root + dir; | |
},basename:function (path, ext) { | |
// EMSCRIPTEN return '/'' for '/', not an empty string | |
if (path === '/') return '/'; | |
var f = PATH.splitPath(path)[2]; | |
if (ext && f.substr(-1 * ext.length) === ext) { | |
f = f.substr(0, f.length - ext.length); | |
} | |
return f; | |
},join:function () { | |
var paths = Array.prototype.slice.call(arguments, 0); | |
return PATH.normalize(paths.filter(function(p, index) { | |
if (typeof p !== 'string') { | |
throw new TypeError('Arguments to path.join must be strings'); | |
} | |
return p; | |
}).join('/')); | |
},resolve:function () { | |
var resolvedPath = '', | |
resolvedAbsolute = false; | |
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { | |
var path = (i >= 0) ? arguments[i] : FS.cwd(); | |
// Skip empty and invalid entries | |
if (typeof path !== 'string') { | |
throw new TypeError('Arguments to path.resolve must be strings'); | |
} else if (!path) { | |
continue; | |
} | |
resolvedPath = path + '/' + resolvedPath; | |
resolvedAbsolute = path.charAt(0) === '/'; | |
} | |
// At this point the path should be resolved to a full absolute path, but | |
// handle relative paths to be safe (might happen when process.cwd() fails) | |
resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) { | |
return !!p; | |
}), !resolvedAbsolute).join('/'); | |
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; | |
},relative:function (from, to) { | |
from = PATH.resolve(from).substr(1); | |
to = PATH.resolve(to).substr(1); | |
function trim(arr) { | |
var start = 0; | |
for (; start < arr.length; start++) { | |
if (arr[start] !== '') break; | |
} | |
var end = arr.length - 1; | |
for (; end >= 0; end--) { | |
if (arr[end] !== '') break; | |
} | |
if (start > end) return []; | |
return arr.slice(start, end - start + 1); | |
} | |
var fromParts = trim(from.split('/')); | |
var toParts = trim(to.split('/')); | |
var length = Math.min(fromParts.length, toParts.length); | |
var samePartsLength = length; | |
for (var i = 0; i < length; i++) { | |
if (fromParts[i] !== toParts[i]) { | |
samePartsLength = i; | |
break; | |
} | |
} | |
var outputParts = []; | |
for (var i = samePartsLength; i < fromParts.length; i++) { | |
outputParts.push('..'); | |
} | |
outputParts = outputParts.concat(toParts.slice(samePartsLength)); | |
return outputParts.join('/'); | |
}}; | |
var TTY={ttys:[],register:function (dev, ops) { | |
TTY.ttys[dev] = { input: [], output: [], ops: ops }; | |
FS.registerDevice(dev, TTY.stream_ops); | |
},stream_ops:{open:function (stream) { | |
// this wouldn't be required if the library wasn't eval'd at first... | |
if (!TTY.utf8) { | |
TTY.utf8 = new Runtime.UTF8Processor(); | |
} | |
var tty = TTY.ttys[stream.node.rdev]; | |
if (!tty) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENODEV); | |
} | |
stream.tty = tty; | |
stream.seekable = false; | |
},close:function (stream) { | |
// flush any pending line data | |
if (stream.tty.output.length) { | |
stream.tty.ops.put_char(stream.tty, 10); | |
} | |
},read:function (stream, buffer, offset, length, pos /* ignored */) { | |
if (!stream.tty || !stream.tty.ops.get_char) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENXIO); | |
} | |
var bytesRead = 0; | |
for (var i = 0; i < length; i++) { | |
var result; | |
try { | |
result = stream.tty.ops.get_char(stream.tty); | |
} catch (e) { | |
throw new FS.ErrnoError(ERRNO_CODES.EIO); | |
} | |
if (result === undefined && bytesRead === 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EAGAIN); | |
} | |
if (result === null || result === undefined) break; | |
bytesRead++; | |
buffer[offset+i] = result; | |
} | |
if (bytesRead) { | |
stream.node.timestamp = Date.now(); | |
} | |
return bytesRead; | |
},write:function (stream, buffer, offset, length, pos) { | |
if (!stream.tty || !stream.tty.ops.put_char) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENXIO); | |
} | |
for (var i = 0; i < length; i++) { | |
try { | |
stream.tty.ops.put_char(stream.tty, buffer[offset+i]); | |
} catch (e) { | |
throw new FS.ErrnoError(ERRNO_CODES.EIO); | |
} | |
} | |
if (length) { | |
stream.node.timestamp = Date.now(); | |
} | |
return i; | |
}},default_tty_ops:{get_char:function (tty) { | |
if (!tty.input.length) { | |
var result = null; | |
if (ENVIRONMENT_IS_NODE) { | |
if (process.stdin.destroyed) { | |
return undefined; | |
} | |
result = process.stdin.read(); | |
} else if (typeof window != 'undefined' && | |
typeof window.prompt == 'function') { | |
// Browser. | |
result = window.prompt('Input: '); // returns null on cancel | |
if (result !== null) { | |
result += '\n'; | |
} | |
} else if (typeof readline == 'function') { | |
// Command line. | |
result = readline(); | |
if (result !== null) { | |
result += '\n'; | |
} | |
} | |
if (!result) { | |
return null; | |
} | |
tty.input = intArrayFromString(result, true); | |
} | |
return tty.input.shift(); | |
},put_char:function (tty, val) { | |
if (val === null || val === 10) { | |
Module['print'](tty.output.join('')); | |
tty.output = []; | |
} else { | |
tty.output.push(TTY.utf8.processCChar(val)); | |
} | |
}},default_tty1_ops:{put_char:function (tty, val) { | |
if (val === null || val === 10) { | |
Module['printErr'](tty.output.join('')); | |
tty.output = []; | |
} else { | |
tty.output.push(TTY.utf8.processCChar(val)); | |
} | |
}}}; | |
var MEMFS={mount:function (mount) { | |
return MEMFS.create_node(null, '/', 0040000 | 0777, 0); | |
},create_node:function (parent, name, mode, dev) { | |
if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { | |
// no supported | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
var node = FS.createNode(parent, name, mode, dev); | |
node.node_ops = MEMFS.node_ops; | |
if (FS.isDir(node.mode)) { | |
node.stream_ops = MEMFS.stream_ops; | |
node.contents = {}; | |
} else if (FS.isFile(node.mode)) { | |
node.stream_ops = MEMFS.stream_ops; | |
node.contents = []; | |
} else if (FS.isLink(node.mode)) { | |
node.stream_ops = MEMFS.stream_ops; | |
} else if (FS.isChrdev(node.mode)) { | |
node.stream_ops = FS.chrdev_stream_ops; | |
} | |
node.timestamp = Date.now(); | |
// add the new node to the parent | |
if (parent) { | |
parent.contents[name] = node; | |
} | |
return node; | |
},node_ops:{getattr:function (node) { | |
var attr = {}; | |
// device numbers reuse inode numbers. | |
attr.dev = FS.isChrdev(node.mode) ? node.id : 1; | |
attr.ino = node.id; | |
attr.mode = node.mode; | |
attr.nlink = 1; | |
attr.uid = 0; | |
attr.gid = 0; | |
attr.rdev = node.rdev; | |
if (FS.isDir(node.mode)) { | |
attr.size = 4096; | |
} else if (FS.isFile(node.mode)) { | |
attr.size = node.contents.length; | |
} else if (FS.isLink(node.mode)) { | |
attr.size = node.link.length; | |
} else { | |
attr.size = 0; | |
} | |
attr.atime = new Date(node.timestamp); | |
attr.mtime = new Date(node.timestamp); | |
attr.ctime = new Date(node.timestamp); | |
// NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize), | |
// but this is not required by the standard. | |
attr.blksize = 4096; | |
attr.blocks = Math.ceil(attr.size / attr.blksize); | |
return attr; | |
},setattr:function (node, attr) { | |
if (attr.mode !== undefined) { | |
node.mode = attr.mode; | |
} | |
if (attr.timestamp !== undefined) { | |
node.timestamp = attr.timestamp; | |
} | |
if (attr.size !== undefined) { | |
var contents = node.contents; | |
if (attr.size < contents.length) contents.length = attr.size; | |
else while (attr.size > contents.length) contents.push(0); | |
} | |
},lookup:function (parent, name) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOENT); | |
},mknod:function (parent, name, mode, dev) { | |
return MEMFS.create_node(parent, name, mode, dev); | |
},rename:function (old_node, new_dir, new_name) { | |
// if we're overwriting a directory at new_name, make sure it's empty. | |
if (FS.isDir(old_node.mode)) { | |
var new_node; | |
try { | |
new_node = FS.lookupNode(new_dir, new_name); | |
} catch (e) { | |
} | |
if (new_node) { | |
for (var i in new_node.contents) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY); | |
} | |
} | |
} | |
// do the internal rewiring | |
delete old_node.parent.contents[old_node.name]; | |
old_node.name = new_name; | |
new_dir.contents[new_name] = old_node; | |
},unlink:function (parent, name) { | |
delete parent.contents[name]; | |
},rmdir:function (parent, name) { | |
var node = FS.lookupNode(parent, name); | |
for (var i in node.contents) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY); | |
} | |
delete parent.contents[name]; | |
},symlink:function (parent, newname, oldpath) { | |
var node = MEMFS.create_node(parent, newname, 0777 | 0120000, 0); | |
node.link = oldpath; | |
return node; | |
},readlink:function (node) { | |
if (!FS.isLink(node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
return node.link; | |
}},stream_ops:{open:function (stream) { | |
if (FS.isDir(stream.node.mode)) { | |
// cache off the directory entries when open'd | |
var entries = ['.', '..'] | |
for (var key in stream.node.contents) { | |
if (!stream.node.contents.hasOwnProperty(key)) { | |
continue; | |
} | |
entries.push(key); | |
} | |
stream.entries = entries; | |
} | |
},read:function (stream, buffer, offset, length, position) { | |
var contents = stream.node.contents; | |
var size = Math.min(contents.length - position, length); | |
if (contents.subarray) { // typed array | |
buffer.set(contents.subarray(position, position + size), offset); | |
} else | |
{ | |
for (var i = 0; i < size; i++) { | |
buffer[offset + i] = contents[position + i]; | |
} | |
} | |
return size; | |
},write:function (stream, buffer, offset, length, position) { | |
var contents = stream.node.contents; | |
while (contents.length < position) contents.push(0); | |
for (var i = 0; i < length; i++) { | |
contents[position + i] = buffer[offset + i]; | |
} | |
stream.node.timestamp = Date.now(); | |
return length; | |
},llseek:function (stream, offset, whence) { | |
var position = offset; | |
if (whence === 1) { // SEEK_CUR. | |
position += stream.position; | |
} else if (whence === 2) { // SEEK_END. | |
if (FS.isFile(stream.node.mode)) { | |
position += stream.node.contents.length; | |
} | |
} | |
if (position < 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
stream.ungotten = []; | |
stream.position = position; | |
return position; | |
},readdir:function (stream) { | |
return stream.entries; | |
},allocate:function (stream, offset, length) { | |
var contents = stream.node.contents; | |
var limit = offset + length; | |
while (limit > contents.length) contents.push(0); | |
},mmap:function (stream, buffer, offset, length, position, prot, flags) { | |
if (!FS.isFile(stream.node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENODEV); | |
} | |
var ptr; | |
var allocated; | |
var contents = stream.node.contents; | |
// Only make a new copy when MAP_PRIVATE is specified. | |
if (!(flags & 0x02)) { | |
// We can't emulate MAP_SHARED when the file is not backed by the buffer | |
// we're mapping to (e.g. the HEAP buffer). | |
assert(contents.buffer === buffer || contents.buffer === buffer.buffer); | |
allocated = false; | |
ptr = contents.byteOffset; | |
} else { | |
// Try to avoid unnecessary slices. | |
if (position > 0 || position + length < contents.length) { | |
if (contents.subarray) { | |
contents = contents.subarray(position, position + length); | |
} else { | |
contents = Array.prototype.slice.call(contents, position, position + length); | |
} | |
} | |
allocated = true; | |
ptr = _malloc(length); | |
if (!ptr) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOMEM); | |
} | |
buffer.set(contents, ptr); | |
} | |
return { ptr: ptr, allocated: allocated }; | |
}}}; | |
var _stdin=allocate(1, "i32*", ALLOC_STATIC); | |
var _stdout=allocate(1, "i32*", ALLOC_STATIC); | |
var _stderr=allocate(1, "i32*", ALLOC_STATIC); | |
function _fflush(stream) { | |
// int fflush(FILE *stream); | |
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fflush.html | |
// we don't currently perform any user-space buffering of data | |
}var FS={root:null,nodes:[null],devices:[null],streams:[null],nextInode:1,name_table:[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,],currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:function (errno) { | |
this.errno = errno; | |
for (var key in ERRNO_CODES) { | |
if (ERRNO_CODES[key] === errno) { | |
this.code = key; | |
break; | |
} | |
} | |
this.message = ERRNO_MESSAGES[errno] + ' : ' + new Error().stack; | |
},handleFSError:function (e) { | |
if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + new Error().stack; | |
return ___setErrNo(e.errno); | |
},hashName:function (parentid, name) { | |
var hash = 0; | |
for (var i = 0; i < name.length; i++) { | |
hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0; | |
} | |
return (parentid + hash) % FS.name_table.length; | |
},hashAddNode:function (node) { | |
var hash = FS.hashName(node.parent.id, node.name); | |
node.name_next = FS.name_table[hash]; | |
FS.name_table[hash] = node; | |
},hashRemoveNode:function (node) { | |
var hash = FS.hashName(node.parent.id, node.name); | |
if (FS.name_table[hash] === node) { | |
FS.name_table[hash] = node.name_next; | |
} else { | |
var current = FS.name_table[hash]; | |
while (current) { | |
if (current.name_next === node) { | |
current.name_next = node.name_next; | |
break; | |
} | |
current = current.name_next; | |
} | |
} | |
},lookupNode:function (parent, name) { | |
var err = FS.mayLookup(parent); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
var hash = FS.hashName(parent.id, name); | |
for (var node = FS.name_table[hash]; node; node = node.name_next) { | |
if (node.parent.id === parent.id && node.name === name) { | |
return node; | |
} | |
} | |
// if we failed to find it in the cache, call into the VFS | |
return FS.lookup(parent, name); | |
},createNode:function (parent, name, mode, rdev) { | |
var node = { | |
id: FS.nextInode++, | |
name: name, | |
mode: mode, | |
node_ops: {}, | |
stream_ops: {}, | |
rdev: rdev, | |
parent: null, | |
mount: null | |
}; | |
if (!parent) { | |
parent = node; // root node sets parent to itself | |
} | |
node.parent = parent; | |
node.mount = parent.mount; | |
// compatibility | |
var readMode = 292 | 73; | |
var writeMode = 146; | |
// NOTE we must use Object.defineProperties instead of individual calls to | |
// Object.defineProperty in order to make closure compiler happy | |
Object.defineProperties(node, { | |
read: { | |
get: function() { return (node.mode & readMode) === readMode; }, | |
set: function(val) { val ? node.mode |= readMode : node.mode &= ~readMode; } | |
}, | |
write: { | |
get: function() { return (node.mode & writeMode) === writeMode; }, | |
set: function(val) { val ? node.mode |= writeMode : node.mode &= ~writeMode; } | |
}, | |
isFolder: { | |
get: function() { return FS.isDir(node.mode); }, | |
}, | |
isDevice: { | |
get: function() { return FS.isChrdev(node.mode); }, | |
}, | |
}); | |
FS.hashAddNode(node); | |
return node; | |
},destroyNode:function (node) { | |
FS.hashRemoveNode(node); | |
},isRoot:function (node) { | |
return node === node.parent; | |
},isMountpoint:function (node) { | |
return node.mounted; | |
},isFile:function (mode) { | |
return (mode & 0170000) === 0100000; | |
},isDir:function (mode) { | |
return (mode & 0170000) === 0040000; | |
},isLink:function (mode) { | |
return (mode & 0170000) === 0120000; | |
},isChrdev:function (mode) { | |
return (mode & 0170000) === 0020000; | |
},isBlkdev:function (mode) { | |
return (mode & 0170000) === 0060000; | |
},isFIFO:function (mode) { | |
return (mode & 0170000) === 0010000; | |
},cwd:function () { | |
return FS.currentPath; | |
},lookupPath:function (path, opts) { | |
path = PATH.resolve(FS.currentPath, path); | |
opts = opts || { recurse_count: 0 }; | |
if (opts.recurse_count > 8) { // max recursive lookup of 8 | |
throw new FS.ErrnoError(ERRNO_CODES.ELOOP); | |
} | |
// split the path | |
var parts = PATH.normalizeArray(path.split('/').filter(function(p) { | |
return !!p; | |
}), false); | |
// start at the root | |
var current = FS.root; | |
var current_path = '/'; | |
for (var i = 0; i < parts.length; i++) { | |
var islast = (i === parts.length-1); | |
if (islast && opts.parent) { | |
// stop resolving | |
break; | |
} | |
current = FS.lookupNode(current, parts[i]); | |
current_path = PATH.join(current_path, parts[i]); | |
// jump to the mount's root node if this is a mountpoint | |
if (FS.isMountpoint(current)) { | |
current = current.mount.root; | |
} | |
// follow symlinks | |
// by default, lookupPath will not follow a symlink if it is the final path component. | |
// setting opts.follow = true will override this behavior. | |
if (!islast || opts.follow) { | |
var count = 0; | |
while (FS.isLink(current.mode)) { | |
var link = FS.readlink(current_path); | |
current_path = PATH.resolve(PATH.dirname(current_path), link); | |
var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count }); | |
current = lookup.node; | |
if (count++ > 40) { // limit max consecutive symlinks to 40 (SYMLOOP_MAX). | |
throw new FS.ErrnoError(ERRNO_CODES.ELOOP); | |
} | |
} | |
} | |
} | |
return { path: current_path, node: current }; | |
},getPath:function (node) { | |
var path; | |
while (true) { | |
if (FS.isRoot(node)) { | |
return path ? PATH.join(node.mount.mountpoint, path) : node.mount.mountpoint; | |
} | |
path = path ? PATH.join(node.name, path) : node.name; | |
node = node.parent; | |
} | |
},flagModes:{"r":0,"rs":8192,"r+":2,"w":1537,"wx":3585,"xw":3585,"w+":1538,"wx+":3586,"xw+":3586,"a":521,"ax":2569,"xa":2569,"a+":522,"ax+":2570,"xa+":2570},modeStringToFlags:function (str) { | |
var flags = FS.flagModes[str]; | |
if (typeof flags === 'undefined') { | |
throw new Error('Unknown file open mode: ' + str); | |
} | |
return flags; | |
},flagsToPermissionString:function (flag) { | |
var accmode = flag & 3; | |
var perms = ['r', 'w', 'rw'][accmode]; | |
if ((flag & 1024)) { | |
perms += 'w'; | |
} | |
return perms; | |
},nodePermissions:function (node, perms) { | |
if (FS.ignorePermissions) { | |
return 0; | |
} | |
// return 0 if any user, group or owner bits are set. | |
if (perms.indexOf('r') !== -1 && !(node.mode & 292)) { | |
return ERRNO_CODES.EACCES; | |
} else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) { | |
return ERRNO_CODES.EACCES; | |
} else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) { | |
return ERRNO_CODES.EACCES; | |
} | |
return 0; | |
},mayLookup:function (dir) { | |
return FS.nodePermissions(dir, 'x'); | |
},mayMknod:function (mode) { | |
switch (mode & 0170000) { | |
case 0100000: | |
case 0020000: | |
case 0060000: | |
case 0010000: | |
case 0140000: | |
return 0; | |
default: | |
return ERRNO_CODES.EINVAL; | |
} | |
},mayCreate:function (dir, name) { | |
try { | |
var node = FS.lookupNode(dir, name); | |
return ERRNO_CODES.EEXIST; | |
} catch (e) { | |
} | |
return FS.nodePermissions(dir, 'wx'); | |
},mayDelete:function (dir, name, isdir) { | |
var node; | |
try { | |
node = FS.lookupNode(dir, name); | |
} catch (e) { | |
return e.errno; | |
} | |
var err = FS.nodePermissions(dir, 'wx'); | |
if (err) { | |
return err; | |
} | |
if (isdir) { | |
if (!FS.isDir(node.mode)) { | |
return ERRNO_CODES.ENOTDIR; | |
} | |
if (FS.isRoot(node) || FS.getPath(node) === FS.currentPath) { | |
return ERRNO_CODES.EBUSY; | |
} | |
} else { | |
if (FS.isDir(node.mode)) { | |
return ERRNO_CODES.EISDIR; | |
} | |
} | |
return 0; | |
},mayOpen:function (node, flags) { | |
if (!node) { | |
return ERRNO_CODES.ENOENT; | |
} | |
if (FS.isLink(node.mode)) { | |
return ERRNO_CODES.ELOOP; | |
} else if (FS.isDir(node.mode)) { | |
if ((flags & 3) !== 0 || // opening for write | |
(flags & 1024)) { | |
return ERRNO_CODES.EISDIR; | |
} | |
} | |
return FS.nodePermissions(node, FS.flagsToPermissionString(flags)); | |
},chrdev_stream_ops:{open:function (stream) { | |
var device = FS.getDevice(stream.node.rdev); | |
// override node's stream ops with the device's | |
stream.stream_ops = device.stream_ops; | |
// forward the open call | |
if (stream.stream_ops.open) { | |
stream.stream_ops.open(stream); | |
} | |
},llseek:function () { | |
throw new FS.ErrnoError(ERRNO_CODES.ESPIPE); | |
}},major:function (dev) { | |
return ((dev) >> 8); | |
},minor:function (dev) { | |
return ((dev) & 0xff); | |
},makedev:function (ma, mi) { | |
return ((ma) << 8 | (mi)); | |
},registerDevice:function (dev, ops) { | |
FS.devices[dev] = { stream_ops: ops }; | |
},getDevice:function (dev) { | |
return FS.devices[dev]; | |
},MAX_OPEN_FDS:4096,nextfd:function (fd_start, fd_end) { | |
fd_start = fd_start || 1; | |
fd_end = fd_end || FS.MAX_OPEN_FDS; | |
for (var fd = fd_start; fd <= fd_end; fd++) { | |
if (!FS.streams[fd]) { | |
return fd; | |
} | |
} | |
throw new FS.ErrnoError(ERRNO_CODES.EMFILE); | |
},getStream:function (fd) { | |
return FS.streams[fd]; | |
},createStream:function (stream, fd_start, fd_end) { | |
var fd = FS.nextfd(fd_start, fd_end); | |
stream.fd = fd; | |
// compatibility | |
Object.defineProperties(stream, { | |
object: { | |
get: function() { return stream.node; }, | |
set: function(val) { stream.node = val; } | |
}, | |
isRead: { | |
get: function() { return (stream.flags & 3) !== 1; } | |
}, | |
isWrite: { | |
get: function() { return (stream.flags & 3) !== 0; } | |
}, | |
isAppend: { | |
get: function() { return (stream.flags & 8); } | |
} | |
}); | |
FS.streams[fd] = stream; | |
return stream; | |
},closeStream:function (fd) { | |
FS.streams[fd] = null; | |
},getMode:function (canRead, canWrite) { | |
var mode = 0; | |
if (canRead) mode |= 292 | 73; | |
if (canWrite) mode |= 146; | |
return mode; | |
},joinPath:function (parts, forceRelative) { | |
var path = PATH.join.apply(null, parts); | |
if (forceRelative && path[0] == '/') path = path.substr(1); | |
return path; | |
},absolutePath:function (relative, base) { | |
return PATH.resolve(base, relative); | |
},standardizePath:function (path) { | |
return PATH.normalize(path); | |
},findObject:function (path, dontResolveLastLink) { | |
var ret = FS.analyzePath(path, dontResolveLastLink); | |
if (ret.exists) { | |
return ret.object; | |
} else { | |
___setErrNo(ret.error); | |
return null; | |
} | |
},analyzePath:function (path, dontResolveLastLink) { | |
// operate from within the context of the symlink's target | |
try { | |
var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink }); | |
path = lookup.path; | |
} catch (e) { | |
} | |
var ret = { | |
isRoot: false, exists: false, error: 0, name: null, path: null, object: null, | |
parentExists: false, parentPath: null, parentObject: null | |
}; | |
try { | |
var lookup = FS.lookupPath(path, { parent: true }); | |
ret.parentExists = true; | |
ret.parentPath = lookup.path; | |
ret.parentObject = lookup.node; | |
ret.name = PATH.basename(path); | |
lookup = FS.lookupPath(path, { follow: !dontResolveLastLink }); | |
ret.exists = true; | |
ret.path = lookup.path; | |
ret.object = lookup.node; | |
ret.name = lookup.node.name; | |
ret.isRoot = lookup.path === '/'; | |
} catch (e) { | |
ret.error = e.errno; | |
}; | |
return ret; | |
},createFolder:function (parent, name, canRead, canWrite) { | |
var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name); | |
var mode = FS.getMode(canRead, canWrite); | |
return FS.mkdir(path, mode); | |
},createPath:function (parent, path, canRead, canWrite) { | |
parent = typeof parent === 'string' ? parent : FS.getPath(parent); | |
var parts = path.split('/').reverse(); | |
while (parts.length) { | |
var part = parts.pop(); | |
if (!part) continue; | |
var current = PATH.join(parent, part); | |
try { | |
FS.mkdir(current, 0777); | |
} catch (e) { | |
// ignore EEXIST | |
} | |
parent = current; | |
} | |
return current; | |
},createFile:function (parent, name, properties, canRead, canWrite) { | |
var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name); | |
var mode = FS.getMode(canRead, canWrite); | |
return FS.create(path, mode); | |
},createDataFile:function (parent, name, data, canRead, canWrite) { | |
var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name); | |
var mode = FS.getMode(canRead, canWrite); | |
var node = FS.create(path, mode); | |
if (data) { | |
if (typeof data === 'string') { | |
var arr = new Array(data.length); | |
for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i); | |
data = arr; | |
} | |
// make sure we can write to the file | |
FS.chmod(path, mode | 146); | |
var stream = FS.open(path, 'w'); | |
FS.write(stream, data, 0, data.length, 0); | |
FS.close(stream); | |
FS.chmod(path, mode); | |
} | |
return node; | |
},createDevice:function (parent, name, input, output) { | |
var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name); | |
var mode = input && output ? 0777 : (input ? 0333 : 0555); | |
if (!FS.createDevice.major) FS.createDevice.major = 64; | |
var dev = FS.makedev(FS.createDevice.major++, 0); | |
// Create a fake device that a set of stream ops to emulate | |
// the old behavior. | |
FS.registerDevice(dev, { | |
open: function(stream) { | |
stream.seekable = false; | |
}, | |
close: function(stream) { | |
// flush any pending line data | |
if (output && output.buffer && output.buffer.length) { | |
output(10); | |
} | |
}, | |
read: function(stream, buffer, offset, length, pos /* ignored */) { | |
var bytesRead = 0; | |
for (var i = 0; i < length; i++) { | |
var result; | |
try { | |
result = input(); | |
} catch (e) { | |
throw new FS.ErrnoError(ERRNO_CODES.EIO); | |
} | |
if (result === undefined && bytesRead === 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EAGAIN); | |
} | |
if (result === null || result === undefined) break; | |
bytesRead++; | |
buffer[offset+i] = result; | |
} | |
if (bytesRead) { | |
stream.node.timestamp = Date.now(); | |
} | |
return bytesRead; | |
}, | |
write: function(stream, buffer, offset, length, pos) { | |
for (var i = 0; i < length; i++) { | |
try { | |
output(buffer[offset+i]); | |
} catch (e) { | |
throw new FS.ErrnoError(ERRNO_CODES.EIO); | |
} | |
} | |
if (length) { | |
stream.node.timestamp = Date.now(); | |
} | |
return i; | |
} | |
}); | |
return FS.mkdev(path, mode, dev); | |
},createLink:function (parent, name, target, canRead, canWrite) { | |
var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name); | |
return FS.symlink(target, path); | |
},forceLoadFile:function (obj) { | |
if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true; | |
var success = true; | |
if (typeof XMLHttpRequest !== 'undefined') { | |
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."); | |
} else if (Module['read']) { | |
// Command-line. | |
try { | |
// WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as | |
// read() will try to parse UTF8. | |
obj.contents = intArrayFromString(Module['read'](obj.url), true); | |
} catch (e) { | |
success = false; | |
} | |
} else { | |
throw new Error('Cannot load without read() or XMLHttpRequest.'); | |
} | |
if (!success) ___setErrNo(ERRNO_CODES.EIO); | |
return success; | |
},createLazyFile:function (parent, name, url, canRead, canWrite) { | |
if (typeof XMLHttpRequest !== 'undefined') { | |
if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc'; | |
// Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse. | |
var LazyUint8Array = function() { | |
this.lengthKnown = false; | |
this.chunks = []; // Loaded chunks. Index is the chunk number | |
} | |
LazyUint8Array.prototype.get = function(idx) { | |
if (idx > this.length-1 || idx < 0) { | |
return undefined; | |
} | |
var chunkOffset = idx % this.chunkSize; | |
var chunkNum = Math.floor(idx / this.chunkSize); | |
return this.getter(chunkNum)[chunkOffset]; | |
} | |
LazyUint8Array.prototype.setDataGetter = function(getter) { | |
this.getter = getter; | |
} | |
LazyUint8Array.prototype.cacheLength = function() { | |
// Find length | |
var xhr = new XMLHttpRequest(); | |
xhr.open('HEAD', url, false); | |
xhr.send(null); | |
if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); | |
var datalength = Number(xhr.getResponseHeader("Content-length")); | |
var header; | |
var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; | |
var chunkSize = 1024*1024; // Chunk size in bytes | |
if (!hasByteServing) chunkSize = datalength; | |
// Function to get a range from the remote URL. | |
var doXHR = (function(from, to) { | |
if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!"); | |
if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!"); | |
// TODO: Use mozResponseArrayBuffer, responseStream, etc. if available. | |
var xhr = new XMLHttpRequest(); | |
xhr.open('GET', url, false); | |
if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); | |
// Some hints to the browser that we want binary data. | |
if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer'; | |
if (xhr.overrideMimeType) { | |
xhr.overrideMimeType('text/plain; charset=x-user-defined'); | |
} | |
xhr.send(null); | |
if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); | |
if (xhr.response !== undefined) { | |
return new Uint8Array(xhr.response || []); | |
} else { | |
return intArrayFromString(xhr.responseText || '', true); | |
} | |
}); | |
var lazyArray = this; | |
lazyArray.setDataGetter(function(chunkNum) { | |
var start = chunkNum * chunkSize; | |
var end = (chunkNum+1) * chunkSize - 1; // including this byte | |
end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block | |
if (typeof(lazyArray.chunks[chunkNum]) === "undefined") { | |
lazyArray.chunks[chunkNum] = doXHR(start, end); | |
} | |
if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!"); | |
return lazyArray.chunks[chunkNum]; | |
}); | |
this._length = datalength; | |
this._chunkSize = chunkSize; | |
this.lengthKnown = true; | |
} | |
var lazyArray = new LazyUint8Array(); | |
Object.defineProperty(lazyArray, "length", { | |
get: function() { | |
if(!this.lengthKnown) { | |
this.cacheLength(); | |
} | |
return this._length; | |
} | |
}); | |
Object.defineProperty(lazyArray, "chunkSize", { | |
get: function() { | |
if(!this.lengthKnown) { | |
this.cacheLength(); | |
} | |
return this._chunkSize; | |
} | |
}); | |
var properties = { isDevice: false, contents: lazyArray }; | |
} else { | |
var properties = { isDevice: false, url: url }; | |
} | |
var node = FS.createFile(parent, name, properties, canRead, canWrite); | |
// This is a total hack, but I want to get this lazy file code out of the | |
// core of MEMFS. If we want to keep this lazy file concept I feel it should | |
// be its own thin LAZYFS proxying calls to MEMFS. | |
if (properties.contents) { | |
node.contents = properties.contents; | |
} else if (properties.url) { | |
node.contents = null; | |
node.url = properties.url; | |
} | |
// override each stream op with one that tries to force load the lazy file first | |
var stream_ops = {}; | |
var keys = Object.keys(node.stream_ops); | |
keys.forEach(function(key) { | |
var fn = node.stream_ops[key]; | |
stream_ops[key] = function() { | |
if (!FS.forceLoadFile(node)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EIO); | |
} | |
return fn.apply(null, arguments); | |
}; | |
}); | |
// use a custom read function | |
stream_ops.read = function(stream, buffer, offset, length, position) { | |
var contents = stream.node.contents; | |
var size = Math.min(contents.length - position, length); | |
if (contents.slice) { // normal array | |
for (var i = 0; i < size; i++) { | |
buffer[offset + i] = contents[position + i]; | |
} | |
} else { | |
for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR | |
buffer[offset + i] = contents.get(position + i); | |
} | |
} | |
return size; | |
}; | |
node.stream_ops = stream_ops; | |
return node; | |
},createPreloadedFile:function (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile) { | |
Browser.init(); | |
// TODO we should allow people to just pass in a complete filename instead | |
// of parent and name being that we just join them anyways | |
var fullname = PATH.resolve(PATH.join(parent, name)); | |
function processData(byteArray) { | |
function finish(byteArray) { | |
if (!dontCreateFile) { | |
FS.createDataFile(parent, name, byteArray, canRead, canWrite); | |
} | |
if (onload) onload(); | |
removeRunDependency('cp ' + fullname); | |
} | |
var handled = false; | |
Module['preloadPlugins'].forEach(function(plugin) { | |
if (handled) return; | |
if (plugin['canHandle'](fullname)) { | |
plugin['handle'](byteArray, fullname, finish, function() { | |
if (onerror) onerror(); | |
removeRunDependency('cp ' + fullname); | |
}); | |
handled = true; | |
} | |
}); | |
if (!handled) finish(byteArray); | |
} | |
addRunDependency('cp ' + fullname); | |
if (typeof url == 'string') { | |
Browser.asyncLoad(url, function(byteArray) { | |
processData(byteArray); | |
}, onerror); | |
} else { | |
processData(url); | |
} | |
},createDefaultDirectories:function () { | |
FS.mkdir('/tmp', 0777); | |
},createDefaultDevices:function () { | |
// create /dev | |
FS.mkdir('/dev', 0777); | |
// setup /dev/null | |
FS.registerDevice(FS.makedev(1, 3), { | |
read: function() { return 0; }, | |
write: function() { return 0; } | |
}); | |
FS.mkdev('/dev/null', 0666, FS.makedev(1, 3)); | |
// setup /dev/tty and /dev/tty1 | |
// stderr needs to print output using Module['printErr'] | |
// so we register a second tty just for it. | |
TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); | |
TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); | |
FS.mkdev('/dev/tty', 0666, FS.makedev(5, 0)); | |
FS.mkdev('/dev/tty1', 0666, FS.makedev(6, 0)); | |
// we're not going to emulate the actual shm device, | |
// just create the tmp dirs that reside in it commonly | |
FS.mkdir('/dev/shm', 0777); | |
FS.mkdir('/dev/shm/tmp', 0777); | |
},createStandardStreams:function () { | |
// TODO deprecate the old functionality of a single | |
// input / output callback and that utilizes FS.createDevice | |
// and instead require a unique set of stream ops | |
// by default, we symlink the standard streams to the | |
// default tty devices. however, if the standard streams | |
// have been overwritten we create a unique device for | |
// them instead. | |
if (Module['stdin']) { | |
FS.createDevice('/dev', 'stdin', Module['stdin']); | |
} else { | |
FS.symlink('/dev/tty', '/dev/stdin'); | |
} | |
if (Module['stdout']) { | |
FS.createDevice('/dev', 'stdout', null, Module['stdout']); | |
} else { | |
FS.symlink('/dev/tty', '/dev/stdout'); | |
} | |
if (Module['stderr']) { | |
FS.createDevice('/dev', 'stderr', null, Module['stderr']); | |
} else { | |
FS.symlink('/dev/tty1', '/dev/stderr'); | |
} | |
// open default streams for the stdin, stdout and stderr devices | |
var stdin = FS.open('/dev/stdin', 'r'); | |
HEAP32[((_stdin)>>2)]=stdin.fd; | |
assert(stdin.fd === 1, 'invalid handle for stdin (' + stdin.fd + ')'); | |
var stdout = FS.open('/dev/stdout', 'w'); | |
HEAP32[((_stdout)>>2)]=stdout.fd; | |
assert(stdout.fd === 2, 'invalid handle for stdout (' + stdout.fd + ')'); | |
var stderr = FS.open('/dev/stderr', 'w'); | |
HEAP32[((_stderr)>>2)]=stderr.fd; | |
assert(stderr.fd === 3, 'invalid handle for stderr (' + stderr.fd + ')'); | |
},staticInit:function () { | |
FS.root = FS.createNode(null, '/', 0040000 | 0777, 0); | |
FS.mount(MEMFS, {}, '/'); | |
FS.createDefaultDirectories(); | |
FS.createDefaultDevices(); | |
},init:function (input, output, error) { | |
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)'); | |
FS.init.initialized = true; | |
// Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here | |
Module['stdin'] = input || Module['stdin']; | |
Module['stdout'] = output || Module['stdout']; | |
Module['stderr'] = error || Module['stderr']; | |
FS.createStandardStreams(); | |
},quit:function () { | |
FS.init.initialized = false; | |
for (var i = 0; i < FS.streams.length; i++) { | |
var stream = FS.streams[i]; | |
if (!stream) { | |
continue; | |
} | |
FS.close(stream); | |
} | |
},mount:function (type, opts, mountpoint) { | |
var mount = { | |
type: type, | |
opts: opts, | |
mountpoint: mountpoint, | |
root: null | |
}; | |
var lookup; | |
if (mountpoint) { | |
lookup = FS.lookupPath(mountpoint, { follow: false }); | |
} | |
// create a root node for the fs | |
var root = type.mount(mount); | |
root.mount = mount; | |
mount.root = root; | |
// assign the mount info to the mountpoint's node | |
if (lookup) { | |
lookup.node.mount = mount; | |
lookup.node.mounted = true; | |
// compatibility update FS.root if we mount to / | |
if (mountpoint === '/') { | |
FS.root = mount.root; | |
} | |
} | |
return root; | |
},lookup:function (parent, name) { | |
return parent.node_ops.lookup(parent, name); | |
},mknod:function (path, mode, dev) { | |
var lookup = FS.lookupPath(path, { parent: true }); | |
var parent = lookup.node; | |
var name = PATH.basename(path); | |
var err = FS.mayCreate(parent, name); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
if (!parent.node_ops.mknod) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
return parent.node_ops.mknod(parent, name, mode, dev); | |
},create:function (path, mode) { | |
mode &= 4095; | |
mode |= 0100000; | |
return FS.mknod(path, mode, 0); | |
},mkdir:function (path, mode) { | |
mode &= 511 | 0001000; | |
mode |= 0040000; | |
return FS.mknod(path, mode, 0); | |
},mkdev:function (path, mode, dev) { | |
mode |= 0020000; | |
return FS.mknod(path, mode, dev); | |
},symlink:function (oldpath, newpath) { | |
var lookup = FS.lookupPath(newpath, { parent: true }); | |
var parent = lookup.node; | |
var newname = PATH.basename(newpath); | |
var err = FS.mayCreate(parent, newname); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
if (!parent.node_ops.symlink) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
return parent.node_ops.symlink(parent, newname, oldpath); | |
},rename:function (old_path, new_path) { | |
var old_dirname = PATH.dirname(old_path); | |
var new_dirname = PATH.dirname(new_path); | |
var old_name = PATH.basename(old_path); | |
var new_name = PATH.basename(new_path); | |
// parents must exist | |
var lookup, old_dir, new_dir; | |
try { | |
lookup = FS.lookupPath(old_path, { parent: true }); | |
old_dir = lookup.node; | |
lookup = FS.lookupPath(new_path, { parent: true }); | |
new_dir = lookup.node; | |
} catch (e) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBUSY); | |
} | |
// need to be part of the same mount | |
if (old_dir.mount !== new_dir.mount) { | |
throw new FS.ErrnoError(ERRNO_CODES.EXDEV); | |
} | |
// source must exist | |
var old_node = FS.lookupNode(old_dir, old_name); | |
// old path should not be an ancestor of the new path | |
var relative = PATH.relative(old_path, new_dirname); | |
if (relative.charAt(0) !== '.') { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
// new path should not be an ancestor of the old path | |
relative = PATH.relative(new_path, old_dirname); | |
if (relative.charAt(0) !== '.') { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY); | |
} | |
// see if the new path already exists | |
var new_node; | |
try { | |
new_node = FS.lookupNode(new_dir, new_name); | |
} catch (e) { | |
// not fatal | |
} | |
// early out if nothing needs to change | |
if (old_node === new_node) { | |
return; | |
} | |
// we'll need to delete the old entry | |
var isdir = FS.isDir(old_node.mode); | |
var err = FS.mayDelete(old_dir, old_name, isdir); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
// need delete permissions if we'll be overwriting. | |
// need create permissions if new doesn't already exist. | |
err = new_node ? | |
FS.mayDelete(new_dir, new_name, isdir) : | |
FS.mayCreate(new_dir, new_name); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
if (!old_dir.node_ops.rename) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBUSY); | |
} | |
// if we are going to change the parent, check write permissions | |
if (new_dir !== old_dir) { | |
err = FS.nodePermissions(old_dir, 'w'); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
} | |
// remove the node from the lookup hash | |
FS.hashRemoveNode(old_node); | |
// do the underlying fs rename | |
try { | |
old_node.node_ops.rename(old_node, new_dir, new_name); | |
} catch (e) { | |
throw e; | |
} finally { | |
// add the node back to the hash (in case node_ops.rename | |
// changed its name) | |
FS.hashAddNode(old_node); | |
} | |
},rmdir:function (path) { | |
var lookup = FS.lookupPath(path, { parent: true }); | |
var parent = lookup.node; | |
var name = PATH.basename(path); | |
var node = FS.lookupNode(parent, name); | |
var err = FS.mayDelete(parent, name, true); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
if (!parent.node_ops.rmdir) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
if (FS.isMountpoint(node)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBUSY); | |
} | |
parent.node_ops.rmdir(parent, name); | |
FS.destroyNode(node); | |
},unlink:function (path) { | |
var lookup = FS.lookupPath(path, { parent: true }); | |
var parent = lookup.node; | |
var name = PATH.basename(path); | |
var node = FS.lookupNode(parent, name); | |
var err = FS.mayDelete(parent, name, false); | |
if (err) { | |
// POSIX says unlink should set EPERM, not EISDIR | |
if (err === ERRNO_CODES.EISDIR) err = ERRNO_CODES.EPERM; | |
throw new FS.ErrnoError(err); | |
} | |
if (!parent.node_ops.unlink) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
if (FS.isMountpoint(node)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBUSY); | |
} | |
parent.node_ops.unlink(parent, name); | |
FS.destroyNode(node); | |
},readlink:function (path) { | |
var lookup = FS.lookupPath(path, { follow: false }); | |
var link = lookup.node; | |
if (!link.node_ops.readlink) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
return link.node_ops.readlink(link); | |
},stat:function (path, dontFollow) { | |
var lookup = FS.lookupPath(path, { follow: !dontFollow }); | |
var node = lookup.node; | |
if (!node.node_ops.getattr) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
return node.node_ops.getattr(node); | |
},lstat:function (path) { | |
return FS.stat(path, true); | |
},chmod:function (path, mode, dontFollow) { | |
var node; | |
if (typeof path === 'string') { | |
var lookup = FS.lookupPath(path, { follow: !dontFollow }); | |
node = lookup.node; | |
} else { | |
node = path; | |
} | |
if (!node.node_ops.setattr) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
node.node_ops.setattr(node, { | |
mode: (mode & 4095) | (node.mode & ~4095), | |
timestamp: Date.now() | |
}); | |
},lchmod:function (path, mode) { | |
FS.chmod(path, mode, true); | |
},fchmod:function (fd, mode) { | |
var stream = FS.getStream(fd); | |
if (!stream) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBADF); | |
} | |
FS.chmod(stream.node, mode); | |
},chown:function (path, uid, gid, dontFollow) { | |
var node; | |
if (typeof path === 'string') { | |
var lookup = FS.lookupPath(path, { follow: !dontFollow }); | |
node = lookup.node; | |
} else { | |
node = path; | |
} | |
if (!node.node_ops.setattr) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
node.node_ops.setattr(node, { | |
timestamp: Date.now() | |
// we ignore the uid / gid for now | |
}); | |
},lchown:function (path, uid, gid) { | |
FS.chown(path, uid, gid, true); | |
},fchown:function (fd, uid, gid) { | |
var stream = FS.getStream(fd); | |
if (!stream) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBADF); | |
} | |
FS.chown(stream.node, uid, gid); | |
},truncate:function (path, len) { | |
if (len < 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
var node; | |
if (typeof path === 'string') { | |
var lookup = FS.lookupPath(path, { follow: true }); | |
node = lookup.node; | |
} else { | |
node = path; | |
} | |
if (!node.node_ops.setattr) { | |
throw new FS.ErrnoError(ERRNO_CODES.EPERM); | |
} | |
if (FS.isDir(node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EISDIR); | |
} | |
if (!FS.isFile(node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
var err = FS.nodePermissions(node, 'w'); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
node.node_ops.setattr(node, { | |
size: len, | |
timestamp: Date.now() | |
}); | |
},ftruncate:function (fd, len) { | |
var stream = FS.getStream(fd); | |
if (!stream) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBADF); | |
} | |
if ((stream.flags & 3) === 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
FS.truncate(stream.node, len); | |
},utime:function (path, atime, mtime) { | |
var lookup = FS.lookupPath(path, { follow: true }); | |
var node = lookup.node; | |
node.node_ops.setattr(node, { | |
timestamp: Math.max(atime, mtime) | |
}); | |
},open:function (path, flags, mode, fd_start, fd_end) { | |
path = PATH.normalize(path); | |
flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags; | |
if ((flags & 512)) { | |
mode = (mode & 4095) | 0100000; | |
} else { | |
mode = 0; | |
} | |
var node; | |
try { | |
var lookup = FS.lookupPath(path, { | |
follow: !(flags & 0200000) | |
}); | |
node = lookup.node; | |
path = lookup.path; | |
} catch (e) { | |
// ignore | |
} | |
// perhaps we need to create the node | |
if ((flags & 512)) { | |
if (node) { | |
// if O_CREAT and O_EXCL are set, error out if the node already exists | |
if ((flags & 2048)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EEXIST); | |
} | |
} else { | |
// node doesn't exist, try to create it | |
node = FS.mknod(path, mode, 0); | |
} | |
} | |
if (!node) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOENT); | |
} | |
// can't truncate a device | |
if (FS.isChrdev(node.mode)) { | |
flags &= ~1024; | |
} | |
// check permissions | |
var err = FS.mayOpen(node, flags); | |
if (err) { | |
throw new FS.ErrnoError(err); | |
} | |
// do truncation if necessary | |
if ((flags & 1024)) { | |
FS.truncate(node, 0); | |
} | |
// register the stream with the filesystem | |
var stream = FS.createStream({ | |
path: path, | |
node: node, | |
flags: flags, | |
seekable: true, | |
position: 0, | |
stream_ops: node.stream_ops, | |
// used by the file family libc calls (fopen, fwrite, ferror, etc.) | |
ungotten: [], | |
error: false | |
}, fd_start, fd_end); | |
// call the new stream's open function | |
if (stream.stream_ops.open) { | |
stream.stream_ops.open(stream); | |
} | |
return stream; | |
},close:function (stream) { | |
try { | |
if (stream.stream_ops.close) { | |
stream.stream_ops.close(stream); | |
} | |
} catch (e) { | |
throw e; | |
} finally { | |
FS.closeStream(stream.fd); | |
} | |
},llseek:function (stream, offset, whence) { | |
if (!stream.seekable || !stream.stream_ops.llseek) { | |
throw new FS.ErrnoError(ERRNO_CODES.ESPIPE); | |
} | |
return stream.stream_ops.llseek(stream, offset, whence); | |
},readdir:function (stream) { | |
if (!stream.stream_ops.readdir) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR); | |
} | |
return stream.stream_ops.readdir(stream); | |
},read:function (stream, buffer, offset, length, position) { | |
if (length < 0 || position < 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
if ((stream.flags & 3) === 1) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBADF); | |
} | |
if (FS.isDir(stream.node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EISDIR); | |
} | |
if (!stream.stream_ops.read) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
var seeking = true; | |
if (typeof position === 'undefined') { | |
position = stream.position; | |
seeking = false; | |
} else if (!stream.seekable) { | |
throw new FS.ErrnoError(ERRNO_CODES.ESPIPE); | |
} | |
var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position); | |
if (!seeking) stream.position += bytesRead; | |
return bytesRead; | |
},write:function (stream, buffer, offset, length, position) { | |
if (length < 0 || position < 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
if ((stream.flags & 3) === 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBADF); | |
} | |
if (FS.isDir(stream.node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.EISDIR); | |
} | |
if (!stream.stream_ops.write) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
var seeking = true; | |
if (typeof position === 'undefined') { | |
position = stream.position; | |
seeking = false; | |
} else if (!stream.seekable) { | |
throw new FS.ErrnoError(ERRNO_CODES.ESPIPE); | |
} | |
if (stream.flags & 8) { | |
// seek to the end before writing in append mode | |
FS.llseek(stream, 0, 2); | |
} | |
var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position); | |
if (!seeking) stream.position += bytesWritten; | |
return bytesWritten; | |
},allocate:function (stream, offset, length) { | |
if (offset < 0 || length <= 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EINVAL); | |
} | |
if ((stream.flags & 3) === 0) { | |
throw new FS.ErrnoError(ERRNO_CODES.EBADF); | |
} | |
if (!FS.isFile(stream.node.mode) && !FS.isDir(node.mode)) { | |
throw new FS.ErrnoError(ERRNO_CODES.ENODEV); | |
} | |
if (!stream.stream_ops.allocate) { | |
throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP); | |
} | |
stream.stream_ops.allocate(stream, offset, length); | |
},mmap:function (stream, buffer, offset, length, position, prot, flags) { | |
// TODO if PROT is PROT_WRITE, make sure we have write access | |
if ((stream.flags & 3) === 1) { | |
throw new FS.ErrnoError(ERRNO_CODES.EACCES); | |
} | |
if (!stream.stream_ops.mmap) { | |
throw new FS.errnoError(ERRNO_CODES.ENODEV); | |
} | |
return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags); | |
}}; | |
var Browser={mainLoop:{scheduler:null,shouldPause:false,paused:false,queue:[],pause:function () { | |
Browser.mainLoop.shouldPause = true; | |
},resume:function () { | |
if (Browser.mainLoop.paused) { | |
Browser.mainLoop.paused = false; | |
Browser.mainLoop.scheduler(); | |
} | |
Browser.mainLoop.shouldPause = false; | |
},updateStatus:function () { | |
if (Module['setStatus']) { | |
var message = Module['statusMessage'] || 'Please wait...'; | |
var remaining = Browser.mainLoop.remainingBlockers; | |
var expected = Browser.mainLoop.expectedBlockers; | |
if (remaining) { | |
if (remaining < expected) { | |
Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')'); | |
} else { | |
Module['setStatus'](message); | |
} | |
} else { | |
Module['setStatus'](''); | |
} | |
} | |
}},isFullScreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function () { | |
if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers | |
if (Browser.initted || ENVIRONMENT_IS_WORKER) return; | |
Browser.initted = true; | |
try { | |
new Blob(); | |
Browser.hasBlobConstructor = true; | |
} catch(e) { | |
Browser.hasBlobConstructor = false; | |
console.log("warning: no blob constructor, cannot create blobs with mimetypes"); | |
} | |
Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null)); | |
Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined; | |
if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') { | |
console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available."); | |
Module.noImageDecoding = true; | |
} | |
// Support for plugins that can process preloaded files. You can add more of these to | |
// your app by creating and appending to Module.preloadPlugins. | |
// | |
// Each plugin is asked if it can handle a file based on the file's name. If it can, | |
// it is given the file's raw data. When it is done, it calls a callback with the file's | |
// (possibly modified) data. For example, a plugin might decompress a file, or it | |
// might create some side data structure for use later (like an Image element, etc.). | |
var imagePlugin = {}; | |
imagePlugin['canHandle'] = function(name) { | |
return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name); | |
}; | |
imagePlugin['handle'] = function(byteArray, name, onload, onerror) { | |
var b = null; | |
if (Browser.hasBlobConstructor) { | |
try { | |
b = new Blob([byteArray], { type: Browser.getMimetype(name) }); | |
if (b.size !== byteArray.length) { // Safari bug #118630 | |
// Safari's Blob can only take an ArrayBuffer | |
b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) }); | |
} | |
} catch(e) { | |
Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder'); | |
} | |
} | |
if (!b) { | |
var bb = new Browser.BlobBuilder(); | |
bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range | |
b = bb.getBlob(); | |
} | |
var url = Browser.URLObject.createObjectURL(b); | |
var img = new Image(); | |
img.onload = function() { | |
assert(img.complete, 'Image ' + name + ' could not be decoded'); | |
var canvas = document.createElement('canvas'); | |
canvas.width = img.width; | |
canvas.height = img.height; | |
var ctx = canvas.getContext('2d'); | |
ctx.drawImage(img, 0, 0); | |
Module["preloadedImages"][name] = canvas; | |
Browser.URLObject.revokeObjectURL(url); | |
if (onload) onload(byteArray); | |
}; | |
img.onerror = function(event) { | |
console.log('Image ' + url + ' could not be decoded'); | |
if (onerror) onerror(); | |
}; | |
img.src = url; | |
}; | |
Module['preloadPlugins'].push(imagePlugin); | |
var audioPlugin = {}; | |
audioPlugin['canHandle'] = function(name) { | |
return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 }; | |
}; | |
audioPlugin['handle'] = function(byteArray, name, onload, onerror) { | |
var done = false; | |
function finish(audio) { | |
if (done) return; | |
done = true; | |
Module["preloadedAudios"][name] = audio; | |
if (onload) onload(byteArray); | |
} | |
function fail() { | |
if (done) return; | |
done = true; | |
Module["preloadedAudios"][name] = new Audio(); // empty shim | |
if (onerror) onerror(); | |
} | |
if (Browser.hasBlobConstructor) { | |
try { | |
var b = new Blob([byteArray], { type: Browser.getMimetype(name) }); | |
} catch(e) { | |
return fail(); | |
} | |
var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this! | |
var audio = new Audio(); | |
audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926 | |
audio.onerror = function(event) { | |
if (done) return; | |
console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach'); | |
function encode64(data) { | |
var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; | |
var PAD = '='; | |
var ret = ''; | |
var leftchar = 0; | |
var leftbits = 0; | |
for (var i = 0; i < data.length; i++) { | |
leftchar = (leftchar << 8) | data[i]; | |
leftbits += 8; | |
while (leftbits >= 6) { | |
var curr = (leftchar >> (leftbits-6)) & 0x3f; | |
leftbits -= 6; | |
ret += BASE[curr]; | |
} | |
} | |
if (leftbits == 2) { | |
ret += BASE[(leftchar&3) << 4]; | |
ret += PAD + PAD; | |
} else if (leftbits == 4) { | |
ret += BASE[(leftchar&0xf) << 2]; | |
ret += PAD; | |
} | |
return ret; | |
} | |
audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray); | |
finish(audio); // we don't wait for confirmation this worked - but it's worth trying | |
}; | |
audio.src = url; | |
// workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror | |
Browser.safeSetTimeout(function() { | |
finish(audio); // try to use it even though it is not necessarily ready to play | |
}, 10000); | |
} else { | |
return fail(); | |
} | |
}; | |
Module['preloadPlugins'].push(audioPlugin); | |
// Canvas event setup | |
var canvas = Module['canvas']; | |
canvas.requestPointerLock = canvas['requestPointerLock'] || | |
canvas['mozRequestPointerLock'] || | |
canvas['webkitRequestPointerLock']; | |
canvas.exitPointerLock = document['exitPointerLock'] || | |
document['mozExitPointerLock'] || | |
document['webkitExitPointerLock'] || | |
function(){}; // no-op if function does not exist | |
canvas.exitPointerLock = canvas.exitPointerLock.bind(document); | |
function pointerLockChange() { | |
Browser.pointerLock = document['pointerLockElement'] === canvas || | |
document['mozPointerLockElement'] === canvas || | |
document['webkitPointerLockElement'] === canvas; | |
} | |
document.addEventListener('pointerlockchange', pointerLockChange, false); | |
document.addEventListener('mozpointerlockchange', pointerLockChange, false); | |
document.addEventListener('webkitpointerlockchange', pointerLockChange, false); | |
if (Module['elementPointerLock']) { | |
canvas.addEventListener("click", function(ev) { | |
if (!Browser.pointerLock && canvas.requestPointerLock) { | |
canvas.requestPointerLock(); | |
ev.preventDefault(); | |
} | |
}, false); | |
} | |
},createContext:function (canvas, useWebGL, setInModule) { | |
var ctx; | |
try { | |
if (useWebGL) { | |
ctx = canvas.getContext('experimental-webgl', { | |
alpha: false | |
}); | |
} else { | |
ctx = canvas.getContext('2d'); | |
} | |
if (!ctx) throw ':('; | |
} catch (e) { | |
Module.print('Could not create canvas - ' + e); | |
return null; | |
} | |
if (useWebGL) { | |
// Set the background of the WebGL canvas to black | |
canvas.style.backgroundColor = "black"; | |
// Warn on context loss | |
canvas.addEventListener('webglcontextlost', function(event) { | |
alert('WebGL context lost. You will need to reload the page.'); | |
}, false); | |
} | |
if (setInModule) { | |
Module.ctx = ctx; | |
Module.useWebGL = useWebGL; | |
Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() }); | |
Browser.init(); | |
} | |
return ctx; | |
},destroyContext:function (canvas, useWebGL, setInModule) {},fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:function (lockPointer, resizeCanvas) { | |
Browser.lockPointer = lockPointer; | |
Browser.resizeCanvas = resizeCanvas; | |
if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true; | |
if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false; | |
var canvas = Module['canvas']; | |
function fullScreenChange() { | |
Browser.isFullScreen = false; | |
if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] || | |
document['mozFullScreenElement'] || document['mozFullscreenElement'] || | |
document['fullScreenElement'] || document['fullscreenElement']) === canvas) { | |
canvas.cancelFullScreen = document['cancelFullScreen'] || | |
document['mozCancelFullScreen'] || | |
document['webkitCancelFullScreen']; | |
canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document); | |
if (Browser.lockPointer) canvas.requestPointerLock(); | |
Browser.isFullScreen = true; | |
if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize(); | |
} else if (Browser.resizeCanvas){ | |
Browser.setWindowedCanvasSize(); | |
} | |
if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen); | |
} | |
if (!Browser.fullScreenHandlersInstalled) { | |
Browser.fullScreenHandlersInstalled = true; | |
document.addEventListener('fullscreenchange', fullScreenChange, false); | |
document.addEventListener('mozfullscreenchange', fullScreenChange, false); | |
document.addEventListener('webkitfullscreenchange', fullScreenChange, false); | |
} | |
canvas.requestFullScreen = canvas['requestFullScreen'] || | |
canvas['mozRequestFullScreen'] || | |
(canvas['webkitRequestFullScreen'] ? function() { canvas['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null); | |
canvas.requestFullScreen(); | |
},requestAnimationFrame:function (func) { | |
if (!window.requestAnimationFrame) { | |
window.requestAnimationFrame = window['requestAnimationFrame'] || | |
window['mozRequestAnimationFrame'] || | |
window['webkitRequestAnimationFrame'] || | |
window['msRequestAnimationFrame'] || | |
window['oRequestAnimationFrame'] || | |
window['setTimeout']; | |
} | |
window.requestAnimationFrame(func); | |
},safeCallback:function (func) { | |
return function() { | |
if (!ABORT) return func.apply(null, arguments); | |
}; | |
},safeRequestAnimationFrame:function (func) { | |
return Browser.requestAnimationFrame(function() { | |
if (!ABORT) func(); | |
}); | |
},safeSetTimeout:function (func, timeout) { | |
return setTimeout(function() { | |
if (!ABORT) func(); | |
}, timeout); | |
},safeSetInterval:function (func, timeout) { | |
return setInterval(function() { | |
if (!ABORT) func(); | |
}, timeout); | |
},getMimetype:function (name) { | |
return { | |
'jpg': 'image/jpeg', | |
'jpeg': 'image/jpeg', | |
'png': 'image/png', | |
'bmp': 'image/bmp', | |
'ogg': 'audio/ogg', | |
'wav': 'audio/wav', | |
'mp3': 'audio/mpeg' | |
}[name.substr(name.lastIndexOf('.')+1)]; | |
},getUserMedia:function (func) { | |
if(!window.getUserMedia) { | |
window.getUserMedia = navigator['getUserMedia'] || | |
navigator['mozGetUserMedia']; | |
} | |
window.getUserMedia(func); | |
},getMovementX:function (event) { | |
return event['movementX'] || | |
event['mozMovementX'] || | |
event['webkitMovementX'] || | |
0; | |
},getMovementY:function (event) { | |
return event['movementY'] || | |
event['mozMovementY'] || | |
event['webkitMovementY'] || | |
0; | |
},mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,calculateMouseEvent:function (event) { // event should be mousemove, mousedown or mouseup | |
if (Browser.pointerLock) { | |
// When the pointer is locked, calculate the coordinates | |
// based on the movement of the mouse. | |
// Workaround for Firefox bug 764498 | |
if (event.type != 'mousemove' && | |
('mozMovementX' in event)) { | |
Browser.mouseMovementX = Browser.mouseMovementY = 0; | |
} else { | |
Browser.mouseMovementX = Browser.getMovementX(event); | |
Browser.mouseMovementY = Browser.getMovementY(event); | |
} | |
// check if SDL is available | |
if (typeof SDL != "undefined") { | |
Browser.mouseX = SDL.mouseX + Browser.mouseMovementX; | |
Browser.mouseY = SDL.mouseY + Browser.mouseMovementY; | |
} else { | |
// just add the mouse delta to the current absolut mouse position | |
// FIXME: ideally this should be clamped against the canvas size and zero | |
Browser.mouseX += Browser.mouseMovementX; | |
Browser.mouseY += Browser.mouseMovementY; | |
} | |
} else { | |
// Otherwise, calculate the movement based on the changes | |
// in the coordinates. | |
var rect = Module["canvas"].getBoundingClientRect(); | |
var x = event.pageX - (window.scrollX + rect.left); | |
var y = event.pageY - (window.scrollY + rect.top); | |
// the canvas might be CSS-scaled compared to its backbuffer; | |
// SDL-using content will want mouse coordinates in terms | |
// of backbuffer units. | |
var cw = Module["canvas"].width; | |
var ch = Module["canvas"].height; | |
x = x * (cw / rect.width); | |
y = y * (ch / rect.height); | |
Browser.mouseMovementX = x - Browser.mouseX; | |
Browser.mouseMovementY = y - Browser.mouseY; | |
Browser.mouseX = x; | |
Browser.mouseY = y; | |
} | |
},xhrLoad:function (url, onload, onerror) { | |
var xhr = new XMLHttpRequest(); | |
xhr.open('GET', url, true); | |
xhr.responseType = 'arraybuffer'; | |
xhr.onload = function() { | |
if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0 | |
onload(xhr.response); | |
} else { | |
onerror(); | |
} | |
}; | |
xhr.onerror = onerror; | |
xhr.send(null); | |
},asyncLoad:function (url, onload, onerror, noRunDep) { | |
Browser.xhrLoad(url, function(arrayBuffer) { | |
assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).'); | |
onload(new Uint8Array(arrayBuffer)); | |
if (!noRunDep) removeRunDependency('al ' + url); | |
}, function(event) { | |
if (onerror) { | |
onerror(); | |
} else { | |
throw 'Loading data file "' + url + '" failed.'; | |
} | |
}); | |
if (!noRunDep) addRunDependency('al ' + url); | |
},resizeListeners:[],updateResizeListeners:function () { | |
var canvas = Module['canvas']; | |
Browser.resizeListeners.forEach(function(listener) { | |
listener(canvas.width, canvas.height); | |
}); | |
},setCanvasSize:function (width, height, noUpdates) { | |
var canvas = Module['canvas']; | |
canvas.width = width; | |
canvas.height = height; | |
if (!noUpdates) Browser.updateResizeListeners(); | |
},windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:function () { | |
var canvas = Module['canvas']; | |
this.windowedWidth = canvas.width; | |
this.windowedHeight = canvas.height; | |
canvas.width = screen.width; | |
canvas.height = screen.height; | |
// check if SDL is available | |
if (typeof SDL != "undefined") { | |
var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]; | |
flags = flags | 0x00800000; // set SDL_FULLSCREEN flag | |
HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags | |
} | |
Browser.updateResizeListeners(); | |
},setWindowedCanvasSize:function () { | |
var canvas = Module['canvas']; | |
canvas.width = this.windowedWidth; | |
canvas.height = this.windowedHeight; | |
// check if SDL is available | |
if (typeof SDL != "undefined") { | |
var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]; | |
flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag | |
HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags | |
} | |
Browser.updateResizeListeners(); | |
}};var SDL={defaults:{width:320,height:200,copyOnLock:true},version:null,surfaces:{},canvasPool:[],events:[],fonts:[null],audios:[null],rwops:[null],music:{audio:null,volume:1},mixerFrequency:22050,mixerFormat:32784,mixerNumChannels:2,mixerChunkSize:1024,channelMinimumNumber:0,GL:false,keyboardState:null,keyboardMap:{},textInput:false,startTime:null,buttonState:0,modState:0,DOMButtons:[0,0,0],DOMEventToSDLEvent:{},keyCodes:{16:1249,17:1248,18:1250,33:1099,34:1102,37:1104,38:1106,39:1103,40:1105,46:127,96:1112,97:1113,98:1114,99:1115,100:1116,101:1117,102:1118,103:1119,104:1120,105:1121,112:1082,113:1083,114:1084,115:1085,116:1086,117:1087,118:1088,119:1089,120:1090,121:1091,122:1092,123:1093,173:45,188:44,190:46,191:47,192:96},scanCodes:{9:43,13:40,27:41,32:44,44:54,46:55,47:56,48:39,49:30,50:31,51:32,52:33,53:34,54:35,55:36,56:37,57:38,92:49,97:4,98:5,99:6,100:7,101:8,102:9,103:10,104:11,105:12,106:13,107:14,108:15,109:16,110:17,111:18,112:19,113:20,114:21,115:22,116:23,117:24,118:25,119:26,120:27,121:28,122:29,305:224,308:226},structs:{Rect:{__size__:16,x:0,y:4,w:8,h:12},PixelFormat:{__size__:36,format:0,palette:4,BitsPerPixel:8,BytesPerPixel:9,padding1:10,padding2:11,Rmask:12,Gmask:16,Bmask:20,Amask:24,Rloss:28,Gloss:29,Bloss:30,Aloss:31,Rshift:32,Gshift:33,Bshift:34,Ashift:35},KeyboardEvent:{__size__:16,type:0,windowID:4,state:8,repeat:9,padding2:10,padding3:11,keysym:12},keysym:{__size__:16,scancode:0,sym:4,mod:8,unicode:12},TextInputEvent:{__size__:264,type:0,windowID:4,text:8},MouseMotionEvent:{__size__:28,type:0,windowID:4,state:8,padding1:9,padding2:10,padding3:11,x:12,y:16,xrel:20,yrel:24},MouseButtonEvent:{__size__:20,type:0,windowID:4,button:8,state:9,padding1:10,padding2:11,x:12,y:16},ResizeEvent:{__size__:12,type:0,w:4,h:8},AudioSpec:{__size__:24,freq:0,format:4,channels:6,silence:7,samples:8,size:12,callback:16,userdata:20},version:{__size__:3,major:0,minor:1,patch:2}},loadRect:function (rect) { | |
return { | |
x: HEAP32[((rect + SDL.structs.Rect.x)>>2)], | |
y: HEAP32[((rect + SDL.structs.Rect.y)>>2)], | |
w: HEAP32[((rect + SDL.structs.Rect.w)>>2)], | |
h: HEAP32[((rect + SDL.structs.Rect.h)>>2)] | |
}; | |
},loadColorToCSSRGB:function (color) { | |
var rgba = HEAP32[((color)>>2)]; | |
return 'rgb(' + (rgba&255) + ',' + ((rgba >> 8)&255) + ',' + ((rgba >> 16)&255) + ')'; | |
},loadColorToCSSRGBA:function (color) { | |
var rgba = HEAP32[((color)>>2)]; | |
return 'rgba(' + (rgba&255) + ',' + ((rgba >> 8)&255) + ',' + ((rgba >> 16)&255) + ',' + (((rgba >> 24)&255)/255) + ')'; | |
},translateColorToCSSRGBA:function (rgba) { | |
return 'rgba(' + (rgba&0xff) + ',' + (rgba>>8 & 0xff) + ',' + (rgba>>16 & 0xff) + ',' + (rgba>>>24)/0xff + ')'; | |
},translateRGBAToCSSRGBA:function (r, g, b, a) { | |
return 'rgba(' + (r&0xff) + ',' + (g&0xff) + ',' + (b&0xff) + ',' + (a&0xff)/255 + ')'; | |
},translateRGBAToColor:function (r, g, b, a) { | |
return r | g << 8 | b << 16 | a << 24; | |
},makeSurface:function (width, height, flags, usePageCanvas, source, rmask, gmask, bmask, amask) { | |
flags = flags || 0; | |
var surf = _malloc(14*Runtime.QUANTUM_SIZE); // SDL_Surface has 14 fields of quantum size | |
var buffer = _malloc(width*height*4); // TODO: only allocate when locked the first time | |
var pixelFormat = _malloc(18*Runtime.QUANTUM_SIZE); | |
flags |= 1; // SDL_HWSURFACE - this tells SDL_MUSTLOCK that this needs to be locked | |
//surface with SDL_HWPALETTE flag is 8bpp surface (1 byte) | |
var is_SDL_HWPALETTE = flags & 0x00200000; | |
var bpp = is_SDL_HWPALETTE ? 1 : 4; | |
HEAP32[((surf+Runtime.QUANTUM_SIZE*0)>>2)]=flags // SDL_Surface.flags | |
HEAP32[((surf+Runtime.QUANTUM_SIZE*1)>>2)]=pixelFormat // SDL_Surface.format TODO | |
HEAP32[((surf+Runtime.QUANTUM_SIZE*2)>>2)]=width // SDL_Surface.w | |
HEAP32[((surf+Runtime.QUANTUM_SIZE*3)>>2)]=height // SDL_Surface.h | |
HEAP32[((surf+Runtime.QUANTUM_SIZE*4)>>2)]=width * bpp // SDL_Surface.pitch, assuming RGBA or indexed for now, | |
// since that is what ImageData gives us in browsers | |
HEAP32[((surf+Runtime.QUANTUM_SIZE*5)>>2)]=buffer // SDL_Surface.pixels | |
HEAP32[((surf+Runtime.QUANTUM_SIZE*6)>>2)]=0 // SDL_Surface.offset | |
HEAP32[((surf+Runtime.QUANTUM_SIZE*14)>>2)]=1 | |
HEAP32[((pixelFormat + SDL.structs.PixelFormat.format)>>2)]=-2042224636 // SDL_PIXELFORMAT_RGBA8888 | |
HEAP32[((pixelFormat + SDL.structs.PixelFormat.palette)>>2)]=0 // TODO | |
HEAP8[((pixelFormat + SDL.structs.PixelFormat.BitsPerPixel)|0)]=bpp * 8 | |
HEAP8[((pixelFormat + SDL.structs.PixelFormat.BytesPerPixel)|0)]=bpp | |
HEAP32[((pixelFormat + SDL.structs.PixelFormat.Rmask)>>2)]=rmask || 0x000000ff | |
HEAP32[((pixelFormat + SDL.structs.PixelFormat.Gmask)>>2)]=gmask || 0x0000ff00 | |
HEAP32[((pixelFormat + SDL.structs.PixelFormat.Bmask)>>2)]=bmask || 0x00ff0000 | |
HEAP32[((pixelFormat + SDL.structs.PixelFormat.Amask)>>2)]=amask || 0xff000000 | |
// Decide if we want to use WebGL or not | |
var useWebGL = (flags & 0x04000000) != 0; // SDL_OPENGL | |
SDL.GL = SDL.GL || useWebGL; | |
var canvas; | |
if (!usePageCanvas) { | |
if (SDL.canvasPool.length > 0) { | |
canvas = SDL.canvasPool.pop(); | |
} else { | |
canvas = document.createElement('canvas'); | |
} | |
canvas.width = width; | |
canvas.height = height; | |
} else { | |
canvas = Module['canvas']; | |
} | |
var ctx = Browser.createContext(canvas, useWebGL, usePageCanvas); | |
SDL.surfaces[surf] = { | |
width: width, | |
height: height, | |
canvas: canvas, | |
ctx: ctx, | |
surf: surf, | |
buffer: buffer, | |
pixelFormat: pixelFormat, | |
alpha: 255, | |
flags: flags, | |
locked: 0, | |
usePageCanvas: usePageCanvas, | |
source: source, | |
isFlagSet: function(flag) { | |
return flags & flag; | |
} | |
}; | |
return surf; | |
},copyIndexedColorData:function (surfData, rX, rY, rW, rH) { | |
// HWPALETTE works with palette | |
// setted by SDL_SetColors | |
if (!surfData.colors) { | |
return; | |
} | |
var fullWidth = Module['canvas'].width; | |
var fullHeight = Module['canvas'].height; | |
var startX = rX || 0; | |
var startY = rY || 0; | |
var endX = (rW || (fullWidth - startX)) + startX; | |
var endY = (rH || (fullHeight - startY)) + startY; | |
var buffer = surfData.buffer; | |
var data = surfData.image.data; | |
var colors = surfData.colors; | |
for (var y = startY; y < endY; ++y) { | |
var indexBase = y * fullWidth; | |
var colorBase = indexBase * 4; | |
for (var x = startX; x < endX; ++x) { | |
// HWPALETTE have only 256 colors (not rgba) | |
var index = HEAPU8[((buffer + indexBase + x)|0)] * 3; | |
var colorOffset = colorBase + x * 4; | |
data[colorOffset ] = colors[index ]; | |
data[colorOffset +1] = colors[index +1]; | |
data[colorOffset +2] = colors[index +2]; | |
//unused: data[colorOffset +3] = color[index +3]; | |
} | |
} | |
},freeSurface:function (surf) { | |
var refcountPointer = surf + Runtime.QUANTUM_SIZE * 14; | |
var refcount = HEAP32[((refcountPointer)>>2)]; | |
if (refcount > 1) { | |
HEAP32[((refcountPointer)>>2)]=refcount - 1; | |
return; | |
} | |
var info = SDL.surfaces[surf]; | |
if (!info.usePageCanvas && info.canvas) SDL.canvasPool.push(info.canvas); | |
_free(info.buffer); | |
_free(info.pixelFormat); | |
_free(surf); | |
SDL.surfaces[surf] = null; | |
},touchX:0,touchY:0,receiveEvent:function (event) { | |
switch(event.type) { | |
case 'touchstart': | |
event.preventDefault(); | |
var touch = event.touches[0]; | |
touchX = touch.pageX; | |
touchY = touch.pageY; | |
var event = { | |
type: 'mousedown', | |
button: 0, | |
pageX: touchX, | |
pageY: touchY | |
}; | |
SDL.DOMButtons[0] = 1; | |
SDL.events.push(event); | |
break; | |
case 'touchmove': | |
event.preventDefault(); | |
var touch = event.touches[0]; | |
touchX = touch.pageX; | |
touchY = touch.pageY; | |
event = { | |
type: 'mousemove', | |
button: 0, | |
pageX: touchX, | |
pageY: touchY | |
}; | |
SDL.events.push(event); | |
break; | |
case 'touchend': | |
event.preventDefault(); | |
event = { | |
type: 'mouseup', | |
button: 0, | |
pageX: touchX, | |
pageY: touchY | |
}; | |
SDL.DOMButtons[0] = 0; | |
SDL.events.push(event); | |
break; | |
case 'mousemove': | |
if (Browser.pointerLock) { | |
// workaround for firefox bug 750111 | |
if ('mozMovementX' in event) { | |
event['movementX'] = event['mozMovementX']; | |
event['movementY'] = event['mozMovementY']; | |
} | |
// workaround for Firefox bug 782777 | |
if (event['movementX'] == 0 && event['movementY'] == 0) { | |
// ignore a mousemove event if it doesn't contain any movement info | |
// (without pointer lock, we infer movement from pageX/pageY, so this check is unnecessary) | |
event.preventDefault(); | |
return; | |
} | |
} | |
// fall through | |
case 'keydown': case 'keyup': case 'keypress': case 'mousedown': case 'mouseup': case 'DOMMouseScroll': case 'mousewheel': | |
if (event.type == 'DOMMouseScroll' || event.type == 'mousewheel') { | |
var button = (event.type == 'DOMMouseScroll' ? event.detail : -event.wheelDelta) > 0 ? 4 : 3; | |
var event2 = { | |
type: 'mousedown', | |
button: button, | |
pageX: event.pageX, | |
pageY: event.pageY | |
}; | |
SDL.events.push(event2); | |
event = { | |
type: 'mouseup', | |
button: button, | |
pageX: event.pageX, | |
pageY: event.pageY | |
}; | |
} else if (event.type == 'mousedown') { | |
SDL.DOMButtons[event.button] = 1; | |
} else if (event.type == 'mouseup') { | |
// ignore extra ups, can happen if we leave the canvas while pressing down, then return, | |
// since we add a mouseup in that case | |
if (!SDL.DOMButtons[event.button]) { | |
event.preventDefault(); | |
return; | |
} | |
SDL.DOMButtons[event.button] = 0; | |
} | |
if (event.type == 'keypress' && !SDL.textInput) { | |
break; | |
} | |
SDL.events.push(event); | |
break; | |
case 'mouseout': | |
// Un-press all pressed mouse buttons, because we might miss the release outside of the canvas | |
for (var i = 0; i < 3; i++) { | |
if (SDL.DOMButtons[i]) { | |
SDL.events.push({ | |
type: 'mouseup', | |
button: i, | |
pageX: event.pageX, | |
pageY: event.pageY | |
}); | |
SDL.DOMButtons[i] = 0; | |
} | |
} | |
break; | |
case 'blur': | |
case 'visibilitychange': { | |
// Un-press all pressed keys: TODO | |
for (var code in SDL.keyboardMap) { | |
SDL.events.push({ | |
type: 'keyup', | |
keyCode: SDL.keyboardMap[code] | |
}); | |
} | |
break; | |
} | |
case 'unload': | |
if (Browser.mainLoop.runner) { | |
SDL.events.push(event); | |
// Force-run a main event loop, since otherwise this event will never be caught! | |
Browser.mainLoop.runner(); | |
} | |
return; | |
case 'resize': | |
SDL.events.push(event); | |
break; | |
} | |
if (SDL.events.length >= 10000) { | |
Module.printErr('SDL event queue full, dropping events'); | |
SDL.events = SDL.events.slice(0, 10000); | |
} | |
// manually triggered resize event doesn't have a preventDefault member | |
if (event.preventDefault) { | |
event.preventDefault(); | |
} | |
return; | |
},handleEvent:function (event) { | |
if (event.handled) return; | |
event.handled = true; | |
switch (event.type) { | |
case 'keydown': case 'keyup': { | |
var down = event.type === 'keydown'; | |
var code = SDL.keyCodes[event.keyCode] || event.keyCode; | |
HEAP8[(((SDL.keyboardState)+(code))|0)]=down; | |
// TODO: lmeta, rmeta, numlock, capslock, KMOD_MODE, KMOD_RESERVED | |
SDL.modState = (HEAP8[(((SDL.keyboardState)+(1248))|0)] ? 0x0040 | 0x0080 : 0) | // KMOD_LCTRL & KMOD_RCTRL | |
(HEAP8[(((SDL.keyboardState)+(1249))|0)] ? 0x0001 | 0x0002 : 0) | // KMOD_LSHIFT & KMOD_RSHIFT | |
(HEAP8[(((SDL.keyboardState)+(1250))|0)] ? 0x0100 | 0x0200 : 0); // KMOD_LALT & KMOD_RALT | |
if (down) { | |
SDL.keyboardMap[code] = event.keyCode; // save the DOM input, which we can use to unpress it during blur | |
} else { | |
delete SDL.keyboardMap[code]; | |
} | |
break; | |
} | |
case 'mousedown': case 'mouseup': | |
if (event.type == 'mousedown') { | |
// SDL_BUTTON(x) is defined as (1 << ((x)-1)). SDL buttons are 1-3, | |
// and DOM buttons are 0-2, so this means that the below formula is | |
// correct. | |
SDL.buttonState |= 1 << event.button; | |
} else if (event.type == 'mouseup') { | |
SDL.buttonState &= ~(1 << event.button); | |
} | |
// fall through | |
case 'mousemove': { | |
Browser.calculateMouseEvent(event); | |
break; | |
} | |
} | |
},makeCEvent:function (event, ptr) { | |
if (typeof event === 'number') { | |
// This is a pointer to a native C event that was SDL_PushEvent'ed | |
_memcpy(ptr, event, SDL.structs.KeyboardEvent.__size__); // XXX | |
return; | |
} | |
SDL.handleEvent(event); | |
switch (event.type) { | |
case 'keydown': case 'keyup': { | |
var down = event.type === 'keydown'; | |
//Module.print('Received key event: ' + event.keyCode); | |
var key = event.keyCode; | |
if (key >= 65 && key <= 90) { | |
key += 32; // make lowercase for SDL | |
} else { | |
key = SDL.keyCodes[event.keyCode] || event.keyCode; | |
} | |
var scan; | |
if (key >= 1024) { | |
scan = key - 1024; | |
} else { | |
scan = SDL.scanCodes[key] || key; | |
} | |
HEAP32[(((ptr)+(SDL.structs.KeyboardEvent.type))>>2)]=SDL.DOMEventToSDLEvent[event.type] | |
HEAP8[(((ptr)+(SDL.structs.KeyboardEvent.state))|0)]=down ? 1 : 0 | |
HEAP8[(((ptr)+(SDL.structs.KeyboardEvent.repeat))|0)]=0 // TODO | |
HEAP32[(((ptr)+(SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.scancode))>>2)]=scan | |
HEAP32[(((ptr)+(SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.sym))>>2)]=key | |
HEAP32[(((ptr)+(SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.mod))>>2)]=SDL.modState | |
HEAP32[(((ptr)+(SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.unicode))>>2)]=key | |
break; | |
} | |
case 'keypress': { | |
HEAP32[(((ptr)+(SDL.structs.TextInputEvent.type))>>2)]=SDL.DOMEventToSDLEvent[event.type] | |
// Not filling in windowID for now | |
var cStr = intArrayFromString(String.fromCharCode(event.charCode)); | |
for (var i = 0; i < cStr.length; ++i) { | |
HEAP8[(((ptr)+(SDL.structs.TextInputEvent.text + i))|0)]=cStr[i]; | |
} | |
break; | |
} | |
case 'mousedown': case 'mouseup': case 'mousemove': { | |
if (event.type != 'mousemove') { | |
var down = event.type === 'mousedown'; | |
HEAP32[(((ptr)+(SDL.structs.MouseButtonEvent.type))>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
HEAP8[(((ptr)+(SDL.structs.MouseButtonEvent.button))|0)]=event.button+1; // DOM buttons are 0-2, SDL 1-3 | |
HEAP8[(((ptr)+(SDL.structs.MouseButtonEvent.state))|0)]=down ? 1 : 0; | |
HEAP32[(((ptr)+(SDL.structs.MouseButtonEvent.x))>>2)]=Browser.mouseX; | |
HEAP32[(((ptr)+(SDL.structs.MouseButtonEvent.y))>>2)]=Browser.mouseY; | |
} else { | |
HEAP32[(((ptr)+(SDL.structs.MouseMotionEvent.type))>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
HEAP8[(((ptr)+(SDL.structs.MouseMotionEvent.state))|0)]=SDL.buttonState; | |
HEAP32[(((ptr)+(SDL.structs.MouseMotionEvent.x))>>2)]=Browser.mouseX; | |
HEAP32[(((ptr)+(SDL.structs.MouseMotionEvent.y))>>2)]=Browser.mouseY; | |
HEAP32[(((ptr)+(SDL.structs.MouseMotionEvent.xrel))>>2)]=Browser.mouseMovementX; | |
HEAP32[(((ptr)+(SDL.structs.MouseMotionEvent.yrel))>>2)]=Browser.mouseMovementY; | |
} | |
break; | |
} | |
case 'unload': { | |
HEAP32[(((ptr)+(SDL.structs.KeyboardEvent.type))>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
break; | |
} | |
case 'resize': { | |
HEAP32[(((ptr)+(SDL.structs.KeyboardEvent.type))>>2)]=SDL.DOMEventToSDLEvent[event.type]; | |
HEAP32[(((ptr)+(SDL.structs.ResizeEvent.w))>>2)]=event.w; | |
HEAP32[(((ptr)+(SDL.structs.ResizeEvent.h))>>2)]=event.h; | |
break; | |
} | |
default: throw 'Unhandled SDL event: ' + event.type; | |
} | |
},estimateTextWidth:function (fontData, text) { | |
var h = fontData.size; | |
var fontString = h + 'px ' + fontData.name; | |
var tempCtx = SDL.ttfContext; | |
tempCtx.save(); | |
tempCtx.font = fontString; | |
var ret = tempCtx.measureText(text).width | 0; | |
tempCtx.restore(); | |
return ret; | |
},allocateChannels:function (num) { // called from Mix_AllocateChannels and init | |
if (SDL.numChannels && SDL.numChannels >= num) return; | |
SDL.numChannels = num; | |
SDL.channels = []; | |
for (var i = 0; i < num; i++) { | |
SDL.channels[i] = { | |
audio: null, | |
volume: 1.0 | |
}; | |
} | |
},setGetVolume:function (info, volume) { | |
if (!info) return 0; | |
var ret = info.volume * 128; // MIX_MAX_VOLUME | |
if (volume != -1) { | |
info.volume = volume / 128; | |
if (info.audio) info.audio.volume = info.volume; | |
} | |
return ret; | |
},debugSurface:function (surfData) { | |
console.log('dumping surface ' + [surfData.surf, surfData.source, surfData.width, surfData.height]); | |
var image = surfData.ctx.getImageData(0, 0, surfData.width, surfData.height); | |
var data = image.data; | |
var num = Math.min(surfData.width, surfData.height); | |
for (var i = 0; i < num; i++) { | |
console.log(' diagonal ' + i + ':' + [data[i*surfData.width*4 + i*4 + 0], data[i*surfData.width*4 + i*4 + 1], data[i*surfData.width*4 + i*4 + 2], data[i*surfData.width*4 + i*4 + 3]]); | |
} | |
}};function _SDL_LockSurface(surf) { | |
var surfData = SDL.surfaces[surf]; | |
surfData.locked++; | |
if (surfData.locked > 1) return 0; | |
surfData.image = surfData.ctx.getImageData(0, 0, surfData.width, surfData.height); | |
if (surf == SDL.screen) { | |
var data = surfData.image.data; | |
var num = data.length; | |
for (var i = 0; i < num/4; i++) { | |
data[i*4+3] = 255; // opacity, as canvases blend alpha | |
} | |
} | |
if (SDL.defaults.copyOnLock) { | |
// Copy pixel data to somewhere accessible to 'C/C++' | |
if (surfData.isFlagSet(0x00200000 /* SDL_HWPALETTE */)) { | |
// If this is neaded then | |
// we should compact the data from 32bpp to 8bpp index. | |
// I think best way to implement this is use | |
// additional colorMap hash (color->index). | |
// Something like this: | |
// | |
// var size = surfData.width * surfData.height; | |
// var data = ''; | |
// for (var i = 0; i<size; i++) { | |
// var color = SDL.translateRGBAToColor( | |
// surfData.image.data[i*4 ], | |
// surfData.image.data[i*4 +1], | |
// surfData.image.data[i*4 +2], | |
// 255); | |
// var index = surfData.colorMap[color]; | |
// HEAP8[(((surfData.buffer)+(i))|0)]=index; | |
// } | |
throw 'CopyOnLock is not supported for SDL_LockSurface with SDL_HWPALETTE flag set' + new Error().stack; | |
} else { | |
HEAPU8.set(surfData.image.data, surfData.buffer); | |
} | |
} | |
// Mark in C/C++-accessible SDL structure | |
// SDL_Surface has the following fields: Uint32 flags, SDL_PixelFormat *format; int w, h; Uint16 pitch; void *pixels; ... | |
// So we have fields all of the same size, and 5 of them before us. | |
// TODO: Use macros like in library.js | |
HEAP32[(((surf)+(5*Runtime.QUANTUM_SIZE))>>2)]=surfData.buffer; | |
return 0; | |
} | |
function _SDL_UnlockSurface(surf) { | |
assert(!SDL.GL); // in GL mode we do not keep around 2D canvases and contexts | |
var surfData = SDL.surfaces[surf]; | |
surfData.locked--; | |
if (surfData.locked > 0) return; | |
// Copy pixel data to image | |
if (surfData.isFlagSet(0x00200000 /* SDL_HWPALETTE */)) { | |
SDL.copyIndexedColorData(surfData); | |
} else if (!surfData.colors) { | |
var data = surfData.image.data; | |
var buffer = surfData.buffer; | |
assert(buffer % 4 == 0, 'Invalid buffer offset: ' + buffer); | |
var src = buffer >> 2; | |
var dst = 0; | |
var isScreen = surf == SDL.screen; | |
var data32 = new Uint32Array(data.buffer); | |
var num = data32.length; | |
while (dst < num) { | |
// HEAP32[src++] is an optimization. Instead, we could do HEAP32[(((buffer)+(dst))>>2)]; | |
data32[dst++] = HEAP32[src++] | (isScreen ? 0xff000000 : 0); | |
} | |
} else { | |
var width = Module['canvas'].width; | |
var height = Module['canvas'].height; | |
var s = surfData.buffer; | |
var data = surfData.image.data; | |
var colors = surfData.colors; | |
for (var y = 0; y < height; y++) { | |
var base = y*width*4; | |
for (var x = 0; x < width; x++) { | |
// See comment above about signs | |
var val = HEAPU8[((s++)|0)] * 3; | |
var start = base + x*4; | |
data[start] = colors[val]; | |
data[start+1] = colors[val+1]; | |
data[start+2] = colors[val+2]; | |
} | |
s += width*3; | |
} | |
} | |
// Copy to canvas | |
surfData.ctx.putImageData(surfData.image, 0, 0); | |
// Note that we save the image, so future writes are fast. But, memory is not yet released | |
} | |
function _SDL_Flip(surf) { | |
// We actually do this in Unlock, since the screen surface has as its canvas | |
// backing the page canvas element | |
} | |
var DRUNTIME={};function __d_newarrayvT(typeInfo, i32) { | |
return ((asm["setTempRet0"](new Array(i32)),i32)|0); | |
} | |
Module["_memcpy"] = _memcpy;var _llvm_memcpy_p0i8_p0i8_i32=_memcpy; | |
function _send(fd, buf, len, flags) { | |
var info = FS.getStream(fd); | |
if (!info) { | |
___setErrNo(ERRNO_CODES.EBADF); | |
return -1; | |
} | |
if (info.socket.readyState === WebSocket.CLOSING || info.socket.readyState === WebSocket.CLOSED) { | |
___setErrNo(ERRNO_CODES.ENOTCONN); | |
return -1; | |
} else if (info.socket.readyState === WebSocket.CONNECTING) { | |
___setErrNo(ERRNO_CODES.EAGAIN); | |
return -1; | |
} | |
info.sender(HEAPU8.subarray(buf, buf+len)); | |
return len; | |
} | |
function _pwrite(fildes, buf, nbyte, offset) { | |
// ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset); | |
// http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html | |
var stream = FS.getStream(fildes); | |
if (!stream) { | |
___setErrNo(ERRNO_CODES.EBADF); | |
return -1; | |
} | |
try { | |
var slab = HEAP8; | |
return FS.write(stream, slab, buf, nbyte, offset); | |
} catch (e) { | |
FS.handleFSError(e); | |
return -1; | |
} | |
}function _write(fildes, buf, nbyte) { | |
// ssize_t write(int fildes, const void *buf, size_t nbyte); | |
// http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html | |
var stream = FS.getStream(fildes); | |
if (!stream) { | |
___setErrNo(ERRNO_CODES.EBADF); | |
return -1; | |
} | |
if (stream && ('socket' in stream)) { | |
return _send(fildes, buf, nbyte, 0); | |
} | |
try { | |
var slab = HEAP8; | |
return FS.write(stream, slab, buf, nbyte); | |
} catch (e) { | |
FS.handleFSError(e); | |
return -1; | |
} | |
}function _fwrite(ptr, size, nitems, stream) { | |
// size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream); | |
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html | |
var bytesToWrite = nitems * size; | |
if (bytesToWrite == 0) return 0; | |
var bytesWritten = _write(stream, ptr, bytesToWrite); | |
if (bytesWritten == -1) { | |
var streamObj = FS.getStream(stream); | |
if (streamObj) streamObj.error = true; | |
return 0; | |
} else { | |
return Math.floor(bytesWritten / size); | |
} | |
} | |
Module["_strlen"] = _strlen; | |
function __reallyNegative(x) { | |
return x < 0 || (x === 0 && (1/x) === -Infinity); | |
}function __formatString(format, varargs) { | |
var textIndex = format; | |
var argIndex = 0; | |
function getNextArg(type) { | |
// NOTE: Explicitly ignoring type safety. Otherwise this fails: | |
// int x = 4; printf("%c\n", (char)x); | |
var ret; | |
if (type === 'double') { | |
ret = HEAPF64[(((varargs)+(argIndex))>>3)]; | |
} else if (type == 'i64') { | |
ret = [HEAP32[(((varargs)+(argIndex))>>2)], | |
HEAP32[(((varargs)+(argIndex+8))>>2)]]; | |
argIndex += 8; // each 32-bit chunk is in a 64-bit block | |
} else { | |
type = 'i32'; // varargs are always i32, i64, or double | |
ret = HEAP32[(((varargs)+(argIndex))>>2)]; | |
} | |
argIndex += Math.max(Runtime.getNativeFieldSize(type), Runtime.getAlignSize(type, null, true)); | |
return ret; | |
} | |
var ret = []; | |
var curr, next, currArg; | |
while(1) { | |
var startTextIndex = textIndex; | |
curr = HEAP8[(textIndex)]; | |
if (curr === 0) break; | |
next = HEAP8[((textIndex+1)|0)]; | |
if (curr == 37) { | |
// Handle flags. | |
var flagAlwaysSigned = false; | |
var flagLeftAlign = false; | |
var flagAlternative = false; | |
var flagZeroPad = false; | |
flagsLoop: while (1) { | |
switch (next) { | |
case 43: | |
flagAlwaysSigned = true; | |
break; | |
case 45: | |
flagLeftAlign = true; | |
break; | |
case 35: | |
flagAlternative = true; | |
break; | |
case 48: | |
if (flagZeroPad) { | |
break flagsLoop; | |
} else { | |
flagZeroPad = true; | |
break; | |
} | |
default: | |
break flagsLoop; | |
} | |
textIndex++; | |
next = HEAP8[((textIndex+1)|0)]; | |
} | |
// Handle width. | |
var width = 0; | |
if (next == 42) { | |
width = getNextArg('i32'); | |
textIndex++; | |
next = HEAP8[((textIndex+1)|0)]; | |
} else { | |
while (next >= 48 && next <= 57) { | |
width = width * 10 + (next - 48); | |
textIndex++; | |
next = HEAP8[((textIndex+1)|0)]; | |
} | |
} | |
// Handle precision. | |
var precisionSet = false; | |
if (next == 46) { | |
var precision = 0; | |
precisionSet = true; | |
textIndex++; | |
next = HEAP8[((textIndex+1)|0)]; | |
if (next == 42) { | |
precision = getNextArg('i32'); | |
textIndex++; | |
} else { | |
while(1) { | |
var precisionChr = HEAP8[((textIndex+1)|0)]; | |
if (precisionChr < 48 || | |
precisionChr > 57) break; | |
precision = precision * 10 + (precisionChr - 48); | |
textIndex++; | |
} | |
} | |
next = HEAP8[((textIndex+1)|0)]; | |
} else { | |
var precision = 6; // Standard default. | |
} | |
// Handle integer sizes. WARNING: These assume a 32-bit architecture! | |
var argSize; | |
switch (String.fromCharCode(next)) { | |
case 'h': | |
var nextNext = HEAP8[((textIndex+2)|0)]; | |
if (nextNext == 104) { | |
textIndex++; | |
argSize = 1; // char (actually i32 in varargs) | |
} else { | |
argSize = 2; // short (actually i32 in varargs) | |
} | |
break; | |
case 'l': | |
var nextNext = HEAP8[((textIndex+2)|0)]; | |
if (nextNext == 108) { | |
textIndex++; | |
argSize = 8; // long long | |
} else { | |
argSize = 4; // long | |
} | |
break; | |
case 'L': // long long | |
case 'q': // int64_t | |
case 'j': // intmax_t | |
argSize = 8; | |
break; | |
case 'z': // size_t | |
case 't': // ptrdiff_t | |
case 'I': // signed ptrdiff_t or unsigned size_t | |
argSize = 4; | |
break; | |
default: | |
argSize = null; | |
} | |
if (argSize) textIndex++; | |
next = HEAP8[((textIndex+1)|0)]; | |
// Handle type specifier. | |
switch (String.fromCharCode(next)) { | |
case 'd': case 'i': case 'u': case 'o': case 'x': case 'X': case 'p': { | |
// Integer. | |
var signed = next == 100 || next == 105; | |
argSize = argSize || 4; | |
var currArg = getNextArg('i' + (argSize * 8)); | |
var origArg = currArg; | |
var argText; | |
// Flatten i64-1 [low, high] into a (slightly rounded) double | |
if (argSize == 8) { | |
currArg = Runtime.makeBigInt(currArg[0], currArg[1], next == 117); | |
} | |
// Truncate to requested size. | |
if (argSize <= 4) { | |
var limit = Math.pow(256, argSize) - 1; | |
currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8); | |
} | |
// Format the number. | |
var currAbsArg = Math.abs(currArg); | |
var prefix = ''; | |
if (next == 100 || next == 105) { | |
if (argSize == 8 && i64Math) argText = i64Math.stringify(origArg[0], origArg[1], null); else | |
argText = reSign(currArg, 8 * argSize, 1).toString(10); | |
} else if (next == 117) { | |
if (argSize == 8 && i64Math) argText = i64Math.stringify(origArg[0], origArg[1], true); else | |
argText = unSign(currArg, 8 * argSize, 1).toString(10); | |
currArg = Math.abs(currArg); | |
} else if (next == 111) { | |
argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8); | |
} else if (next == 120 || next == 88) { | |
prefix = (flagAlternative && currArg != 0) ? '0x' : ''; | |
if (argSize == 8 && i64Math) { | |
if (origArg[1]) { | |
argText = (origArg[1]>>>0).toString(16); | |
var lower = (origArg[0]>>>0).toString(16); | |
while (lower.length < 8) lower = '0' + lower; | |
argText += lower; | |
} else { | |
argText = (origArg[0]>>>0).toString(16); | |
} | |
} else | |
if (currArg < 0) { | |
// Represent negative numbers in hex as 2's complement. | |
currArg = -currArg; | |
argText = (currAbsArg - 1).toString(16); | |
var buffer = []; | |
for (var i = 0; i < argText.length; i++) { | |
buffer.push((0xF - parseInt(argText[i], 16)).toString(16)); | |
} | |
argText = buffer.join(''); | |
while (argText.length < argSize * 2) argText = 'f' + argText; | |
} else { | |
argText = currAbsArg.toString(16); | |
} | |
if (next == 88) { | |
prefix = prefix.toUpperCase(); | |
argText = argText.toUpperCase(); | |
} | |
} else if (next == 112) { | |
if (currAbsArg === 0) { | |
argText = '(nil)'; | |
} else { | |
prefix = '0x'; | |
argText = currAbsArg.toString(16); | |
} | |
} | |
if (precisionSet) { | |
while (argText.length < precision) { | |
argText = '0' + argText; | |
} | |
} | |
// Add sign if needed | |
if (flagAlwaysSigned) { | |
if (currArg < 0) { | |
prefix = '-' + prefix; | |
} else { | |
prefix = '+' + prefix; | |
} | |
} | |
// Add padding. | |
while (prefix.length + argText.length < width) { | |
if (flagLeftAlign) { | |
argText += ' '; | |
} else { | |
if (flagZeroPad) { | |
argText = '0' + argText; | |
} else { | |
prefix = ' ' + prefix; | |
} | |
} | |
} | |
// Insert the result into the buffer. | |
argText = prefix + argText; | |
argText.split('').forEach(function(chr) { | |
ret.push(chr.charCodeAt(0)); | |
}); | |
break; | |
} | |
case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': { | |
// Float. | |
var currArg = getNextArg('double'); | |
var argText; | |
if (isNaN(currArg)) { | |
argText = 'nan'; | |
flagZeroPad = false; | |
} else if (!isFinite(currArg)) { | |
argText = (currArg < 0 ? '-' : '') + 'inf'; | |
flagZeroPad = false; | |
} else { | |
var isGeneral = false; | |
var effectivePrecision = Math.min(precision, 20); | |
// Convert g/G to f/F or e/E, as per: | |
// http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html | |
if (next == 103 || next == 71) { | |
isGeneral = true; | |
precision = precision || 1; | |
var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10); | |
if (precision > exponent && exponent >= -4) { | |
next = ((next == 103) ? 'f' : 'F').charCodeAt(0); | |
precision -= exponent + 1; | |
} else { | |
next = ((next == 103) ? 'e' : 'E').charCodeAt(0); | |
precision--; | |
} | |
effectivePrecision = Math.min(precision, 20); | |
} | |
if (next == 101 || next == 69) { | |
argText = currArg.toExponential(effectivePrecision); | |
// Make sure the exponent has at least 2 digits. | |
if (/[eE][-+]\d$/.test(argText)) { | |
argText = argText.slice(0, -1) + '0' + argText.slice(-1); | |
} | |
} else if (next == 102 || next == 70) { | |
argText = currArg.toFixed(effectivePrecision); | |
if (currArg === 0 && __reallyNegative(currArg)) { | |
argText = '-' + argText; | |
} | |
} | |
var parts = argText.split('e'); | |
if (isGeneral && !flagAlternative) { | |
// Discard trailing zeros and periods. | |
while (parts[0].length > 1 && parts[0].indexOf('.') != -1 && | |
(parts[0].slice(-1) == '0' || parts[0].slice(-1) == '.')) { | |
parts[0] = parts[0].slice(0, -1); | |
} | |
} else { | |
// Make sure we have a period in alternative mode. | |
if (flagAlternative && argText.indexOf('.') == -1) parts[0] += '.'; | |
// Zero pad until required precision. | |
while (precision > effectivePrecision++) parts[0] += '0'; | |
} | |
argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : ''); | |
// Capitalize 'E' if needed. | |
if (next == 69) argText = argText.toUpperCase(); | |
// Add sign. | |
if (flagAlwaysSigned && currArg >= 0) { | |
argText = '+' + argText; | |
} | |
} | |
// Add padding. | |
while (argText.length < width) { | |
if (flagLeftAlign) { | |
argText += ' '; | |
} else { | |
if (flagZeroPad && (argText[0] == '-' || argText[0] == '+')) { | |
argText = argText[0] + '0' + argText.slice(1); | |
} else { | |
argText = (flagZeroPad ? '0' : ' ') + argText; | |
} | |
} | |
} | |
// Adjust case. | |
if (next < 97) argText = argText.toUpperCase(); | |
// Insert the result into the buffer. | |
argText.split('').forEach(function(chr) { | |
ret.push(chr.charCodeAt(0)); | |
}); | |
break; | |
} | |
case 's': { | |
// String. | |
var arg = getNextArg('i8*'); | |
var argLength = arg ? _strlen(arg) : '(null)'.length; | |
if (precisionSet) argLength = Math.min(argLength, precision); | |
if (!flagLeftAlign) { | |
while (argLength < width--) { | |
ret.push(32); | |
} | |
} | |
if (arg) { | |
for (var i = 0; i < argLength; i++) { | |
ret.push(HEAPU8[((arg++)|0)]); | |
} | |
} else { | |
ret = ret.concat(intArrayFromString('(null)'.substr(0, argLength), true)); | |
} | |
if (flagLeftAlign) { | |
while (argLength < width--) { | |
ret.push(32); | |
} | |
} | |
break; | |
} | |
case 'c': { | |
// Character. | |
if (flagLeftAlign) ret.push(getNextArg('i8')); | |
while (--width > 0) { | |
ret.push(32); | |
} | |
if (!flagLeftAlign) ret.push(getNextArg('i8')); | |
break; | |
} | |
case 'n': { | |
// Write the length written so far to the next parameter. | |
var ptr = getNextArg('i32*'); | |
HEAP32[((ptr)>>2)]=ret.length | |
break; | |
} | |
case '%': { | |
// Literal percent sign. | |
ret.push(curr); | |
break; | |
} | |
default: { | |
// Unknown specifiers remain untouched. | |
for (var i = startTextIndex; i < textIndex + 2; i++) { | |
ret.push(HEAP8[(i)]); | |
} | |
} | |
} | |
textIndex += 2; | |
// TODO: Support a/A (hex float) and m (last error) specifiers. | |
// TODO: Support %1${specifier} for arg selection. | |
} else { | |
ret.push(curr); | |
textIndex += 1; | |
} | |
} | |
return ret; | |
}function _fprintf(stream, format, varargs) { | |
// int fprintf(FILE *restrict stream, const char *restrict format, ...); | |
// http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html | |
var result = __formatString(format, varargs); | |
var stack = Runtime.stackSave(); | |
var ret = _fwrite(allocate(result, 'i8', ALLOC_STACK), 1, result.length, stream); | |
Runtime.stackRestore(stack); | |
return ret; | |
}function _printf(format, varargs) { | |
// int printf(const char *restrict format, ...); | |
// http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html | |
var stdout = HEAP32[((_stdout)>>2)]; | |
return _fprintf(stdout, format, varargs); | |
} | |
function _SDL_Init(what) { | |
SDL.startTime = Date.now(); | |
// capture all key events. we just keep down and up, but also capture press to prevent default actions | |
if (!Module['doNotCaptureKeyboard']) { | |
document.addEventListener("keydown", SDL.receiveEvent); | |
document.addEventListener("keyup", SDL.receiveEvent); | |
document.addEventListener("keypress", SDL.receiveEvent); | |
document.addEventListener("blur", SDL.receiveEvent); | |
document.addEventListener("visibilitychange", SDL.receiveEvent); | |
} | |
window.addEventListener("unload", SDL.receiveEvent); | |
SDL.keyboardState = _malloc(0x10000); // Our SDL needs 512, but 64K is safe for older SDLs | |
_memset(SDL.keyboardState, 0, 0x10000); | |
// Initialize this structure carefully for closure | |
SDL.DOMEventToSDLEvent['keydown'] = 0x300 /* SDL_KEYDOWN */; | |
SDL.DOMEventToSDLEvent['keyup'] = 0x301 /* SDL_KEYUP */; | |
SDL.DOMEventToSDLEvent['keypress'] = 0x303 /* SDL_TEXTINPUT */; | |
SDL.DOMEventToSDLEvent['mousedown'] = 0x401 /* SDL_MOUSEBUTTONDOWN */; | |
SDL.DOMEventToSDLEvent['mouseup'] = 0x402 /* SDL_MOUSEBUTTONUP */; | |
SDL.DOMEventToSDLEvent['mousemove'] = 0x400 /* SDL_MOUSEMOTION */; | |
SDL.DOMEventToSDLEvent['unload'] = 0x100 /* SDL_QUIT */; | |
SDL.DOMEventToSDLEvent['resize'] = 0x7001 /* SDL_VIDEORESIZE/SDL_EVENT_COMPAT2 */; | |
return 0; // success | |
} | |
function _SDL_SetVideoMode(width, height, depth, flags) { | |
['mousedown', 'mouseup', 'mousemove', 'DOMMouseScroll', 'mousewheel', 'mouseout'].forEach(function(event) { | |
Module['canvas'].addEventListener(event, SDL.receiveEvent, true); | |
}); | |
Browser.setCanvasSize(width, height, true); | |
// Free the old surface first. | |
if (SDL.screen) { | |
SDL.freeSurface(SDL.screen); | |
SDL.screen = null; | |
} | |
SDL.screen = SDL.makeSurface(width, height, flags, true, 'screen'); | |
if (!SDL.addedResizeListener) { | |
SDL.addedResizeListener = true; | |
Browser.resizeListeners.push(function(w, h) { | |
SDL.receiveEvent({ | |
type: 'resize', | |
w: w, | |
h: h | |
}); | |
}); | |
} | |
return SDL.screen; | |
} | |
function __adEq2() { | |
Module['printErr']('missing function: _adEq2'); abort(-1); | |
} | |
function __d_assert_msg() { | |
Module['printErr']('missing function: _d_assert_msg'); abort(-1); | |
} | |
function __d_array_bounds(moduleInfo, i32) { | |
} | |
function __d_assert() { | |
Module['printErr']('missing function: _d_assert'); abort(-1); | |
} | |
function __d_arrayappendT() { | |
Module['printErr']('missing function: _d_arrayappendT'); abort(-1); | |
} | |
Module["_memset"] = _memset;var _llvm_memset_p0i8_i32=_memset; | |
function __d_allocmemoryT() { | |
Module['printErr']('missing function: _d_allocmemoryT'); abort(-1); | |
} | |
function __D4core6memory2GC6extendFNaNbPvkkZk() { | |
Module['printErr']('missing function: _D4core6memory2GC6extendFNaNbPvkkZk'); abort(-1); | |
} | |
function __D4core6memory2GC6qallocFNaNbkkZS4core6memory8BlkInfo_() { | |
Module['printErr']('missing function: _D4core6memory2GC6qallocFNaNbkkZS4core6memory8BlkInfo_'); abort(-1); | |
} | |
function __D4core5bitop3bsrFNaNbNfkZi() { | |
Module['printErr']('missing function: _D4core5bitop3bsrFNaNbNfkZi'); abort(-1); | |
} | |
function __d_arraysetcapacity() { | |
Module['printErr']('missing function: _d_arraysetcapacity'); abort(-1); | |
} | |
function __D6object9Exception6__ctorMFNaNbNfAyaAyakC6object9ThrowableZC9Exception() { | |
Module['printErr']('missing function: _D6object9Exception6__ctorMFNaNbNfAyaAyakC6object9ThrowableZC9Exception'); abort(-1); | |
} | |
function __d_newclass() { | |
Module['printErr']('missing function: _d_newclass'); abort(-1); | |
} | |
function __d_throw_exception() { | |
Module['printErr']('missing function: _d_throw_exception'); abort(-1); | |
} | |
function __D3std5ascii7isDigitFNaNbNfwZb() { | |
Module['printErr']('missing function: _D3std5ascii7isDigitFNaNbNfwZb'); abort(-1); | |
} | |
function __adDupT() { | |
Module['printErr']('missing function: _adDupT'); abort(-1); | |
} | |
function __D3std9exception7bailOutFNaNfAyakxAaZv() { | |
Module['printErr']('missing function: _D3std9exception7bailOutFNaNfAyakxAaZv'); abort(-1); | |
} | |
function __D3std4conv13ConvException6__ctorMFAyaAyakZC3std4conv13ConvException() { | |
Module['printErr']('missing function: _D3std4conv13ConvException6__ctorMFAyaAyakZC3std4conv13ConvException'); abort(-1); | |
} | |
function __D3std4conv21ConvOverflowException6__ctorMFAyaAyakZC3std4conv21ConvOverflowException() { | |
Module['printErr']('missing function: _D3std4conv21ConvOverflowException6__ctorMFAyaAyakZC3std4conv21ConvOverflowException'); abort(-1); | |
} | |
function __D3std6format15FormatException6__ctorMFAyaAyakC6object9ThrowableZC3std6format15FormatException() { | |
Module['printErr']('missing function: _D3std6format15FormatException6__ctorMFAyaAyakC6object9ThrowableZC3std6format15FormatException'); abort(-1); | |
} | |
function __D3std3utf6encodeFNaNfKG4awZk() { | |
Module['printErr']('missing function: _D3std3utf6encodeFNaNfKG4awZk'); abort(-1); | |
} | |
function __d_array_slice_copy() { | |
Module['printErr']('missing function: _d_array_slice_copy'); abort(-1); | |
} | |
function __D3std3utf12UTFException6__ctorMFAyakAyakC6object9ThrowableZC3std3utf12UTFException() { | |
Module['printErr']('missing function: _D3std3utf12UTFException6__ctorMFAyakAyakC6object9ThrowableZC3std3utf12UTFException'); abort(-1); | |
} | |
function __D3std3utf12isValidDcharFNaNbNfwZb() { | |
Module['printErr']('missing function: _D3std3utf12isValidDcharFNaNbNfwZb'); abort(-1); | |
} | |
function _llvm_uadd_with_overflow_i32(x, y) { | |
x = x>>>0; | |
y = y>>>0; | |
return ((asm["setTempRet0"](x+y > 4294967295),(x+y)>>>0)|0); | |
} | |
function _llvm_lifetime_start() {} | |
function _llvm_lifetime_end() {} | |
function _abort() { | |
Module['abort'](); | |
} | |
function ___errno_location() { | |
return ___errno_state; | |
}var ___errno=___errno_location; | |
function _sbrk(bytes) { | |
// Implement a Linux-like 'memory area' for our 'process'. | |
// Changes the size of the memory area by |bytes|; returns the | |
// address of the previous top ('break') of the memory area | |
// We control the "dynamic" memory - DYNAMIC_BASE to DYNAMICTOP | |
var self = _sbrk; | |
if (!self.called) { | |
DYNAMICTOP = alignMemoryPage(DYNAMICTOP); // make sure we start out aligned | |
self.called = true; | |
assert(Runtime.dynamicAlloc); | |
self.alloc = Runtime.dynamicAlloc; | |
Runtime.dynamicAlloc = function() { abort('cannot dynamically allocate, sbrk now has control') }; | |
} | |
var ret = DYNAMICTOP; | |
if (bytes != 0) self.alloc(bytes); | |
return ret; // Previous break location. | |
} | |
function _sysconf(name) { | |
// long sysconf(int name); | |
// http://pubs.opengroup.org/onlinepubs/009695399/functions/sysconf.html | |
switch(name) { | |
case 8: return PAGE_SIZE; | |
case 54: | |
case 56: | |
case 21: | |
case 61: | |
case 63: | |
case 22: | |
case 67: | |
case 23: | |
case 24: | |
case 25: | |
case 26: | |
case 27: | |
case 69: | |
case 28: | |
case 101: | |
case 70: | |
case 71: | |
case 29: | |
case 30: | |
case 199: | |
case 75: | |
case 76: | |
case 32: | |
case 43: | |
case 44: | |
case 80: | |
case 46: | |
case 47: | |
case 45: | |
case 48: | |
case 49: | |
case 42: | |
case 82: | |
case 33: | |
case 7: | |
case 108: | |
case 109: | |
case 107: | |
case 112: | |
case 119: | |
case 121: | |
return 200809; | |
case 13: | |
case 104: | |
case 94: | |
case 95: | |
case 34: | |
case 35: | |
case 77: | |
case 81: | |
case 83: | |
case 84: | |
case 85: | |
case 86: | |
case 87: | |
case 88: | |
case 89: | |
case 90: | |
case 91: | |
case 94: | |
case 95: | |
case 110: | |
case 111: | |
case 113: | |
case 114: | |
case 115: | |
case 116: | |
case 117: | |
case 118: | |
case 120: | |
case 40: | |
case 16: | |
case 79: | |
case 19: | |
return -1; | |
case 92: | |
case 93: | |
case 5: | |
case 72: | |
case 6: | |
case 74: | |
case 92: | |
case 93: | |
case 96: | |
case 97: | |
case 98: | |
case 99: | |
case 102: | |
case 103: | |
case 105: | |
return 1; | |
case 38: | |
case 66: | |
case 50: | |
case 51: | |
case 4: | |
return 1024; | |
case 15: | |
case 64: | |
case 41: | |
return 32; | |
case 55: | |
case 37: | |
case 17: | |
return 2147483647; | |
case 18: | |
case 1: | |
return 47839; | |
case 59: | |
case 57: | |
return 99; | |
case 68: | |
case 58: | |
return 2048; | |
case 0: return 2097152; | |
case 3: return 65536; | |
case 14: return 32768; | |
case 73: return 32767; | |
case 39: return 16384; | |
case 60: return 1000; | |
case 106: return 700; | |
case 52: return 256; | |
case 62: return 255; | |
case 2: return 100; | |
case 65: return 64; | |
case 36: return 20; | |
case 100: return 16; | |
case 20: return 6; | |
case 53: return 4; | |
case 10: return 1; | |
} | |
___setErrNo(ERRNO_CODES.EINVAL); | |
return -1; | |
} | |
function _time(ptr) { | |
var ret = Math.floor(Date.now()/1000); | |
if (ptr) { | |
HEAP32[((ptr)>>2)]=ret | |
} | |
return ret; | |
} | |
FS.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; | |
___errno_state = Runtime.staticAlloc(4); HEAP32[((___errno_state)>>2)]=0; | |
Module["requestFullScreen"] = function(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) }; | |
Module["requestAnimationFrame"] = function(func) { Browser.requestAnimationFrame(func) }; | |
Module["pauseMainLoop"] = function() { Browser.mainLoop.pause() }; | |
Module["resumeMainLoop"] = function() { Browser.mainLoop.resume() }; | |
Module["getUserMedia"] = function() { Browser.getUserMedia() } | |
STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP); | |
staticSealed = true; // seal the static portion of memory | |
STACK_MAX = STACK_BASE + 5242880; | |
DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX); | |
assert(DYNAMIC_BASE < TOTAL_MEMORY); // Stack must fit in TOTAL_MEMORY; allocations from here on may enlarge TOTAL_MEMORY | |
var ctlz_i8 = allocate([8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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_DYNAMIC); | |
var cttz_i8 = allocate([8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0], "i8", ALLOC_DYNAMIC); | |
var Math_min = Math.min; | |
function invoke_iiii(index,a1,a2,a3) { | |
try { | |
return Module["dynCall_iiii"](index,a1,a2,a3); | |
} catch(e) { | |
if (typeof e !== 'number' && e !== 'longjmp') throw e; | |
asm["setThrew"](1, 0); | |
} | |
} | |
function invoke_vi(index,a1) { | |
try { | |
Module["dynCall_vi"](index,a1); | |
} catch(e) { | |
if (typeof e !== 'number' && e !== 'longjmp') throw e; | |
asm["setThrew"](1, 0); | |
} | |
} | |
function invoke_ii(index,a1) { | |
try { | |
return Module["dynCall_ii"](index,a1); | |
} catch(e) { | |
if (typeof e !== 'number' && e !== 'longjmp') throw e; | |
asm["setThrew"](1, 0); | |
} | |
} | |
function invoke_v(index) { | |
try { | |
Module["dynCall_v"](index); | |
} catch(e) { | |
if (typeof e !== 'number' && e !== 'longjmp') throw e; | |
asm["setThrew"](1, 0); | |
} | |
} | |
function invoke_iii(index,a1,a2) { | |
try { | |
return Module["dynCall_iii"](index,a1,a2); | |
} catch(e) { | |
if (typeof e !== 'number' && e !== 'longjmp') throw e; | |
asm["setThrew"](1, 0); | |
} | |
} | |
function asmPrintInt(x, y) { | |
Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack); | |
} | |
function asmPrintFloat(x, y) { | |
Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack); | |
} | |
// EMSCRIPTEN_START_ASM | |
var asm=(function(global,env,buffer){"use asm";var a=new global.Int8Array(buffer);var b=new global.Int16Array(buffer);var c=new global.Int32Array(buffer);var d=new global.Uint8Array(buffer);var e=new global.Uint16Array(buffer);var f=new global.Uint32Array(buffer);var g=new global.Float32Array(buffer);var h=new global.Float64Array(buffer);var i=env.STACKTOP|0;var j=env.STACK_MAX|0;var k=env.tempDoublePtr|0;var l=env.ABORT|0;var m=env.cttz_i8|0;var n=env.ctlz_i8|0;var o=env.__D3std3utf12UTFException6__vtblZ|0;var p=env.__D3std4conv21ConvOverflowException6__vtblZ|0;var q=env.__D14TypeInfo_Const6__vtblZ|0;var r=env.__D10TypeInfo_a6__initZ|0;var s=env.__D3std6format12__ModuleInfoZ|0;var t=env.__D3std4conv13ConvException7__ClassZ|0;var u=env.__D3std4conv13ConvException6__vtblZ|0;var v=env.__D3std4conv21ConvOverflowException6__initZ|0;var w=env.__D3std3utf12UTFException6__initZ|0;var x=env.__D3std6format15FormatException6__initZ|0;var y=env.__D11TypeInfo_Ai6__initZ|0;var z=env.__D15TypeInfo_Struct6__vtblZ|0;var A=env.__D3std4conv21ConvOverflowException7__ClassZ|0;var B=env.__D9Exception7__ClassZ|0;var C=env.__D9Exception6__vtblZ|0;var D=env.__D3std4conv13ConvException6__initZ|0;var E=env.__D3std6format15FormatException6__vtblZ|0;var F=env.__D3std5array12__ModuleInfoZ|0;var G=env.__D3std9algorithm12__ModuleInfoZ|0;var H=env.__D14TypeInfo_Array6__vtblZ|0;var I=env.__D3std6format15FormatException7__ClassZ|0;var J=env.__D3std3utf12__ModuleInfoZ|0;var K=env.__D3std3utf12UTFException7__ClassZ|0;var L=env.__D3SDL12__ModuleInfoZ|0;var M=env.__D3std5stdio12__ModuleInfoZ|0;var N=env.__D12TypeInfo_Aya6__initZ|0;var O=env.__D9Exception6__initZ|0;var P=env.__Dmodule_ref|0;var Q=+env.NaN;var R=+env.Infinity;var S=0;var T=0;var U=0;var V=0;var W=0,X=0,Y=0,Z=0,_=0.0,$=0,aa=0,ab=0,ac=0.0;var ad=0;var ae=0;var af=0;var ag=0;var ah=0;var ai=0;var aj=0;var ak=0;var al=0;var am=0;var an=global.Math.floor;var ao=global.Math.abs;var ap=global.Math.sqrt;var aq=global.Math.pow;var ar=global.Math.cos;var as=global.Math.sin;var at=global.Math.tan;var au=global.Math.acos;var av=global.Math.asin;var aw=global.Math.atan;var ax=global.Math.atan2;var ay=global.Math.exp;var az=global.Math.log;var aA=global.Math.ceil;var aB=global.Math.imul;var aC=env.abort;var aD=env.assert;var aE=env.asmPrintInt;var aF=env.asmPrintFloat;var aG=env.min;var aH=env.invoke_iiii;var aI=env.invoke_vi;var aJ=env.invoke_ii;var aK=env.invoke_v;var aL=env.invoke_iii;var aM=env._llvm_lifetime_end;var aN=env.__D3std9exception7bailOutFNaNfAyakxAaZv;var aO=env.__D3std3utf12UTFException6__ctorMFAyakAyakC6object9ThrowableZC3std3utf12UTFException;var aP=env._sysconf;var aQ=env.__d_assert_msg;var aR=env._abort;var aS=env._fprintf;var aT=env._send;var aU=env._printf;var aV=env._SDL_SetVideoMode;var aW=env._SDL_LockSurface;var aX=env.__reallyNegative;var aY=env._fflush;var aZ=env.__d_newclass;var a_=env._SDL_UnlockSurface;var a$=env.__d_array_slice_copy;var a0=env.___setErrNo;var a1=env._fwrite;var a2=env.__D4core6memory2GC6extendFNaNbPvkkZk;var a3=env._SDL_Flip;var a4=env.__adDupT;var a5=env.__d_newarrayvT;var a6=env._write;var a7=env.__d_allocmemoryT;var a8=env.__d_arraysetcapacity;var a9=env.__adEq2;var ba=env.__D4core5bitop3bsrFNaNbNfkZi;var bb=env.__D3std4conv21ConvOverflowException6__ctorMFAyaAyakZC3std4conv21ConvOverflowException;var bc=env.__d_throw_exception;var bd=env.__D3std6format15FormatException6__ctorMFAyaAyakC6object9ThrowableZC3std6format15FormatException;var be=env._llvm_uadd_with_overflow_i32;var bf=env._emscripten_set_main_loop;var bg=env.__formatString;var bh=env.__D6object9Exception6__ctorMFNaNbNfAyaAyakC6object9ThrowableZC9Exception;var bi=env.__d_assert;var bj=env.__D3std4conv13ConvException6__ctorMFAyaAyakZC3std4conv13ConvException;var bk=env._pwrite;var bl=env._sbrk;var bm=env.__d_array_bounds;var bn=env.__D3std5ascii7isDigitFNaNbNfwZb;var bo=env._SDL_Init;var bp=env.___errno_location;var bq=env.__D3std3utf12isValidDcharFNaNbNfwZb;var br=env.__D4core6memory2GC6qallocFNaNbkkZS4core6memory8BlkInfo_;var bs=env.__d_arrayappendT;var bt=env.__D3std3utf6encodeFNaNfKG4awZk;var bu=env._time;var bv=env._llvm_lifetime_start; | |
// EMSCRIPTEN_START_FUNCS | |
function bB(a){a=a|0;var b=0;b=i;i=i+a|0;i=i+7>>3<<3;return b|0}function bC(){return i|0}function bD(a){a=a|0;i=a}function bE(a,b){a=a|0;b=b|0;if((S|0)==0){S=a;T=b}}function bF(b){b=b|0;a[k]=a[b];a[k+1|0]=a[b+1|0];a[k+2|0]=a[b+2|0];a[k+3|0]=a[b+3|0]}function bG(b){b=b|0;a[k]=a[b];a[k+1|0]=a[b+1|0];a[k+2|0]=a[b+2|0];a[k+3|0]=a[b+3|0];a[k+4|0]=a[b+4|0];a[k+5|0]=a[b+5|0];a[k+6|0]=a[b+6|0];a[k+7|0]=a[b+7|0]}function bH(a){a=a|0;ad=a}function bI(a){a=a|0;ae=a}function bJ(a){a=a|0;af=a}function bK(a){a=a|0;ag=a}function bL(a){a=a|0;ah=a}function bM(a){a=a|0;ai=a}function bN(a){a=a|0;aj=a}function bO(a){a=a|0;ak=a}function bP(a){a=a|0;al=a}function bQ(a){a=a|0;am=a}function bR(){c[532]=z;c[561]=L;c[562]=M;c[563]=G;c[568]=H;c[572]=q;c[574]=r}function bS(){var b=0,d=0,e=0,f=0,g=0;aW(c[702]|0)|0;b=0;do{d=b*2560|0;e=255-b|0;f=0;do{g=(f<<2)+d|0;a[(c[(c[702]|0)+20>>2]|0)+g|0]=(c[704]|0)+f&127;a[(c[(c[702]|0)+20>>2]|0)+(g|1)|0]=(c[704]|0)+b&127;a[(c[(c[702]|0)+20>>2]|0)+(g|2)|0]=e+(c[704]|0)&127;f=f+1|0;}while((f|0)!=640);b=b+1|0;}while((b|0)!=480);a_(c[702]|0);a3(c[702]|0)|0;c[704]=(c[704]|0)+1;return}function bT(){bS();return}function bU(b,d,e,f,g,h,j,k,l,m,n,o){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,Y=0,Z=0;p=i;i=i+232|0;q=p|0;r=p+8|0;s=p+16|0;t=p+56|0;u=p+64|0;v=p+72|0;w=p+112|0;x=p+128|0;y=p+168|0;z=p+176|0;A=p+184|0;B=p+224|0;c[B>>2]=n;c[B+4>>2]=o;o=x;n=a7(2128)|0;C=n;D=C|0;X=0;a[D]=X&255;X=X>>8;a[D+1|0]=X&255;X=X>>8;a[D+2|0]=X&255;X=X>>8;a[D+3|0]=X&255;D=C+4|0;X=0;a[D]=X&255;X=X>>8;a[D+1|0]=X&255;X=X>>8;a[D+2|0]=X&255;X=X>>8;a[D+3|0]=X&255;c[n+4>>2]=0;c[n+8>>2]=0;c[w>>2]=0;c[w+4>>2]=0;c[n>>2]=a8(N|0,0,w|0)|0;w=p+120|0;c[w>>2]=n;ck(o|0,2192,36)|0;ca(x,m);m=c[w>>2]|0;if((m|0)==0){E=0;F=0}else{E=c[m+4>>2]|0;F=c[m+8>>2]|0}m=bs(N|0,B|0,E|0,F|0)|0;F=B|0;c[F>>2]=m;m=B+4|0;c[m>>2]=ad;E=bs(N|0,B|0,k|0,l|0)|0;c[F>>2]=E;c[m>>2]=ad;E=v;l=a7(2128)|0;k=l;w=k|0;X=0;a[w]=X&255;X=X>>8;a[w+1|0]=X&255;X=X>>8;a[w+2|0]=X&255;X=X>>8;a[w+3|0]=X&255;w=k+4|0;X=0;a[w]=X&255;X=X>>8;a[w+1|0]=X&255;X=X>>8;a[w+2|0]=X&255;X=X>>8;a[w+3|0]=X&255;c[l+4>>2]=0;c[l+8>>2]=0;c[t>>2]=0;c[t+4>>2]=0;c[l>>2]=a8(N|0,0,t|0)|0;t=u|0;c[t>>2]=l;ck(E|0,2192,36)|0;ca(v,j);j=c[t>>2]|0;if((j|0)==0){G=0;H=0}else{G=c[j+4>>2]|0;H=c[j+8>>2]|0}j=bs(N|0,B|0,G|0,H|0)|0;c[F>>2]=j;c[m>>2]=ad;j=bs(N|0,B|0,g|0,h|0)|0;c[F>>2]=j;c[m>>2]=ad;j=s;h=a7(2128)|0;g=h;H=g|0;X=0;a[H]=X&255;X=X>>8;a[H+1|0]=X&255;X=X>>8;a[H+2|0]=X&255;X=X>>8;a[H+3|0]=X&255;H=g+4|0;X=0;a[H]=X&255;X=X>>8;a[H+1|0]=X&255;X=X>>8;a[H+2|0]=X&255;X=X>>8;a[H+3|0]=X&255;c[h+4>>2]=0;c[h+8>>2]=0;c[q>>2]=0;c[q+4>>2]=0;c[h>>2]=a8(N|0,0,q|0)|0;q=r|0;c[q>>2]=h;ck(j|0,2192,36)|0;b5(s,f);f=c[q>>2]|0;if((f|0)==0){I=0;J=0}else{I=c[f+4>>2]|0;J=c[f+8>>2]|0}f=bs(N|0,B|0,I|0,J|0)|0;c[F>>2]=f;c[m>>2]=ad;f=bs(N|0,B|0,d|0,e|0)|0;c[F>>2]=f;c[m>>2]=ad;f=A;e=a7(2128)|0;d=e;J=d|0;X=0;a[J]=X&255;X=X>>8;a[J+1|0]=X&255;X=X>>8;a[J+2|0]=X&255;X=X>>8;a[J+3|0]=X&255;J=d+4|0;X=0;a[J]=X&255;X=X>>8;a[J+1|0]=X&255;X=X>>8;a[J+2|0]=X&255;X=X>>8;a[J+3|0]=X&255;c[e+4>>2]=0;c[e+8>>2]=0;c[y>>2]=0;c[y+4>>2]=0;c[e>>2]=a8(N|0,0,y|0)|0;y=z|0;c[y>>2]=e;ck(f|0,2192,36)|0;b5(A,b);b=c[y>>2]|0;if((b|0)==0){K=0;L=0;M=K;O=0;P=M;Q=L;R=bs(N|0,B|0,P|0,Q|0)|0;S=ad;T=R;U=S;c[F>>2]=T;c[m>>2]=U;V=B|0;W=c[V>>2]|0;Y=B+4|0;Z=c[Y>>2]|0;i=p;return(ad=Z,W)|0}K=c[b+4>>2]|0;L=c[b+8>>2]|0;M=K;O=0;P=M;Q=L;R=bs(N|0,B|0,P|0,Q|0)|0;S=ad;T=R;U=S;c[F>>2]=T;c[m>>2]=U;V=B|0;W=c[V>>2]|0;Y=B+4|0;Z=c[Y>>2]|0;i=p;return(ad=Z,W)|0}function bV(a,b){a=a|0;b=b|0;var d=0;if((c[b>>2]|0)!=(c[a>>2]|0)){d=0;return d|0}d=(a9(c[b+4>>2]|0,c[b+8>>2]|0,c[a+4>>2]|0,c[a+8>>2]|0,2272)|0)!=0;return d|0}function bW(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0;d=i;i=i+16|0;e=d|0;f=a|0;a=c[f>>2]|0;if((a|0)==0){g=a7(2128)|0;h=g;cm(g|0,0,12);c[f>>2]=h;j=h}else{j=a}a=c[j+4>>2]|0;h=a+b|0;if(h>>>0<=(c[j>>2]|0)>>>0){i=d;return}j=(ba(h|0)|0)+1|0;g=cv(1e3,0,j,(j|0)<0?-1:0)|0;j=cn(g,ad,100,0)|0;g=ad;k=0;l=(g|0)>(k|0)|(g|0)==(k|0)&j>>>0>200>>>0;k=cx(l?200:j,l?0:g,h,0)|0;g=cn(k,ad,99,0)|0;k=cv(g,ad,100,0)|0;g=k;k=g>>>0>h>>>0?g:h;h=a2(k-a|0,b|0,c[(c[f>>2]|0)+8>>2]|0)|0;if((h|0)!=0){c[c[f>>2]>>2]=h;i=d;return}h=by[c[(c[N>>2]|0)+40>>2]&3](_$object_TypeInfo____D12TypeInfo_Aya6__initZ_to_$object_TypeInfo_Array__)|0;br(e|0,(by[c[(c[h>>2]|0)+48>>2]&3](h)|0)<<1&2^2|0,k|0);c[c[f>>2]>>2]=c[e+4>>2];k=e|0;if((a|0)!=0){e=c[(c[f>>2]|0)+8>>2]|0;h=c[k>>2]|0;ck(h|0,e|0,a)|0}e=c[f>>2]|0;f=c[k>>2]|0;c[e+4>>2]=a;c[e+8>>2]=f;i=d;return}function bX(){var a=0,b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0;a=i;b=a5(y|0,3)|0;d=b;b=ad;e=b;c[e>>2]=10;c[b+4>>2]=11;c[b+8>>2]=12;b=d;f=e;bY(b,f);if(!(b$(b,f)|0)){f=d>>>0>8;b=+b7(f?3:0,f?1232:2328,f?8:d,e,0,0,0,0,0,0);f=ad;aQ(b|0,f|0,0,0,8128)|0;return 0}if((d|0)==0){g=bo(32)|0;h=aV(640,480,32,0)|0;c[702]=h;bf(2,60,1);i=a;return 0}else{j=e;k=d}while(1){d=c[j>>2]|0;e=aB(d,d)|0;aU(1304,(d=i,i=i+8|0,c[d>>2]=e,d)|0)|0;i=d;d=k-1|0;if((d|0)==0){break}else{j=j+4|0;k=d}}g=bo(32)|0;h=aV(640,480,32,0)|0;c[702]=h;bf(2,60,1);i=a;return 0}function bY(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;d=a;a=b;L52:while(1){e=d;f=a;if(d>>>0<=25){g=66;break}b=bZ(e,f)|0;if(b>>>0>=d>>>0){g=45;break}h=a+(b<<2)|0;b=c[h>>2]|0;i=be(d|0,-1|0)|0;j=i;if(!ad){g=47;break}i=a+(j<<2)|0;c[h>>2]=c[i>>2];c[i>>2]=b;h=j;j=-1;while(1){k=j;while(1){l=k+1|0;if(l>>>0>=d>>>0){g=51;break L52}m=a+(l<<2)|0;n=c[m>>2]|0;if((n|0)<(b|0)){k=l}else{o=h;break}}while(1){if((o|0)==0){p=0;break}q=o-1|0;if(q>>>0>=d>>>0){g=55;break L52}if((b|0)<(c[a+(q<<2)>>2]|0)){o=q}else{p=q;break}}if(l>>>0>=p>>>0){break}if(d>>>0<=p>>>0){g=59;break L52}q=a+(p<<2)|0;c[m>>2]=c[q>>2];c[q>>2]=n;h=p;j=l}j=c[i>>2]|0;c[i>>2]=n;c[m>>2]=j;j=k+2|0;if(j>>>0>d>>>0){g=62;break}h=a+(j<<2)|0;b=d-j|0;j=p+1|0;q=j>>>0<l>>>0?j:l;if(q>>>0>d>>>0){g=64;break}j=b>>>0>q>>>0;bY(j?q:b,j?a:h);d=j?b:q;a=j?h:a}if((g|0)==55){bm(G|0,8418)}else if((g|0)==59){bm(G|0,8385)}else if((g|0)==62){bm(G|0,8428)}else if((g|0)==64){bm(G|0,8430)}else if((g|0)==66){b_(e,f);return}else if((g|0)==45){bm(G|0,8407)}else if((g|0)==51){bm(G|0,8417)}else if((g|0)==47){bm(G|0,8385)}}function bZ(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;d=a;a=b;b=d>>>1;if((d|0)==0){bm(G|0,8315);return 0}if(b>>>0>=d>>>0){bm(G|0,8315);return 0}e=a+(b<<2)|0;f=c[a>>2]|0;g=c[e>>2]|0;h=be(d|0,-1|0)|0;i=h;if(!ad){bm(G|0,8316);return 0}h=a+(i<<2)|0;j=c[h>>2]|0;k=(g|0)<(j|0)|((f|0)<(g|0))<<2|((f|0)<(j|0))<<1;if((k|0)==7){return b|0}else if((k|0)==1){if(d>>>0<=i>>>0){bm(G|0,8385);return 0}c[a>>2]=j;c[h>>2]=f;l=c[a>>2]|0;c[a>>2]=c[e>>2];c[e>>2]=l;return b|0}else if((k|0)==6){if(d>>>0<=i>>>0){bm(G|0,8385);return 0}c[e>>2]=j;c[h>>2]=g;return b|0}else if((k|0)==3){c[a>>2]=g;c[e>>2]=f;return b|0}else if((k|0)==4){if(d>>>0<=i>>>0){bm(G|0,8385);return 0}c[e>>2]=j;c[h>>2]=g;g=c[a>>2]|0;c[a>>2]=c[e>>2];c[e>>2]=g;return b|0}else if((k|0)==0){if(d>>>0<=i>>>0){bm(G|0,8385);return 0}c[a>>2]=j;c[h>>2]=f;return b|0}else{bi(0,0,8340);return 0}return 0}function b_(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;d=a;a=b;if(d>>>0<2){return}b=d-1|0;e=d-2|0;L120:while(1){if((e|0)==-1){f=114;break}if(e>>>0>=d>>>0){f=100;break}g=c[a+(e<<2)>>2]|0;h=e;while(1){if(h>>>0>=b>>>0){f=103;break}i=h+1|0;if(i>>>0>=d>>>0){f=105;break L120}j=c[a+(i<<2)>>2]|0;k=h>>>0<d>>>0;if((j|0)>=(g|0)){f=110;break}if(!k){f=108;break L120}c[a+(h<<2)>>2]=j;h=i}if((f|0)==103){f=0;if(h>>>0>=d>>>0){f=115;break}}else if((f|0)==110){f=0;if(!k){f=116;break}}c[a+(h<<2)>>2]=g;e=e-1|0}if((f|0)==100){bm(G|0,8356)}else if((f|0)==105){bm(G|0,8358)}else if((f|0)==108){bm(G|0,8359)}else if((f|0)==114){return}else if((f|0)==116){bm(G|0,8362)}else if((f|0)==115){bm(G|0,8362)}}function b$(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0;d=a;a=b;if((d|0)==0){e=1;return e|0}b=d-1|0;f=0;while(1){if(f>>>0>=b>>>0){e=1;g=128;break}h=f+1|0;if(h>>>0>=d>>>0){g=122;break}if(f>>>0>=d>>>0){g=124;break}i=c[a+(h<<2)>>2]|0;j=c[a+(f<<2)>>2]|0;if((i|0)<(j|0)){g=126;break}else{f=h}}if((g|0)==124){bm(G|0,9302);return 0}else if((g|0)==128){return e|0}else if((g|0)==126){if((j|0)<(i|0)){a=+bU(h,0,0,f,0,0,i,0,0,j,0);j=ad;aQ(a|0,j|0,0,0,9303)|0;return 0}else{e=0;return e|0}}else if((g|0)==122){bm(G|0,9302);return 0}return 0}function b0(b){b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,q=0,r=0,t=0,u=0,w=0,y=0,z=0,D=0,F=0,G=0,H=0,J=0,K=0,L=0,M=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ab=0,ac=0,ae=0,af=0,ag=0,ah=0,ai=0,aj=0,ak=0,al=0,am=0,an=0,ao=0,ap=0,aq=0,ar=0,as=0,at=0,au=0,av=0,aw=0,ax=0,ay=0,az=0,aA=0;e=i;i=i+88|0;f=e|0;g=e+8|0;h=e+16|0;j=e+24|0;k=e+32|0;l=e+40|0;m=e+48|0;n=e+56|0;o=e+64|0;q=e+72|0;r=e+80|0;t=b|0;u=b+11|0;a[u]=0;c[t>>2]=0;w=b+4|0;c[w>>2]=2147483646;y=b+12|0;c[y>>2]=0;c[y+4>>2]=0;z=b+28|0;D=z|0;F=b+32|0;G=(b|0)==0;H=o|0;J=o+4|0;K=b+9|0;L=b+10|0;M=h|0;P=k|0;Q=r|0;R=r+4|0;r=q|0;S=q+4|0;q=0;L159:while(1){T=c[D>>2]|0;if(q>>>0>=T>>>0){U=263;break}V=c[F>>2]|0;W=V+q|0;X=a[W]|0;Y=X&255;if((Y|0)==40){U=133;break}else if((Y|0)==45){if(G){U=183;break}a[u]=a[u]|1;q=q+1|0;continue}else if((Y|0)==43){if(G){U=186;break}a[u]=a[u]|8;q=q+1|0;continue}else if((Y|0)==35){if(G){U=189;break}a[u]=a[u]|16;q=q+1|0;continue}else if((Y|0)==48){if(G){U=192;break}a[u]=a[u]|2;q=q+1|0;continue}else if((Y|0)==32){if(G){U=195;break}a[u]=a[u]|4;q=q+1|0;continue}else if((Y|0)==42){Z=q+1|0;if(Z>>>0>=T>>>0){U=198;break}if(!(bn(d[V+Z|0]|0)|0)){c[t>>2]=2147483647;q=Z;continue}Z=c[D>>2]|0;if((Z|0)==0){U=201;break}_=(c[F>>2]|0)+1|0;c[D>>2]=Z-1;c[F>>2]=_;c[t>>2]=-(b1()|0);if((c[D>>2]|0)==0){U=203;break}if((a[c[F>>2]|0]|0)==36){q=1;continue}else{U=205;break}}else if((Y|0)==49|(Y|0)==50|(Y|0)==51|(Y|0)==52|(Y|0)==53|(Y|0)==54|(Y|0)==55|(Y|0)==56|(Y|0)==57){if(q>>>0>T>>>0){U=208;break}c[H>>2]=T-q;c[J>>2]=W;W=b8()|0;if((c[H>>2]|0)==0){U=210;break}_=c[J>>2]|0;Z=_-(c[F>>2]|0)|0;$=c[o>>2]|0;aa=c[o+4>>2]|0;do{if(($|0)!=0){c[k>>2]=$;c[k+4>>2]=aa;if((c[P>>2]|0)==0){U=215;break L159}c[l>>2]=0;if((cf(l)|0)!=36){break}if(W>>>0>255){U=218;break L159}ab=W&255;a[K]=ab;a[L]=ab;q=Z+1|0;continue L159}}while(0);aa=c[H>>2]|0;do{if((aa|0)!=0){if((a[_]|0)!=58){break}if(W>>>0>255){U=223;break L159}a[K]=W&255;$=_+1|0;c[H>>2]=aa-1;c[J>>2]=$;ab=c[o>>2]|0;ac=c[o+4>>2]|0;if((ab|0)==0){U=228}else{c[h>>2]=ab;c[h+4>>2]=ac;if((c[M>>2]|0)==0){U=226;break L159}c[j>>2]=0;if((cf(j)|0)==36){ae=-1;af=$}else{U=228}}if((U|0)==228){U=0;$=b8()|0;if(($&255|0)!=($|0)){U=229;break L159}ae=$&255;af=c[J>>2]|0}a[L]=ae;$=c[F>>2]|0;ac=af-$|0;if(ac>>>0>=(c[D>>2]|0)>>>0){U=232;break L159}if((a[$+ac|0]|0)==36){q=ac+1|0;continue L159}else{U=234;break L159}}}while(0);if((W|0)<=-1){U=236;break}c[t>>2]=W;q=Z;continue}else if((Y|0)==46){aa=q+1|0;if(aa>>>0>=T>>>0){U=239;break}_=V+aa|0;ac=a[_]|0;if((ac<<24>>24|0)==42){$=q+2|0;if($>>>0>=T>>>0){U=242;break}if(!(bn(d[V+$|0]|0)|0)){c[w>>2]=2147483647;q=$;continue}ab=c[D>>2]|0;if($>>>0>ab>>>0){U=245;break}ag=(c[F>>2]|0)+$|0;c[D>>2]=ab-$;c[F>>2]=ag;c[w>>2]=-(b1()|0);if((c[D>>2]|0)==0){U=247;break}if((a[c[F>>2]|0]|0)==36){q=1;continue}else{U=249;break}}else if((ac<<24>>24|0)==45){c[w>>2]=0;if(aa>>>0>T>>>0){U=252;break}c[r>>2]=T-aa;c[S>>2]=_;b1()|0;q=(c[S>>2]|0)-(c[F>>2]|0)|0;continue}else{if(!(bn(ac&255|0)|0)){c[w>>2]=0;q=aa;continue}ac=c[D>>2]|0;if(aa>>>0>ac>>>0){U=256;break}_=(c[F>>2]|0)+aa|0;c[Q>>2]=ac-aa;c[R>>2]=_;c[w>>2]=b1()|0;q=(c[R>>2]|0)-(c[F>>2]|0)|0;continue}}else{U=259;break}}if((U|0)==133){R=q+1|0;w=n|0;Q=n+4|0;S=R;r=0;t=T;af=T;ae=V;L222:while(1){L=(r|0)==0;if(L){J=S;j=t;M=af;h=ae;while(1){if(J>>>0<j>>>0){ah=j;ai=M}else{if(q>>>0>M>>>0){U=270;break L222}c[n>>2]=29;c[n+4>>2]=592;o=a4(2272,M-q|0,h+q|0)|0;H=bs(N|0,n|0,o|0,ad|0)|0;c[w>>2]=H;c[Q>>2]=ad;aN(c[n>>2]|0,c[n+4>>2]|0,833,0,0);H=c[D>>2]|0;ah=H;ai=H}aj=J+1|0;if(J>>>0>=ah>>>0){U=265;break L222}ak=c[F>>2]|0;if((a[ak+J|0]|0)==37){break}else{J=aj;j=ah;M=ai;h=ak}}if(aj>>>0>=ah>>>0){U=267;break}h=(a[ak+aj|0]|0)==45?J+2|0:aj;if(h>>>0>=ah>>>0){U=269;break}M=a[ak+h|0]|0;if((M<<24>>24|0)==124){al=h;am=ah;an=ak;U=157;break}else if((M<<24>>24|0)==41){ao=h;ap=ah;aq=ai;ar=ak;U=155}else{as=M;at=h;au=ah;av=ai;aw=ak;U=156}}else{h=S;M=t;j=af;Y=ae;while(1){if(h>>>0<M>>>0){ax=M;ay=j}else{if(q>>>0>j>>>0){U=271;break L222}c[n>>2]=29;c[n+4>>2]=592;Z=a4(2272,j-q|0,Y+q|0)|0;W=bs(N|0,n|0,Z|0,ad|0)|0;c[w>>2]=W;c[Q>>2]=ad;aN(c[n>>2]|0,c[n+4>>2]|0,833,0,0);W=c[D>>2]|0;ax=W;ay=W}W=h+1|0;if(h>>>0>=ax>>>0){U=264;break L222}Z=c[F>>2]|0;if((a[Z+h|0]|0)!=37){h=W;M=ax;j=ay;Y=Z;continue}if(W>>>0>=ax>>>0){U=266;break L222}H=(a[Z+W|0]|0)==45?h+2|0:W;if(H>>>0>=ax>>>0){U=268;break L222}W=a[Z+H|0]|0;if((W<<24>>24|0)==124){h=H;M=ax;j=ay;Y=Z}else if((W<<24>>24|0)==41){ao=H;ap=ax;aq=ay;ar=Z;U=155;break}else{as=W;at=H;au=ax;av=ay;aw=Z;U=156;break}}}if((U|0)==155){U=0;if(L){al=ao;am=ap;an=ar;U=157;break}else{S=ao;r=r-1|0;t=ap;af=aq;ae=ar;continue}}else if((U|0)==156){U=0;S=at;r=(as<<24>>24==40)+r|0;t=au;af=av;ae=aw;continue}}if((U|0)==157){if(al>>>0>=am>>>0){bm(s|0,860)}do{if((a[an+al|0]|0)==124){aw=al+1|0;ae=aw;while(1){az=ae+1|0;if(ae>>>0>=am>>>0){U=162;break}if((a[an+ae|0]|0)!=37){ae=az;continue}if(az>>>0>=am>>>0){U=165;break}av=a[an+az|0]|0;if((av<<24>>24|0)==41){U=171;break}else if((av<<24>>24|0)!=37){U=168;break}ae=ae+2|0}if((U|0)==162){bm(s|0,865)}else if((U|0)==165){bm(s|0,867)}else if((U|0)==168){L=aZ(B|0)|0;c[L>>2]=C;c[L+4>>2]=0;av=L+8|0;ck(av|0,O+8|0,28)|0;av=c[D>>2]|0;if(az>>>0>av>>>0){bm(s|0,874)}else{af=(c[F>>2]|0)+az|0;c[m>>2]=29;c[m+4>>2]=240;au=a4(2272,av-az|0,af|0)|0;af=bs(N|0,m|0,au|0,ad|0)|0;c[m>>2]=af;c[m+4>>2]=ad;bc(bh(L|0,0,872,0,0,c[m>>2]|0,c[m+4>>2]|0)|0)}}else if((U|0)==171){L=al-1|0;if(!(L>>>0<=am>>>0&R>>>0<=L>>>0)){bm(s|0,876)}c[y>>2]=L-R;c[y+4>>2]=an+R;if(ae>>>0<=am>>>0&aw>>>0<=ae>>>0){L=b+20|0;c[L>>2]=ae-aw;c[L+4>>2]=an+aw;aA=az;break}else{bm(s|0,877)}}}else{L=al-1|0;if(L>>>0<=am>>>0&R>>>0<=L>>>0){c[y>>2]=L-R;c[y+4>>2]=an+R;L=b+20|0;c[L>>2]=0;c[L+4>>2]=0;aA=al;break}else{bm(s|0,881)}}}while(0);a[b+8|0]=40;al=aA+1|0;if(al>>>0>am>>>0){bm(s|0,887)}else{c[D>>2]=am-al;c[F>>2]=an+al;i=e;return}}else if((U|0)==264){bm(s|0,840)}else if((U|0)==265){bm(s|0,840)}else if((U|0)==266){bm(s|0,845)}else if((U|0)==267){bm(s|0,845)}else if((U|0)==268){bm(s|0,847)}else if((U|0)==269){bm(s|0,847)}else if((U|0)==270){bm(s|0,834)}else if((U|0)==271){bm(s|0,834)}}else if((U|0)==183){aQ(0,0,0,0,688)|0}else if((U|0)==186){aQ(0,0,0,0,694)|0}else if((U|0)==189){aQ(0,0,0,0,696)|0}else if((U|0)==192){aQ(0,0,0,0,690)|0}else if((U|0)==195){aQ(0,0,0,0,692)|0}else if((U|0)==198){bm(s|0,895)}else if((U|0)==201){bm(s|0,899)}else if((U|0)==203){bm(s|0,903)}else if((U|0)==205){al=aZ(I|0)|0;an=al;c[al>>2]=E;c[al+4>>2]=0;am=al+8|0;ck(am|0,x+8|0,28)|0;bc(bd(an|0,0,903,0,0,0,0)|0)}else if((U|0)==208){bm(s|0,913)}else if((U|0)==210){an=aZ(I|0)|0;c[an>>2]=E;c[an+4>>2]=0;am=an+8|0;ck(am|0,x+8|0,28)|0;am=c[b+28>>2]|0;if(q>>>0>am>>>0){bm(s|0,917)}else{al=(c[F>>2]|0)+q|0;c[f>>2]=28;c[f+4>>2]=1024;aA=a4(2272,am-q|0,al|0)|0;al=bs(N|0,f|0,aA|0,ad|0)|0;c[f>>2]=al;c[f+4>>2]=ad;bc(bd(an|0,0,916,0,0,c[f>>2]|0,c[f+4>>2]|0)|0)}}else if((U|0)==215){aQ(0,0,0,0,607)|0}else if((U|0)==218){f=aZ(A|0)|0;an=f;c[f>>2]=p;c[f+4>>2]=0;al=f+8|0;ck(al|0,v+8|0,28)|0;bc(bb(an|0,1274,0,0,0,0)|0)}else if((U|0)==223){an=aZ(A|0)|0;al=an;c[an>>2]=p;c[an+4>>2]=0;f=an+8|0;ck(f|0,v+8|0,28)|0;bc(bb(al|0,1274,0,0,0,0)|0)}else if((U|0)==226){aQ(0,0,0,0,607)|0}else if((U|0)==229){al=aZ(A|0)|0;f=al;c[al>>2]=p;c[al+4>>2]=0;an=al+8|0;ck(an|0,v+8|0,28)|0;bc(bb(f|0,1804,0,0,0,0)|0)}else if((U|0)==232){bm(s|0,940)}else if((U|0)==234){f=aZ(I|0)|0;an=f;c[f>>2]=E;c[f+4>>2]=0;al=f+8|0;ck(al|0,x+8|0,28)|0;bc(bd(an|0,0,940,0,0,0,0)|0)}else if((U|0)==236){an=aZ(A|0)|0;al=an;c[an>>2]=p;c[an+4>>2]=0;f=an+8|0;ck(f|0,v+8|0,28)|0;bc(bb(al|0,339,0,0,0,0)|0)}else if((U|0)==239){bm(s|0,951)}else if((U|0)==242){bm(s|0,953)}else if((U|0)==245){bm(s|0,957)}else if((U|0)==247){bm(s|0,961)}else if((U|0)==249){al=aZ(I|0)|0;f=al;c[al>>2]=E;c[al+4>>2]=0;an=al+8|0;ck(an|0,x+8|0,28)|0;bc(bd(f|0,0,961,0,0,0,0)|0)}else if((U|0)==252){bm(s|0,974)}else if((U|0)==256){bm(s|0,980)}else if((U|0)==259){f=q+1|0;a[b+8|0]=X;if(f>>>0>T>>>0){bm(s|0,993)}else{c[D>>2]=T-f;c[F>>2]=V+f;i=e;return}}else if((U|0)==263){U=aZ(B|0)|0;e=U;c[U>>2]=C;c[U+4>>2]=0;f=U+8|0;ck(f|0,O+8|0,28)|0;f=c[z>>2]|0;U=c[z+4>>2]|0;c[g>>2]=28;c[g+4>>2]=48;z=a4(2272,f|0,U|0)|0;U=bs(N|0,g|0,z|0,ad|0)|0;c[g>>2]=U;c[g+4>>2]=ad;bc(bh(e|0,0,997,0,0,c[g>>2]|0,c[g+4>>2]|0)|0)}}function b1(b){b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,q=0,r=0,s=0,t=0,u=0,w=0,x=0,y=0,z=0,B=0,C=0,D=0,E=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0;d=i;i=i+16|0;e=d|0;f=d+8|0;g=e|0;h=b|0;j=b+4|0;k=0;l=0;m=0;L326:while(1){n=k;L328:while(1){if(m){o=275;break}while(1){q=c[b>>2]|0;r=c[b+4>>2]|0;if((q|0)==0){o=318;break L326}c[e>>2]=q;c[e+4>>2]=r;if((c[g>>2]|0)==0){o=320;break L326}c[f>>2]=0;r=cf(f)|0;q=r-48|0;if(q>>>0<10){s=r;t=q;break L328}if((r|0)==45){break}else if((r|0)!=43){o=317;break L326}r=c[h>>2]|0;if((r|0)==0){o=303;break L326}q=c[j>>2]|0;u=a[q]|0;if(u<<24>>24>-1){w=q+1|0;x=r-1|0}else{r=7-(ba(~u&255|0)|0)|0;u=(r-2|0)>>>0>4?1:r;r=c[h>>2]|0;if(u>>>0>r>>>0){o=307;break L326}w=(c[j>>2]|0)+u|0;x=r-u|0}c[h>>2]=x;c[j>>2]=w}u=c[h>>2]|0;if((u|0)==0){o=295;break L326}r=c[j>>2]|0;q=a[r]|0;if(q<<24>>24>-1){y=r+1|0;z=u-1|0}else{u=7-(ba(~q&255|0)|0)|0;q=(u-2|0)>>>0>4?1:u;u=c[h>>2]|0;if(q>>>0>u>>>0){o=299;break L326}y=(c[j>>2]|0)+q|0;z=u-q|0}c[h>>2]=z;c[j>>2]=y;n=-1}if((o|0)==275){o=0;q=c[b>>2]|0;u=c[b+4>>2]|0;if((q|0)==0){o=314;break}c[e>>2]=q;c[e+4>>2]=u;if((c[g>>2]|0)==0){o=319;break}c[f>>2]=0;u=cf(f)|0;q=u-48|0;if(q>>>0<10){s=u;t=q}else{o=313;break}}if((l|0)>214748363){if((l|0)!=214748364){o=315;break}if((s+n|0)>>>0>55){o=316;break}}q=t+(l*10|0)|0;u=c[h>>2]|0;if((u|0)==0){o=286;break}r=c[j>>2]|0;B=a[r]|0;if(B<<24>>24>-1){C=r+1|0;D=u-1|0}else{u=7-(ba(~B&255|0)|0)|0;B=(u-2|0)>>>0>4?1:u;u=c[h>>2]|0;if(B>>>0>u>>>0){o=290;break}C=(c[j>>2]|0)+B|0;D=u-B|0}c[h>>2]=D;c[j>>2]=C;k=n;l=q;m=1}if((o|0)==307){bm(F|0,451);return 0}else if((o|0)==295){aQ(0,0,0,0,432)|0;return 0}else if((o|0)==303){aQ(0,0,0,0,432)|0;return 0}else if((o|0)==299){bm(F|0,451);return 0}else if((o|0)==290){bm(F|0,451);return 0}else if((o|0)==313){E=(n|0)==-1;G=-l|0;H=E?G:l;i=d;return H|0}else if((o|0)==314){E=(n|0)==-1;G=-l|0;H=E?G:l;i=d;return H|0}else if((o|0)==315){I=aZ(A|0)|0;J=I;K=I;c[K>>2]=p;L=I+4|0;M=L;c[M>>2]=0;N=I+8|0;ck(N|0,v+8|0,28)|0;O=bb(J|0,1804,0,0,0,0)|0;P=O;bc(P|0);return 0}else if((o|0)==316){I=aZ(A|0)|0;J=I;K=I;c[K>>2]=p;L=I+4|0;M=L;c[M>>2]=0;N=I+8|0;ck(N|0,v+8|0,28)|0;O=bb(J|0,1804,0,0,0,0)|0;P=O;bc(P|0);return 0}else if((o|0)==317){Q=b|0;R=c[Q>>2]|0;S=b+4|0;T=c[S>>2]|0;b2(1806,0,0,R);return 0}else if((o|0)==318){Q=b|0;R=c[Q>>2]|0;S=b+4|0;T=c[S>>2]|0;b2(1806,0,0,R);return 0}else if((o|0)==319){U=aQ(0,0,0,0,607)|0;return 0}else if((o|0)==320){U=aQ(0,0,0,0,607)|0;return 0}else if((o|0)==286){aQ(0,0,0,0,432)|0;return 0}return 0}function b2(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0;g=i;i=i+8|0;h=g|0;g=aZ(t|0)|0;j=g;c[g>>2]=u;c[g+4>>2]=0;k=g+8|0;ck(k|0,D+8|0,28)|0;k=+b3(e,f);c[h>>2]=11;c[h+4>>2]=2016;f=bs(N|0,h|0,k|0,ad|0)|0;k=h|0;c[k>>2]=f;f=h+4|0;c[f>>2]=ad;e=bs(N|0,h|0,0,0)|0;c[k>>2]=e;c[f>>2]=ad;bc(bj(j|0,a|0,b|0,d|0,c[h>>2]|0,c[h+4>>2]|0)|0)}function b3(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0;d=i;i=i+24|0;e=d|0;f=d+8|0;g=d+16|0;if((a|0)==0){h=1944;j=12;i=d;return(ad=h,j)|0}c[e>>2]=a;c[e+4>>2]=b;if((c[e>>2]|0)==0){aQ(0,0,0,0,607)|0;return 0}c[f>>2]=0;cf(f)|0;c[g>>2]=1;c[g+4>>2]=1936;f=+b4();e=bs(N|0,g|0,f|0,ad|0)|0;f=g|0;c[f>>2]=e;e=g+4|0;c[e>>2]=ad;b=bs(N|0,g|0,0,0)|0;c[f>>2]=b;c[e>>2]=ad;h=c[g+4>>2]|0;j=c[g>>2]|0;i=d;return(ad=h,j)|0}function b4(b){b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0;d=i;i=i+64|0;e=d|0;f=d+8|0;g=d+16|0;h=a7(2128)|0;j=h;k=j|0;X=0;a[k]=X&255;X=X>>8;a[k+1|0]=X&255;X=X>>8;a[k+2|0]=X&255;X=X>>8;a[k+3|0]=X&255;k=j+4|0;X=0;a[k]=X&255;X=X>>8;a[k+1|0]=X&255;X=X>>8;a[k+2|0]=X&255;X=X>>8;a[k+3|0]=X&255;k=h+4|0;c[k>>2]=0;j=h+8|0;c[j>>2]=0;c[g>>2]=0;c[g+4>>2]=0;l=h;c[h>>2]=a8(N|0,0,g|0)|0;g=d+24|0;ck(g|0,2192,36)|0;g=f|0;c[g>>2]=l;c[e>>2]=-1;l=bt(b|0,e|0)|0;if(l>>>0>=5){bm(F|0,2289);return 0}bW(f);f=c[g>>2]|0;g=f+4|0;b=c[g>>2]|0;h=be(b|0,l|0)|0;c[g>>2]=h;if(ad){bm(F|0,2339);return 0}else{h=(c[f+8>>2]|0)+b|0;ck(h|0,e|0,l)|0;i=d;return(ad=c[j>>2]|0,c[k>>2]|0)|0}return 0}function b5(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;g=i;i=i+48|0;h=f;f=i;i=i+4|0;i=i+7>>3<<3;c[f>>2]=c[h>>2];h=g|0;j=g+40|0;k=e&255;l=e>>>8&255;m=e>>>16&255;n=e>>>24&255;if((a[b+8|0]|0)==114){o=(a[b+11|0]&8)==0;p=f|0;bW(f);q=c[p>>2]|0;r=q+4|0;s=c[r>>2]|0;t=(c[q+8>>2]|0)+s|0;if(o){a[t]=k;c[r>>2]=s+1;bW(f);o=c[p>>2]|0;q=o+4|0;u=c[q>>2]|0;a[(c[o+8>>2]|0)+u|0]=l;c[q>>2]=u+1;bW(f);u=c[p>>2]|0;q=u+4|0;o=c[q>>2]|0;a[(c[u+8>>2]|0)+o|0]=m;c[q>>2]=o+1;bW(f);o=c[p>>2]|0;q=o+4|0;u=c[q>>2]|0;a[(c[o+8>>2]|0)+u|0]=n;c[q>>2]=u+1;i=g;return}else{a[t]=n;c[r>>2]=s+1;bW(f);s=c[p>>2]|0;r=s+4|0;n=c[r>>2]|0;a[(c[s+8>>2]|0)+n|0]=m;c[r>>2]=n+1;bW(f);n=c[p>>2]|0;r=n+4|0;m=c[r>>2]|0;a[(c[n+8>>2]|0)+m|0]=l;c[r>>2]=m+1;bW(f);m=c[p>>2]|0;p=m+4|0;r=c[p>>2]|0;a[(c[m+8>>2]|0)+r|0]=k;c[p>>2]=r+1;i=g;return}}r=e;e=0;p=f|0;c[j>>2]=d[p]|d[p+1|0]<<8|d[p+2|0]<<16|d[p+3|0]<<24;p=h;j=b;ck(p|0,j|0,36)|0;j=a[h+8|0]|0;if((j<<24>>24|0)==111){v=8;b6(0,v,h,r,e);i=g;return}else if((j<<24>>24|0)==120|(j<<24>>24|0)==88){v=16;b6(0,v,h,r,e);i=g;return}else if((j<<24>>24|0)==115|(j<<24>>24|0)==100|(j<<24>>24|0)==117){v=10;b6(0,v,h,r,e);i=g;return}else if((j<<24>>24|0)==98){v=2;b6(0,v,h,r,e);i=g;return}else{g=aZ(I|0)|0;e=g;c[g>>2]=E;c[g+4>>2]=0;r=g+8|0;ck(r|0,x+8|0,28)|0;bc(bd(e|0,0,1328,0,0,0,0)|0)}}function b6(b,d,e,f,g,h){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0;j=i;i=i+64|0;k=h;h=i;i=i+4|0;i=i+7>>3<<3;c[h>>2]=c[k>>2];k=j|0;l=e+4|0;m=c[l>>2]|0;if((m|0)==2147483646){c[l>>2]=1;n=a[e+11|0]|0;o=1}else{p=e+11|0;q=a[p]&-3;a[p]=q;n=q;o=m}m=e+11|0;q=n&3;if(q<<24>>24==0){r=32}else{r=q<<24>>24==2?48:0}if((n&8)==0){t=n<<3&32}else{t=43}if((d|0)==10){u=b?45:t}else{u=0}cm(k|0,-1|0,64);t=d;b=0;q=e+8|0;p=64;v=g;w=f;x=0;y=0;while(1){z=p-1|0;if(z>>>0>=64){A=362;break}B=k+z|0;C=cz(w,v,t,b)|0;a[B]=C&255;D=cy(w,v,t,b)|0;E=ad;G=C;if((G&254)>>>0<10){H=G+48|0}else{H=((a[q]|0)==120?87:55)+G|0}a[B]=H&255;if((D|0)==0&(E|0)==0){break}else{p=z;v=E;w=D;x=x-1|0;y=y+1|0}}if((A|0)==362){bm(s|0,1386)}if(z>>>0>=65){bm(s|0,1391)}z=65-p|0;do{if((d|0)==8){if((n&16)==0){I=u}else{I=o>>>0>z>>>0?u:48}J=I;K=c[e>>2]|0;L=(I<<24>>24!=0)<<31>>31;M=0;A=374}else{p=c[e>>2]|0;w=(u<<24>>24!=0)<<31>>31;if((d|0)!=16){J=u;K=p;L=w;M=0;A=374;break}if((n&16)==0|(f|0)==0&(g|0)==0){J=u;K=p;L=w;M=1;A=374}else{N=2;O=u;P=p;Q=w;R=1}}}while(0);if((A|0)==374){N=0;O=J;P=K;Q=L;R=M}M=o-z|0;L=P-z+Q-N+((M|0)>0?-M|0:0)|0;M=(L|0)>0;do{if(M){if((r<<24>>24|0)==48){c[l>>2]=L+z;break}else if((r<<24>>24|0)==0){break}K=h|0;J=y-o|0;A=P+Q-1-N-o-((J|0)>-1?J:-1)|0;J=0;do{bW(h);u=c[K>>2]|0;n=u+4|0;d=c[n>>2]|0;a[(c[u+8>>2]|0)+d|0]=32;c[n>>2]=d+1;J=J+1|0;}while((J|0)!=(A|0))}}while(0);if(O<<24>>24!=0){bW(h);L=c[h>>2]|0;A=L+4|0;J=c[A>>2]|0;a[(c[L+8>>2]|0)+J|0]=O;c[A>>2]=J+1}do{if(R){if((a[m]&16)==0|(f|0)==0&(g|0)==0){break}bW(h);J=h|0;A=c[J>>2]|0;O=A+4|0;L=c[O>>2]|0;a[(c[A+8>>2]|0)+L|0]=48;c[O>>2]=L+1;L=(a[q]|0)==120?120:88;bW(h);O=c[J>>2]|0;J=O+4|0;A=c[J>>2]|0;a[(c[O+8>>2]|0)+A|0]=L;c[J>>2]=A+1}}while(0);q=c[l>>2]|0;do{if(!((f|0)==0&(g|0)==0&(q|0)==0)){l=h|0;if((q-z|0)>0){m=x+(q-1)|0;R=0;do{bW(h);A=c[l>>2]|0;J=A+4|0;L=c[J>>2]|0;a[(c[A+8>>2]|0)+L|0]=48;c[J>>2]=L+1;R=R+1|0;}while((R|0)!=(m|0))}bW(h);m=c[l>>2]|0;R=m+4|0;L=c[R>>2]|0;J=be(L|0,z|0)|0;c[R>>2]=J;if(ad){bm(F|0,2339)}else{J=(c[m+8>>2]|0)+L|0;ck(J|0,B|0,z)|0;break}}}while(0);if(r<<24>>24!=0|M^1){i=j;return}M=h|0;r=y-o|0;y=P+Q-1-N-o-((r|0)>-1?r:-1)|0;r=0;do{bW(h);o=c[M>>2]|0;N=o+4|0;Q=c[N>>2]|0;a[(c[o+8>>2]|0)+Q|0]=32;c[N>>2]=Q+1;r=r+1|0;}while((r|0)!=(y|0));i=j;return}function b7(b,d,e,f,g,h,j,k,l,m){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0;n=i;i=i+72|0;o=n|0;p=n+8|0;q=n+16|0;r=n+24|0;s=n+64|0;c[s>>2]=l;c[s+4>>2]=m;m=bs(N|0,s|0,j|0,k|0)|0;k=s|0;c[k>>2]=m;m=s+4|0;c[m>>2]=ad;j=bs(N|0,s|0,g|0,h|0)|0;c[k>>2]=j;c[m>>2]=ad;j=r;h=a7(2128)|0;g=h;l=g|0;X=0;a[l]=X&255;X=X>>8;a[l+1|0]=X&255;X=X>>8;a[l+2|0]=X&255;X=X>>8;a[l+3|0]=X&255;l=g+4|0;X=0;a[l]=X&255;X=X>>8;a[l+1|0]=X&255;X=X>>8;a[l+2|0]=X&255;X=X>>8;a[l+3|0]=X&255;l=h+4|0;c[l>>2]=0;g=h+8|0;c[g>>2]=0;c[q>>2]=0;c[q+4>>2]=0;t=h;c[h>>2]=a8(N|0,0,q|0)|0;ck(j|0,2192,36)|0;c[p>>2]=t;c[o>>2]=e;c[o+4>>2]=f;cb(r,o);o=bs(N|0,s|0,c[l>>2]|0,c[g>>2]|0)|0;c[k>>2]=o;c[m>>2]=ad;o=bs(N|0,s|0,b|0,d|0)|0;c[k>>2]=o;c[m>>2]=ad;i=n;return(ad=c[s+4>>2]|0,c[s>>2]|0)|0}function b8(b){b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,q=0,r=0,s=0,t=0;d=i;i=i+16|0;e=d|0;f=d+8|0;g=e|0;h=b|0;j=b+4|0;k=1;l=0;while(1){m=c[b>>2]|0;n=c[b+4>>2]|0;if((m|0)==0){o=415;break}c[e>>2]=m;c[e+4>>2]=n;if((c[g>>2]|0)==0){o=403;break}c[f>>2]=0;n=cf(f)|0;m=n-48|0;if(m>>>0>=10){o=415;break}if(l>>>0>429496728){if((l|0)!=429496729|n>>>0>53){o=417;break}}n=m+(l*10|0)|0;m=c[h>>2]|0;if((m|0)==0){o=408;break}q=c[j>>2]|0;r=a[q]|0;if(r<<24>>24>-1){s=q+1|0;t=m-1|0}else{m=7-(ba(~r&255|0)|0)|0;r=(m-2|0)>>>0>4?1:m;m=c[h>>2]|0;if(r>>>0>m>>>0){o=412;break}s=(c[j>>2]|0)+r|0;t=m-r|0}c[h>>2]=t;c[j>>2]=s;k=0;l=n}if((o|0)==403){aQ(0,0,0,0,607)|0;return 0}else if((o|0)==408){aQ(0,0,0,0,432)|0;return 0}else if((o|0)==412){bm(F|0,451);return 0}else if((o|0)==415){if(k){b9(1806,0,0,c[b>>2]|0);return 0}else{i=d;return l|0}}else if((o|0)==417){o=aZ(A|0)|0;l=o;c[o>>2]=p;c[o+4>>2]=0;d=o+8|0;ck(d|0,v+8|0,28)|0;bc(bb(l|0,1804,0,0,0,0)|0);return 0}return 0}function b9(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0;g=i;i=i+8|0;h=g|0;g=aZ(t|0)|0;j=g;c[g>>2]=u;c[g+4>>2]=0;k=g+8|0;ck(k|0,D+8|0,28)|0;k=+b3(e,f);c[h>>2]=11;c[h+4>>2]=1776;f=bs(N|0,h|0,k|0,ad|0)|0;k=h|0;c[k>>2]=f;f=h+4|0;c[f>>2]=ad;e=bs(N|0,h|0,0,0)|0;c[k>>2]=e;c[f>>2]=ad;bc(bj(j|0,a|0,b|0,d|0,c[h>>2]|0,c[h+4>>2]|0)|0)}function ca(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;g=i;i=i+48|0;h=f;f=i;i=i+4|0;i=i+7>>3<<3;c[f>>2]=c[h>>2];h=g|0;j=g+40|0;k=e&255;l=e>>>8&255;m=e>>>16&255;n=e>>>24&255;if((a[b+8|0]|0)==114){o=(a[b+11|0]&8)==0;p=f|0;bW(f);q=c[p>>2]|0;r=q+4|0;s=c[r>>2]|0;t=(c[q+8>>2]|0)+s|0;if(o){a[t]=k;c[r>>2]=s+1;bW(f);o=c[p>>2]|0;q=o+4|0;u=c[q>>2]|0;a[(c[o+8>>2]|0)+u|0]=l;c[q>>2]=u+1;bW(f);u=c[p>>2]|0;q=u+4|0;o=c[q>>2]|0;a[(c[u+8>>2]|0)+o|0]=m;c[q>>2]=o+1;bW(f);o=c[p>>2]|0;q=o+4|0;u=c[q>>2]|0;a[(c[o+8>>2]|0)+u|0]=n;c[q>>2]=u+1;i=g;return}else{a[t]=n;c[r>>2]=s+1;bW(f);s=c[p>>2]|0;r=s+4|0;n=c[r>>2]|0;a[(c[s+8>>2]|0)+n|0]=m;c[r>>2]=n+1;bW(f);n=c[p>>2]|0;r=n+4|0;m=c[r>>2]|0;a[(c[n+8>>2]|0)+m|0]=l;c[r>>2]=m+1;bW(f);m=c[p>>2]|0;p=m+4|0;r=c[p>>2]|0;a[(c[m+8>>2]|0)+r|0]=k;c[p>>2]=r+1;i=g;return}}r=e;p=(e|0)<0?-1:0;k=f|0;c[j>>2]=d[k]|d[k+1|0]<<8|d[k+2|0]<<16|d[k+3|0]<<24;k=h;j=b;ck(k|0,j|0,36)|0;j=a[h+8|0]|0;if((j<<24>>24|0)==98){v=2}else if((j<<24>>24|0)==111){v=8}else if((j<<24>>24|0)==120|(j<<24>>24|0)==88){v=16}else if((j<<24>>24|0)==115|(j<<24>>24|0)==100|(j<<24>>24|0)==117){v=10}else{j=aZ(I|0)|0;k=j;c[j>>2]=E;c[j+4>>2]=0;b=j+8|0;ck(b|0,x+8|0,28)|0;bc(bd(k|0,0,1328,0,0,0,0)|0)}k=(v|0)==10&(e|0)<0;e=co(0,0,r,p)|0;b6(k,v,h,(k?e:r)|0,(k?ad:p)&0);i=g;return}function cb(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,D=0,E=0,G=0;g=i;i=i+88|0;h=g|0;j=g+8|0;k=g+16|0;l=g+24|0;m=g+32|0;n=g+40|0;o=g+48|0;p=b+8|0;q=a[p]|0;if((q<<24>>24|0)==114){r=e|0;s=e+4|0;while(1){if((c[e>>2]|0)==0){t=487;break}ca(b,c[c[e+4>>2]>>2]|0);u=c[r>>2]|0;if((u|0)==0){t=437;break}v=(c[s>>2]|0)+4|0;c[r>>2]=u-1;c[s>>2]=v}if((t|0)==487){i=g;return}else if((t|0)==437){aQ(0,0,0,0,413)|0}}else if((q<<24>>24|0)==115){if((f|0)==0){aQ(0,0,0,0,2310)|0}bW(f);s=f|0;r=(c[s>>2]|0)+4|0;v=c[r>>2]|0;u=be(v|0,1)|0;c[r>>2]=u;if(ad){bm(F|0,2339)}a$((c[(c[s>>2]|0)+8>>2]|0)+v|0,1,1544,1);L540:do{if((c[e>>2]|0)!=0){v=c[e+4>>2]|0;c[k>>2]=d[s]|d[s+1|0]<<8|d[s+2|0]<<16|d[s+3|0]<<24;ca(b,c[v>>2]|0);v=e|0;u=c[v>>2]|0;if((u|0)==0){aQ(0,0,0,0,413)|0}r=e+4|0;w=j|0;x=u;while(1){u=c[r>>2]|0;y=x-1|0;c[v>>2]=y;c[r>>2]=u+4;if((y|0)==0){break L540}bW(f);y=(c[s>>2]|0)+4|0;u=c[y>>2]|0;z=be(u|0,2)|0;c[y>>2]=z;if(ad){t=449;break}a$((c[(c[s>>2]|0)+8>>2]|0)+u|0,2,1536,2);if((c[e>>2]|0)==0){t=451;break}u=c[e+4>>2]|0;c[w>>2]=d[s]|d[s+1|0]<<8|d[s+2|0]<<16|d[s+3|0]<<24;ca(b,c[u>>2]|0);u=c[v>>2]|0;if((u|0)==0){t=453;break}else{x=u}}if((t|0)==449){bm(F|0,2339)}else if((t|0)==451){aQ(0,0,0,0,587)|0}else if((t|0)==453){aQ(0,0,0,0,413)|0}}}while(0);bW(f);j=(c[s>>2]|0)+4|0;k=c[j>>2]|0;x=be(k|0,1)|0;c[j>>2]=x;if(ad){bm(F|0,2339)}a$((c[(c[s>>2]|0)+8>>2]|0)+k|0,1,1528,1);i=g;return}else if((q<<24>>24|0)==40){q=e|0;if((c[q>>2]|0)==0){i=g;return}k=o;s=b+12|0;x=o+28|0;j=(b|0)==0;v=b+11|0;w=f|0;r=h|0;h=b+20|0;u=b+24|0;b=e+4|0;z=(f|0)==0;while(1){c[k>>2]=c[548];c[k+4>>2]=c[549];c[k+8>>2]=c[550];c[k+12>>2]=c[551];c[k+16>>2]=c[552];c[k+20>>2]=c[553];c[k+24>>2]=c[554];y=c[s+4>>2]|0;c[x>>2]=c[s>>2];c[x+4>>2]=y;ce(o)|0;if(j){t=461;break}if((c[e>>2]|0)==0){t=463;break}y=c[e+4>>2]|0;if((a[v]&1)==0){c[r>>2]=d[w]|d[w+1|0]<<8|d[w+2|0]<<16|d[w+3|0]<<24;ca(o,c[y>>2]|0)}else{ca(o,c[y>>2]|0)}if((c[u>>2]|0)==0){y=c[q>>2]|0;if((y|0)==0){t=479;break}A=(c[b>>2]|0)+4|0;D=y-1|0;c[q>>2]=D;c[b>>2]=A;if((D|0)==0){t=491;break}D=c[x>>2]|0;A=c[x+4>>2]|0;if(z){t=482;break}bW(f);y=(c[w>>2]|0)+4|0;E=c[y>>2]|0;G=be(E|0,D|0)|0;c[y>>2]=G;if(ad){t=484;break}a$((c[(c[w>>2]|0)+8>>2]|0)+E|0,D|0,A|0,D|0);continue}D=c[x>>2]|0;A=c[x+4>>2]|0;if(z){t=469;break}bW(f);E=(c[w>>2]|0)+4|0;G=c[E>>2]|0;y=be(G|0,D|0)|0;c[E>>2]=y;if(ad){t=471;break}a$((c[(c[w>>2]|0)+8>>2]|0)+G|0,D|0,A|0,D|0);D=c[q>>2]|0;if((D|0)==0){t=473;break}A=(c[b>>2]|0)+4|0;G=D-1|0;c[q>>2]=G;c[b>>2]=A;if((G|0)==0){t=490;break}G=c[h+4>>2]|0;A=c[h>>2]|0;bW(f);D=(c[w>>2]|0)+4|0;y=c[D>>2]|0;E=be(y|0,A|0)|0;c[D>>2]=E;if(ad){t=476;break}a$((c[(c[w>>2]|0)+8>>2]|0)+y|0,A|0,G|0,A|0)}if((t|0)==490){i=g;return}else if((t|0)==491){i=g;return}else if((t|0)==461){aQ(0,0,0,0,687)|0}else if((t|0)==463){aQ(0,0,0,0,587)|0}else if((t|0)==469){aQ(0,0,0,0,2310)|0}else if((t|0)==471){bm(F|0,2339)}else if((t|0)==473){aQ(0,0,0,0,413)|0}else if((t|0)==476){bm(F|0,2339)}else if((t|0)==479){aQ(0,0,0,0,413)|0}else if((t|0)==482){aQ(0,0,0,0,2310)|0}else if((t|0)==484){bm(F|0,2339)}}else{t=aZ(B|0)|0;g=t;c[t>>2]=C;c[t+4>>2]=0;w=t+8|0;ck(w|0,O+8|0,28)|0;w=a[p]|0;c[n>>2]=39;c[n+4>>2]=1488;p=a7(2128)|0;t=p;f=t|0;X=0;a[f]=X&255;X=X>>8;a[f+1|0]=X&255;X=X>>8;a[f+2|0]=X&255;X=X>>8;a[f+3|0]=X&255;f=t+4|0;X=0;a[f]=X&255;X=X>>8;a[f+1|0]=X&255;X=X>>8;a[f+2|0]=X&255;X=X>>8;a[f+3|0]=X&255;f=p+4|0;c[f>>2]=0;t=p+8|0;c[t>>2]=0;c[m>>2]=0;c[m+4>>2]=0;c[p>>2]=a8(N|0,0,m|0)|0;m=l|0;c[m>>2]=p;bW(l);l=c[m>>2]|0;m=l+4|0;p=c[m>>2]|0;a[(c[l+8>>2]|0)+p|0]=w;c[m>>2]=p+1;p=bs(N|0,n|0,c[f>>2]|0,c[t>>2]|0)|0;c[n>>2]=p;c[n+4>>2]=ad;bc(bh(g|0,0,2154,0,0,c[n>>2]|0,c[n+4>>2]|0)|0)}}function cc(){return}function cd(){c[566]=c[P>>2];c[P>>2]=2264;return}function ce(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,t=0,u=0,v=0;e=i;f=d;d=i;i=i+4|0;i=i+7>>3<<3;c[d>>2]=c[f>>2];if((b|0)==0){aQ(0,0,0,0,749)|0;return 0}f=b+28|0;g=f|0;h=c[g>>2]|0;if((h|0)==0){i=e;return 0}j=b+32|0;b=d|0;k=0;l=h;while(1){if(k>>>0>=l>>>0){m=519;break}n=c[j>>2]|0;if((a[n+k|0]|0)==37){o=k+1|0;if(o>>>0>=l>>>0){m=502;break}p=k>>>0<=l>>>0;if((a[n+o|0]|0)!=37){m=504;break}if(!p){m=512;break}bW(d);h=c[b>>2]|0;q=h+4|0;r=c[q>>2]|0;t=be(r|0,k|0)|0;c[q>>2]=t;if(ad){m=514;break}a$((c[h+8>>2]|0)+r|0,k|0,n|0,k|0);r=c[g>>2]|0;if(o>>>0>r>>>0){m=516;break}h=(c[j>>2]|0)+o|0;t=r-o|0;c[g>>2]=t;c[j>>2]=h;u=0;v=t}else{u=k;v=l}k=u+1|0;l=v}if((m|0)==502){bm(s|0,755);return 0}else if((m|0)==504){if(!p){bm(s|0,758);return 0}bW(d);p=c[b>>2]|0;v=p+4|0;l=c[v>>2]|0;u=be(l|0,k|0)|0;c[v>>2]=u;if(ad){bm(F|0,2339);return 0}a$((c[p+8>>2]|0)+l|0,k|0,n|0,k|0);k=c[g>>2]|0;if(o>>>0>k>>>0){bm(s|0,759);return 0}else{n=(c[j>>2]|0)+o|0;c[g>>2]=k-o;c[j>>2]=n;b0();i=e;return 1}}else if((m|0)==512){bm(s|0,765);return 0}else if((m|0)==514){bm(F|0,2339);return 0}else if((m|0)==516){bm(s|0,766);return 0}else if((m|0)==519){m=c[f+4>>2]|0;n=c[f>>2]|0;bW(d);d=c[b>>2]|0;b=d+4|0;j=c[b>>2]|0;o=be(j|0,n|0)|0;c[b>>2]=o;if(ad){bm(F|0,2339);return 0}else{a$((c[d+8>>2]|0)+j|0,n|0,m|0,n|0);c[f>>2]=0;c[f+4>>2]=0;i=e;return 0}}return 0}function cf(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0;f=e|0;g=c[b>>2]|0;if(g>>>0>=(c[f>>2]|0)>>>0){aQ(0,0,0,0,950)|0;return 0}h=e+4|0;do{if((a[(c[h>>2]|0)+g|0]|0)>-1){c[b>>2]=g+1;if(g>>>0<(c[f>>2]|0)>>>0){i=d[(c[h>>2]|0)+g|0]|0;break}else{bm(J|0,959);return 0}}else{i=cg(b)|0}}while(0);if(bq(i|0)|0){return i|0}else{bi(0,0,954);return 0}return 0}function cg(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0;f=c[e+4>>2]|0;g=c[b>>2]|0;h=f+g|0;i=(c[e>>2]|0)-g|0;e=a[h]|0;j=e&255;if((j&128|0)==0){bi(0,0,1142);return 0}if((i|0)==1){bc(ch(0,0,0,h)|0);return 0}k=d[f+(g+1)|0]|0;if((k&192|0)!=128){bc(ch(0,0,i,h)|0);return 0}l=j<<6;j=k&63|l;if((e&32)==0){if((l&1920|0)==0){bc(ch(0,0,i,h)|0);return 0}else{c[b>>2]=g+2;return j&2047|0}}if((i|0)==2){bc(ch(0,0,0,h)|0);return 0}l=d[f+(g+2)|0]|0;if((l&192|0)!=128){bc(ch(0,0,i,h)|0);return 0}k=j<<6;j=l&63|k;if((e&16)==0){l=j&65535;if((k&63488|0)==0){bc(ch(0,0,i,h)|0);return 0}if(bq(l|0)|0){c[b>>2]=(c[b>>2]|0)+3;return l|0}else{bc(ch(0,0,i,h)|0);return 0}}if((i|0)==3){bc(ch(0,0,0,h)|0);return 0}l=d[f+(g+3)|0]|0;if((l&192|0)!=128){bc(ch(0,0,i,h)|0);return 0}if((e&8)!=0){bc(ch(0,0,i,h)|0);return 0}e=j<<6;if((e&2031616|0)==0){bc(ch(0,0,i,h)|0);return 0}else{c[b>>2]=g+4;return l&63|e&2097088|0}return 0}function ch(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0;h=i;i=i+16|0;j=h|0;k=f;f=g;g=0;while(1){if(g>>>0>=4){l=563;break}if(g>>>0>=k>>>0){l=565;break}c[j+(g<<2)>>2]=d[f+g|0]|0;m=g+1|0;if(!(m>>>0<k>>>0&m>>>0<4)){l=568;break}if((a[f+m|0]&-64)<<24>>24==-128){g=m}else{l=568;break}}if((l|0)==563){bm(J|0,1110);return 0}else if((l|0)==565){bm(J|0,1110);return 0}else if((l|0)==568){l=aZ(K|0)|0;g=l;c[l>>2]=o;c[l+4>>2]=0;f=l+8|0;ck(f|0,w+8|0,48)|0;f=aO(g|0,0,1113,0,0,m|0,b|0,e|0)|0;if(m>>>0<5){e=bw[c[(c[f>>2]|0)+20>>2]&1](f,m,j|0)|0;i=h;return e|0}else{bm(J|0,1113);return 0}}return 0}function ci(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ab=0,ac=0,ad=0,ae=0,af=0,ag=0,ah=0,ai=0,aj=0,ak=0,al=0,am=0,an=0,ao=0,ap=0,aq=0,ar=0,as=0,at=0,au=0,av=0,aw=0,ax=0,ay=0,az=0,aA=0,aB=0,aC=0,aD=0,aE=0,aF=0,aG=0;do{if(a>>>0<245){if(a>>>0<11){b=16}else{b=a+11&-8}d=b>>>3;e=c[584]|0;f=e>>>(d>>>0);if((f&3|0)!=0){g=(f&1^1)+d|0;h=g<<1;i=2376+(h<<2)|0;j=2376+(h+2<<2)|0;h=c[j>>2]|0;k=h+8|0;l=c[k>>2]|0;do{if((i|0)==(l|0)){c[584]=e&~(1<<g)}else{if(l>>>0<(c[588]|0)>>>0){aR();return 0}m=l+12|0;if((c[m>>2]|0)==(h|0)){c[m>>2]=i;c[j>>2]=l;break}else{aR();return 0}}}while(0);l=g<<3;c[h+4>>2]=l|3;j=h+(l|4)|0;c[j>>2]=c[j>>2]|1;n=k;return n|0}if(b>>>0<=(c[586]|0)>>>0){o=b;break}if((f|0)!=0){j=2<<d;l=f<<d&(j|-j);j=(l&-l)-1|0;l=j>>>12&16;i=j>>>(l>>>0);j=i>>>5&8;m=i>>>(j>>>0);i=m>>>2&4;p=m>>>(i>>>0);m=p>>>1&2;q=p>>>(m>>>0);p=q>>>1&1;r=(j|l|i|m|p)+(q>>>(p>>>0))|0;p=r<<1;q=2376+(p<<2)|0;m=2376+(p+2<<2)|0;p=c[m>>2]|0;i=p+8|0;l=c[i>>2]|0;do{if((q|0)==(l|0)){c[584]=e&~(1<<r)}else{if(l>>>0<(c[588]|0)>>>0){aR();return 0}j=l+12|0;if((c[j>>2]|0)==(p|0)){c[j>>2]=q;c[m>>2]=l;break}else{aR();return 0}}}while(0);l=r<<3;m=l-b|0;c[p+4>>2]=b|3;q=p;e=q+b|0;c[q+(b|4)>>2]=m|1;c[q+l>>2]=m;l=c[586]|0;if((l|0)!=0){q=c[589]|0;d=l>>>3;l=d<<1;f=2376+(l<<2)|0;k=c[584]|0;h=1<<d;do{if((k&h|0)==0){c[584]=k|h;s=f;t=2376+(l+2<<2)|0}else{d=2376+(l+2<<2)|0;g=c[d>>2]|0;if(g>>>0>=(c[588]|0)>>>0){s=g;t=d;break}aR();return 0}}while(0);c[t>>2]=q;c[s+12>>2]=q;c[q+8>>2]=s;c[q+12>>2]=f}c[586]=m;c[589]=e;n=i;return n|0}l=c[585]|0;if((l|0)==0){o=b;break}h=(l&-l)-1|0;l=h>>>12&16;k=h>>>(l>>>0);h=k>>>5&8;p=k>>>(h>>>0);k=p>>>2&4;r=p>>>(k>>>0);p=r>>>1&2;d=r>>>(p>>>0);r=d>>>1&1;g=c[2640+((h|l|k|p|r)+(d>>>(r>>>0))<<2)>>2]|0;r=g;d=g;p=(c[g+4>>2]&-8)-b|0;while(1){g=c[r+16>>2]|0;if((g|0)==0){k=c[r+20>>2]|0;if((k|0)==0){break}else{u=k}}else{u=g}g=(c[u+4>>2]&-8)-b|0;k=g>>>0<p>>>0;r=u;d=k?u:d;p=k?g:p}r=d;i=c[588]|0;if(r>>>0<i>>>0){aR();return 0}e=r+b|0;m=e;if(r>>>0>=e>>>0){aR();return 0}e=c[d+24>>2]|0;f=c[d+12>>2]|0;do{if((f|0)==(d|0)){q=d+20|0;g=c[q>>2]|0;if((g|0)==0){k=d+16|0;l=c[k>>2]|0;if((l|0)==0){v=0;break}else{w=l;x=k}}else{w=g;x=q}while(1){q=w+20|0;g=c[q>>2]|0;if((g|0)!=0){w=g;x=q;continue}q=w+16|0;g=c[q>>2]|0;if((g|0)==0){break}else{w=g;x=q}}if(x>>>0<i>>>0){aR();return 0}else{c[x>>2]=0;v=w;break}}else{q=c[d+8>>2]|0;if(q>>>0<i>>>0){aR();return 0}g=q+12|0;if((c[g>>2]|0)!=(d|0)){aR();return 0}k=f+8|0;if((c[k>>2]|0)==(d|0)){c[g>>2]=f;c[k>>2]=q;v=f;break}else{aR();return 0}}}while(0);L906:do{if((e|0)!=0){f=d+28|0;i=2640+(c[f>>2]<<2)|0;do{if((d|0)==(c[i>>2]|0)){c[i>>2]=v;if((v|0)!=0){break}c[585]=c[585]&~(1<<c[f>>2]);break L906}else{if(e>>>0<(c[588]|0)>>>0){aR();return 0}q=e+16|0;if((c[q>>2]|0)==(d|0)){c[q>>2]=v}else{c[e+20>>2]=v}if((v|0)==0){break L906}}}while(0);if(v>>>0<(c[588]|0)>>>0){aR();return 0}c[v+24>>2]=e;f=c[d+16>>2]|0;do{if((f|0)!=0){if(f>>>0<(c[588]|0)>>>0){aR();return 0}else{c[v+16>>2]=f;c[f+24>>2]=v;break}}}while(0);f=c[d+20>>2]|0;if((f|0)==0){break}if(f>>>0<(c[588]|0)>>>0){aR();return 0}else{c[v+20>>2]=f;c[f+24>>2]=v;break}}}while(0);if(p>>>0<16){e=p+b|0;c[d+4>>2]=e|3;f=r+(e+4)|0;c[f>>2]=c[f>>2]|1}else{c[d+4>>2]=b|3;c[r+(b|4)>>2]=p|1;c[r+(p+b)>>2]=p;f=c[586]|0;if((f|0)!=0){e=c[589]|0;i=f>>>3;f=i<<1;q=2376+(f<<2)|0;k=c[584]|0;g=1<<i;do{if((k&g|0)==0){c[584]=k|g;y=q;z=2376+(f+2<<2)|0}else{i=2376+(f+2<<2)|0;l=c[i>>2]|0;if(l>>>0>=(c[588]|0)>>>0){y=l;z=i;break}aR();return 0}}while(0);c[z>>2]=e;c[y+12>>2]=e;c[e+8>>2]=y;c[e+12>>2]=q}c[586]=p;c[589]=m}f=d+8|0;if((f|0)==0){o=b;break}else{n=f}return n|0}else{if(a>>>0>4294967231){o=-1;break}f=a+11|0;g=f&-8;k=c[585]|0;if((k|0)==0){o=g;break}r=-g|0;i=f>>>8;do{if((i|0)==0){A=0}else{if(g>>>0>16777215){A=31;break}f=(i+1048320|0)>>>16&8;l=i<<f;h=(l+520192|0)>>>16&4;j=l<<h;l=(j+245760|0)>>>16&2;B=14-(h|f|l)+(j<<l>>>15)|0;A=g>>>((B+7|0)>>>0)&1|B<<1}}while(0);i=c[2640+(A<<2)>>2]|0;L714:do{if((i|0)==0){C=0;D=r;E=0}else{if((A|0)==31){F=0}else{F=25-(A>>>1)|0}d=0;m=r;p=i;q=g<<F;e=0;while(1){B=c[p+4>>2]&-8;l=B-g|0;if(l>>>0<m>>>0){if((B|0)==(g|0)){C=p;D=l;E=p;break L714}else{G=p;H=l}}else{G=d;H=m}l=c[p+20>>2]|0;B=c[p+16+(q>>>31<<2)>>2]|0;j=(l|0)==0|(l|0)==(B|0)?e:l;if((B|0)==0){C=G;D=H;E=j;break}else{d=G;m=H;p=B;q=q<<1;e=j}}}}while(0);if((E|0)==0&(C|0)==0){i=2<<A;r=k&(i|-i);if((r|0)==0){o=g;break}i=(r&-r)-1|0;r=i>>>12&16;e=i>>>(r>>>0);i=e>>>5&8;q=e>>>(i>>>0);e=q>>>2&4;p=q>>>(e>>>0);q=p>>>1&2;m=p>>>(q>>>0);p=m>>>1&1;I=c[2640+((i|r|e|q|p)+(m>>>(p>>>0))<<2)>>2]|0}else{I=E}if((I|0)==0){J=D;K=C}else{p=I;m=D;q=C;while(1){e=(c[p+4>>2]&-8)-g|0;r=e>>>0<m>>>0;i=r?e:m;e=r?p:q;r=c[p+16>>2]|0;if((r|0)!=0){p=r;m=i;q=e;continue}r=c[p+20>>2]|0;if((r|0)==0){J=i;K=e;break}else{p=r;m=i;q=e}}}if((K|0)==0){o=g;break}if(J>>>0>=((c[586]|0)-g|0)>>>0){o=g;break}q=K;m=c[588]|0;if(q>>>0<m>>>0){aR();return 0}p=q+g|0;k=p;if(q>>>0>=p>>>0){aR();return 0}e=c[K+24>>2]|0;i=c[K+12>>2]|0;do{if((i|0)==(K|0)){r=K+20|0;d=c[r>>2]|0;if((d|0)==0){j=K+16|0;B=c[j>>2]|0;if((B|0)==0){L=0;break}else{M=B;N=j}}else{M=d;N=r}while(1){r=M+20|0;d=c[r>>2]|0;if((d|0)!=0){M=d;N=r;continue}r=M+16|0;d=c[r>>2]|0;if((d|0)==0){break}else{M=d;N=r}}if(N>>>0<m>>>0){aR();return 0}else{c[N>>2]=0;L=M;break}}else{r=c[K+8>>2]|0;if(r>>>0<m>>>0){aR();return 0}d=r+12|0;if((c[d>>2]|0)!=(K|0)){aR();return 0}j=i+8|0;if((c[j>>2]|0)==(K|0)){c[d>>2]=i;c[j>>2]=r;L=i;break}else{aR();return 0}}}while(0);L764:do{if((e|0)!=0){i=K+28|0;m=2640+(c[i>>2]<<2)|0;do{if((K|0)==(c[m>>2]|0)){c[m>>2]=L;if((L|0)!=0){break}c[585]=c[585]&~(1<<c[i>>2]);break L764}else{if(e>>>0<(c[588]|0)>>>0){aR();return 0}r=e+16|0;if((c[r>>2]|0)==(K|0)){c[r>>2]=L}else{c[e+20>>2]=L}if((L|0)==0){break L764}}}while(0);if(L>>>0<(c[588]|0)>>>0){aR();return 0}c[L+24>>2]=e;i=c[K+16>>2]|0;do{if((i|0)!=0){if(i>>>0<(c[588]|0)>>>0){aR();return 0}else{c[L+16>>2]=i;c[i+24>>2]=L;break}}}while(0);i=c[K+20>>2]|0;if((i|0)==0){break}if(i>>>0<(c[588]|0)>>>0){aR();return 0}else{c[L+20>>2]=i;c[i+24>>2]=L;break}}}while(0);do{if(J>>>0<16){e=J+g|0;c[K+4>>2]=e|3;i=q+(e+4)|0;c[i>>2]=c[i>>2]|1}else{c[K+4>>2]=g|3;c[q+(g|4)>>2]=J|1;c[q+(J+g)>>2]=J;i=J>>>3;if(J>>>0<256){e=i<<1;m=2376+(e<<2)|0;r=c[584]|0;j=1<<i;do{if((r&j|0)==0){c[584]=r|j;O=m;P=2376+(e+2<<2)|0}else{i=2376+(e+2<<2)|0;d=c[i>>2]|0;if(d>>>0>=(c[588]|0)>>>0){O=d;P=i;break}aR();return 0}}while(0);c[P>>2]=k;c[O+12>>2]=k;c[q+(g+8)>>2]=O;c[q+(g+12)>>2]=m;break}e=p;j=J>>>8;do{if((j|0)==0){Q=0}else{if(J>>>0>16777215){Q=31;break}r=(j+1048320|0)>>>16&8;i=j<<r;d=(i+520192|0)>>>16&4;B=i<<d;i=(B+245760|0)>>>16&2;l=14-(d|r|i)+(B<<i>>>15)|0;Q=J>>>((l+7|0)>>>0)&1|l<<1}}while(0);j=2640+(Q<<2)|0;c[q+(g+28)>>2]=Q;c[q+(g+20)>>2]=0;c[q+(g+16)>>2]=0;m=c[585]|0;l=1<<Q;if((m&l|0)==0){c[585]=m|l;c[j>>2]=e;c[q+(g+24)>>2]=j;c[q+(g+12)>>2]=e;c[q+(g+8)>>2]=e;break}if((Q|0)==31){R=0}else{R=25-(Q>>>1)|0}l=J<<R;m=c[j>>2]|0;while(1){if((c[m+4>>2]&-8|0)==(J|0)){break}S=m+16+(l>>>31<<2)|0;j=c[S>>2]|0;if((j|0)==0){T=721;break}else{l=l<<1;m=j}}if((T|0)==721){if(S>>>0<(c[588]|0)>>>0){aR();return 0}else{c[S>>2]=e;c[q+(g+24)>>2]=m;c[q+(g+12)>>2]=e;c[q+(g+8)>>2]=e;break}}l=m+8|0;j=c[l>>2]|0;i=c[588]|0;if(m>>>0<i>>>0){aR();return 0}if(j>>>0<i>>>0){aR();return 0}else{c[j+12>>2]=e;c[l>>2]=e;c[q+(g+8)>>2]=j;c[q+(g+12)>>2]=m;c[q+(g+24)>>2]=0;break}}}while(0);q=K+8|0;if((q|0)==0){o=g;break}else{n=q}return n|0}}while(0);K=c[586]|0;if(o>>>0<=K>>>0){S=K-o|0;J=c[589]|0;if(S>>>0>15){R=J;c[589]=R+o;c[586]=S;c[R+(o+4)>>2]=S|1;c[R+K>>2]=S;c[J+4>>2]=o|3}else{c[586]=0;c[589]=0;c[J+4>>2]=K|3;S=J+(K+4)|0;c[S>>2]=c[S>>2]|1}n=J+8|0;return n|0}J=c[587]|0;if(o>>>0<J>>>0){S=J-o|0;c[587]=S;J=c[590]|0;K=J;c[590]=K+o;c[K+(o+4)>>2]=S|1;c[J+4>>2]=o|3;n=J+8|0;return n|0}do{if((c[576]|0)==0){J=aP(8)|0;if((J-1&J|0)==0){c[578]=J;c[577]=J;c[579]=-1;c[580]=-1;c[581]=0;c[695]=0;c[576]=(bu(0)|0)&-16^1431655768;break}else{aR();return 0}}}while(0);J=o+48|0;S=c[578]|0;K=o+47|0;R=S+K|0;Q=-S|0;S=R&Q;if(S>>>0<=o>>>0){n=0;return n|0}O=c[694]|0;do{if((O|0)!=0){P=c[692]|0;L=P+S|0;if(L>>>0<=P>>>0|L>>>0>O>>>0){n=0}else{break}return n|0}}while(0);L973:do{if((c[695]&4|0)==0){O=c[590]|0;L975:do{if((O|0)==0){T=751}else{L=O;P=2784;while(1){U=P|0;M=c[U>>2]|0;if(M>>>0<=L>>>0){V=P+4|0;if((M+(c[V>>2]|0)|0)>>>0>L>>>0){break}}M=c[P+8>>2]|0;if((M|0)==0){T=751;break L975}else{P=M}}if((P|0)==0){T=751;break}L=R-(c[587]|0)&Q;if(L>>>0>=2147483647){W=0;break}m=bl(L|0)|0;e=(m|0)==((c[U>>2]|0)+(c[V>>2]|0)|0);X=e?m:-1;Y=e?L:0;Z=m;_=L;T=760}}while(0);do{if((T|0)==751){O=bl(0)|0;if((O|0)==-1){W=0;break}g=O;L=c[577]|0;m=L-1|0;if((m&g|0)==0){$=S}else{$=S-g+(m+g&-L)|0}L=c[692]|0;g=L+$|0;if(!($>>>0>o>>>0&$>>>0<2147483647)){W=0;break}m=c[694]|0;if((m|0)!=0){if(g>>>0<=L>>>0|g>>>0>m>>>0){W=0;break}}m=bl($|0)|0;g=(m|0)==(O|0);X=g?O:-1;Y=g?$:0;Z=m;_=$;T=760}}while(0);L995:do{if((T|0)==760){m=-_|0;if((X|0)!=-1){aa=Y;ab=X;T=771;break L973}do{if((Z|0)!=-1&_>>>0<2147483647&_>>>0<J>>>0){g=c[578]|0;O=K-_+g&-g;if(O>>>0>=2147483647){ac=_;break}if((bl(O|0)|0)==-1){bl(m|0)|0;W=Y;break L995}else{ac=O+_|0;break}}else{ac=_}}while(0);if((Z|0)==-1){W=Y}else{aa=ac;ab=Z;T=771;break L973}}}while(0);c[695]=c[695]|4;ad=W;T=768}else{ad=0;T=768}}while(0);do{if((T|0)==768){if(S>>>0>=2147483647){break}W=bl(S|0)|0;Z=bl(0)|0;if(!((Z|0)!=-1&(W|0)!=-1&W>>>0<Z>>>0)){break}ac=Z-W|0;Z=ac>>>0>(o+40|0)>>>0;Y=Z?W:-1;if((Y|0)!=-1){aa=Z?ac:ad;ab=Y;T=771}}}while(0);do{if((T|0)==771){ad=(c[692]|0)+aa|0;c[692]=ad;if(ad>>>0>(c[693]|0)>>>0){c[693]=ad}ad=c[590]|0;L1015:do{if((ad|0)==0){S=c[588]|0;if((S|0)==0|ab>>>0<S>>>0){c[588]=ab}c[696]=ab;c[697]=aa;c[699]=0;c[593]=c[576];c[592]=-1;S=0;do{Y=S<<1;ac=2376+(Y<<2)|0;c[2376+(Y+3<<2)>>2]=ac;c[2376+(Y+2<<2)>>2]=ac;S=S+1|0;}while(S>>>0<32);S=ab+8|0;if((S&7|0)==0){ae=0}else{ae=-S&7}S=aa-40-ae|0;c[590]=ab+ae;c[587]=S;c[ab+(ae+4)>>2]=S|1;c[ab+(aa-36)>>2]=40;c[591]=c[580]}else{S=2784;while(1){af=c[S>>2]|0;ag=S+4|0;ah=c[ag>>2]|0;if((ab|0)==(af+ah|0)){T=783;break}ac=c[S+8>>2]|0;if((ac|0)==0){break}else{S=ac}}do{if((T|0)==783){if((c[S+12>>2]&8|0)!=0){break}ac=ad;if(!(ac>>>0>=af>>>0&ac>>>0<ab>>>0)){break}c[ag>>2]=ah+aa;ac=c[590]|0;Y=(c[587]|0)+aa|0;Z=ac;W=ac+8|0;if((W&7|0)==0){ai=0}else{ai=-W&7}W=Y-ai|0;c[590]=Z+ai;c[587]=W;c[Z+(ai+4)>>2]=W|1;c[Z+(Y+4)>>2]=40;c[591]=c[580];break L1015}}while(0);if(ab>>>0<(c[588]|0)>>>0){c[588]=ab}S=ab+aa|0;Y=2784;while(1){aj=Y|0;if((c[aj>>2]|0)==(S|0)){T=793;break}Z=c[Y+8>>2]|0;if((Z|0)==0){break}else{Y=Z}}do{if((T|0)==793){if((c[Y+12>>2]&8|0)!=0){break}c[aj>>2]=ab;S=Y+4|0;c[S>>2]=(c[S>>2]|0)+aa;S=ab+8|0;if((S&7|0)==0){ak=0}else{ak=-S&7}S=ab+(aa+8)|0;if((S&7|0)==0){al=0}else{al=-S&7}S=ab+(al+aa)|0;Z=S;W=ak+o|0;ac=ab+W|0;_=ac;K=S-(ab+ak)-o|0;c[ab+(ak+4)>>2]=o|3;do{if((Z|0)==(c[590]|0)){J=(c[587]|0)+K|0;c[587]=J;c[590]=_;c[ab+(W+4)>>2]=J|1}else{if((Z|0)==(c[589]|0)){J=(c[586]|0)+K|0;c[586]=J;c[589]=_;c[ab+(W+4)>>2]=J|1;c[ab+(J+W)>>2]=J;break}J=aa+4|0;X=c[ab+(J+al)>>2]|0;if((X&3|0)==1){$=X&-8;V=X>>>3;L1060:do{if(X>>>0<256){U=c[ab+((al|8)+aa)>>2]|0;Q=c[ab+(aa+12+al)>>2]|0;R=2376+(V<<1<<2)|0;do{if((U|0)!=(R|0)){if(U>>>0<(c[588]|0)>>>0){aR();return 0}if((c[U+12>>2]|0)==(Z|0)){break}aR();return 0}}while(0);if((Q|0)==(U|0)){c[584]=c[584]&~(1<<V);break}do{if((Q|0)==(R|0)){am=Q+8|0}else{if(Q>>>0<(c[588]|0)>>>0){aR();return 0}m=Q+8|0;if((c[m>>2]|0)==(Z|0)){am=m;break}aR();return 0}}while(0);c[U+12>>2]=Q;c[am>>2]=U}else{R=S;m=c[ab+((al|24)+aa)>>2]|0;P=c[ab+(aa+12+al)>>2]|0;do{if((P|0)==(R|0)){O=al|16;g=ab+(J+O)|0;L=c[g>>2]|0;if((L|0)==0){e=ab+(O+aa)|0;O=c[e>>2]|0;if((O|0)==0){an=0;break}else{ao=O;ap=e}}else{ao=L;ap=g}while(1){g=ao+20|0;L=c[g>>2]|0;if((L|0)!=0){ao=L;ap=g;continue}g=ao+16|0;L=c[g>>2]|0;if((L|0)==0){break}else{ao=L;ap=g}}if(ap>>>0<(c[588]|0)>>>0){aR();return 0}else{c[ap>>2]=0;an=ao;break}}else{g=c[ab+((al|8)+aa)>>2]|0;if(g>>>0<(c[588]|0)>>>0){aR();return 0}L=g+12|0;if((c[L>>2]|0)!=(R|0)){aR();return 0}e=P+8|0;if((c[e>>2]|0)==(R|0)){c[L>>2]=P;c[e>>2]=g;an=P;break}else{aR();return 0}}}while(0);if((m|0)==0){break}P=ab+(aa+28+al)|0;U=2640+(c[P>>2]<<2)|0;do{if((R|0)==(c[U>>2]|0)){c[U>>2]=an;if((an|0)!=0){break}c[585]=c[585]&~(1<<c[P>>2]);break L1060}else{if(m>>>0<(c[588]|0)>>>0){aR();return 0}Q=m+16|0;if((c[Q>>2]|0)==(R|0)){c[Q>>2]=an}else{c[m+20>>2]=an}if((an|0)==0){break L1060}}}while(0);if(an>>>0<(c[588]|0)>>>0){aR();return 0}c[an+24>>2]=m;R=al|16;P=c[ab+(R+aa)>>2]|0;do{if((P|0)!=0){if(P>>>0<(c[588]|0)>>>0){aR();return 0}else{c[an+16>>2]=P;c[P+24>>2]=an;break}}}while(0);P=c[ab+(J+R)>>2]|0;if((P|0)==0){break}if(P>>>0<(c[588]|0)>>>0){aR();return 0}else{c[an+20>>2]=P;c[P+24>>2]=an;break}}}while(0);aq=ab+(($|al)+aa)|0;ar=$+K|0}else{aq=Z;ar=K}J=aq+4|0;c[J>>2]=c[J>>2]&-2;c[ab+(W+4)>>2]=ar|1;c[ab+(ar+W)>>2]=ar;J=ar>>>3;if(ar>>>0<256){V=J<<1;X=2376+(V<<2)|0;P=c[584]|0;m=1<<J;do{if((P&m|0)==0){c[584]=P|m;as=X;at=2376+(V+2<<2)|0}else{J=2376+(V+2<<2)|0;U=c[J>>2]|0;if(U>>>0>=(c[588]|0)>>>0){as=U;at=J;break}aR();return 0}}while(0);c[at>>2]=_;c[as+12>>2]=_;c[ab+(W+8)>>2]=as;c[ab+(W+12)>>2]=X;break}V=ac;m=ar>>>8;do{if((m|0)==0){au=0}else{if(ar>>>0>16777215){au=31;break}P=(m+1048320|0)>>>16&8;$=m<<P;J=($+520192|0)>>>16&4;U=$<<J;$=(U+245760|0)>>>16&2;Q=14-(J|P|$)+(U<<$>>>15)|0;au=ar>>>((Q+7|0)>>>0)&1|Q<<1}}while(0);m=2640+(au<<2)|0;c[ab+(W+28)>>2]=au;c[ab+(W+20)>>2]=0;c[ab+(W+16)>>2]=0;X=c[585]|0;Q=1<<au;if((X&Q|0)==0){c[585]=X|Q;c[m>>2]=V;c[ab+(W+24)>>2]=m;c[ab+(W+12)>>2]=V;c[ab+(W+8)>>2]=V;break}if((au|0)==31){av=0}else{av=25-(au>>>1)|0}Q=ar<<av;X=c[m>>2]|0;while(1){if((c[X+4>>2]&-8|0)==(ar|0)){break}aw=X+16+(Q>>>31<<2)|0;m=c[aw>>2]|0;if((m|0)==0){T=866;break}else{Q=Q<<1;X=m}}if((T|0)==866){if(aw>>>0<(c[588]|0)>>>0){aR();return 0}else{c[aw>>2]=V;c[ab+(W+24)>>2]=X;c[ab+(W+12)>>2]=V;c[ab+(W+8)>>2]=V;break}}Q=X+8|0;m=c[Q>>2]|0;$=c[588]|0;if(X>>>0<$>>>0){aR();return 0}if(m>>>0<$>>>0){aR();return 0}else{c[m+12>>2]=V;c[Q>>2]=V;c[ab+(W+8)>>2]=m;c[ab+(W+12)>>2]=X;c[ab+(W+24)>>2]=0;break}}}while(0);n=ab+(ak|8)|0;return n|0}}while(0);Y=ad;W=2784;while(1){ax=c[W>>2]|0;if(ax>>>0<=Y>>>0){ay=c[W+4>>2]|0;az=ax+ay|0;if(az>>>0>Y>>>0){break}}W=c[W+8>>2]|0}W=ax+(ay-39)|0;if((W&7|0)==0){aA=0}else{aA=-W&7}W=ax+(ay-47+aA)|0;ac=W>>>0<(ad+16|0)>>>0?Y:W;W=ac+8|0;_=ab+8|0;if((_&7|0)==0){aB=0}else{aB=-_&7}_=aa-40-aB|0;c[590]=ab+aB;c[587]=_;c[ab+(aB+4)>>2]=_|1;c[ab+(aa-36)>>2]=40;c[591]=c[580];c[ac+4>>2]=27;c[W>>2]=c[696];c[W+4>>2]=c[2788>>2];c[W+8>>2]=c[2792>>2];c[W+12>>2]=c[2796>>2];c[696]=ab;c[697]=aa;c[699]=0;c[698]=W;W=ac+28|0;c[W>>2]=7;if((ac+32|0)>>>0<az>>>0){_=W;while(1){W=_+4|0;c[W>>2]=7;if((_+8|0)>>>0<az>>>0){_=W}else{break}}}if((ac|0)==(Y|0)){break}_=ac-ad|0;W=Y+(_+4)|0;c[W>>2]=c[W>>2]&-2;c[ad+4>>2]=_|1;c[Y+_>>2]=_;W=_>>>3;if(_>>>0<256){K=W<<1;Z=2376+(K<<2)|0;S=c[584]|0;m=1<<W;do{if((S&m|0)==0){c[584]=S|m;aC=Z;aD=2376+(K+2<<2)|0}else{W=2376+(K+2<<2)|0;Q=c[W>>2]|0;if(Q>>>0>=(c[588]|0)>>>0){aC=Q;aD=W;break}aR();return 0}}while(0);c[aD>>2]=ad;c[aC+12>>2]=ad;c[ad+8>>2]=aC;c[ad+12>>2]=Z;break}K=ad;m=_>>>8;do{if((m|0)==0){aE=0}else{if(_>>>0>16777215){aE=31;break}S=(m+1048320|0)>>>16&8;Y=m<<S;ac=(Y+520192|0)>>>16&4;W=Y<<ac;Y=(W+245760|0)>>>16&2;Q=14-(ac|S|Y)+(W<<Y>>>15)|0;aE=_>>>((Q+7|0)>>>0)&1|Q<<1}}while(0);m=2640+(aE<<2)|0;c[ad+28>>2]=aE;c[ad+20>>2]=0;c[ad+16>>2]=0;Z=c[585]|0;Q=1<<aE;if((Z&Q|0)==0){c[585]=Z|Q;c[m>>2]=K;c[ad+24>>2]=m;c[ad+12>>2]=ad;c[ad+8>>2]=ad;break}if((aE|0)==31){aF=0}else{aF=25-(aE>>>1)|0}Q=_<<aF;Z=c[m>>2]|0;while(1){if((c[Z+4>>2]&-8|0)==(_|0)){break}aG=Z+16+(Q>>>31<<2)|0;m=c[aG>>2]|0;if((m|0)==0){T=901;break}else{Q=Q<<1;Z=m}}if((T|0)==901){if(aG>>>0<(c[588]|0)>>>0){aR();return 0}else{c[aG>>2]=K;c[ad+24>>2]=Z;c[ad+12>>2]=ad;c[ad+8>>2]=ad;break}}Q=Z+8|0;_=c[Q>>2]|0;m=c[588]|0;if(Z>>>0<m>>>0){aR();return 0}if(_>>>0<m>>>0){aR();return 0}else{c[_+12>>2]=K;c[Q>>2]=K;c[ad+8>>2]=_;c[ad+12>>2]=Z;c[ad+24>>2]=0;break}}}while(0);ad=c[587]|0;if(ad>>>0<=o>>>0){break}_=ad-o|0;c[587]=_;ad=c[590]|0;Q=ad;c[590]=Q+o;c[Q+(o+4)>>2]=_|1;c[ad+4>>2]=o|3;n=ad+8|0;return n|0}}while(0);c[(bp()|0)>>2]=12;n=0;return n|0}function cj(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0;if((a|0)==0){return}b=a-8|0;d=b;e=c[588]|0;if(b>>>0<e>>>0){aR()}f=c[a-4>>2]|0;g=f&3;if((g|0)==1){aR()}h=f&-8;i=a+(h-8)|0;j=i;L1232:do{if((f&1|0)==0){k=c[b>>2]|0;if((g|0)==0){return}l=-8-k|0;m=a+l|0;n=m;o=k+h|0;if(m>>>0<e>>>0){aR()}if((n|0)==(c[589]|0)){p=a+(h-4)|0;if((c[p>>2]&3|0)!=3){q=n;r=o;break}c[586]=o;c[p>>2]=c[p>>2]&-2;c[a+(l+4)>>2]=o|1;c[i>>2]=o;return}p=k>>>3;if(k>>>0<256){k=c[a+(l+8)>>2]|0;s=c[a+(l+12)>>2]|0;t=2376+(p<<1<<2)|0;do{if((k|0)!=(t|0)){if(k>>>0<e>>>0){aR()}if((c[k+12>>2]|0)==(n|0)){break}aR()}}while(0);if((s|0)==(k|0)){c[584]=c[584]&~(1<<p);q=n;r=o;break}do{if((s|0)==(t|0)){u=s+8|0}else{if(s>>>0<e>>>0){aR()}v=s+8|0;if((c[v>>2]|0)==(n|0)){u=v;break}aR()}}while(0);c[k+12>>2]=s;c[u>>2]=k;q=n;r=o;break}t=m;p=c[a+(l+24)>>2]|0;v=c[a+(l+12)>>2]|0;do{if((v|0)==(t|0)){w=a+(l+20)|0;x=c[w>>2]|0;if((x|0)==0){y=a+(l+16)|0;z=c[y>>2]|0;if((z|0)==0){A=0;break}else{B=z;C=y}}else{B=x;C=w}while(1){w=B+20|0;x=c[w>>2]|0;if((x|0)!=0){B=x;C=w;continue}w=B+16|0;x=c[w>>2]|0;if((x|0)==0){break}else{B=x;C=w}}if(C>>>0<e>>>0){aR()}else{c[C>>2]=0;A=B;break}}else{w=c[a+(l+8)>>2]|0;if(w>>>0<e>>>0){aR()}x=w+12|0;if((c[x>>2]|0)!=(t|0)){aR()}y=v+8|0;if((c[y>>2]|0)==(t|0)){c[x>>2]=v;c[y>>2]=w;A=v;break}else{aR()}}}while(0);if((p|0)==0){q=n;r=o;break}v=a+(l+28)|0;m=2640+(c[v>>2]<<2)|0;do{if((t|0)==(c[m>>2]|0)){c[m>>2]=A;if((A|0)!=0){break}c[585]=c[585]&~(1<<c[v>>2]);q=n;r=o;break L1232}else{if(p>>>0<(c[588]|0)>>>0){aR()}k=p+16|0;if((c[k>>2]|0)==(t|0)){c[k>>2]=A}else{c[p+20>>2]=A}if((A|0)==0){q=n;r=o;break L1232}}}while(0);if(A>>>0<(c[588]|0)>>>0){aR()}c[A+24>>2]=p;t=c[a+(l+16)>>2]|0;do{if((t|0)!=0){if(t>>>0<(c[588]|0)>>>0){aR()}else{c[A+16>>2]=t;c[t+24>>2]=A;break}}}while(0);t=c[a+(l+20)>>2]|0;if((t|0)==0){q=n;r=o;break}if(t>>>0<(c[588]|0)>>>0){aR()}else{c[A+20>>2]=t;c[t+24>>2]=A;q=n;r=o;break}}else{q=d;r=h}}while(0);d=q;if(d>>>0>=i>>>0){aR()}A=a+(h-4)|0;e=c[A>>2]|0;if((e&1|0)==0){aR()}do{if((e&2|0)==0){if((j|0)==(c[590]|0)){B=(c[587]|0)+r|0;c[587]=B;c[590]=q;c[q+4>>2]=B|1;if((q|0)!=(c[589]|0)){return}c[589]=0;c[586]=0;return}if((j|0)==(c[589]|0)){B=(c[586]|0)+r|0;c[586]=B;c[589]=q;c[q+4>>2]=B|1;c[d+B>>2]=B;return}B=(e&-8)+r|0;C=e>>>3;L1335:do{if(e>>>0<256){u=c[a+h>>2]|0;g=c[a+(h|4)>>2]|0;b=2376+(C<<1<<2)|0;do{if((u|0)!=(b|0)){if(u>>>0<(c[588]|0)>>>0){aR()}if((c[u+12>>2]|0)==(j|0)){break}aR()}}while(0);if((g|0)==(u|0)){c[584]=c[584]&~(1<<C);break}do{if((g|0)==(b|0)){D=g+8|0}else{if(g>>>0<(c[588]|0)>>>0){aR()}f=g+8|0;if((c[f>>2]|0)==(j|0)){D=f;break}aR()}}while(0);c[u+12>>2]=g;c[D>>2]=u}else{b=i;f=c[a+(h+16)>>2]|0;t=c[a+(h|4)>>2]|0;do{if((t|0)==(b|0)){p=a+(h+12)|0;v=c[p>>2]|0;if((v|0)==0){m=a+(h+8)|0;k=c[m>>2]|0;if((k|0)==0){E=0;break}else{F=k;G=m}}else{F=v;G=p}while(1){p=F+20|0;v=c[p>>2]|0;if((v|0)!=0){F=v;G=p;continue}p=F+16|0;v=c[p>>2]|0;if((v|0)==0){break}else{F=v;G=p}}if(G>>>0<(c[588]|0)>>>0){aR()}else{c[G>>2]=0;E=F;break}}else{p=c[a+h>>2]|0;if(p>>>0<(c[588]|0)>>>0){aR()}v=p+12|0;if((c[v>>2]|0)!=(b|0)){aR()}m=t+8|0;if((c[m>>2]|0)==(b|0)){c[v>>2]=t;c[m>>2]=p;E=t;break}else{aR()}}}while(0);if((f|0)==0){break}t=a+(h+20)|0;u=2640+(c[t>>2]<<2)|0;do{if((b|0)==(c[u>>2]|0)){c[u>>2]=E;if((E|0)!=0){break}c[585]=c[585]&~(1<<c[t>>2]);break L1335}else{if(f>>>0<(c[588]|0)>>>0){aR()}g=f+16|0;if((c[g>>2]|0)==(b|0)){c[g>>2]=E}else{c[f+20>>2]=E}if((E|0)==0){break L1335}}}while(0);if(E>>>0<(c[588]|0)>>>0){aR()}c[E+24>>2]=f;b=c[a+(h+8)>>2]|0;do{if((b|0)!=0){if(b>>>0<(c[588]|0)>>>0){aR()}else{c[E+16>>2]=b;c[b+24>>2]=E;break}}}while(0);b=c[a+(h+12)>>2]|0;if((b|0)==0){break}if(b>>>0<(c[588]|0)>>>0){aR()}else{c[E+20>>2]=b;c[b+24>>2]=E;break}}}while(0);c[q+4>>2]=B|1;c[d+B>>2]=B;if((q|0)!=(c[589]|0)){H=B;break}c[586]=B;return}else{c[A>>2]=e&-2;c[q+4>>2]=r|1;c[d+r>>2]=r;H=r}}while(0);r=H>>>3;if(H>>>0<256){d=r<<1;e=2376+(d<<2)|0;A=c[584]|0;E=1<<r;do{if((A&E|0)==0){c[584]=A|E;I=e;J=2376+(d+2<<2)|0}else{r=2376+(d+2<<2)|0;h=c[r>>2]|0;if(h>>>0>=(c[588]|0)>>>0){I=h;J=r;break}aR()}}while(0);c[J>>2]=q;c[I+12>>2]=q;c[q+8>>2]=I;c[q+12>>2]=e;return}e=q;I=H>>>8;do{if((I|0)==0){K=0}else{if(H>>>0>16777215){K=31;break}J=(I+1048320|0)>>>16&8;d=I<<J;E=(d+520192|0)>>>16&4;A=d<<E;d=(A+245760|0)>>>16&2;r=14-(E|J|d)+(A<<d>>>15)|0;K=H>>>((r+7|0)>>>0)&1|r<<1}}while(0);I=2640+(K<<2)|0;c[q+28>>2]=K;c[q+20>>2]=0;c[q+16>>2]=0;r=c[585]|0;d=1<<K;do{if((r&d|0)==0){c[585]=r|d;c[I>>2]=e;c[q+24>>2]=I;c[q+12>>2]=q;c[q+8>>2]=q}else{if((K|0)==31){L=0}else{L=25-(K>>>1)|0}A=H<<L;J=c[I>>2]|0;while(1){if((c[J+4>>2]&-8|0)==(H|0)){break}M=J+16+(A>>>31<<2)|0;E=c[M>>2]|0;if((E|0)==0){N=1078;break}else{A=A<<1;J=E}}if((N|0)==1078){if(M>>>0<(c[588]|0)>>>0){aR()}else{c[M>>2]=e;c[q+24>>2]=J;c[q+12>>2]=q;c[q+8>>2]=q;break}}A=J+8|0;B=c[A>>2]|0;E=c[588]|0;if(J>>>0<E>>>0){aR()}if(B>>>0<E>>>0){aR()}else{c[B+12>>2]=e;c[A>>2]=e;c[q+8>>2]=B;c[q+12>>2]=J;c[q+24>>2]=0;break}}}while(0);q=(c[592]|0)-1|0;c[592]=q;if((q|0)==0){O=2792}else{return}while(1){q=c[O>>2]|0;if((q|0)==0){break}else{O=q+8|0}}c[592]=-1;return}function ck(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;f=b|0;if((b&3)==(d&3)){while(b&3){if((e|0)==0)return f|0;a[b]=a[d]|0;b=b+1|0;d=d+1|0;e=e-1|0}while((e|0)>=4){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0;e=e-4|0}}while((e|0)>0){a[b]=a[d]|0;b=b+1|0;d=d+1|0;e=e-1|0}return f|0}function cl(b){b=b|0;var c=0;c=b;while(a[c]|0){c=c+1|0}return c-b|0}function cm(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0;f=b+e|0;if((e|0)>=20){d=d&255;e=b&3;g=d|d<<8|d<<16|d<<24;h=f&~3;if(e){e=b+4-e|0;while((b|0)<(e|0)){a[b]=d;b=b+1|0}}while((b|0)<(h|0)){c[b>>2]=g;b=b+4|0}}while((b|0)<(f|0)){a[b]=d;b=b+1|0}}function cn(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=a+c>>>0;return(ad=b+d+(e>>>0<a>>>0|0)>>>0,e|0)|0}function co(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=b-d>>>0;e=b-d-(c>>>0>a>>>0|0)>>>0;return(ad=e,a-c>>>0|0)|0}function cp(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){ad=b<<c|(a&(1<<c)-1<<32-c)>>>32-c;return a<<c}ad=a<<c-32;return 0}function cq(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){ad=b>>>c;return a>>>c|(b&(1<<c)-1)<<32-c}ad=0;return b>>>c-32|0}function cr(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){ad=b>>c;return a>>>c|(b&(1<<c)-1)<<32-c}ad=(b|0)<0?-1:0;return b>>c-32|0}function cs(b){b=b|0;var c=0;c=a[n+(b>>>24)|0]|0;if((c|0)<8)return c|0;c=a[n+(b>>16&255)|0]|0;if((c|0)<8)return c+8|0;c=a[n+(b>>8&255)|0]|0;if((c|0)<8)return c+16|0;return(a[n+(b&255)|0]|0)+24|0}function ct(b){b=b|0;var c=0;c=a[m+(b&255)|0]|0;if((c|0)<8)return c|0;c=a[m+(b>>8&255)|0]|0;if((c|0)<8)return c+8|0;c=a[m+(b>>16&255)|0]|0;if((c|0)<8)return c+16|0;return(a[m+(b>>>24)|0]|0)+24|0}function cu(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;c=a&65535;d=b&65535;e=aB(d,c)|0;f=a>>>16;a=(e>>>16)+(aB(d,f)|0)|0;d=b>>>16;b=aB(d,c)|0;return(ad=(a>>>16)+(aB(d,f)|0)+(((a&65535)+b|0)>>>16)|0,a+b<<16|e&65535|0)|0}function cv(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;e=b>>31|((b|0)<0?-1:0)<<1;f=((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1;g=d>>31|((d|0)<0?-1:0)<<1;h=((d|0)<0?-1:0)>>31|((d|0)<0?-1:0)<<1;i=co(e^a,f^b,e,f)|0;b=ad;a=g^e;e=h^f;f=co((cA(i,b,co(g^c,h^d,g,h)|0,ad,0)|0)^a,ad^e,a,e)|0;return(ad=ad,f)|0}function cw(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;f=i;i=i+8|0;g=f|0;h=b>>31|((b|0)<0?-1:0)<<1;j=((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1;k=e>>31|((e|0)<0?-1:0)<<1;l=((e|0)<0?-1:0)>>31|((e|0)<0?-1:0)<<1;m=co(h^a,j^b,h,j)|0;b=ad;a=co(k^d,l^e,k,l)|0;cA(m,b,a,ad,g)|0;a=co(c[g>>2]^h,c[g+4>>2]^j,h,j)|0;j=ad;i=f;return(ad=j,a)|0}function cx(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0;e=a;a=c;c=cu(e,a)|0;f=ad;return(ad=(aB(b,a)|0)+(aB(d,e)|0)+f|f&0,c|0|0)|0}function cy(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=cA(a,b,c,d,0)|0;return(ad=ad,e)|0}function cz(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;f=i;i=i+8|0;g=f|0;cA(a,b,d,e,g)|0;i=f;return(ad=c[g+4>>2]|0,c[g>>2]|0)|0}function cA(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0;g=a;h=b;i=h;j=d;k=e;l=k;if((i|0)==0){m=(f|0)!=0;if((l|0)==0){if(m){c[f>>2]=(g>>>0)%(j>>>0);c[f+4>>2]=0}n=0;o=(g>>>0)/(j>>>0)>>>0;return(ad=n,o)|0}else{if(!m){n=0;o=0;return(ad=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=b&0;n=0;o=0;return(ad=n,o)|0}}m=(l|0)==0;do{if((j|0)==0){if(m){if((f|0)!=0){c[f>>2]=(i>>>0)%(j>>>0);c[f+4>>2]=0}n=0;o=(i>>>0)/(j>>>0)>>>0;return(ad=n,o)|0}if((g|0)==0){if((f|0)!=0){c[f>>2]=0;c[f+4>>2]=(i>>>0)%(l>>>0)}n=0;o=(i>>>0)/(l>>>0)>>>0;return(ad=n,o)|0}p=l-1|0;if((p&l|0)==0){if((f|0)!=0){c[f>>2]=a|0;c[f+4>>2]=p&i|b&0}n=0;o=i>>>((ct(l|0)|0)>>>0);return(ad=n,o)|0}p=(cs(l|0)|0)-(cs(i|0)|0)|0;if(p>>>0<=30){q=p+1|0;r=31-p|0;s=q;t=i<<r|g>>>(q>>>0);u=i>>>(q>>>0);v=0;w=g<<r;break}if((f|0)==0){n=0;o=0;return(ad=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=h|b&0;n=0;o=0;return(ad=n,o)|0}else{if(!m){r=(cs(l|0)|0)-(cs(i|0)|0)|0;if(r>>>0<=31){q=r+1|0;p=31-r|0;x=r-31>>31;s=q;t=g>>>(q>>>0)&x|i<<p;u=i>>>(q>>>0)&x;v=0;w=g<<p;break}if((f|0)==0){n=0;o=0;return(ad=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=h|b&0;n=0;o=0;return(ad=n,o)|0}p=j-1|0;if((p&j|0)!=0){x=(cs(j|0)|0)+33-(cs(i|0)|0)|0;q=64-x|0;r=32-x|0;y=r>>31;z=x-32|0;A=z>>31;s=x;t=r-1>>31&i>>>(z>>>0)|(i<<r|g>>>(x>>>0))&A;u=A&i>>>(x>>>0);v=g<<q&y;w=(i<<q|g>>>(z>>>0))&y|g<<r&x-33>>31;break}if((f|0)!=0){c[f>>2]=p&g;c[f+4>>2]=0}if((j|0)==1){n=h|b&0;o=a|0|0;return(ad=n,o)|0}else{p=ct(j|0)|0;n=i>>>(p>>>0)|0;o=i<<32-p|g>>>(p>>>0)|0;return(ad=n,o)|0}}}while(0);if((s|0)==0){B=w;C=v;D=u;E=t;F=0;G=0}else{g=d|0|0;d=k|e&0;e=cn(g,d,-1,-1)|0;k=ad;i=w;w=v;v=u;u=t;t=s;s=0;while(1){H=w>>>31|i<<1;I=s|w<<1;j=u<<1|i>>>31|0;a=u>>>31|v<<1|0;co(e,k,j,a)|0;b=ad;h=b>>31|((b|0)<0?-1:0)<<1;J=h&1;K=co(j,a,h&g,(((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1)&d)|0;L=ad;b=t-1|0;if((b|0)==0){break}else{i=H;w=I;v=L;u=K;t=b;s=J}}B=H;C=I;D=L;E=K;F=0;G=J}J=C;C=0;if((f|0)!=0){c[f>>2]=E;c[f+4>>2]=D}n=(J|0)>>>31|(B|C)<<1|(C<<1|J>>>31)&0|F;o=(J<<1|0>>>31)&-2|G;return(ad=n,o)|0}function cB(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return bw[a&1](b|0,c|0,d|0)|0}function cC(a,b){a=a|0;b=b|0;bx[a&1](b|0)}function cD(a,b){a=a|0;b=b|0;return by[a&3](b|0)|0}function cE(a){a=a|0;bz[a&3]()}function cF(a,b,c){a=a|0;b=b|0;c=c|0;return bA[a&1](b|0,c|0)|0}function cG(a,b,c){a=a|0;b=b|0;c=c|0;aC(0);return 0}function cH(a){a=a|0;aC(1)}function cI(a){a=a|0;aC(2);return 0}function cJ(){aC(3)}function cK(a,b){a=a|0;b=b|0;aC(4);return 0} | |
// EMSCRIPTEN_END_FUNCS | |
var bw=[cG,cG];var bx=[cH,cH];var by=[cI,cI,bV,cI];var bz=[cJ,cJ,bT,cJ];var bA=[cK,cK];return{_strlen:cl,_free:cj,_main:bX,__GLOBAL__I_a:cc,_memset:cm,_malloc:ci,_memcpy:ck,__D3sdl16__moduleinfoCtorZ:cd,runPostSets:bR,stackAlloc:bB,stackSave:bC,stackRestore:bD,setThrew:bE,setTempRet0:bH,setTempRet1:bI,setTempRet2:bJ,setTempRet3:bK,setTempRet4:bL,setTempRet5:bM,setTempRet6:bN,setTempRet7:bO,setTempRet8:bP,setTempRet9:bQ,dynCall_iiii:cB,dynCall_vi:cC,dynCall_ii:cD,dynCall_v:cE,dynCall_iii:cF}}) | |
// EMSCRIPTEN_END_ASM | |
({ "Math": Math, "Int8Array": Int8Array, "Int16Array": Int16Array, "Int32Array": Int32Array, "Uint8Array": Uint8Array, "Uint16Array": Uint16Array, "Uint32Array": Uint32Array, "Float32Array": Float32Array, "Float64Array": Float64Array }, { "abort": abort, "assert": assert, "asmPrintInt": asmPrintInt, "asmPrintFloat": asmPrintFloat, "min": Math_min, "invoke_iiii": invoke_iiii, "invoke_vi": invoke_vi, "invoke_ii": invoke_ii, "invoke_v": invoke_v, "invoke_iii": invoke_iii, "_llvm_lifetime_end": _llvm_lifetime_end, "__D3std9exception7bailOutFNaNfAyakxAaZv": __D3std9exception7bailOutFNaNfAyakxAaZv, "__D3std3utf12UTFException6__ctorMFAyakAyakC6object9ThrowableZC3std3utf12UTFException": __D3std3utf12UTFException6__ctorMFAyakAyakC6object9ThrowableZC3std3utf12UTFException, "_sysconf": _sysconf, "__d_assert_msg": __d_assert_msg, "_abort": _abort, "_fprintf": _fprintf, "_send": _send, "_printf": _printf, "_SDL_SetVideoMode": _SDL_SetVideoMode, "_SDL_LockSurface": _SDL_LockSurface, "__reallyNegative": __reallyNegative, "_fflush": _fflush, "__d_newclass": __d_newclass, "_SDL_UnlockSurface": _SDL_UnlockSurface, "__d_array_slice_copy": __d_array_slice_copy, "___setErrNo": ___setErrNo, "_fwrite": _fwrite, "__D4core6memory2GC6extendFNaNbPvkkZk": __D4core6memory2GC6extendFNaNbPvkkZk, "_SDL_Flip": _SDL_Flip, "__adDupT": __adDupT, "__d_newarrayvT": __d_newarrayvT, "_write": _write, "__d_allocmemoryT": __d_allocmemoryT, "__d_arraysetcapacity": __d_arraysetcapacity, "__adEq2": __adEq2, "__D4core5bitop3bsrFNaNbNfkZi": __D4core5bitop3bsrFNaNbNfkZi, "__D3std4conv21ConvOverflowException6__ctorMFAyaAyakZC3std4conv21ConvOverflowException": __D3std4conv21ConvOverflowException6__ctorMFAyaAyakZC3std4conv21ConvOverflowException, "__d_throw_exception": __d_throw_exception, "__D3std6format15FormatException6__ctorMFAyaAyakC6object9ThrowableZC3std6format15FormatException": __D3std6format15FormatException6__ctorMFAyaAyakC6object9ThrowableZC3std6format15FormatException, "_llvm_uadd_with_overflow_i32": _llvm_uadd_with_overflow_i32, "_emscripten_set_main_loop": _emscripten_set_main_loop, "__formatString": __formatString, "__D6object9Exception6__ctorMFNaNbNfAyaAyakC6object9ThrowableZC9Exception": __D6object9Exception6__ctorMFNaNbNfAyaAyakC6object9ThrowableZC9Exception, "__d_assert": __d_assert, "__D3std4conv13ConvException6__ctorMFAyaAyakZC3std4conv13ConvException": __D3std4conv13ConvException6__ctorMFAyaAyakZC3std4conv13ConvException, "_pwrite": _pwrite, "_sbrk": _sbrk, "__d_array_bounds": __d_array_bounds, "__D3std5ascii7isDigitFNaNbNfwZb": __D3std5ascii7isDigitFNaNbNfwZb, "_SDL_Init": _SDL_Init, "___errno_location": ___errno_location, "__D3std3utf12isValidDcharFNaNbNfwZb": __D3std3utf12isValidDcharFNaNbNfwZb, "__D4core6memory2GC6qallocFNaNbkkZS4core6memory8BlkInfo_": __D4core6memory2GC6qallocFNaNbkkZS4core6memory8BlkInfo_, "__d_arrayappendT": __d_arrayappendT, "__D3std3utf6encodeFNaNfKG4awZk": __D3std3utf6encodeFNaNfKG4awZk, "_time": _time, "_llvm_lifetime_start": _llvm_lifetime_start, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "cttz_i8": cttz_i8, "ctlz_i8": ctlz_i8, "NaN": NaN, "Infinity": Infinity, "__D3std3utf12UTFException6__vtblZ": __D3std3utf12UTFException6__vtblZ, "__D3std4conv21ConvOverflowException6__vtblZ": __D3std4conv21ConvOverflowException6__vtblZ, "__D14TypeInfo_Const6__vtblZ": __D14TypeInfo_Const6__vtblZ, "__D10TypeInfo_a6__initZ": __D10TypeInfo_a6__initZ, "__D3std6format12__ModuleInfoZ": __D3std6format12__ModuleInfoZ, "__D3std4conv13ConvException7__ClassZ": __D3std4conv13ConvException7__ClassZ, "__D3std4conv13ConvException6__vtblZ": __D3std4conv13ConvException6__vtblZ, "__D3std4conv21ConvOverflowException6__initZ": __D3std4conv21ConvOverflowException6__initZ, "__D3std3utf12UTFException6__initZ": __D3std3utf12UTFException6__initZ, "__D3std6format15FormatException6__initZ": __D3std6format15FormatException6__initZ, "__D11TypeInfo_Ai6__initZ": __D11TypeInfo_Ai6__initZ, "__D15TypeInfo_Struct6__vtblZ": __D15TypeInfo_Struct6__vtblZ, "__D3std4conv21ConvOverflowException7__ClassZ": __D3std4conv21ConvOverflowException7__ClassZ, "__D9Exception7__ClassZ": __D9Exception7__ClassZ, "__D9Exception6__vtblZ": __D9Exception6__vtblZ, "__D3std4conv13ConvException6__initZ": __D3std4conv13ConvException6__initZ, "__D3std6format15FormatException6__vtblZ": __D3std6format15FormatException6__vtblZ, "__D3std5array12__ModuleInfoZ": __D3std5array12__ModuleInfoZ, "__D3std9algorithm12__ModuleInfoZ": __D3std9algorithm12__ModuleInfoZ, "__D14TypeInfo_Array6__vtblZ": __D14TypeInfo_Array6__vtblZ, "__D3std6format15FormatException7__ClassZ": __D3std6format15FormatException7__ClassZ, "__D3std3utf12__ModuleInfoZ": __D3std3utf12__ModuleInfoZ, "__D3std3utf12UTFException7__ClassZ": __D3std3utf12UTFException7__ClassZ, "__D3SDL12__ModuleInfoZ": __D3SDL12__ModuleInfoZ, "__D3std5stdio12__ModuleInfoZ": __D3std5stdio12__ModuleInfoZ, "__D12TypeInfo_Aya6__initZ": __D12TypeInfo_Aya6__initZ, "__D9Exception6__initZ": __D9Exception6__initZ, "__Dmodule_ref": __Dmodule_ref }, buffer); | |
var _strlen = Module["_strlen"] = asm["_strlen"]; | |
var _free = Module["_free"] = asm["_free"]; | |
var _main = Module["_main"] = asm["_main"]; | |
var __GLOBAL__I_a = Module["__GLOBAL__I_a"] = asm["__GLOBAL__I_a"]; | |
var _memset = Module["_memset"] = asm["_memset"]; | |
var _malloc = Module["_malloc"] = asm["_malloc"]; | |
var _memcpy = Module["_memcpy"] = asm["_memcpy"]; | |
var __D3sdl16__moduleinfoCtorZ = Module["__D3sdl16__moduleinfoCtorZ"] = asm["__D3sdl16__moduleinfoCtorZ"]; | |
var runPostSets = Module["runPostSets"] = asm["runPostSets"]; | |
var dynCall_iiii = Module["dynCall_iiii"] = asm["dynCall_iiii"]; | |
var dynCall_vi = Module["dynCall_vi"] = asm["dynCall_vi"]; | |
var dynCall_ii = Module["dynCall_ii"] = asm["dynCall_ii"]; | |
var dynCall_v = Module["dynCall_v"] = asm["dynCall_v"]; | |
var dynCall_iii = Module["dynCall_iii"] = asm["dynCall_iii"]; | |
Runtime.stackAlloc = function(size) { return asm['stackAlloc'](size) }; | |
Runtime.stackSave = function() { return asm['stackSave']() }; | |
Runtime.stackRestore = function(top) { asm['stackRestore'](top) }; | |
// TODO: strip out parts of this we do not need | |
//======= begin closure i64 code ======= | |
// Copyright 2009 The Closure Library Authors. All Rights Reserved. | |
// | |
// Licensed under the Apache License, Version 2.0 (the "License"); | |
// you may not use this file except in compliance with the License. | |
// You may obtain a copy of the License at | |
// | |
// http://www.apache.org/licenses/LICENSE-2.0 | |
// | |
// Unless required by applicable law or agreed to in writing, software | |
// distributed under the License is distributed on an "AS-IS" BASIS, | |
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
// See the License for the specific language governing permissions and | |
// limitations under the License. | |
/** | |
* @fileoverview Defines a Long class for representing a 64-bit two's-complement | |
* integer value, which faithfully simulates the behavior of a Java "long". This | |
* implementation is derived from LongLib in GWT. | |
* | |
*/ | |
var i64Math = (function() { // Emscripten wrapper | |
var goog = { math: {} }; | |
/** | |
* Constructs a 64-bit two's-complement integer, given its low and high 32-bit | |
* values as *signed* integers. See the from* functions below for more | |
* convenient ways of constructing Longs. | |
* | |
* The internal representation of a long is the two given signed, 32-bit values. | |
* We use 32-bit pieces because these are the size of integers on which | |
* Javascript performs bit-operations. For operations like addition and | |
* multiplication, we split each number into 16-bit pieces, which can easily be | |
* multiplied within Javascript's floating-point representation without overflow | |
* or change in sign. | |
* | |
* In the algorithms below, we frequently reduce the negative case to the | |
* positive case by negating the input(s) and then post-processing the result. | |
* Note that we must ALWAYS check specially whether those values are MIN_VALUE | |
* (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as | |
* a positive number, it overflows back into a negative). Not handling this | |
* case would often result in infinite recursion. | |
* | |
* @param {number} low The low (signed) 32 bits of the long. | |
* @param {number} high The high (signed) 32 bits of the long. | |
* @constructor | |
*/ | |
goog.math.Long = function(low, high) { | |
/** | |
* @type {number} | |
* @private | |
*/ | |
this.low_ = low | 0; // force into 32 signed bits. | |
/** | |
* @type {number} | |
* @private | |
*/ | |
this.high_ = high | 0; // force into 32 signed bits. | |
}; | |
// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the | |
// from* methods on which they depend. | |
/** | |
* A cache of the Long representations of small integer values. | |
* @type {!Object} | |
* @private | |
*/ | |
goog.math.Long.IntCache_ = {}; | |
/** | |
* Returns a Long representing the given (32-bit) integer value. | |
* @param {number} value The 32-bit integer in question. | |
* @return {!goog.math.Long} The corresponding Long value. | |
*/ | |
goog.math.Long.fromInt = function(value) { | |
if (-128 <= value && value < 128) { | |
var cachedObj = goog.math.Long.IntCache_[value]; | |
if (cachedObj) { | |
return cachedObj; | |
} | |
} | |
var obj = new goog.math.Long(value | 0, value < 0 ? -1 : 0); | |
if (-128 <= value && value < 128) { | |
goog.math.Long.IntCache_[value] = obj; | |
} | |
return obj; | |
}; | |
/** | |
* Returns a Long representing the given value, provided that it is a finite | |
* number. Otherwise, zero is returned. | |
* @param {number} value The number in question. | |
* @return {!goog.math.Long} The corresponding Long value. | |
*/ | |
goog.math.Long.fromNumber = function(value) { | |
if (isNaN(value) || !isFinite(value)) { | |
return goog.math.Long.ZERO; | |
} else if (value <= -goog.math.Long.TWO_PWR_63_DBL_) { | |
return goog.math.Long.MIN_VALUE; | |
} else if (value + 1 >= goog.math.Long.TWO_PWR_63_DBL_) { | |
return goog.math.Long.MAX_VALUE; | |
} else if (value < 0) { | |
return goog.math.Long.fromNumber(-value).negate(); | |
} else { | |
return new goog.math.Long( | |
(value % goog.math.Long.TWO_PWR_32_DBL_) | 0, | |
(value / goog.math.Long.TWO_PWR_32_DBL_) | 0); | |
} | |
}; | |
/** | |
* Returns a Long representing the 64-bit integer that comes by concatenating | |
* the given high and low bits. Each is assumed to use 32 bits. | |
* @param {number} lowBits The low 32-bits. | |
* @param {number} highBits The high 32-bits. | |
* @return {!goog.math.Long} The corresponding Long value. | |
*/ | |
goog.math.Long.fromBits = function(lowBits, highBits) { | |
return new goog.math.Long(lowBits, highBits); | |
}; | |
/** | |
* Returns a Long representation of the given string, written using the given | |
* radix. | |
* @param {string} str The textual representation of the Long. | |
* @param {number=} opt_radix The radix in which the text is written. | |
* @return {!goog.math.Long} The corresponding Long value. | |
*/ | |
goog.math.Long.fromString = function(str, opt_radix) { | |
if (str.length == 0) { | |
throw Error('number format error: empty string'); | |
} | |
var radix = opt_radix || 10; | |
if (radix < 2 || 36 < radix) { | |
throw Error('radix out of range: ' + radix); | |
} | |
if (str.charAt(0) == '-') { | |
return goog.math.Long.fromString(str.substring(1), radix).negate(); | |
} else if (str.indexOf('-') >= 0) { | |
throw Error('number format error: interior "-" character: ' + str); | |
} | |
// Do several (8) digits each time through the loop, so as to | |
// minimize the calls to the very expensive emulated div. | |
var radixToPower = goog.math.Long.fromNumber(Math.pow(radix, 8)); | |
var result = goog.math.Long.ZERO; | |
for (var i = 0; i < str.length; i += 8) { | |
var size = Math.min(8, str.length - i); | |
var value = parseInt(str.substring(i, i + size), radix); | |
if (size < 8) { | |
var power = goog.math.Long.fromNumber(Math.pow(radix, size)); | |
result = result.multiply(power).add(goog.math.Long.fromNumber(value)); | |
} else { | |
result = result.multiply(radixToPower); | |
result = result.add(goog.math.Long.fromNumber(value)); | |
} | |
} | |
return result; | |
}; | |
// NOTE: the compiler should inline these constant values below and then remove | |
// these variables, so there should be no runtime penalty for these. | |
/** | |
* Number used repeated below in calculations. This must appear before the | |
* first call to any from* function below. | |
* @type {number} | |
* @private | |
*/ | |
goog.math.Long.TWO_PWR_16_DBL_ = 1 << 16; | |
/** | |
* @type {number} | |
* @private | |
*/ | |
goog.math.Long.TWO_PWR_24_DBL_ = 1 << 24; | |
/** | |
* @type {number} | |
* @private | |
*/ | |
goog.math.Long.TWO_PWR_32_DBL_ = | |
goog.math.Long.TWO_PWR_16_DBL_ * goog.math.Long.TWO_PWR_16_DBL_; | |
/** | |
* @type {number} | |
* @private | |
*/ | |
goog.math.Long.TWO_PWR_31_DBL_ = | |
goog.math.Long.TWO_PWR_32_DBL_ / 2; | |
/** | |
* @type {number} | |
* @private | |
*/ | |
goog.math.Long.TWO_PWR_48_DBL_ = | |
goog.math.Long.TWO_PWR_32_DBL_ * goog.math.Long.TWO_PWR_16_DBL_; | |
/** | |
* @type {number} | |
* @private | |
*/ | |
goog.math.Long.TWO_PWR_64_DBL_ = | |
goog.math.Long.TWO_PWR_32_DBL_ * goog.math.Long.TWO_PWR_32_DBL_; | |
/** | |
* @type {number} | |
* @private | |
*/ | |
goog.math.Long.TWO_PWR_63_DBL_ = | |
goog.math.Long.TWO_PWR_64_DBL_ / 2; | |
/** @type {!goog.math.Long} */ | |
goog.math.Long.ZERO = goog.math.Long.fromInt(0); | |
/** @type {!goog.math.Long} */ | |
goog.math.Long.ONE = goog.math.Long.fromInt(1); | |
/** @type {!goog.math.Long} */ | |
goog.math.Long.NEG_ONE = goog.math.Long.fromInt(-1); | |
/** @type {!goog.math.Long} */ | |
goog.math.Long.MAX_VALUE = | |
goog.math.Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); | |
/** @type {!goog.math.Long} */ | |
goog.math.Long.MIN_VALUE = goog.math.Long.fromBits(0, 0x80000000 | 0); | |
/** | |
* @type {!goog.math.Long} | |
* @private | |
*/ | |
goog.math.Long.TWO_PWR_24_ = goog.math.Long.fromInt(1 << 24); | |
/** @return {number} The value, assuming it is a 32-bit integer. */ | |
goog.math.Long.prototype.toInt = function() { | |
return this.low_; | |
}; | |
/** @return {number} The closest floating-point representation to this value. */ | |
goog.math.Long.prototype.toNumber = function() { | |
return this.high_ * goog.math.Long.TWO_PWR_32_DBL_ + | |
this.getLowBitsUnsigned(); | |
}; | |
/** | |
* @param {number=} opt_radix The radix in which the text should be written. | |
* @return {string} The textual representation of this value. | |
*/ | |
goog.math.Long.prototype.toString = function(opt_radix) { | |
var radix = opt_radix || 10; | |
if (radix < 2 || 36 < radix) { | |
throw Error('radix out of range: ' + radix); | |
} | |
if (this.isZero()) { | |
return '0'; | |
} | |
if (this.isNegative()) { | |
if (this.equals(goog.math.Long.MIN_VALUE)) { | |
// We need to change the Long value before it can be negated, so we remove | |
// the bottom-most digit in this base and then recurse to do the rest. | |
var radixLong = goog.math.Long.fromNumber(radix); | |
var div = this.div(radixLong); | |
var rem = div.multiply(radixLong).subtract(this); | |
return div.toString(radix) + rem.toInt().toString(radix); | |
} else { | |
return '-' + this.negate().toString(radix); | |
} | |
} | |
// Do several (6) digits each time through the loop, so as to | |
// minimize the calls to the very expensive emulated div. | |
var radixToPower = goog.math.Long.fromNumber(Math.pow(radix, 6)); | |
var rem = this; | |
var result = ''; | |
while (true) { | |
var remDiv = rem.div(radixToPower); | |
var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); | |
var digits = intval.toString(radix); | |
rem = remDiv; | |
if (rem.isZero()) { | |
return digits + result; | |
} else { | |
while (digits.length < 6) { | |
digits = '0' + digits; | |
} | |
result = '' + digits + result; | |
} | |
} | |
}; | |
/** @return {number} The high 32-bits as a signed value. */ | |
goog.math.Long.prototype.getHighBits = function() { | |
return this.high_; | |
}; | |
/** @return {number} The low 32-bits as a signed value. */ | |
goog.math.Long.prototype.getLowBits = function() { | |
return this.low_; | |
}; | |
/** @return {number} The low 32-bits as an unsigned value. */ | |
goog.math.Long.prototype.getLowBitsUnsigned = function() { | |
return (this.low_ >= 0) ? | |
this.low_ : goog.math.Long.TWO_PWR_32_DBL_ + this.low_; | |
}; | |
/** | |
* @return {number} Returns the number of bits needed to represent the absolute | |
* value of this Long. | |
*/ | |
goog.math.Long.prototype.getNumBitsAbs = function() { | |
if (this.isNegative()) { | |
if (this.equals(goog.math.Long.MIN_VALUE)) { | |
return 64; | |
} else { | |
return this.negate().getNumBitsAbs(); | |
} | |
} else { | |
var val = this.high_ != 0 ? this.high_ : this.low_; | |
for (var bit = 31; bit > 0; bit--) { | |
if ((val & (1 << bit)) != 0) { | |
break; | |
} | |
} | |
return this.high_ != 0 ? bit + 33 : bit + 1; | |
} | |
}; | |
/** @return {boolean} Whether this value is zero. */ | |
goog.math.Long.prototype.isZero = function() { | |
return this.high_ == 0 && this.low_ == 0; | |
}; | |
/** @return {boolean} Whether this value is negative. */ | |
goog.math.Long.prototype.isNegative = function() { | |
return this.high_ < 0; | |
}; | |
/** @return {boolean} Whether this value is odd. */ | |
goog.math.Long.prototype.isOdd = function() { | |
return (this.low_ & 1) == 1; | |
}; | |
/** | |
* @param {goog.math.Long} other Long to compare against. | |
* @return {boolean} Whether this Long equals the other. | |
*/ | |
goog.math.Long.prototype.equals = function(other) { | |
return (this.high_ == other.high_) && (this.low_ == other.low_); | |
}; | |
/** | |
* @param {goog.math.Long} other Long to compare against. | |
* @return {boolean} Whether this Long does not equal the other. | |
*/ | |
goog.math.Long.prototype.notEquals = function(other) { | |
return (this.high_ != other.high_) || (this.low_ != other.low_); | |
}; | |
/** | |
* @param {goog.math.Long} other Long to compare against. | |
* @return {boolean} Whether this Long is less than the other. | |
*/ | |
goog.math.Long.prototype.lessThan = function(other) { | |
return this.compare(other) < 0; | |
}; | |
/** | |
* @param {goog.math.Long} other Long to compare against. | |
* @return {boolean} Whether this Long is less than or equal to the other. | |
*/ | |
goog.math.Long.prototype.lessThanOrEqual = function(other) { | |
return this.compare(other) <= 0; | |
}; | |
/** | |
* @param {goog.math.Long} other Long to compare against. | |
* @return {boolean} Whether this Long is greater than the other. | |
*/ | |
goog.math.Long.prototype.greaterThan = function(other) { | |
return this.compare(other) > 0; | |
}; | |
/** | |
* @param {goog.math.Long} other Long to compare against. | |
* @return {boolean} Whether this Long is greater than or equal to the other. | |
*/ | |
goog.math.Long.prototype.greaterThanOrEqual = function(other) { | |
return this.compare(other) >= 0; | |
}; | |
/** | |
* Compares this Long with the given one. | |
* @param {goog.math.Long} other Long to compare against. | |
* @return {number} 0 if they are the same, 1 if the this is greater, and -1 | |
* if the given one is greater. | |
*/ | |
goog.math.Long.prototype.compare = function(other) { | |
if (this.equals(other)) { | |
return 0; | |
} | |
var thisNeg = this.isNegative(); | |
var otherNeg = other.isNegative(); | |
if (thisNeg && !otherNeg) { | |
return -1; | |
} | |
if (!thisNeg && otherNeg) { | |
return 1; | |
} | |
// at this point, the signs are the same, so subtraction will not overflow | |
if (this.subtract(other).isNegative()) { | |
return -1; | |
} else { | |
return 1; | |
} | |
}; | |
/** @return {!goog.math.Long} The negation of this value. */ | |
goog.math.Long.prototype.negate = function() { | |
if (this.equals(goog.math.Long.MIN_VALUE)) { | |
return goog.math.Long.MIN_VALUE; | |
} else { | |
return this.not().add(goog.math.Long.ONE); | |
} | |
}; | |
/** | |
* Returns the sum of this and the given Long. | |
* @param {goog.math.Long} other Long to add to this one. | |
* @return {!goog.math.Long} The sum of this and the given Long. | |
*/ | |
goog.math.Long.prototype.add = function(other) { | |
// Divide each number into 4 chunks of 16 bits, and then sum the chunks. | |
var a48 = this.high_ >>> 16; | |
var a32 = this.high_ & 0xFFFF; | |
var a16 = this.low_ >>> 16; | |
var a00 = this.low_ & 0xFFFF; | |
var b48 = other.high_ >>> 16; | |
var b32 = other.high_ & 0xFFFF; | |
var b16 = other.low_ >>> 16; | |
var b00 = other.low_ & 0xFFFF; | |
var c48 = 0, c32 = 0, c16 = 0, c00 = 0; | |
c00 += a00 + b00; | |
c16 += c00 >>> 16; | |
c00 &= 0xFFFF; | |
c16 += a16 + b16; | |
c32 += c16 >>> 16; | |
c16 &= 0xFFFF; | |
c32 += a32 + b32; | |
c48 += c32 >>> 16; | |
c32 &= 0xFFFF; | |
c48 += a48 + b48; | |
c48 &= 0xFFFF; | |
return goog.math.Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); | |
}; | |
/** | |
* Returns the difference of this and the given Long. | |
* @param {goog.math.Long} other Long to subtract from this. | |
* @return {!goog.math.Long} The difference of this and the given Long. | |
*/ | |
goog.math.Long.prototype.subtract = function(other) { | |
return this.add(other.negate()); | |
}; | |
/** | |
* Returns the product of this and the given long. | |
* @param {goog.math.Long} other Long to multiply with this. | |
* @return {!goog.math.Long} The product of this and the other. | |
*/ | |
goog.math.Long.prototype.multiply = function(other) { | |
if (this.isZero()) { | |
return goog.math.Long.ZERO; | |
} else if (other.isZero()) { | |
return goog.math.Long.ZERO; | |
} | |
if (this.equals(goog.math.Long.MIN_VALUE)) { | |
return other.isOdd() ? goog.math.Long.MIN_VALUE : goog.math.Long.ZERO; | |
} else if (other.equals(goog.math.Long.MIN_VALUE)) { | |
return this.isOdd() ? goog.math.Long.MIN_VALUE : goog.math.Long.ZERO; | |
} | |
if (this.isNegative()) { | |
if (other.isNegative()) { | |
return this.negate().multiply(other.negate()); | |
} else { | |
return this.negate().multiply(other).negate(); | |
} | |
} else if (other.isNegative()) { | |
return this.multiply(other.negate()).negate(); | |
} | |
// If both longs are small, use float multiplication | |
if (this.lessThan(goog.math.Long.TWO_PWR_24_) && | |
other.lessThan(goog.math.Long.TWO_PWR_24_)) { | |
return goog.math.Long.fromNumber(this.toNumber() * other.toNumber()); | |
} | |
// Divide each long into 4 chunks of 16 bits, and then add up 4x4 products. | |
// We can skip products that would overflow. | |
var a48 = this.high_ >>> 16; | |
var a32 = this.high_ & 0xFFFF; | |
var a16 = this.low_ >>> 16; | |
var a00 = this.low_ & 0xFFFF; | |
var b48 = other.high_ >>> 16; | |
var b32 = other.high_ & 0xFFFF; | |
var b16 = other.low_ >>> 16; | |
var b00 = other.low_ & 0xFFFF; | |
var c48 = 0, c32 = 0, c16 = 0, c00 = 0; | |
c00 += a00 * b00; | |
c16 += c00 >>> 16; | |
c00 &= 0xFFFF; | |
c16 += a16 * b00; | |
c32 += c16 >>> 16; | |
c16 &= 0xFFFF; | |
c16 += a00 * b16; | |
c32 += c16 >>> 16; | |
c16 &= 0xFFFF; | |
c32 += a32 * b00; | |
c48 += c32 >>> 16; | |
c32 &= 0xFFFF; | |
c32 += a16 * b16; | |
c48 += c32 >>> 16; | |
c32 &= 0xFFFF; | |
c32 += a00 * b32; | |
c48 += c32 >>> 16; | |
c32 &= 0xFFFF; | |
c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; | |
c48 &= 0xFFFF; | |
return goog.math.Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); | |
}; | |
/** | |
* Returns this Long divided by the given one. | |
* @param {goog.math.Long} other Long by which to divide. | |
* @return {!goog.math.Long} This Long divided by the given one. | |
*/ | |
goog.math.Long.prototype.div = function(other) { | |
if (other.isZero()) { | |
throw Error('division by zero'); | |
} else if (this.isZero()) { | |
return goog.math.Long.ZERO; | |
} | |
if (this.equals(goog.math.Long.MIN_VALUE)) { | |
if (other.equals(goog.math.Long.ONE) || | |
other.equals(goog.math.Long.NEG_ONE)) { | |
return goog.math.Long.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE | |
} else if (other.equals(goog.math.Long.MIN_VALUE)) { | |
return goog.math.Long.ONE; | |
} else { | |
// At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. | |
var halfThis = this.shiftRight(1); | |
var approx = halfThis.div(other).shiftLeft(1); | |
if (approx.equals(goog.math.Long.ZERO)) { | |
return other.isNegative() ? goog.math.Long.ONE : goog.math.Long.NEG_ONE; | |
} else { | |
var rem = this.subtract(other.multiply(approx)); | |
var result = approx.add(rem.div(other)); | |
return result; | |
} | |
} | |
} else if (other.equals(goog.math.Long.MIN_VALUE)) { | |
return goog.math.Long.ZERO; | |
} | |
if (this.isNegative()) { | |
if (other.isNegative()) { | |
return this.negate().div(other.negate()); | |
} else { | |
return this.negate().div(other).negate(); | |
} | |
} else if (other.isNegative()) { | |
return this.div(other.negate()).negate(); | |
} | |
// Repeat the following until the remainder is less than other: find a | |
// floating-point that approximates remainder / other *from below*, add this | |
// into the result, and subtract it from the remainder. It is critical that | |
// the approximate value is less than or equal to the real value so that the | |
// remainder never becomes negative. | |
var res = goog.math.Long.ZERO; | |
var rem = this; | |
while (rem.greaterThanOrEqual(other)) { | |
// Approximate the result of division. This may be a little greater or | |
// smaller than the actual value. | |
var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); | |
// We will tweak the approximate result by changing it in the 48-th digit or | |
// the smallest non-fractional digit, whichever is larger. | |
var log2 = Math.ceil(Math.log(approx) / Math.LN2); | |
var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); | |
// Decrease the approximation until it is smaller than the remainder. Note | |
// that if it is too large, the product overflows and is negative. | |
var approxRes = goog.math.Long.fromNumber(approx); | |
var approxRem = approxRes.multiply(other); | |
while (approxRem.isNegative() || approxRem.greaterThan(rem)) { | |
approx -= delta; | |
approxRes = goog.math.Long.fromNumber(approx); | |
approxRem = approxRes.multiply(other); | |
} | |
// We know the answer can't be zero... and actually, zero would cause | |
// infinite recursion since we would make no progress. | |
if (approxRes.isZero()) { | |
approxRes = goog.math.Long.ONE; | |
} | |
res = res.add(approxRes); | |
rem = rem.subtract(approxRem); | |
} | |
return res; | |
}; | |
/** | |
* Returns this Long modulo the given one. | |
* @param {goog.math.Long} other Long by which to mod. | |
* @return {!goog.math.Long} This Long modulo the given one. | |
*/ | |
goog.math.Long.prototype.modulo = function(other) { | |
return this.subtract(this.div(other).multiply(other)); | |
}; | |
/** @return {!goog.math.Long} The bitwise-NOT of this value. */ | |
goog.math.Long.prototype.not = function() { | |
return goog.math.Long.fromBits(~this.low_, ~this.high_); | |
}; | |
/** | |
* Returns the bitwise-AND of this Long and the given one. | |
* @param {goog.math.Long} other The Long with which to AND. | |
* @return {!goog.math.Long} The bitwise-AND of this and the other. | |
*/ | |
goog.math.Long.prototype.and = function(other) { | |
return goog.math.Long.fromBits(this.low_ & other.low_, | |
this.high_ & other.high_); | |
}; | |
/** | |
* Returns the bitwise-OR of this Long and the given one. | |
* @param {goog.math.Long} other The Long with which to OR. | |
* @return {!goog.math.Long} The bitwise-OR of this and the other. | |
*/ | |
goog.math.Long.prototype.or = function(other) { | |
return goog.math.Long.fromBits(this.low_ | other.low_, | |
this.high_ | other.high_); | |
}; | |
/** | |
* Returns the bitwise-XOR of this Long and the given one. | |
* @param {goog.math.Long} other The Long with which to XOR. | |
* @return {!goog.math.Long} The bitwise-XOR of this and the other. | |
*/ | |
goog.math.Long.prototype.xor = function(other) { | |
return goog.math.Long.fromBits(this.low_ ^ other.low_, | |
this.high_ ^ other.high_); | |
}; | |
/** | |
* Returns this Long with bits shifted to the left by the given amount. | |
* @param {number} numBits The number of bits by which to shift. | |
* @return {!goog.math.Long} This shifted to the left by the given amount. | |
*/ | |
goog.math.Long.prototype.shiftLeft = function(numBits) { | |
numBits &= 63; | |
if (numBits == 0) { | |
return this; | |
} else { | |
var low = this.low_; | |
if (numBits < 32) { | |
var high = this.high_; | |
return goog.math.Long.fromBits( | |
low << numBits, | |
(high << numBits) | (low >>> (32 - numBits))); | |
} else { | |
return goog.math.Long.fromBits(0, low << (numBits - 32)); | |
} | |
} | |
}; | |
/** | |
* Returns this Long with bits shifted to the right by the given amount. | |
* @param {number} numBits The number of bits by which to shift. | |
* @return {!goog.math.Long} This shifted to the right by the given amount. | |
*/ | |
goog.math.Long.prototype.shiftRight = function(numBits) { | |
numBits &= 63; | |
if (numBits == 0) { | |
return this; | |
} else { | |
var high = this.high_; | |
if (numBits < 32) { | |
var low = this.low_; | |
return goog.math.Long.fromBits( | |
(low >>> numBits) | (high << (32 - numBits)), | |
high >> numBits); | |
} else { | |
return goog.math.Long.fromBits( | |
high >> (numBits - 32), | |
high >= 0 ? 0 : -1); | |
} | |
} | |
}; | |
/** | |
* Returns this Long with bits shifted to the right by the given amount, with | |
* the new top bits matching the current sign bit. | |
* @param {number} numBits The number of bits by which to shift. | |
* @return {!goog.math.Long} This shifted to the right by the given amount, with | |
* zeros placed into the new leading bits. | |
*/ | |
goog.math.Long.prototype.shiftRightUnsigned = function(numBits) { | |
numBits &= 63; | |
if (numBits == 0) { | |
return this; | |
} else { | |
var high = this.high_; | |
if (numBits < 32) { | |
var low = this.low_; | |
return goog.math.Long.fromBits( | |
(low >>> numBits) | (high << (32 - numBits)), | |
high >>> numBits); | |
} else if (numBits == 32) { | |
return goog.math.Long.fromBits(high, 0); | |
} else { | |
return goog.math.Long.fromBits(high >>> (numBits - 32), 0); | |
} | |
} | |
}; | |
//======= begin jsbn ======= | |
var navigator = { appName: 'Modern Browser' }; // polyfill a little | |
// Copyright (c) 2005 Tom Wu | |
// All Rights Reserved. | |
// http://www-cs-students.stanford.edu/~tjw/jsbn/ | |
/* | |
* Copyright (c) 2003-2005 Tom Wu | |
* All Rights Reserved. | |
* | |
* Permission is hereby granted, free of charge, to any person obtaining | |
* a copy of this software and associated documentation files (the | |
* "Software"), to deal in the Software without restriction, including | |
* without limitation the rights to use, copy, modify, merge, publish, | |
* distribute, sublicense, and/or sell copies of the Software, and to | |
* permit persons to whom the Software is furnished to do so, subject to | |
* the following conditions: | |
* | |
* The above copyright notice and this permission notice shall be | |
* included in all copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, | |
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY | |
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | |
* | |
* IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, | |
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER | |
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF | |
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT | |
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
* | |
* In addition, the following condition applies: | |
* | |
* All redistributions must retain an intact copy of this copyright notice | |
* and disclaimer. | |
*/ | |
// Basic JavaScript BN library - subset useful for RSA encryption. | |
// Bits per digit | |
var dbits; | |
// JavaScript engine analysis | |
var canary = 0xdeadbeefcafe; | |
var j_lm = ((canary&0xffffff)==0xefcafe); | |
// (public) Constructor | |
function BigInteger(a,b,c) { | |
if(a != null) | |
if("number" == typeof a) this.fromNumber(a,b,c); | |
else if(b == null && "string" != typeof a) this.fromString(a,256); | |
else this.fromString(a,b); | |
} | |
// return new, unset BigInteger | |
function nbi() { return new BigInteger(null); } | |
// am: Compute w_j += (x*this_i), propagate carries, | |
// c is initial carry, returns final carry. | |
// c < 3*dvalue, x < 2*dvalue, this_i < dvalue | |
// We need to select the fastest one that works in this environment. | |
// am1: use a single mult and divide to get the high bits, | |
// max digit bits should be 26 because | |
// max internal value = 2*dvalue^2-2*dvalue (< 2^53) | |
function am1(i,x,w,j,c,n) { | |
while(--n >= 0) { | |
var v = x*this[i++]+w[j]+c; | |
c = Math.floor(v/0x4000000); | |
w[j++] = v&0x3ffffff; | |
} | |
return c; | |
} | |
// am2 avoids a big mult-and-extract completely. | |
// Max digit bits should be <= 30 because we do bitwise ops | |
// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) | |
function am2(i,x,w,j,c,n) { | |
var xl = x&0x7fff, xh = x>>15; | |
while(--n >= 0) { | |
var l = this[i]&0x7fff; | |
var h = this[i++]>>15; | |
var m = xh*l+h*xl; | |
l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); | |
c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); | |
w[j++] = l&0x3fffffff; | |
} | |
return c; | |
} | |
// Alternately, set max digit bits to 28 since some | |
// browsers slow down when dealing with 32-bit numbers. | |
function am3(i,x,w,j,c,n) { | |
var xl = x&0x3fff, xh = x>>14; | |
while(--n >= 0) { | |
var l = this[i]&0x3fff; | |
var h = this[i++]>>14; | |
var m = xh*l+h*xl; | |
l = xl*l+((m&0x3fff)<<14)+w[j]+c; | |
c = (l>>28)+(m>>14)+xh*h; | |
w[j++] = l&0xfffffff; | |
} | |
return c; | |
} | |
if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { | |
BigInteger.prototype.am = am2; | |
dbits = 30; | |
} | |
else if(j_lm && (navigator.appName != "Netscape")) { | |
BigInteger.prototype.am = am1; | |
dbits = 26; | |
} | |
else { // Mozilla/Netscape seems to prefer am3 | |
BigInteger.prototype.am = am3; | |
dbits = 28; | |
} | |
BigInteger.prototype.DB = dbits; | |
BigInteger.prototype.DM = ((1<<dbits)-1); | |
BigInteger.prototype.DV = (1<<dbits); | |
var BI_FP = 52; | |
BigInteger.prototype.FV = Math.pow(2,BI_FP); | |
BigInteger.prototype.F1 = BI_FP-dbits; | |
BigInteger.prototype.F2 = 2*dbits-BI_FP; | |
// Digit conversions | |
var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; | |
var BI_RC = new Array(); | |
var rr,vv; | |
rr = "0".charCodeAt(0); | |
for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; | |
rr = "a".charCodeAt(0); | |
for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; | |
rr = "A".charCodeAt(0); | |
for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; | |
function int2char(n) { return BI_RM.charAt(n); } | |
function intAt(s,i) { | |
var c = BI_RC[s.charCodeAt(i)]; | |
return (c==null)?-1:c; | |
} | |
// (protected) copy this to r | |
function bnpCopyTo(r) { | |
for(var i = this.t-1; i >= 0; --i) r[i] = this[i]; | |
r.t = this.t; | |
r.s = this.s; | |
} | |
// (protected) set from integer value x, -DV <= x < DV | |
function bnpFromInt(x) { | |
this.t = 1; | |
this.s = (x<0)?-1:0; | |
if(x > 0) this[0] = x; | |
else if(x < -1) this[0] = x+DV; | |
else this.t = 0; | |
} | |
// return bigint initialized to value | |
function nbv(i) { var r = nbi(); r.fromInt(i); return r; } | |
// (protected) set from string and radix | |
function bnpFromString(s,b) { | |
var k; | |
if(b == 16) k = 4; | |
else if(b == 8) k = 3; | |
else if(b == 256) k = 8; // byte array | |
else if(b == 2) k = 1; | |
else if(b == 32) k = 5; | |
else if(b == 4) k = 2; | |
else { this.fromRadix(s,b); return; } | |
this.t = 0; | |
this.s = 0; | |
var i = s.length, mi = false, sh = 0; | |
while(--i >= 0) { | |
var x = (k==8)?s[i]&0xff:intAt(s,i); | |
if(x < 0) { | |
if(s.charAt(i) == "-") mi = true; | |
continue; | |
} | |
mi = false; | |
if(sh == 0) | |
this[this.t++] = x; | |
else if(sh+k > this.DB) { | |
this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh; | |
this[this.t++] = (x>>(this.DB-sh)); | |
} | |
else | |
this[this.t-1] |= x<<sh; | |
sh += k; | |
if(sh >= this.DB) sh -= this.DB; | |
} | |
if(k == 8 && (s[0]&0x80) != 0) { | |
this.s = -1; | |
if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh; | |
} | |
this.clamp(); | |
if(mi) BigInteger.ZERO.subTo(this,this); | |
} | |
// (protected) clamp off excess high words | |
function bnpClamp() { | |
var c = this.s&this.DM; | |
while(this.t > 0 && this[this.t-1] == c) --this.t; | |
} | |
// (public) return string representation in given radix | |
function bnToString(b) { | |
if(this.s < 0) return "-"+this.negate().toString(b); | |
var k; | |
if(b == 16) k = 4; | |
else if(b == 8) k = 3; | |
else if(b == 2) k = 1; | |
else if(b == 32) k = 5; | |
else if(b == 4) k = 2; | |
else return this.toRadix(b); | |
var km = (1<<k)-1, d, m = false, r = "", i = this.t; | |
var p = this.DB-(i*this.DB)%k; | |
if(i-- > 0) { | |
if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } | |
while(i >= 0) { | |
if(p < k) { | |
d = (this[i]&((1<<p)-1))<<(k-p); | |
d |= this[--i]>>(p+=this.DB-k); | |
} | |
else { | |
d = (this[i]>>(p-=k))&km; | |
if(p <= 0) { p += this.DB; --i; } | |
} | |
if(d > 0) m = true; | |
if(m) r += int2char(d); | |
} | |
} | |
return m?r:"0"; | |
} | |
// (public) -this | |
function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } | |
// (public) |this| | |
function bnAbs() { return (this.s<0)?this.negate():this; } | |
// (public) return + if this > a, - if this < a, 0 if equal | |
function bnCompareTo(a) { | |
var r = this.s-a.s; | |
if(r != 0) return r; | |
var i = this.t; | |
r = i-a.t; | |
if(r != 0) return (this.s<0)?-r:r; | |
while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; | |
return 0; | |
} | |
// returns bit length of the integer x | |
function nbits(x) { | |
var r = 1, t; | |
if((t=x>>>16) != 0) { x = t; r += 16; } | |
if((t=x>>8) != 0) { x = t; r += 8; } | |
if((t=x>>4) != 0) { x = t; r += 4; } | |
if((t=x>>2) != 0) { x = t; r += 2; } | |
if((t=x>>1) != 0) { x = t; r += 1; } | |
return r; | |
} | |
// (public) return the number of bits in "this" | |
function bnBitLength() { | |
if(this.t <= 0) return 0; | |
return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); | |
} | |
// (protected) r = this << n*DB | |
function bnpDLShiftTo(n,r) { | |
var i; | |
for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; | |
for(i = n-1; i >= 0; --i) r[i] = 0; | |
r.t = this.t+n; | |
r.s = this.s; | |
} | |
// (protected) r = this >> n*DB | |
function bnpDRShiftTo(n,r) { | |
for(var i = n; i < this.t; ++i) r[i-n] = this[i]; | |
r.t = Math.max(this.t-n,0); | |
r.s = this.s; | |
} | |
// (protected) r = this << n | |
function bnpLShiftTo(n,r) { | |
var bs = n%this.DB; | |
var cbs = this.DB-bs; | |
var bm = (1<<cbs)-1; | |
var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i; | |
for(i = this.t-1; i >= 0; --i) { | |
r[i+ds+1] = (this[i]>>cbs)|c; | |
c = (this[i]&bm)<<bs; | |
} | |
for(i = ds-1; i >= 0; --i) r[i] = 0; | |
r[ds] = c; | |
r.t = this.t+ds+1; | |
r.s = this.s; | |
r.clamp(); | |
} | |
// (protected) r = this >> n | |
function bnpRShiftTo(n,r) { | |
r.s = this.s; | |
var ds = Math.floor(n/this.DB); | |
if(ds >= this.t) { r.t = 0; return; } | |
var bs = n%this.DB; | |
var cbs = this.DB-bs; | |
var bm = (1<<bs)-1; | |
r[0] = this[ds]>>bs; | |
for(var i = ds+1; i < this.t; ++i) { | |
r[i-ds-1] |= (this[i]&bm)<<cbs; | |
r[i-ds] = this[i]>>bs; | |
} | |
if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs; | |
r.t = this.t-ds; | |
r.clamp(); | |
} | |
// (protected) r = this - a | |
function bnpSubTo(a,r) { | |
var i = 0, c = 0, m = Math.min(a.t,this.t); | |
while(i < m) { | |
c += this[i]-a[i]; | |
r[i++] = c&this.DM; | |
c >>= this.DB; | |
} | |
if(a.t < this.t) { | |
c -= a.s; | |
while(i < this.t) { | |
c += this[i]; | |
r[i++] = c&this.DM; | |
c >>= this.DB; | |
} | |
c += this.s; | |
} | |
else { | |
c += this.s; | |
while(i < a.t) { | |
c -= a[i]; | |
r[i++] = c&this.DM; | |
c >>= this.DB; | |
} | |
c -= a.s; | |
} | |
r.s = (c<0)?-1:0; | |
if(c < -1) r[i++] = this.DV+c; | |
else if(c > 0) r[i++] = c; | |
r.t = i; | |
r.clamp(); | |
} | |
// (protected) r = this * a, r != this,a (HAC 14.12) | |
// "this" should be the larger one if appropriate. | |
function bnpMultiplyTo(a,r) { | |
var x = this.abs(), y = a.abs(); | |
var i = x.t; | |
r.t = i+y.t; | |
while(--i >= 0) r[i] = 0; | |
for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); | |
r.s = 0; | |
r.clamp(); | |
if(this.s != a.s) BigInteger.ZERO.subTo(r,r); | |
} | |
// (protected) r = this^2, r != this (HAC 14.16) | |
function bnpSquareTo(r) { | |
var x = this.abs(); | |
var i = r.t = 2*x.t; | |
while(--i >= 0) r[i] = 0; | |
for(i = 0; i < x.t-1; ++i) { | |
var c = x.am(i,x[i],r,2*i,0,1); | |
if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { | |
r[i+x.t] -= x.DV; | |
r[i+x.t+1] = 1; | |
} | |
} | |
if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); | |
r.s = 0; | |
r.clamp(); | |
} | |
// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) | |
// r != q, this != m. q or r may be null. | |
function bnpDivRemTo(m,q,r) { | |
var pm = m.abs(); | |
if(pm.t <= 0) return; | |
var pt = this.abs(); | |
if(pt.t < pm.t) { | |
if(q != null) q.fromInt(0); | |
if(r != null) this.copyTo(r); | |
return; | |
} | |
if(r == null) r = nbi(); | |
var y = nbi(), ts = this.s, ms = m.s; | |
var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus | |
if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } | |
else { pm.copyTo(y); pt.copyTo(r); } | |
var ys = y.t; | |
var y0 = y[ys-1]; | |
if(y0 == 0) return; | |
var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0); | |
var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2; | |
var i = r.t, j = i-ys, t = (q==null)?nbi():q; | |
y.dlShiftTo(j,t); | |
if(r.compareTo(t) >= 0) { | |
r[r.t++] = 1; | |
r.subTo(t,r); | |
} | |
BigInteger.ONE.dlShiftTo(ys,t); | |
t.subTo(y,y); // "negative" y so we can replace sub with am later | |
while(y.t < ys) y[y.t++] = 0; | |
while(--j >= 0) { | |
// Estimate quotient digit | |
var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); | |
if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out | |
y.dlShiftTo(j,t); | |
r.subTo(t,r); | |
while(r[i] < --qd) r.subTo(t,r); | |
} | |
} | |
if(q != null) { | |
r.drShiftTo(ys,q); | |
if(ts != ms) BigInteger.ZERO.subTo(q,q); | |
} | |
r.t = ys; | |
r.clamp(); | |
if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder | |
if(ts < 0) BigInteger.ZERO.subTo(r,r); | |
} | |
// (public) this mod a | |
function bnMod(a) { | |
var r = nbi(); | |
this.abs().divRemTo(a,null,r); | |
if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); | |
return r; | |
} | |
// Modular reduction using "classic" algorithm | |
function Classic(m) { this.m = m; } | |
function cConvert(x) { | |
if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); | |
else return x; | |
} | |
function cRevert(x) { return x; } | |
function cReduce(x) { x.divRemTo(this.m,null,x); } | |
function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } | |
function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } | |
Classic.prototype.convert = cConvert; | |
Classic.prototype.revert = cRevert; | |
Classic.prototype.reduce = cReduce; | |
Classic.prototype.mulTo = cMulTo; | |
Classic.prototype.sqrTo = cSqrTo; | |
// (protected) return "-1/this % 2^DB"; useful for Mont. reduction | |
// justification: | |
// xy == 1 (mod m) | |
// xy = 1+km | |
// xy(2-xy) = (1+km)(1-km) | |
// x[y(2-xy)] = 1-k^2m^2 | |
// x[y(2-xy)] == 1 (mod m^2) | |
// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 | |
// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. | |
// JS multiply "overflows" differently from C/C++, so care is needed here. | |
function bnpInvDigit() { | |
if(this.t < 1) return 0; | |
var x = this[0]; | |
if((x&1) == 0) return 0; | |
var y = x&3; // y == 1/x mod 2^2 | |
y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 | |
y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 | |
y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 | |
// last step - calculate inverse mod DV directly; | |
// assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints | |
y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits | |
// we really want the negative inverse, and -DV < y < DV | |
return (y>0)?this.DV-y:-y; | |
} | |
// Montgomery reduction | |
function Montgomery(m) { | |
this.m = m; | |
this.mp = m.invDigit(); | |
this.mpl = this.mp&0x7fff; | |
this.mph = this.mp>>15; | |
this.um = (1<<(m.DB-15))-1; | |
this.mt2 = 2*m.t; | |
} | |
// xR mod m | |
function montConvert(x) { | |
var r = nbi(); | |
x.abs().dlShiftTo(this.m.t,r); | |
r.divRemTo(this.m,null,r); | |
if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); | |
return r; | |
} | |
// x/R mod m | |
function montRevert(x) { | |
var r = nbi(); | |
x.copyTo(r); | |
this.reduce(r); | |
return r; | |
} | |
// x = x/R mod m (HAC 14.32) | |
function montReduce(x) { | |
while(x.t <= this.mt2) // pad x so am has enough room later | |
x[x.t++] = 0; | |
for(var i = 0; i < this.m.t; ++i) { | |
// faster way of calculating u0 = x[i]*mp mod DV | |
var j = x[i]&0x7fff; | |
var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; | |
// use am to combine the multiply-shift-add into one call | |
j = i+this.m.t; | |
x[j] += this.m.am(0,u0,x,i,0,this.m.t); | |
// propagate carry | |
while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } | |
} | |
x.clamp(); | |
x.drShiftTo(this.m.t,x); | |
if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); | |
} | |
// r = "x^2/R mod m"; x != r | |
function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } | |
// r = "xy/R mod m"; x,y != r | |
function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } | |
Montgomery.prototype.convert = montConvert; | |
Montgomery.prototype.revert = montRevert; | |
Montgomery.prototype.reduce = montReduce; | |
Montgomery.prototype.mulTo = montMulTo; | |
Montgomery.prototype.sqrTo = montSqrTo; | |
// (protected) true iff this is even | |
function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } | |
// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) | |
function bnpExp(e,z) { | |
if(e > 0xffffffff || e < 1) return BigInteger.ONE; | |
var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; | |
g.copyTo(r); | |
while(--i >= 0) { | |
z.sqrTo(r,r2); | |
if((e&(1<<i)) > 0) z.mulTo(r2,g,r); | |
else { var t = r; r = r2; r2 = t; } | |
} | |
return z.revert(r); | |
} | |
// (public) this^e % m, 0 <= e < 2^32 | |
function bnModPowInt(e,m) { | |
var z; | |
if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); | |
return this.exp(e,z); | |
} | |
// protected | |
BigInteger.prototype.copyTo = bnpCopyTo; | |
BigInteger.prototype.fromInt = bnpFromInt; | |
BigInteger.prototype.fromString = bnpFromString; | |
BigInteger.prototype.clamp = bnpClamp; | |
BigInteger.prototype.dlShiftTo = bnpDLShiftTo; | |
BigInteger.prototype.drShiftTo = bnpDRShiftTo; | |
BigInteger.prototype.lShiftTo = bnpLShiftTo; | |
BigInteger.prototype.rShiftTo = bnpRShiftTo; | |
BigInteger.prototype.subTo = bnpSubTo; | |
BigInteger.prototype.multiplyTo = bnpMultiplyTo; | |
BigInteger.prototype.squareTo = bnpSquareTo; | |
BigInteger.prototype.divRemTo = bnpDivRemTo; | |
BigInteger.prototype.invDigit = bnpInvDigit; | |
BigInteger.prototype.isEven = bnpIsEven; | |
BigInteger.prototype.exp = bnpExp; | |
// public | |
BigInteger.prototype.toString = bnToString; | |
BigInteger.prototype.negate = bnNegate; | |
BigInteger.prototype.abs = bnAbs; | |
BigInteger.prototype.compareTo = bnCompareTo; | |
BigInteger.prototype.bitLength = bnBitLength; | |
BigInteger.prototype.mod = bnMod; | |
BigInteger.prototype.modPowInt = bnModPowInt; | |
// "constants" | |
BigInteger.ZERO = nbv(0); | |
BigInteger.ONE = nbv(1); | |
// jsbn2 stuff | |
// (protected) convert from radix string | |
function bnpFromRadix(s,b) { | |
this.fromInt(0); | |
if(b == null) b = 10; | |
var cs = this.chunkSize(b); | |
var d = Math.pow(b,cs), mi = false, j = 0, w = 0; | |
for(var i = 0; i < s.length; ++i) { | |
var x = intAt(s,i); | |
if(x < 0) { | |
if(s.charAt(i) == "-" && this.signum() == 0) mi = true; | |
continue; | |
} | |
w = b*w+x; | |
if(++j >= cs) { | |
this.dMultiply(d); | |
this.dAddOffset(w,0); | |
j = 0; | |
w = 0; | |
} | |
} | |
if(j > 0) { | |
this.dMultiply(Math.pow(b,j)); | |
this.dAddOffset(w,0); | |
} | |
if(mi) BigInteger.ZERO.subTo(this,this); | |
} | |
// (protected) return x s.t. r^x < DV | |
function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } | |
// (public) 0 if this == 0, 1 if this > 0 | |
function bnSigNum() { | |
if(this.s < 0) return -1; | |
else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; | |
else return 1; | |
} | |
// (protected) this *= n, this >= 0, 1 < n < DV | |
function bnpDMultiply(n) { | |
this[this.t] = this.am(0,n-1,this,0,0,this.t); | |
++this.t; | |
this.clamp(); | |
} | |
// (protected) this += n << w words, this >= 0 | |
function bnpDAddOffset(n,w) { | |
if(n == 0) return; | |
while(this.t <= w) this[this.t++] = 0; | |
this[w] += n; | |
while(this[w] >= this.DV) { | |
this[w] -= this.DV; | |
if(++w >= this.t) this[this.t++] = 0; | |
++this[w]; | |
} | |
} | |
// (protected) convert to radix string | |
function bnpToRadix(b) { | |
if(b == null) b = 10; | |
if(this.signum() == 0 || b < 2 || b > 36) return "0"; | |
var cs = this.chunkSize(b); | |
var a = Math.pow(b,cs); | |
var d = nbv(a), y = nbi(), z = nbi(), r = ""; | |
this.divRemTo(d,y,z); | |
while(y.signum() > 0) { | |
r = (a+z.intValue()).toString(b).substr(1) + r; | |
y.divRemTo(d,y,z); | |
} | |
return z.intValue().toString(b) + r; | |
} | |
// (public) return value as integer | |
function bnIntValue() { | |
if(this.s < 0) { | |
if(this.t == 1) return this[0]-this.DV; | |
else if(this.t == 0) return -1; | |
} | |
else if(this.t == 1) return this[0]; | |
else if(this.t == 0) return 0; | |
// assumes 16 < DB < 32 | |
return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0]; | |
} | |
// (protected) r = this + a | |
function bnpAddTo(a,r) { | |
var i = 0, c = 0, m = Math.min(a.t,this.t); | |
while(i < m) { | |
c += this[i]+a[i]; | |
r[i++] = c&this.DM; | |
c >>= this.DB; | |
} | |
if(a.t < this.t) { | |
c += a.s; | |
while(i < this.t) { | |
c += this[i]; | |
r[i++] = c&this.DM; | |
c >>= this.DB; | |
} | |
c += this.s; | |
} | |
else { | |
c += this.s; | |
while(i < a.t) { | |
c += a[i]; | |
r[i++] = c&this.DM; | |
c >>= this.DB; | |
} | |
c += a.s; | |
} | |
r.s = (c<0)?-1:0; | |
if(c > 0) r[i++] = c; | |
else if(c < -1) r[i++] = this.DV+c; | |
r.t = i; | |
r.clamp(); | |
} | |
BigInteger.prototype.fromRadix = bnpFromRadix; | |
BigInteger.prototype.chunkSize = bnpChunkSize; | |
BigInteger.prototype.signum = bnSigNum; | |
BigInteger.prototype.dMultiply = bnpDMultiply; | |
BigInteger.prototype.dAddOffset = bnpDAddOffset; | |
BigInteger.prototype.toRadix = bnpToRadix; | |
BigInteger.prototype.intValue = bnIntValue; | |
BigInteger.prototype.addTo = bnpAddTo; | |
//======= end jsbn ======= | |
// Emscripten wrapper | |
var Wrapper = { | |
abs: function(l, h) { | |
var x = new goog.math.Long(l, h); | |
var ret; | |
if (x.isNegative()) { | |
ret = x.negate(); | |
} else { | |
ret = x; | |
} | |
HEAP32[tempDoublePtr>>2] = ret.low_; | |
HEAP32[tempDoublePtr+4>>2] = ret.high_; | |
}, | |
ensureTemps: function() { | |
if (Wrapper.ensuredTemps) return; | |
Wrapper.ensuredTemps = true; | |
Wrapper.two32 = new BigInteger(); | |
Wrapper.two32.fromString('4294967296', 10); | |
Wrapper.two64 = new BigInteger(); | |
Wrapper.two64.fromString('18446744073709551616', 10); | |
Wrapper.temp1 = new BigInteger(); | |
Wrapper.temp2 = new BigInteger(); | |
}, | |
lh2bignum: function(l, h) { | |
var a = new BigInteger(); | |
a.fromString(h.toString(), 10); | |
var b = new BigInteger(); | |
a.multiplyTo(Wrapper.two32, b); | |
var c = new BigInteger(); | |
c.fromString(l.toString(), 10); | |
var d = new BigInteger(); | |
c.addTo(b, d); | |
return d; | |
}, | |
stringify: function(l, h, unsigned) { | |
var ret = new goog.math.Long(l, h).toString(); | |
if (unsigned && ret[0] == '-') { | |
// unsign slowly using jsbn bignums | |
Wrapper.ensureTemps(); | |
var bignum = new BigInteger(); | |
bignum.fromString(ret, 10); | |
ret = new BigInteger(); | |
Wrapper.two64.addTo(bignum, ret); | |
ret = ret.toString(10); | |
} | |
return ret; | |
}, | |
fromString: function(str, base, min, max, unsigned) { | |
Wrapper.ensureTemps(); | |
var bignum = new BigInteger(); | |
bignum.fromString(str, base); | |
var bigmin = new BigInteger(); | |
bigmin.fromString(min, 10); | |
var bigmax = new BigInteger(); | |
bigmax.fromString(max, 10); | |
if (unsigned && bignum.compareTo(BigInteger.ZERO) < 0) { | |
var temp = new BigInteger(); | |
bignum.addTo(Wrapper.two64, temp); | |
bignum = temp; | |
} | |
var error = false; | |
if (bignum.compareTo(bigmin) < 0) { | |
bignum = bigmin; | |
error = true; | |
} else if (bignum.compareTo(bigmax) > 0) { | |
bignum = bigmax; | |
error = true; | |
} | |
var ret = goog.math.Long.fromString(bignum.toString()); // min-max checks should have clamped this to a range goog.math.Long can handle well | |
HEAP32[tempDoublePtr>>2] = ret.low_; | |
HEAP32[tempDoublePtr+4>>2] = ret.high_; | |
if (error) throw 'range error'; | |
} | |
}; | |
return Wrapper; | |
})(); | |
//======= end closure i64 code ======= | |
// === Auto-generated postamble setup entry stuff === | |
function ExitStatus(status) { | |
this.name = "ExitStatus"; | |
this.message = "Program terminated with exit(" + status + ")"; | |
this.status = status; | |
}; | |
ExitStatus.prototype = new Error(); | |
ExitStatus.prototype.constructor = ExitStatus; | |
var initialStackTop; | |
Module['callMain'] = Module.callMain = function callMain(args) { | |
assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)'); | |
assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called'); | |
args = args || []; | |
ensureInitRuntime(); | |
var argc = args.length+1; | |
function pad() { | |
for (var i = 0; i < 4-1; i++) { | |
argv.push(0); | |
} | |
} | |
var argv = [allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_NORMAL) ]; | |
pad(); | |
for (var i = 0; i < argc-1; i = i + 1) { | |
argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL)); | |
pad(); | |
} | |
argv.push(0); | |
argv = allocate(argv, 'i32', ALLOC_NORMAL); | |
initialStackTop = STACKTOP; | |
try { | |
var ret = Module['_main'](argc, argv, 0); | |
// if we're not running an evented main loop, it's time to exit | |
if (!Module['noExitRuntime']) { | |
exit(ret); | |
} | |
} | |
catch(e) { | |
if (e instanceof ExitStatus) { | |
// exit() throws this once it's done to make sure execution | |
// has been stopped completely | |
return; | |
} else if (e == 'SimulateInfiniteLoop') { | |
// running an evented main loop, don't immediately exit | |
Module['noExitRuntime'] = true; | |
return; | |
} else { | |
throw e; | |
} | |
} | |
} | |
function run(args) { | |
args = args || Module['arguments']; | |
if (runDependencies > 0) { | |
Module.printErr('run() called, but dependencies remain, so not running'); | |
return; | |
} | |
preRun(); | |
if (runDependencies > 0) { | |
// a preRun added a dependency, run will be called later | |
return; | |
} | |
function doRun() { | |
ensureInitRuntime(); | |
preMain(); | |
calledRun = true; | |
if (Module['_main'] && shouldRunNow) { | |
Module['callMain'](args); | |
} | |
postRun(); | |
} | |
if (Module['setStatus']) { | |
Module['setStatus']('Running...'); | |
setTimeout(function() { | |
setTimeout(function() { | |
Module['setStatus'](''); | |
}, 1); | |
if (!ABORT) doRun(); | |
}, 1); | |
} else { | |
doRun(); | |
} | |
} | |
Module['run'] = Module.run = run; | |
function exit(status) { | |
ABORT = true; | |
EXITSTATUS = status; | |
STACKTOP = initialStackTop; | |
// exit the runtime | |
exitRuntime(); | |
// throw an exception to halt the current execution | |
throw new ExitStatus(status); | |
} | |
Module['exit'] = Module.exit = exit; | |
function abort(text) { | |
if (text) { | |
Module.print(text); | |
} | |
ABORT = true; | |
EXITSTATUS = 1; | |
throw 'abort() at ' + (new Error().stack); | |
} | |
Module['abort'] = Module.abort = abort; | |
// {{PRE_RUN_ADDITIONS}} | |
if (Module['preInit']) { | |
if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']]; | |
while (Module['preInit'].length > 0) { | |
Module['preInit'].pop()(); | |
} | |
} | |
// shouldRunNow refers to calling main(), not run(). | |
var shouldRunNow = true; | |
if (Module['noInitialRun']) { | |
shouldRunNow = false; | |
} | |
run(); | |
// {{POST_RUN_ADDITIONS}} | |
// {{MODULE_ADDITIONS}} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment