Path: blob/main/misc/emulator/n64/sm64/sm64.us.f3dex2e.js
28553 views
var moduleOverrides = {};1var key;2for (key in Module) {3if (Module.hasOwnProperty(key)) {4moduleOverrides[key] = Module[key];5}6}78var arguments_ = [];9var thisProgram = './this.program';10var quit_ = function(status, toThrow) {11throw toThrow;12};1314var ENVIRONMENT_IS_WEB = false;15var ENVIRONMENT_IS_WORKER = false;16var ENVIRONMENT_IS_NODE = false;17var ENVIRONMENT_IS_SHELL = false;18ENVIRONMENT_IS_WEB = typeof window === 'object';19ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';2021ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string';22ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;2324if (Module['ENVIRONMENT']) {25throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -s ENVIRONMENT=web or -s ENVIRONMENT=node)');26}27282930// `/` should be present at the end if `scriptDirectory` is not empty31var scriptDirectory = '';32function locateFile(path) {33if (Module['locateFile']) {34return Module['locateFile'](path, scriptDirectory);35}36return scriptDirectory + path;37}3839// Hooks that are implemented differently in different runtime environments.40var read_,41readAsync,42readBinary,43setWindowTitle;4445var nodeFS;46var nodePath;4748if (ENVIRONMENT_IS_NODE) {49if (ENVIRONMENT_IS_WORKER) {50scriptDirectory = require('path').dirname(scriptDirectory) + '/';51} else {52scriptDirectory = __dirname + '/';53}545556read_ = function shell_read(filename, binary) {57if (!nodeFS) nodeFS = require('fs');58if (!nodePath) nodePath = require('path');59filename = nodePath['normalize'](filename);60return nodeFS['readFileSync'](filename, binary ? null : 'utf8');61};6263readBinary = function readBinary(filename) {64var ret = read_(filename, true);65if (!ret.buffer) {66ret = new Uint8Array(ret);67}68assert(ret.buffer);69return ret;70};7172737475if (process['argv'].length > 1) {76thisProgram = process['argv'][1].replace(/\\/g, '/');77}7879arguments_ = process['argv'].slice(2);8081if (typeof module !== 'undefined') {82module['exports'] = Module;83}8485process['on']('uncaughtException', function(ex) {86// suppress ExitStatus exceptions from showing an error87if (!(ex instanceof ExitStatus)) {88throw ex;89}90});9192process['on']('unhandledRejection', abort);9394quit_ = function(status) {95process['exit'](status);96};9798Module['inspect'] = function () { return '[Emscripten Module object]'; };99100101102} else103if (ENVIRONMENT_IS_SHELL) {104105106if (typeof read != 'undefined') {107read_ = function shell_read(f) {108return read(f);109};110}111112readBinary = function readBinary(f) {113var data;114if (typeof readbuffer === 'function') {115return new Uint8Array(readbuffer(f));116}117data = read(f, 'binary');118assert(typeof data === 'object');119return data;120};121122if (typeof scriptArgs != 'undefined') {123arguments_ = scriptArgs;124} else if (typeof arguments != 'undefined') {125arguments_ = arguments;126}127128if (typeof quit === 'function') {129quit_ = function(status) {130quit(status);131};132}133134if (typeof print !== 'undefined') {135// Prefer to use print/printErr where they exist, as they usually work better.136if (typeof console === 'undefined') console = /** @type{!Console} */({});137console.log = /** @type{!function(this:Console, ...*): undefined} */ (print);138console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr !== 'undefined' ? printErr : print);139}140141142} else143144// Note that this includes Node.js workers when relevant (pthreads is enabled).145// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and146// ENVIRONMENT_IS_NODE.147if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {148if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled149scriptDirectory = self.location.href;150} else if (document.currentScript) { // web151scriptDirectory = document.currentScript.src;152}153// blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.154// otherwise, slice off the final part of the url to find the script directory.155// if scriptDirectory does not contain a slash, lastIndexOf will return -1,156// and scriptDirectory will correctly be replaced with an empty string.157if (scriptDirectory.indexOf('blob:') !== 0) {158scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf('/')+1);159} else {160scriptDirectory = '';161}162163164// Differentiate the Web Worker from the Node Worker case, as reading must165// be done differently.166{167168169read_ = function shell_read(url) {170var xhr = new XMLHttpRequest();171xhr.open('GET', url, false);172xhr.send(null);173return xhr.responseText;174};175176if (ENVIRONMENT_IS_WORKER) {177readBinary = function readBinary(url) {178var xhr = new XMLHttpRequest();179xhr.open('GET', url, false);180xhr.responseType = 'arraybuffer';181xhr.send(null);182return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));183};184}185186readAsync = function readAsync(url, onload, onerror) {187var xhr = new XMLHttpRequest();188xhr.open('GET', url, true);189xhr.responseType = 'arraybuffer';190xhr.onload = function xhr_onload() {191if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0192onload(xhr.response);193return;194}195onerror();196};197xhr.onerror = onerror;198xhr.send(null);199};200201202203204}205206setWindowTitle = function(title) { document.title = title };207} else208{209throw new Error('environment detection error');210}211212213// Set up the out() and err() hooks, which are how we can print to stdout or214// stderr, respectively.215var out = Module['print'] || console.log.bind(console);216var err = Module['printErr'] || console.warn.bind(console);217218// Merge back in the overrides219for (key in moduleOverrides) {220if (moduleOverrides.hasOwnProperty(key)) {221Module[key] = moduleOverrides[key];222}223}224// Free the object hierarchy contained in the overrides, this lets the GC225// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.226moduleOverrides = null;227228// Emit code to handle expected values on the Module object. This applies Module.x229// to the proper local x. This has two benefits: first, we only emit it if it is230// expected to arrive, and second, by using a local everywhere else that can be231// minified.232if (Module['arguments']) arguments_ = Module['arguments'];if (!Object.getOwnPropertyDescriptor(Module, 'arguments')) Object.defineProperty(Module, 'arguments', { configurable: true, get: function() { abort('Module.arguments has been replaced with plain arguments_') } });233if (Module['thisProgram']) thisProgram = Module['thisProgram'];if (!Object.getOwnPropertyDescriptor(Module, 'thisProgram')) Object.defineProperty(Module, 'thisProgram', { configurable: true, get: function() { abort('Module.thisProgram has been replaced with plain thisProgram') } });234if (Module['quit']) quit_ = Module['quit'];if (!Object.getOwnPropertyDescriptor(Module, 'quit')) Object.defineProperty(Module, 'quit', { configurable: true, get: function() { abort('Module.quit has been replaced with plain quit_') } });235236// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message237// Assertions on removed incoming Module JS APIs.238assert(typeof Module['memoryInitializerPrefixURL'] === 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead');239assert(typeof Module['pthreadMainPrefixURL'] === 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead');240assert(typeof Module['cdInitializerPrefixURL'] === 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead');241assert(typeof Module['filePackagePrefixURL'] === 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead');242assert(typeof Module['read'] === 'undefined', 'Module.read option was removed (modify read_ in JS)');243assert(typeof Module['readAsync'] === 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)');244assert(typeof Module['readBinary'] === 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)');245assert(typeof Module['setWindowTitle'] === 'undefined', 'Module.setWindowTitle option was removed (modify setWindowTitle in JS)');246assert(typeof Module['TOTAL_MEMORY'] === 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY');247if (!Object.getOwnPropertyDescriptor(Module, 'read')) Object.defineProperty(Module, 'read', { configurable: true, get: function() { abort('Module.read has been replaced with plain read_') } });248if (!Object.getOwnPropertyDescriptor(Module, 'readAsync')) Object.defineProperty(Module, 'readAsync', { configurable: true, get: function() { abort('Module.readAsync has been replaced with plain readAsync') } });249if (!Object.getOwnPropertyDescriptor(Module, 'readBinary')) Object.defineProperty(Module, 'readBinary', { configurable: true, get: function() { abort('Module.readBinary has been replaced with plain readBinary') } });250// TODO: add when SDL2 is fixed if (!Object.getOwnPropertyDescriptor(Module, 'setWindowTitle')) Object.defineProperty(Module, 'setWindowTitle', { configurable: true, get: function() { abort('Module.setWindowTitle has been replaced with plain setWindowTitle') } });251var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js';252var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js';253var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js';254var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js';255256257// TODO remove when SDL2 is fixed (also see above)258259260261// Copyright 2017 The Emscripten Authors. All rights reserved.262// Emscripten is available under two separate licenses, the MIT license and the263// University of Illinois/NCSA Open Source License. Both these licenses can be264// found in the LICENSE file.265266// {{PREAMBLE_ADDITIONS}}267268var STACK_ALIGN = 16;269270// stack management, and other functionality that is provided by the compiled code,271// should not be used before it is ready272273/** @suppress{duplicate} */274var stackSave;275/** @suppress{duplicate} */276var stackRestore;277/** @suppress{duplicate} */278var stackAlloc;279280stackSave = stackRestore = stackAlloc = function() {281abort('cannot use the stack before compiled code is ready to run, and has provided stack access');282};283284function staticAlloc(size) {285abort('staticAlloc is no longer available at runtime; instead, perform static allocations at compile time (using makeStaticAlloc)');286}287288function dynamicAlloc(size) {289assert(DYNAMICTOP_PTR);290var ret = HEAP32[DYNAMICTOP_PTR>>2];291var end = (ret + size + 15) & -16;292assert(end <= HEAP8.length, 'failure to dynamicAlloc - memory growth etc. is not supported there, call malloc/sbrk directly');293HEAP32[DYNAMICTOP_PTR>>2] = end;294return ret;295}296297function alignMemory(size, factor) {298if (!factor) factor = STACK_ALIGN; // stack alignment (16-byte) by default299return Math.ceil(size / factor) * factor;300}301302function getNativeTypeSize(type) {303switch (type) {304case 'i1': case 'i8': return 1;305case 'i16': return 2;306case 'i32': return 4;307case 'i64': return 8;308case 'float': return 4;309case 'double': return 8;310default: {311if (type[type.length-1] === '*') {312return 4; // A pointer313} else if (type[0] === 'i') {314var bits = Number(type.substr(1));315assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type);316return bits / 8;317} else {318return 0;319}320}321}322}323324function warnOnce(text) {325if (!warnOnce.shown) warnOnce.shown = {};326if (!warnOnce.shown[text]) {327warnOnce.shown[text] = 1;328err(text);329}330}331332333334335336337// Wraps a JS function as a wasm function with a given signature.338function convertJsFunctionToWasm(func, sig) {339340// If the type reflection proposal is available, use the new341// "WebAssembly.Function" constructor.342// Otherwise, construct a minimal wasm module importing the JS function and343// re-exporting it.344if (typeof WebAssembly.Function === "function") {345var typeNames = {346'i': 'i32',347'j': 'i64',348'f': 'f32',349'd': 'f64'350};351var type = {352parameters: [],353results: sig[0] == 'v' ? [] : [typeNames[sig[0]]]354};355for (var i = 1; i < sig.length; ++i) {356type.parameters.push(typeNames[sig[i]]);357}358return new WebAssembly.Function(type, func);359}360361// The module is static, with the exception of the type section, which is362// generated based on the signature passed in.363var typeSection = [3640x01, // id: section,3650x00, // length: 0 (placeholder)3660x01, // count: 13670x60, // form: func368];369var sigRet = sig.slice(0, 1);370var sigParam = sig.slice(1);371var typeCodes = {372'i': 0x7f, // i32373'j': 0x7e, // i64374'f': 0x7d, // f32375'd': 0x7c, // f64376};377378// Parameters, length + signatures379typeSection.push(sigParam.length);380for (var i = 0; i < sigParam.length; ++i) {381typeSection.push(typeCodes[sigParam[i]]);382}383384// Return values, length + signatures385// With no multi-return in MVP, either 0 (void) or 1 (anything else)386if (sigRet == 'v') {387typeSection.push(0x00);388} else {389typeSection = typeSection.concat([0x01, typeCodes[sigRet]]);390}391392// Write the overall length of the type section back into the section header393// (excepting the 2 bytes for the section id and length)394typeSection[1] = typeSection.length - 2;395396// Rest of the module is static397var bytes = new Uint8Array([3980x00, 0x61, 0x73, 0x6d, // magic ("\0asm")3990x01, 0x00, 0x00, 0x00, // version: 1400].concat(typeSection, [4010x02, 0x07, // import section402// (import "e" "f" (func 0 (type 0)))4030x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00,4040x07, 0x05, // export section405// (export "f" (func 0 (type 0)))4060x01, 0x01, 0x66, 0x00, 0x00,407]));408409// We can compile this wasm module synchronously because it is very small.410// This accepts an import (at "e.f"), that it reroutes to an export (at "f")411var module = new WebAssembly.Module(bytes);412var instance = new WebAssembly.Instance(module, {413'e': {414'f': func415}416});417var wrappedFunc = instance.exports['f'];418return wrappedFunc;419}420421var freeTableIndexes = [];422423// Add a wasm function to the table.424function addFunctionWasm(func, sig) {425var table = wasmTable;426var ret;427// Reuse a free index if there is one, otherwise grow.428if (freeTableIndexes.length) {429ret = freeTableIndexes.pop();430} else {431ret = table.length;432// Grow the table433try {434table.grow(1);435} catch (err) {436if (!(err instanceof RangeError)) {437throw err;438}439throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.';440}441}442443// Set the new value.444try {445// Attempting to call this with JS function will cause of table.set() to fail446table.set(ret, func);447} catch (err) {448if (!(err instanceof TypeError)) {449throw err;450}451assert(typeof sig !== 'undefined', 'Missing signature argument to addFunction');452var wrapped = convertJsFunctionToWasm(func, sig);453table.set(ret, wrapped);454}455456return ret;457}458459function removeFunctionWasm(index) {460freeTableIndexes.push(index);461}462463// 'sig' parameter is required for the llvm backend but only when func is not464// already a WebAssembly function.465function addFunction(func, sig) {466assert(typeof func !== 'undefined');467468return addFunctionWasm(func, sig);469}470471function removeFunction(index) {472removeFunctionWasm(index);473}474475476477var funcWrappers = {};478479function getFuncWrapper(func, sig) {480if (!func) return; // on null pointer, return undefined481assert(sig);482if (!funcWrappers[sig]) {483funcWrappers[sig] = {};484}485var sigCache = funcWrappers[sig];486if (!sigCache[func]) {487// optimize away arguments usage in common cases488if (sig.length === 1) {489sigCache[func] = function dynCall_wrapper() {490return dynCall(sig, func);491};492} else if (sig.length === 2) {493sigCache[func] = function dynCall_wrapper(arg) {494return dynCall(sig, func, [arg]);495};496} else {497// general case498sigCache[func] = function dynCall_wrapper() {499return dynCall(sig, func, Array.prototype.slice.call(arguments));500};501}502}503return sigCache[func];504}505506507508509510function makeBigInt(low, high, unsigned) {511return unsigned ? ((+((low>>>0)))+((+((high>>>0)))*4294967296.0)) : ((+((low>>>0)))+((+((high|0)))*4294967296.0));512}513514/** @param {Array=} args */515function dynCall(sig, ptr, args) {516if (args && args.length) {517// j (64-bit integer) must be passed in as two numbers [low 32, high 32].518assert(args.length === sig.substring(1).replace(/j/g, '--').length);519assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\'');520return Module['dynCall_' + sig].apply(null, [ptr].concat(args));521} else {522assert(sig.length == 1);523assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\'');524return Module['dynCall_' + sig].call(null, ptr);525}526}527528var tempRet0 = 0;529530var setTempRet0 = function(value) {531tempRet0 = value;532};533534var getTempRet0 = function() {535return tempRet0;536};537538function getCompilerSetting(name) {539throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for getCompilerSetting or emscripten_get_compiler_setting to work';540}541542var Runtime = {543// helpful errors544getTempRet0: function() { abort('getTempRet0() is now a top-level function, after removing the Runtime object. Remove "Runtime."') },545staticAlloc: function() { abort('staticAlloc() is now a top-level function, after removing the Runtime object. Remove "Runtime."') },546stackAlloc: function() { abort('stackAlloc() is now a top-level function, after removing the Runtime object. Remove "Runtime."') },547};548549// The address globals begin at. Very low in memory, for code size and optimization opportunities.550// Above 0 is static memory, starting with globals.551// Then the stack.552// Then 'dynamic' memory for sbrk.553var GLOBAL_BASE = 1024;554555556557558// === Preamble library stuff ===559560// Documentation for the public APIs defined in this file must be updated in:561// site/source/docs/api_reference/preamble.js.rst562// A prebuilt local version of the documentation is available at:563// site/build/text/docs/api_reference/preamble.js.txt564// You can also build docs locally as HTML or other formats in site/565// An online HTML version (which may be of a different version of Emscripten)566// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html567568569var wasmBinary;if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];if (!Object.getOwnPropertyDescriptor(Module, 'wasmBinary')) Object.defineProperty(Module, 'wasmBinary', { configurable: true, get: function() { abort('Module.wasmBinary has been replaced with plain wasmBinary') } });570var noExitRuntime;if (Module['noExitRuntime']) noExitRuntime = Module['noExitRuntime'];if (!Object.getOwnPropertyDescriptor(Module, 'noExitRuntime')) Object.defineProperty(Module, 'noExitRuntime', { configurable: true, get: function() { abort('Module.noExitRuntime has been replaced with plain noExitRuntime') } });571572573if (typeof WebAssembly !== 'object') {574abort('No WebAssembly support found. Build with -s WASM=0 to target JavaScript instead.');575}576577578// In MINIMAL_RUNTIME, setValue() and getValue() are only available when building with safe heap enabled, for heap safety checking.579// In traditional runtime, setValue() and getValue() are always available (although their use is highly discouraged due to perf penalties)580581/** @param {number} ptr582@param {number} value583@param {string} type584@param {number|boolean=} noSafe */585function setValue(ptr, value, type, noSafe) {586type = type || 'i8';587if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit588switch(type) {589case 'i1': HEAP8[((ptr)>>0)]=value; break;590case 'i8': HEAP8[((ptr)>>0)]=value; break;591case 'i16': HEAP16[((ptr)>>1)]=value; break;592case 'i32': HEAP32[((ptr)>>2)]=value; break;593case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break;594case 'float': HEAPF32[((ptr)>>2)]=value; break;595case 'double': HEAPF64[((ptr)>>3)]=value; break;596default: abort('invalid type for setValue: ' + type);597}598}599600/** @param {number} ptr601@param {string} type602@param {number|boolean=} noSafe */603function getValue(ptr, type, noSafe) {604type = type || 'i8';605if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit606switch(type) {607case 'i1': return HEAP8[((ptr)>>0)];608case 'i8': return HEAP8[((ptr)>>0)];609case 'i16': return HEAP16[((ptr)>>1)];610case 'i32': return HEAP32[((ptr)>>2)];611case 'i64': return HEAP32[((ptr)>>2)];612case 'float': return HEAPF32[((ptr)>>2)];613case 'double': return HEAPF64[((ptr)>>3)];614default: abort('invalid type for getValue: ' + type);615}616return null;617}618619620621622623// Wasm globals624625var wasmMemory;626627// In fastcomp asm.js, we don't need a wasm Table at all.628// In the wasm backend, we polyfill the WebAssembly object,629// so this creates a (non-native-wasm) table for us.630var wasmTable = new WebAssembly.Table({631'initial': 1821,632'maximum': 1821 + 0,633'element': 'anyfunc'634});635636637//========================================638// Runtime essentials639//========================================640641// whether we are quitting the application. no code should run after this.642// set in exit() and abort()643var ABORT = false;644645// set by exit() and abort(). Passed to 'onExit' handler.646// NOTE: This is also used as the process return code code in shell environments647// but only when noExitRuntime is false.648var EXITSTATUS = 0;649650/** @type {function(*, string=)} */651function assert(condition, text) {652if (!condition) {653abort('Assertion failed: ' + text);654}655}656657// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)658function getCFunc(ident) {659var func = Module['_' + ident]; // closure exported function660assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported');661return func;662}663664// C calling interface.665/** @param {Array=} argTypes666@param {Arguments|Array=} args667@param {Object=} opts */668function ccall(ident, returnType, argTypes, args, opts) {669// For fast lookup of conversion functions670var toC = {671'string': function(str) {672var ret = 0;673if (str !== null && str !== undefined && str !== 0) { // null string674// at most 4 bytes per UTF-8 code point, +1 for the trailing '\0'675var len = (str.length << 2) + 1;676ret = stackAlloc(len);677stringToUTF8(str, ret, len);678}679return ret;680},681'array': function(arr) {682var ret = stackAlloc(arr.length);683writeArrayToMemory(arr, ret);684return ret;685}686};687688function convertReturnValue(ret) {689if (returnType === 'string') return UTF8ToString(ret);690if (returnType === 'boolean') return Boolean(ret);691return ret;692}693694var func = getCFunc(ident);695var cArgs = [];696var stack = 0;697assert(returnType !== 'array', 'Return type should not be "array".');698if (args) {699for (var i = 0; i < args.length; i++) {700var converter = toC[argTypes[i]];701if (converter) {702if (stack === 0) stack = stackSave();703cArgs[i] = converter(args[i]);704} else {705cArgs[i] = args[i];706}707}708}709var ret = func.apply(null, cArgs);710711ret = convertReturnValue(ret);712if (stack !== 0) stackRestore(stack);713return ret;714}715716/** @param {Array=} argTypes717@param {Object=} opts */718function cwrap(ident, returnType, argTypes, opts) {719return function() {720return ccall(ident, returnType, argTypes, arguments, opts);721}722}723724var ALLOC_NORMAL = 0; // Tries to use _malloc()725var ALLOC_STACK = 1; // Lives for the duration of the current function call726var ALLOC_DYNAMIC = 2; // Cannot be freed except through sbrk727var ALLOC_NONE = 3; // Do not allocate728729// allocate(): This is for internal use. You can use it yourself as well, but the interface730// is a little tricky (see docs right below). The reason is that it is optimized731// for multiple syntaxes to save space in generated code. So you should732// normally not use allocate(), and instead allocate memory using _malloc(),733// initialize it with setValue(), and so forth.734// @slab: An array of data, or a number. If a number, then the size of the block to allocate,735// in *bytes* (note that this is sometimes confusing: the next parameter does not736// affect this!)737// @types: Either an array of types, one for each byte (or 0 if no type at that position),738// or a single type which is used for the entire block. This only matters if there739// is initial data - if @slab is a number, then this does not matter at all and is740// ignored.741// @allocator: How to allocate memory, see ALLOC_*742/** @type {function((TypedArray|Array<number>|number), string, number, number=)} */743function allocate(slab, types, allocator, ptr) {744var zeroinit, size;745if (typeof slab === 'number') {746zeroinit = true;747size = slab;748} else {749zeroinit = false;750size = slab.length;751}752753var singleType = typeof types === 'string' ? types : null;754755var ret;756if (allocator == ALLOC_NONE) {757ret = ptr;758} else {759ret = [_malloc,760stackAlloc,761dynamicAlloc][allocator](Math.max(size, singleType ? 1 : types.length));762}763764if (zeroinit) {765var stop;766ptr = ret;767assert((ret & 3) == 0);768stop = ret + (size & ~3);769for (; ptr < stop; ptr += 4) {770HEAP32[((ptr)>>2)]=0;771}772stop = ret + size;773while (ptr < stop) {774HEAP8[((ptr++)>>0)]=0;775}776return ret;777}778779if (singleType === 'i8') {780if (slab.subarray || slab.slice) {781HEAPU8.set(/** @type {!Uint8Array} */ (slab), ret);782} else {783HEAPU8.set(new Uint8Array(slab), ret);784}785return ret;786}787788var i = 0, type, typeSize, previousType;789while (i < size) {790var curr = slab[i];791792type = singleType || types[i];793if (type === 0) {794i++;795continue;796}797assert(type, 'Must know what type to store in allocate!');798799if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later800801setValue(ret+i, curr, type);802803// no need to look up size unless type changes, so cache it804if (previousType !== type) {805typeSize = getNativeTypeSize(type);806previousType = type;807}808i += typeSize;809}810811return ret;812}813814// Allocate memory during any stage of startup - static memory early on, dynamic memory later, malloc when ready815function getMemory(size) {816if (!runtimeInitialized) return dynamicAlloc(size);817return _malloc(size);818}819820821// runtime_strings.js: Strings related runtime functions that are part of both MINIMAL_RUNTIME and regular runtime.822823// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the given array that contains uint8 values, returns824// a copy of that string as a Javascript String object.825826var UTF8Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined;827828/**829* @param {number} idx830* @param {number=} maxBytesToRead831* @return {string}832*/833function UTF8ArrayToString(u8Array, idx, maxBytesToRead) {834var endIdx = idx + maxBytesToRead;835var endPtr = idx;836// TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.837// Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.838// (As a tiny code save trick, compare endPtr against endIdx using a negation, so that undefined means Infinity)839while (u8Array[endPtr] && !(endPtr >= endIdx)) ++endPtr;840841if (endPtr - idx > 16 && u8Array.subarray && UTF8Decoder) {842return UTF8Decoder.decode(u8Array.subarray(idx, endPtr));843} else {844var str = '';845// If building with TextDecoder, we have already computed the string length above, so test loop end condition against that846while (idx < endPtr) {847// For UTF8 byte structure, see:848// http://en.wikipedia.org/wiki/UTF-8#Description849// https://www.ietf.org/rfc/rfc2279.txt850// https://tools.ietf.org/html/rfc3629851var u0 = u8Array[idx++];852if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }853var u1 = u8Array[idx++] & 63;854if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }855var u2 = u8Array[idx++] & 63;856if ((u0 & 0xF0) == 0xE0) {857u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;858} else {859if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte 0x' + u0.toString(16) + ' encountered when deserializing a UTF-8 string on the asm.js/wasm heap to a JS string!');860u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (u8Array[idx++] & 63);861}862863if (u0 < 0x10000) {864str += String.fromCharCode(u0);865} else {866var ch = u0 - 0x10000;867str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));868}869}870}871return str;872}873874// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the emscripten HEAP, returns a875// copy of that string as a Javascript String object.876// maxBytesToRead: an optional length that specifies the maximum number of bytes to read. You can omit877// this parameter to scan the string until the first \0 byte. If maxBytesToRead is878// passed, and the string at [ptr, ptr+maxBytesToReadr[ contains a null byte in the879// middle, then the string will cut short at that byte index (i.e. maxBytesToRead will880// not produce a string of exact length [ptr, ptr+maxBytesToRead[)881// N.B. mixing frequent uses of UTF8ToString() with and without maxBytesToRead may882// throw JS JIT optimizations off, so it is worth to consider consistently using one883// style or the other.884/**885* @param {number} ptr886* @param {number=} maxBytesToRead887* @return {string}888*/889function UTF8ToString(ptr, maxBytesToRead) {890return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';891}892893// Copies the given Javascript String object 'str' to the given byte array at address 'outIdx',894// encoded in UTF8 form and null-terminated. The copy will require at most str.length*4+1 bytes of space in the HEAP.895// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.896// Parameters:897// str: the Javascript string to copy.898// outU8Array: the array to copy to. Each index in this array is assumed to be one 8-byte element.899// outIdx: The starting offset in the array to begin the copying.900// maxBytesToWrite: The maximum number of bytes this function can write to the array.901// This count should include the null terminator,902// i.e. if maxBytesToWrite=1, only the null terminator will be written and nothing else.903// maxBytesToWrite=0 does not write any bytes to the output, not even the null terminator.904// Returns the number of bytes written, EXCLUDING the null terminator.905906function stringToUTF8Array(str, outU8Array, outIdx, maxBytesToWrite) {907if (!(maxBytesToWrite > 0)) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes.908return 0;909910var startIdx = outIdx;911var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.912for (var i = 0; i < str.length; ++i) {913// Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.914// See http://unicode.org/faq/utf_bom.html#utf16-3915// For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629916var u = str.charCodeAt(i); // possibly a lead surrogate917if (u >= 0xD800 && u <= 0xDFFF) {918var u1 = str.charCodeAt(++i);919u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF);920}921if (u <= 0x7F) {922if (outIdx >= endIdx) break;923outU8Array[outIdx++] = u;924} else if (u <= 0x7FF) {925if (outIdx + 1 >= endIdx) break;926outU8Array[outIdx++] = 0xC0 | (u >> 6);927outU8Array[outIdx++] = 0x80 | (u & 63);928} else if (u <= 0xFFFF) {929if (outIdx + 2 >= endIdx) break;930outU8Array[outIdx++] = 0xE0 | (u >> 12);931outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);932outU8Array[outIdx++] = 0x80 | (u & 63);933} else {934if (outIdx + 3 >= endIdx) break;935if (u >= 0x200000) warnOnce('Invalid Unicode code point 0x' + u.toString(16) + ' encountered when serializing a JS string to an UTF-8 string on the asm.js/wasm heap! (Valid unicode code points should be in range 0-0x1FFFFF).');936outU8Array[outIdx++] = 0xF0 | (u >> 18);937outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63);938outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);939outU8Array[outIdx++] = 0x80 | (u & 63);940}941}942// Null-terminate the pointer to the buffer.943outU8Array[outIdx] = 0;944return outIdx - startIdx;945}946947// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',948// null-terminated and encoded in UTF8 form. The copy will require at most str.length*4+1 bytes of space in the HEAP.949// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.950// Returns the number of bytes written, EXCLUDING the null terminator.951952function stringToUTF8(str, outPtr, maxBytesToWrite) {953assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');954return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite);955}956957// Returns the number of bytes the given Javascript string takes if encoded as a UTF8 byte array, EXCLUDING the null terminator byte.958function lengthBytesUTF8(str) {959var len = 0;960for (var i = 0; i < str.length; ++i) {961// Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.962// See http://unicode.org/faq/utf_bom.html#utf16-3963var u = str.charCodeAt(i); // possibly a lead surrogate964if (u >= 0xD800 && u <= 0xDFFF) u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF);965if (u <= 0x7F) ++len;966else if (u <= 0x7FF) len += 2;967else if (u <= 0xFFFF) len += 3;968else len += 4;969}970return len;971}972973974975// runtime_strings_extra.js: Strings related runtime functions that are available only in regular runtime.976977// Given a pointer 'ptr' to a null-terminated ASCII-encoded string in the emscripten HEAP, returns978// a copy of that string as a Javascript String object.979980function AsciiToString(ptr) {981var str = '';982while (1) {983var ch = HEAPU8[((ptr++)>>0)];984if (!ch) return str;985str += String.fromCharCode(ch);986}987}988989// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',990// null-terminated and encoded in ASCII form. The copy will require at most str.length+1 bytes of space in the HEAP.991992function stringToAscii(str, outPtr) {993return writeAsciiToMemory(str, outPtr, false);994}995996// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns997// a copy of that string as a Javascript String object.998999var UTF16Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-16le') : undefined;10001001function UTF16ToString(ptr) {1002assert(ptr % 2 == 0, 'Pointer passed to UTF16ToString must be aligned to two bytes!');1003var endPtr = ptr;1004// TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.1005// Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.1006var idx = endPtr >> 1;1007while (HEAP16[idx]) ++idx;1008endPtr = idx << 1;10091010if (endPtr - ptr > 32 && UTF16Decoder) {1011return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr));1012} else {1013var i = 0;10141015var str = '';1016while (1) {1017var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];1018if (codeUnit == 0) return str;1019++i;1020// fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.1021str += String.fromCharCode(codeUnit);1022}1023}1024}10251026// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',1027// null-terminated and encoded in UTF16 form. The copy will require at most str.length*4+2 bytes of space in the HEAP.1028// Use the function lengthBytesUTF16() to compute the exact number of bytes (excluding null terminator) that this function will write.1029// Parameters:1030// str: the Javascript string to copy.1031// outPtr: Byte address in Emscripten HEAP where to write the string to.1032// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null1033// terminator, i.e. if maxBytesToWrite=2, only the null terminator will be written and nothing else.1034// maxBytesToWrite<2 does not write any bytes to the output, not even the null terminator.1035// Returns the number of bytes written, EXCLUDING the null terminator.10361037function stringToUTF16(str, outPtr, maxBytesToWrite) {1038assert(outPtr % 2 == 0, 'Pointer passed to stringToUTF16 must be aligned to two bytes!');1039assert(typeof maxBytesToWrite == 'number', 'stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');1040// Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.1041if (maxBytesToWrite === undefined) {1042maxBytesToWrite = 0x7FFFFFFF;1043}1044if (maxBytesToWrite < 2) return 0;1045maxBytesToWrite -= 2; // Null terminator.1046var startPtr = outPtr;1047var numCharsToWrite = (maxBytesToWrite < str.length*2) ? (maxBytesToWrite / 2) : str.length;1048for (var i = 0; i < numCharsToWrite; ++i) {1049// charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.1050var codeUnit = str.charCodeAt(i); // possibly a lead surrogate1051HEAP16[((outPtr)>>1)]=codeUnit;1052outPtr += 2;1053}1054// Null-terminate the pointer to the HEAP.1055HEAP16[((outPtr)>>1)]=0;1056return outPtr - startPtr;1057}10581059// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.10601061function lengthBytesUTF16(str) {1062return str.length*2;1063}10641065function UTF32ToString(ptr) {1066assert(ptr % 4 == 0, 'Pointer passed to UTF32ToString must be aligned to four bytes!');1067var i = 0;10681069var str = '';1070while (1) {1071var utf32 = HEAP32[(((ptr)+(i*4))>>2)];1072if (utf32 == 0)1073return str;1074++i;1075// Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.1076// See http://unicode.org/faq/utf_bom.html#utf16-31077if (utf32 >= 0x10000) {1078var ch = utf32 - 0x10000;1079str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));1080} else {1081str += String.fromCharCode(utf32);1082}1083}1084}10851086// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',1087// null-terminated and encoded in UTF32 form. The copy will require at most str.length*4+4 bytes of space in the HEAP.1088// Use the function lengthBytesUTF32() to compute the exact number of bytes (excluding null terminator) that this function will write.1089// Parameters:1090// str: the Javascript string to copy.1091// outPtr: Byte address in Emscripten HEAP where to write the string to.1092// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null1093// terminator, i.e. if maxBytesToWrite=4, only the null terminator will be written and nothing else.1094// maxBytesToWrite<4 does not write any bytes to the output, not even the null terminator.1095// Returns the number of bytes written, EXCLUDING the null terminator.10961097function stringToUTF32(str, outPtr, maxBytesToWrite) {1098assert(outPtr % 4 == 0, 'Pointer passed to stringToUTF32 must be aligned to four bytes!');1099assert(typeof maxBytesToWrite == 'number', 'stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');1100// Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.1101if (maxBytesToWrite === undefined) {1102maxBytesToWrite = 0x7FFFFFFF;1103}1104if (maxBytesToWrite < 4) return 0;1105var startPtr = outPtr;1106var endPtr = startPtr + maxBytesToWrite - 4;1107for (var i = 0; i < str.length; ++i) {1108// Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.1109// See http://unicode.org/faq/utf_bom.html#utf16-31110var codeUnit = str.charCodeAt(i); // possibly a lead surrogate1111if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {1112var trailSurrogate = str.charCodeAt(++i);1113codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);1114}1115HEAP32[((outPtr)>>2)]=codeUnit;1116outPtr += 4;1117if (outPtr + 4 > endPtr) break;1118}1119// Null-terminate the pointer to the HEAP.1120HEAP32[((outPtr)>>2)]=0;1121return outPtr - startPtr;1122}11231124// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.11251126function lengthBytesUTF32(str) {1127var len = 0;1128for (var i = 0; i < str.length; ++i) {1129// Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.1130// See http://unicode.org/faq/utf_bom.html#utf16-31131var codeUnit = str.charCodeAt(i);1132if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) ++i; // possibly a lead surrogate, so skip over the tail surrogate.1133len += 4;1134}11351136return len;1137}11381139// Allocate heap space for a JS string, and write it there.1140// It is the responsibility of the caller to free() that memory.1141function allocateUTF8(str) {1142var size = lengthBytesUTF8(str) + 1;1143var ret = _malloc(size);1144if (ret) stringToUTF8Array(str, HEAP8, ret, size);1145return ret;1146}11471148// Allocate stack space for a JS string, and write it there.1149function allocateUTF8OnStack(str) {1150var size = lengthBytesUTF8(str) + 1;1151var ret = stackAlloc(size);1152stringToUTF8Array(str, HEAP8, ret, size);1153return ret;1154}11551156// Deprecated: This function should not be called because it is unsafe and does not provide1157// a maximum length limit of how many bytes it is allowed to write. Prefer calling the1158// function stringToUTF8Array() instead, which takes in a maximum length that can be used1159// to be secure from out of bounds writes.1160/** @deprecated1161@param {boolean=} dontAddNull */1162function writeStringToMemory(string, buffer, dontAddNull) {1163warnOnce('writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!');11641165var /** @type {number} */ lastChar, /** @type {number} */ end;1166if (dontAddNull) {1167// stringToUTF8Array always appends null. If we don't want to do that, remember the1168// character that existed at the location where the null will be placed, and restore1169// that after the write (below).1170end = buffer + lengthBytesUTF8(string);1171lastChar = HEAP8[end];1172}1173stringToUTF8(string, buffer, Infinity);1174if (dontAddNull) HEAP8[end] = lastChar; // Restore the value under the null character.1175}11761177function writeArrayToMemory(array, buffer) {1178assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)')1179HEAP8.set(array, buffer);1180}11811182/** @param {boolean=} dontAddNull */1183function writeAsciiToMemory(str, buffer, dontAddNull) {1184for (var i = 0; i < str.length; ++i) {1185assert(str.charCodeAt(i) === str.charCodeAt(i)&0xff);1186HEAP8[((buffer++)>>0)]=str.charCodeAt(i);1187}1188// Null-terminate the pointer to the HEAP.1189if (!dontAddNull) HEAP8[((buffer)>>0)]=0;1190}1191119211931194// Memory management11951196var PAGE_SIZE = 16384;1197var WASM_PAGE_SIZE = 65536;1198var ASMJS_PAGE_SIZE = 16777216;11991200function alignUp(x, multiple) {1201if (x % multiple > 0) {1202x += multiple - (x % multiple);1203}1204return x;1205}12061207var HEAP,1208/** @type {ArrayBuffer} */1209buffer,1210/** @type {Int8Array} */1211HEAP8,1212/** @type {Uint8Array} */1213HEAPU8,1214/** @type {Int16Array} */1215HEAP16,1216/** @type {Uint16Array} */1217HEAPU16,1218/** @type {Int32Array} */1219HEAP32,1220/** @type {Uint32Array} */1221HEAPU32,1222/** @type {Float32Array} */1223HEAPF32,1224/** @type {Float64Array} */1225HEAPF64;12261227function updateGlobalBufferAndViews(buf) {1228buffer = buf;1229Module['HEAP8'] = HEAP8 = new Int8Array(buf);1230Module['HEAP16'] = HEAP16 = new Int16Array(buf);1231Module['HEAP32'] = HEAP32 = new Int32Array(buf);1232Module['HEAPU8'] = HEAPU8 = new Uint8Array(buf);1233Module['HEAPU16'] = HEAPU16 = new Uint16Array(buf);1234Module['HEAPU32'] = HEAPU32 = new Uint32Array(buf);1235Module['HEAPF32'] = HEAPF32 = new Float32Array(buf);1236Module['HEAPF64'] = HEAPF64 = new Float64Array(buf);1237}12381239var STATIC_BASE = 1024,1240STACK_BASE = 19593120,1241STACKTOP = STACK_BASE,1242STACK_MAX = 14350240,1243DYNAMIC_BASE = 19593120,1244DYNAMICTOP_PTR = 14350080;12451246assert(STACK_BASE % 16 === 0, 'stack must start aligned');1247assert(DYNAMIC_BASE % 16 === 0, 'heap must start aligned');1248124912501251var TOTAL_STACK = 5242880;1252if (Module['TOTAL_STACK']) assert(TOTAL_STACK === Module['TOTAL_STACK'], 'the stack size can no longer be determined at runtime')12531254var INITIAL_INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 20971520;if (!Object.getOwnPropertyDescriptor(Module, 'INITIAL_MEMORY')) Object.defineProperty(Module, 'INITIAL_MEMORY', { configurable: true, get: function() { abort('Module.INITIAL_MEMORY has been replaced with plain INITIAL_INITIAL_MEMORY') } });12551256assert(INITIAL_INITIAL_MEMORY >= TOTAL_STACK, 'INITIAL_MEMORY should be larger than TOTAL_STACK, was ' + INITIAL_INITIAL_MEMORY + '! (TOTAL_STACK=' + TOTAL_STACK + ')');12571258// check for full engine support (use string 'subarray' to avoid closure compiler confusion)1259assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray !== undefined && Int32Array.prototype.set !== undefined,1260'JS engine does not provide full typed array support');1261126212631264126512661267// In standalone mode, the wasm creates the memory, and the user can't provide it.1268// In non-standalone/normal mode, we create the memory here.12691270// Create the main memory. (Note: this isn't used in STANDALONE_WASM mode since the wasm1271// memory is created in the wasm, not in JS.)12721273if (Module['wasmMemory']) {1274wasmMemory = Module['wasmMemory'];1275} else1276{1277wasmMemory = new WebAssembly.Memory({1278'initial': INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE1279,1280'maximum': INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE1281});1282}128312841285if (wasmMemory) {1286buffer = wasmMemory.buffer;1287}12881289// If the user provides an incorrect length, just use that length instead rather than providing the user to1290// specifically provide the memory length with Module['INITIAL_MEMORY'].1291INITIAL_INITIAL_MEMORY = buffer.byteLength;1292assert(INITIAL_INITIAL_MEMORY % WASM_PAGE_SIZE === 0);1293updateGlobalBufferAndViews(buffer);12941295HEAP32[DYNAMICTOP_PTR>>2] = DYNAMIC_BASE;12961297129812991300// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.1301function writeStackCookie() {1302assert((STACK_MAX & 3) == 0);1303// The stack grows downwards1304HEAPU32[(STACK_MAX >> 2)+1] = 0x2135467;1305HEAPU32[(STACK_MAX >> 2)+2] = 0x89BACDFE;1306// Also test the global address 0 for integrity.1307// We don't do this with ASan because ASan does its own checks for this.1308HEAP32[0] = 0x63736d65; /* 'emsc' */1309}13101311function checkStackCookie() {1312var cookie1 = HEAPU32[(STACK_MAX >> 2)+1];1313var cookie2 = HEAPU32[(STACK_MAX >> 2)+2];1314if (cookie1 != 0x2135467 || cookie2 != 0x89BACDFE) {1315abort('Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x2135467, but received 0x' + cookie2.toString(16) + ' ' + cookie1.toString(16));1316}1317// Also test the global address 0 for integrity.1318// We don't do this with ASan because ASan does its own checks for this.1319if (HEAP32[0] !== 0x63736d65 /* 'emsc' */) abort('Runtime error: The application has corrupted its heap memory area (address zero)!');1320}13211322function abortStackOverflow(allocSize) {1323abort('Stack overflow! Attempted to allocate ' + allocSize + ' bytes on the stack, but stack has only ' + (STACK_MAX - stackSave() + allocSize) + ' bytes available!');1324}13251326132713281329// Endianness check (note: assumes compiler arch was little-endian)1330(function() {1331var h16 = new Int16Array(1);1332var h8 = new Int8Array(h16.buffer);1333h16[0] = 0x6373;1334if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian!';1335})();13361337function abortFnPtrError(ptr, sig) {1338abort("Invalid function pointer " + ptr + " called with signature '" + sig + "'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this). Build with ASSERTIONS=2 for more info.");1339}1340134113421343function callRuntimeCallbacks(callbacks) {1344while(callbacks.length > 0) {1345var callback = callbacks.shift();1346if (typeof callback == 'function') {1347callback();1348continue;1349}1350var func = callback.func;1351if (typeof func === 'number') {1352if (callback.arg === undefined) {1353Module['dynCall_v'](func);1354} else {1355Module['dynCall_vi'](func, callback.arg);1356}1357} else {1358func(callback.arg === undefined ? null : callback.arg);1359}1360}1361}13621363var __ATPRERUN__ = []; // functions called before the runtime is initialized1364var __ATINIT__ = []; // functions called during startup1365var __ATMAIN__ = []; // functions called when main() is to be run1366var __ATEXIT__ = []; // functions called during shutdown1367var __ATPOSTRUN__ = []; // functions called after the main() is called13681369var runtimeInitialized = false;1370var runtimeExited = false;137113721373function preRun() {13741375if (Module['preRun']) {1376if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];1377while (Module['preRun'].length) {1378addOnPreRun(Module['preRun'].shift());1379}1380}13811382callRuntimeCallbacks(__ATPRERUN__);1383}13841385function initRuntime() {1386checkStackCookie();1387assert(!runtimeInitialized);1388runtimeInitialized = true;1389if (!Module["noFSInit"] && !FS.init.initialized) FS.init();1390TTY.init();1391callRuntimeCallbacks(__ATINIT__);1392}13931394function preMain() {1395checkStackCookie();1396FS.ignorePermissions = false;1397callRuntimeCallbacks(__ATMAIN__);1398}13991400function exitRuntime() {1401checkStackCookie();1402runtimeExited = true;1403}14041405function postRun() {1406checkStackCookie();14071408if (Module['postRun']) {1409if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];1410while (Module['postRun'].length) {1411addOnPostRun(Module['postRun'].shift());1412}1413}14141415callRuntimeCallbacks(__ATPOSTRUN__);1416}14171418function addOnPreRun(cb) {1419__ATPRERUN__.unshift(cb);1420}14211422function addOnInit(cb) {1423__ATINIT__.unshift(cb);1424}14251426function addOnPreMain(cb) {1427__ATMAIN__.unshift(cb);1428}14291430function addOnExit(cb) {1431}14321433function addOnPostRun(cb) {1434__ATPOSTRUN__.unshift(cb);1435}14361437/** @param {number|boolean=} ignore */1438function unSign(value, bits, ignore) {1439if (value >= 0) {1440return value;1441}1442return 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 bitshifts1443: Math.pow(2, bits) + value;1444}1445/** @param {number|boolean=} ignore */1446function reSign(value, bits, ignore) {1447if (value <= 0) {1448return value;1449}1450var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 321451: Math.pow(2, bits-1);1452if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that1453// but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors1454// TODO: In i64 mode 1, resign the two parts separately and safely1455value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts1456}1457return value;1458}145914601461// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul14621463// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround14641465// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz3214661467// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc14681469assert(Math.imul, 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');1470assert(Math.fround, 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');1471assert(Math.clz32, 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');1472assert(Math.trunc, 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');14731474var Math_abs = Math.abs;1475var Math_cos = Math.cos;1476var Math_sin = Math.sin;1477var Math_tan = Math.tan;1478var Math_acos = Math.acos;1479var Math_asin = Math.asin;1480var Math_atan = Math.atan;1481var Math_atan2 = Math.atan2;1482var Math_exp = Math.exp;1483var Math_log = Math.log;1484var Math_sqrt = Math.sqrt;1485var Math_ceil = Math.ceil;1486var Math_floor = Math.floor;1487var Math_pow = Math.pow;1488var Math_imul = Math.imul;1489var Math_fround = Math.fround;1490var Math_round = Math.round;1491var Math_min = Math.min;1492var Math_max = Math.max;1493var Math_clz32 = Math.clz32;1494var Math_trunc = Math.trunc;1495149614971498// A counter of dependencies for calling run(). If we need to1499// do asynchronous work before running, increment this and1500// decrement it. Incrementing must happen in a place like1501// Module.preRun (used by emcc to add file preloading).1502// Note that you can add dependencies in preRun, even though1503// it happens right before run - run will be postponed until1504// the dependencies are met.1505var runDependencies = 0;1506var runDependencyWatcher = null;1507var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled1508var runDependencyTracking = {};15091510function getUniqueRunDependency(id) {1511var orig = id;1512while (1) {1513if (!runDependencyTracking[id]) return id;1514id = orig + Math.random();1515}1516}15171518function addRunDependency(id) {1519runDependencies++;15201521if (Module['monitorRunDependencies']) {1522Module['monitorRunDependencies'](runDependencies);1523}15241525if (id) {1526assert(!runDependencyTracking[id]);1527runDependencyTracking[id] = 1;1528if (runDependencyWatcher === null && typeof setInterval !== 'undefined') {1529// Check for missing dependencies every few seconds1530runDependencyWatcher = setInterval(function() {1531if (ABORT) {1532clearInterval(runDependencyWatcher);1533runDependencyWatcher = null;1534return;1535}1536var shown = false;1537for (var dep in runDependencyTracking) {1538if (!shown) {1539shown = true;1540err('still waiting on run dependencies:');1541}1542err('dependency: ' + dep);1543}1544if (shown) {1545err('(end of list)');1546}1547}, 10000);1548}1549} else {1550err('warning: run dependency added without ID');1551}1552}15531554function removeRunDependency(id) {1555runDependencies--;15561557if (Module['monitorRunDependencies']) {1558Module['monitorRunDependencies'](runDependencies);1559}15601561if (id) {1562assert(runDependencyTracking[id]);1563delete runDependencyTracking[id];1564} else {1565err('warning: run dependency removed without ID');1566}1567if (runDependencies == 0) {1568if (runDependencyWatcher !== null) {1569clearInterval(runDependencyWatcher);1570runDependencyWatcher = null;1571}1572if (dependenciesFulfilled) {1573var callback = dependenciesFulfilled;1574dependenciesFulfilled = null;1575callback(); // can add another dependenciesFulfilled1576}1577}1578}15791580Module["preloadedImages"] = {}; // maps url to image data1581Module["preloadedAudios"] = {}; // maps url to audio data158215831584/** @param {string|number=} what */1585function abort(what) {1586if (Module['onAbort']) {1587Module['onAbort'](what);1588}15891590what += '';1591out(what);1592err(what);15931594ABORT = true;1595EXITSTATUS = 1;15961597var output = 'abort(' + what + ') at ' + stackTrace();1598what = output;15991600// Throw a wasm runtime error, because a JS error might be seen as a foreign1601// exception, which means we'd run destructors on it. We need the error to1602// simply make the program stop.1603throw new WebAssembly.RuntimeError(what);1604}160516061607var memoryInitializer = null;160816091610161116121613161416151616// Copyright 2017 The Emscripten Authors. All rights reserved.1617// Emscripten is available under two separate licenses, the MIT license and the1618// University of Illinois/NCSA Open Source License. Both these licenses can be1619// found in the LICENSE file.16201621// Prefix of data URIs emitted by SINGLE_FILE and related options.1622var dataURIPrefix = 'data:application/octet-stream;base64,';16231624// Indicates whether filename is a base64 data URI.1625function isDataURI(filename) {1626return String.prototype.startsWith ?1627filename.startsWith(dataURIPrefix) :1628filename.indexOf(dataURIPrefix) === 0;1629}16301631163216331634var wasmBinaryFile = 'sm64.us.f3dex2e.wasm';1635if (!isDataURI(wasmBinaryFile)) {1636wasmBinaryFile = locateFile(wasmBinaryFile);1637}16381639function getBinary() {1640try {1641if (wasmBinary) {1642return new Uint8Array(wasmBinary);1643}16441645if (readBinary) {1646return readBinary(wasmBinaryFile);1647} else {1648throw "both async and sync fetching of the wasm failed";1649}1650}1651catch (err) {1652abort(err);1653}1654}16551656function getBinaryPromise() {1657// if we don't have the binary yet, and have the Fetch api, use that1658// in some environments, like Electron's render process, Fetch api may be present, but have a different context than expected, let's only use it on the Web1659if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && typeof fetch === 'function') {1660return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) {1661if (!response['ok']) {1662throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";1663}1664return response['arrayBuffer']();1665}).catch(function () {1666return getBinary();1667});1668}1669// Otherwise, getBinary should be able to get it synchronously1670return new Promise(function(resolve, reject) {1671resolve(getBinary());1672});1673}1674167516761677// Create the wasm instance.1678// Receives the wasm imports, returns the exports.1679function createWasm() {1680// prepare imports1681var info = {1682'env': asmLibraryArg,1683'wasi_snapshot_preview1': asmLibraryArg1684};1685// Load the wasm module and create an instance of using native support in the JS engine.1686// handle a generated wasm instance, receiving its exports and1687// performing other necessary setup1688/** @param {WebAssembly.Module=} module*/1689function receiveInstance(instance, module) {1690var exports = instance.exports;1691Module['asm'] = exports;1692removeRunDependency('wasm-instantiate');1693}1694// we can't run yet (except in a pthread, where we have a custom sync instantiator)1695addRunDependency('wasm-instantiate');169616971698// Async compilation can be confusing when an error on the page overwrites Module1699// (for example, if the order of elements is wrong, and the one defining Module is1700// later), so we save Module and check it later.1701var trueModule = Module;1702function receiveInstantiatedSource(output) {1703// 'output' is a WebAssemblyInstantiatedSource object which has both the module and instance.1704// receiveInstance() will swap in the exports (to Module.asm) so they can be called1705assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?');1706trueModule = null;1707// TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.1708// When the regression is fixed, can restore the above USE_PTHREADS-enabled path.1709receiveInstance(output['instance']);1710}171117121713function instantiateArrayBuffer(receiver) {1714return getBinaryPromise().then(function(binary) {1715return WebAssembly.instantiate(binary, info);1716}).then(receiver, function(reason) {1717err('failed to asynchronously prepare wasm: ' + reason);1718abort(reason);1719});1720}17211722// Prefer streaming instantiation if available.1723function instantiateAsync() {1724if (!wasmBinary &&1725typeof WebAssembly.instantiateStreaming === 'function' &&1726!isDataURI(wasmBinaryFile) &&1727typeof fetch === 'function') {1728fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function (response) {1729var result = WebAssembly.instantiateStreaming(response, info);1730return result.then(receiveInstantiatedSource, function(reason) {1731// We expect the most common failure cause to be a bad MIME type for the binary,1732// in which case falling back to ArrayBuffer instantiation should work.1733err('wasm streaming compile failed: ' + reason);1734err('falling back to ArrayBuffer instantiation');1735instantiateArrayBuffer(receiveInstantiatedSource);1736});1737});1738} else {1739return instantiateArrayBuffer(receiveInstantiatedSource);1740}1741}1742// User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback1743// to manually instantiate the Wasm module themselves. This allows pages to run the instantiation parallel1744// to any other async startup actions they are performing.1745if (Module['instantiateWasm']) {1746try {1747var exports = Module['instantiateWasm'](info, receiveInstance);1748return exports;1749} catch(e) {1750err('Module.instantiateWasm callback failed with error: ' + e);1751return false;1752}1753}17541755instantiateAsync();1756return {}; // no exports yet; we'll fill them in later1757}175817591760// Globals used by JS i64 conversions1761var tempDouble;1762var tempI64;17631764// === Body ===17651766var ASM_CONSTS = {17673069901: function($0) {requestAnimationFrame(function(time) { dynCall("vd", $0, [time]); })},17683069970: function($0) {var s = localStorage.sm64_save_file; if (s && s.length === 684) { try { var binary = atob(s); if (binary.length === 512) { for (var i = 0; i < 512; i++) { HEAPU8[$0 + i] = binary.charCodeAt(i); } return 1; } } catch (e) { } } return 0;},17693070210: function($0) {var str = ""; for (var i = 0; i < 512; i++) { str += String.fromCharCode(HEAPU8[$0 + i]); } localStorage.sm64_save_file = btoa(str);},17708775252: function($0, $1, $2) {var w = $0; var h = $1; var pixels = $2; if (!Module['SDL2']) Module['SDL2'] = {}; var SDL2 = Module['SDL2']; if (SDL2.ctxCanvas !== Module['canvas']) { SDL2.ctx = Module['createContext'](Module['canvas'], false, true); SDL2.ctxCanvas = Module['canvas']; } if (SDL2.w !== w || SDL2.h !== h || SDL2.imageCtx !== SDL2.ctx) { SDL2.image = SDL2.ctx.createImageData(w, h); SDL2.w = w; SDL2.h = h; SDL2.imageCtx = SDL2.ctx; } var data = SDL2.image.data; var src = pixels >> 2; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = 0xff; src++; dst += 4; } } else { if (SDL2.data32Data !== data) { SDL2.data32 = new Int32Array(data.buffer); SDL2.data8 = new Uint8Array(data.buffer); } var data32 = SDL2.data32; num = data32.length; data32.set(HEAP32.subarray(src, src + num)); var data8 = SDL2.data8; var i = 3; var j = i + 4*num; if (num % 8 == 0) { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; } } else { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; } } } SDL2.ctx.putImageData(SDL2.image, 0, 0); return 0;},17718776707: function($0, $1, $2, $3, $4) {var w = $0; var h = $1; var hot_x = $2; var hot_y = $3; var pixels = $4; var canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; var ctx = canvas.getContext("2d"); var image = ctx.createImageData(w, h); var data = image.data; var src = pixels >> 2; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = (val >> 24) & 0xff; src++; dst += 4; } } else { var data32 = new Int32Array(data.buffer); num = data32.length; data32.set(HEAP32.subarray(src, src + num)); } ctx.putImageData(image, 0, 0); var url = hot_x === 0 && hot_y === 0 ? "url(" + canvas.toDataURL() + "), auto" : "url(" + canvas.toDataURL() + ") " + hot_x + " " + hot_y + ", auto"; var urlBuf = _malloc(url.length + 1); stringToUTF8(url, urlBuf, url.length + 1); return urlBuf;},17728777696: function($0) {if (Module['canvas']) { Module['canvas'].style['cursor'] = UTF8ToString($0); } return 0;},17738777789: function() {if (Module['canvas']) { Module['canvas'].style['cursor'] = 'none'; }},17748779014: function() {return screen.width;},17758779041: function() {return screen.height;},17768779069: function() {return window.innerWidth;},17778779101: function() {return window.innerHeight;},17788779179: function($0) {if (typeof Module['setWindowTitle'] !== 'undefined') { Module['setWindowTitle'](UTF8ToString($0)); } return 0;},17798779333: function() {if (typeof(AudioContext) !== 'undefined') { return 1; } else if (typeof(webkitAudioContext) !== 'undefined') { return 1; } return 0;},17808779499: function() {if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) { return 1; } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') { return 1; } return 0;},17818779725: function($0) {if(typeof(Module['SDL2']) === 'undefined') { Module['SDL2'] = {}; } var SDL2 = Module['SDL2']; if (!$0) { SDL2.audio = {}; } else { SDL2.capture = {}; } if (!SDL2.audioContext) { if (typeof(AudioContext) !== 'undefined') { SDL2.audioContext = new AudioContext(); } else if (typeof(webkitAudioContext) !== 'undefined') { SDL2.audioContext = new webkitAudioContext(); } } return SDL2.audioContext === undefined ? -1 : 0;},17828780208: function() {var SDL2 = Module['SDL2']; return SDL2.audioContext.sampleRate;},17838780278: function($0, $1, $2, $3) {var SDL2 = Module['SDL2']; var have_microphone = function(stream) { if (SDL2.capture.silenceTimer !== undefined) { clearTimeout(SDL2.capture.silenceTimer); SDL2.capture.silenceTimer = undefined; } SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream); SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1); SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) { if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; } audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0); SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode); SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination); SDL2.capture.stream = stream; }; var no_microphone = function(error) { }; SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0); var silence_callback = function() { SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.silenceTimer = setTimeout(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) { navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone); } else if (navigator.webkitGetUserMedia !== undefined) { navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone); }},17848781930: function($0, $1, $2, $3) {var SDL2 = Module['SDL2']; SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0); SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) { if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; } SDL2.audio.currentOutputBuffer = e['outputBuffer']; dynCall('vi', $2, [$3]); }; SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']);},17858782340: function($0, $1) {var SDL2 = Module['SDL2']; var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(c); if (channelData.length != $1) { throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } if (numChannels == 1) { for (var j = 0; j < $1; ++j) { setValue($0 + (j * 4), channelData[j], 'float'); } } else { for (var j = 0; j < $1; ++j) { setValue($0 + (((j * numChannels) + c) * 4), channelData[j], 'float'); } } }},17868782945: function($0, $1) {var SDL2 = Module['SDL2']; var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels']; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c); if (channelData.length != $1) { throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } for (var j = 0; j < $1; ++j) { channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2]; } }},17878783425: function($0) {var SDL2 = Module['SDL2']; if ($0) { if (SDL2.capture.silenceTimer !== undefined) { clearTimeout(SDL2.capture.silenceTimer); } if (SDL2.capture.stream !== undefined) { var tracks = SDL2.capture.stream.getAudioTracks(); for (var i = 0; i < tracks.length; i++) { SDL2.capture.stream.removeTrack(tracks[i]); } SDL2.capture.stream = undefined; } if (SDL2.capture.scriptProcessorNode !== undefined) { SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {}; SDL2.capture.scriptProcessorNode.disconnect(); SDL2.capture.scriptProcessorNode = undefined; } if (SDL2.capture.mediaStreamNode !== undefined) { SDL2.capture.mediaStreamNode.disconnect(); SDL2.capture.mediaStreamNode = undefined; } if (SDL2.capture.silenceBuffer !== undefined) { SDL2.capture.silenceBuffer = undefined } SDL2.capture = undefined; } else { if (SDL2.audio.scriptProcessorNode != undefined) { SDL2.audio.scriptProcessorNode.disconnect(); SDL2.audio.scriptProcessorNode = undefined; } SDL2.audio = undefined; } if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) { SDL2.audioContext.close(); SDL2.audioContext = undefined; }}1788};17891790function _emscripten_asm_const_iii(code, sigPtr, argbuf) {1791var args = readAsmConstArgs(sigPtr, argbuf);1792return ASM_CONSTS[code].apply(null, args);1793}1794179517961797// STATICTOP = STATIC_BASE + 14349216;1798/* global initializers */ __ATINIT__.push({ func: function() { ___wasm_call_ctors() } });17991800180118021803/* no memory initializer */1804// {{PRE_LIBRARY}}180518061807function demangle(func) {1808warnOnce('warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling');1809return func;1810}18111812function demangleAll(text) {1813var regex =1814/\b_Z[\w\d_]+/g;1815return text.replace(regex,1816function(x) {1817var y = demangle(x);1818return x === y ? x : (y + ' [' + x + ']');1819});1820}18211822function jsStackTrace() {1823var err = new Error();1824if (!err.stack) {1825// IE10+ special cases: It does have callstack info, but it is only populated if an Error object is thrown,1826// so try that as a special-case.1827try {1828throw new Error();1829} catch(e) {1830err = e;1831}1832if (!err.stack) {1833return '(no stack trace available)';1834}1835}1836return err.stack.toString();1837}18381839function stackTrace() {1840var js = jsStackTrace();1841if (Module['extraStackTrace']) js += '\n' + Module['extraStackTrace']();1842return demangleAll(js);1843}18441845function ___assert_fail(condition, filename, line, func) {1846abort('Assertion failed: ' + UTF8ToString(condition) + ', at: ' + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']);1847}18481849function ___handle_stack_overflow() {1850abort('stack overflow')1851}185218531854function ___setErrNo(value) {1855if (Module['___errno_location']) HEAP32[((Module['___errno_location']())>>2)]=value;1856else err('failed to set errno from JS');1857return value;1858}185918601861var PATH={splitPath:function(filename) {1862var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;1863return splitPathRe.exec(filename).slice(1);1864},normalizeArray:function(parts, allowAboveRoot) {1865// if the path tries to go above the root, `up` ends up > 01866var up = 0;1867for (var i = parts.length - 1; i >= 0; i--) {1868var last = parts[i];1869if (last === '.') {1870parts.splice(i, 1);1871} else if (last === '..') {1872parts.splice(i, 1);1873up++;1874} else if (up) {1875parts.splice(i, 1);1876up--;1877}1878}1879// if the path is allowed to go above the root, restore leading ..s1880if (allowAboveRoot) {1881for (; up; up--) {1882parts.unshift('..');1883}1884}1885return parts;1886},normalize:function(path) {1887var isAbsolute = path.charAt(0) === '/',1888trailingSlash = path.substr(-1) === '/';1889// Normalize the path1890path = PATH.normalizeArray(path.split('/').filter(function(p) {1891return !!p;1892}), !isAbsolute).join('/');1893if (!path && !isAbsolute) {1894path = '.';1895}1896if (path && trailingSlash) {1897path += '/';1898}1899return (isAbsolute ? '/' : '') + path;1900},dirname:function(path) {1901var result = PATH.splitPath(path),1902root = result[0],1903dir = result[1];1904if (!root && !dir) {1905// No dirname whatsoever1906return '.';1907}1908if (dir) {1909// It has a dirname, strip trailing slash1910dir = dir.substr(0, dir.length - 1);1911}1912return root + dir;1913},basename:function(path) {1914// EMSCRIPTEN return '/'' for '/', not an empty string1915if (path === '/') return '/';1916var lastSlash = path.lastIndexOf('/');1917if (lastSlash === -1) return path;1918return path.substr(lastSlash+1);1919},extname:function(path) {1920return PATH.splitPath(path)[3];1921},join:function() {1922var paths = Array.prototype.slice.call(arguments, 0);1923return PATH.normalize(paths.join('/'));1924},join2:function(l, r) {1925return PATH.normalize(l + '/' + r);1926}};192719281929var PATH_FS={resolve:function() {1930var resolvedPath = '',1931resolvedAbsolute = false;1932for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {1933var path = (i >= 0) ? arguments[i] : FS.cwd();1934// Skip empty and invalid entries1935if (typeof path !== 'string') {1936throw new TypeError('Arguments to path.resolve must be strings');1937} else if (!path) {1938return ''; // an invalid portion invalidates the whole thing1939}1940resolvedPath = path + '/' + resolvedPath;1941resolvedAbsolute = path.charAt(0) === '/';1942}1943// At this point the path should be resolved to a full absolute path, but1944// handle relative paths to be safe (might happen when process.cwd() fails)1945resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) {1946return !!p;1947}), !resolvedAbsolute).join('/');1948return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';1949},relative:function(from, to) {1950from = PATH_FS.resolve(from).substr(1);1951to = PATH_FS.resolve(to).substr(1);1952function trim(arr) {1953var start = 0;1954for (; start < arr.length; start++) {1955if (arr[start] !== '') break;1956}1957var end = arr.length - 1;1958for (; end >= 0; end--) {1959if (arr[end] !== '') break;1960}1961if (start > end) return [];1962return arr.slice(start, end - start + 1);1963}1964var fromParts = trim(from.split('/'));1965var toParts = trim(to.split('/'));1966var length = Math.min(fromParts.length, toParts.length);1967var samePartsLength = length;1968for (var i = 0; i < length; i++) {1969if (fromParts[i] !== toParts[i]) {1970samePartsLength = i;1971break;1972}1973}1974var outputParts = [];1975for (var i = samePartsLength; i < fromParts.length; i++) {1976outputParts.push('..');1977}1978outputParts = outputParts.concat(toParts.slice(samePartsLength));1979return outputParts.join('/');1980}};19811982var TTY={ttys:[],init:function () {1983// https://github.com/emscripten-core/emscripten/pull/15551984// if (ENVIRONMENT_IS_NODE) {1985// // currently, FS.init does not distinguish if process.stdin is a file or TTY1986// // device, it always assumes it's a TTY device. because of this, we're forcing1987// // process.stdin to UTF8 encoding to at least make stdin reading compatible1988// // with text files until FS.init can be refactored.1989// process['stdin']['setEncoding']('utf8');1990// }1991},shutdown:function() {1992// https://github.com/emscripten-core/emscripten/pull/15551993// if (ENVIRONMENT_IS_NODE) {1994// // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?1995// // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation1996// // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?1997// // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle1998// // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call1999// process['stdin']['pause']();2000// }2001},register:function(dev, ops) {2002TTY.ttys[dev] = { input: [], output: [], ops: ops };2003FS.registerDevice(dev, TTY.stream_ops);2004},stream_ops:{open:function(stream) {2005var tty = TTY.ttys[stream.node.rdev];2006if (!tty) {2007throw new FS.ErrnoError(43);2008}2009stream.tty = tty;2010stream.seekable = false;2011},close:function(stream) {2012// flush any pending line data2013stream.tty.ops.flush(stream.tty);2014},flush:function(stream) {2015stream.tty.ops.flush(stream.tty);2016},read:function(stream, buffer, offset, length, pos /* ignored */) {2017if (!stream.tty || !stream.tty.ops.get_char) {2018throw new FS.ErrnoError(60);2019}2020var bytesRead = 0;2021for (var i = 0; i < length; i++) {2022var result;2023try {2024result = stream.tty.ops.get_char(stream.tty);2025} catch (e) {2026throw new FS.ErrnoError(29);2027}2028if (result === undefined && bytesRead === 0) {2029throw new FS.ErrnoError(6);2030}2031if (result === null || result === undefined) break;2032bytesRead++;2033buffer[offset+i] = result;2034}2035if (bytesRead) {2036stream.node.timestamp = Date.now();2037}2038return bytesRead;2039},write:function(stream, buffer, offset, length, pos) {2040if (!stream.tty || !stream.tty.ops.put_char) {2041throw new FS.ErrnoError(60);2042}2043try {2044for (var i = 0; i < length; i++) {2045stream.tty.ops.put_char(stream.tty, buffer[offset+i]);2046}2047} catch (e) {2048throw new FS.ErrnoError(29);2049}2050if (length) {2051stream.node.timestamp = Date.now();2052}2053return i;2054}},default_tty_ops:{get_char:function(tty) {2055if (!tty.input.length) {2056var result = null;2057if (ENVIRONMENT_IS_NODE) {2058// we will read data by chunks of BUFSIZE2059var BUFSIZE = 256;2060var buf = Buffer.alloc ? Buffer.alloc(BUFSIZE) : new Buffer(BUFSIZE);2061var bytesRead = 0;20622063try {2064bytesRead = nodeFS.readSync(process.stdin.fd, buf, 0, BUFSIZE, null);2065} catch(e) {2066// Cross-platform differences: on Windows, reading EOF throws an exception, but on other OSes,2067// reading EOF returns 0. Uniformize behavior by treating the EOF exception to return 0.2068if (e.toString().indexOf('EOF') != -1) bytesRead = 0;2069else throw e;2070}20712072if (bytesRead > 0) {2073result = buf.slice(0, bytesRead).toString('utf-8');2074} else {2075result = null;2076}2077} else2078if (typeof window != 'undefined' &&2079typeof window.prompt == 'function') {2080// Browser.2081result = window.prompt('Input: '); // returns null on cancel2082if (result !== null) {2083result += '\n';2084}2085} else if (typeof readline == 'function') {2086// Command line.2087result = readline();2088if (result !== null) {2089result += '\n';2090}2091}2092if (!result) {2093return null;2094}2095tty.input = intArrayFromString(result, true);2096}2097return tty.input.shift();2098},put_char:function(tty, val) {2099if (val === null || val === 10) {2100out(UTF8ArrayToString(tty.output, 0));2101tty.output = [];2102} else {2103if (val != 0) tty.output.push(val); // val == 0 would cut text output off in the middle.2104}2105},flush:function(tty) {2106if (tty.output && tty.output.length > 0) {2107out(UTF8ArrayToString(tty.output, 0));2108tty.output = [];2109}2110}},default_tty1_ops:{put_char:function(tty, val) {2111if (val === null || val === 10) {2112err(UTF8ArrayToString(tty.output, 0));2113tty.output = [];2114} else {2115if (val != 0) tty.output.push(val);2116}2117},flush:function(tty) {2118if (tty.output && tty.output.length > 0) {2119err(UTF8ArrayToString(tty.output, 0));2120tty.output = [];2121}2122}}};21232124var MEMFS={ops_table:null,mount:function(mount) {2125return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);2126},createNode:function(parent, name, mode, dev) {2127if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {2128// no supported2129throw new FS.ErrnoError(63);2130}2131if (!MEMFS.ops_table) {2132MEMFS.ops_table = {2133dir: {2134node: {2135getattr: MEMFS.node_ops.getattr,2136setattr: MEMFS.node_ops.setattr,2137lookup: MEMFS.node_ops.lookup,2138mknod: MEMFS.node_ops.mknod,2139rename: MEMFS.node_ops.rename,2140unlink: MEMFS.node_ops.unlink,2141rmdir: MEMFS.node_ops.rmdir,2142readdir: MEMFS.node_ops.readdir,2143symlink: MEMFS.node_ops.symlink2144},2145stream: {2146llseek: MEMFS.stream_ops.llseek2147}2148},2149file: {2150node: {2151getattr: MEMFS.node_ops.getattr,2152setattr: MEMFS.node_ops.setattr2153},2154stream: {2155llseek: MEMFS.stream_ops.llseek,2156read: MEMFS.stream_ops.read,2157write: MEMFS.stream_ops.write,2158allocate: MEMFS.stream_ops.allocate,2159mmap: MEMFS.stream_ops.mmap,2160msync: MEMFS.stream_ops.msync2161}2162},2163link: {2164node: {2165getattr: MEMFS.node_ops.getattr,2166setattr: MEMFS.node_ops.setattr,2167readlink: MEMFS.node_ops.readlink2168},2169stream: {}2170},2171chrdev: {2172node: {2173getattr: MEMFS.node_ops.getattr,2174setattr: MEMFS.node_ops.setattr2175},2176stream: FS.chrdev_stream_ops2177}2178};2179}2180var node = FS.createNode(parent, name, mode, dev);2181if (FS.isDir(node.mode)) {2182node.node_ops = MEMFS.ops_table.dir.node;2183node.stream_ops = MEMFS.ops_table.dir.stream;2184node.contents = {};2185} else if (FS.isFile(node.mode)) {2186node.node_ops = MEMFS.ops_table.file.node;2187node.stream_ops = MEMFS.ops_table.file.stream;2188node.usedBytes = 0; // The actual number of bytes used in the typed array, as opposed to contents.length which gives the whole capacity.2189// When the byte data of the file is populated, this will point to either a typed array, or a normal JS array. Typed arrays are preferred2190// for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size2191// penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme.2192node.contents = null;2193} else if (FS.isLink(node.mode)) {2194node.node_ops = MEMFS.ops_table.link.node;2195node.stream_ops = MEMFS.ops_table.link.stream;2196} else if (FS.isChrdev(node.mode)) {2197node.node_ops = MEMFS.ops_table.chrdev.node;2198node.stream_ops = MEMFS.ops_table.chrdev.stream;2199}2200node.timestamp = Date.now();2201// add the new node to the parent2202if (parent) {2203parent.contents[name] = node;2204}2205return node;2206},getFileDataAsRegularArray:function(node) {2207if (node.contents && node.contents.subarray) {2208var arr = [];2209for (var i = 0; i < node.usedBytes; ++i) arr.push(node.contents[i]);2210return arr; // Returns a copy of the original data.2211}2212return node.contents; // No-op, the file contents are already in a JS array. Return as-is.2213},getFileDataAsTypedArray:function(node) {2214if (!node.contents) return new Uint8Array(0);2215if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.2216return new Uint8Array(node.contents);2217},expandFileStorage:function(node, newCapacity) {2218var prevCapacity = node.contents ? node.contents.length : 0;2219if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.2220// Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.2221// For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to2222// avoid overshooting the allocation cap by a very large margin.2223var CAPACITY_DOUBLING_MAX = 1024 * 1024;2224newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) | 0);2225if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.2226var oldContents = node.contents;2227node.contents = new Uint8Array(newCapacity); // Allocate new storage.2228if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); // Copy old data over to the new storage.2229return;2230},resizeFileStorage:function(node, newSize) {2231if (node.usedBytes == newSize) return;2232if (newSize == 0) {2233node.contents = null; // Fully decommit when requesting a resize to zero.2234node.usedBytes = 0;2235return;2236}2237if (!node.contents || node.contents.subarray) { // Resize a typed array if that is being used as the backing store.2238var oldContents = node.contents;2239node.contents = new Uint8Array(newSize); // Allocate new storage.2240if (oldContents) {2241node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.2242}2243node.usedBytes = newSize;2244return;2245}2246// Backing with a JS array.2247if (!node.contents) node.contents = [];2248if (node.contents.length > newSize) node.contents.length = newSize;2249else while (node.contents.length < newSize) node.contents.push(0);2250node.usedBytes = newSize;2251},node_ops:{getattr:function(node) {2252var attr = {};2253// device numbers reuse inode numbers.2254attr.dev = FS.isChrdev(node.mode) ? node.id : 1;2255attr.ino = node.id;2256attr.mode = node.mode;2257attr.nlink = 1;2258attr.uid = 0;2259attr.gid = 0;2260attr.rdev = node.rdev;2261if (FS.isDir(node.mode)) {2262attr.size = 4096;2263} else if (FS.isFile(node.mode)) {2264attr.size = node.usedBytes;2265} else if (FS.isLink(node.mode)) {2266attr.size = node.link.length;2267} else {2268attr.size = 0;2269}2270attr.atime = new Date(node.timestamp);2271attr.mtime = new Date(node.timestamp);2272attr.ctime = new Date(node.timestamp);2273// NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),2274// but this is not required by the standard.2275attr.blksize = 4096;2276attr.blocks = Math.ceil(attr.size / attr.blksize);2277return attr;2278},setattr:function(node, attr) {2279if (attr.mode !== undefined) {2280node.mode = attr.mode;2281}2282if (attr.timestamp !== undefined) {2283node.timestamp = attr.timestamp;2284}2285if (attr.size !== undefined) {2286MEMFS.resizeFileStorage(node, attr.size);2287}2288},lookup:function(parent, name) {2289throw FS.genericErrors[44];2290},mknod:function(parent, name, mode, dev) {2291return MEMFS.createNode(parent, name, mode, dev);2292},rename:function(old_node, new_dir, new_name) {2293// if we're overwriting a directory at new_name, make sure it's empty.2294if (FS.isDir(old_node.mode)) {2295var new_node;2296try {2297new_node = FS.lookupNode(new_dir, new_name);2298} catch (e) {2299}2300if (new_node) {2301for (var i in new_node.contents) {2302throw new FS.ErrnoError(55);2303}2304}2305}2306// do the internal rewiring2307delete old_node.parent.contents[old_node.name];2308old_node.name = new_name;2309new_dir.contents[new_name] = old_node;2310old_node.parent = new_dir;2311},unlink:function(parent, name) {2312delete parent.contents[name];2313},rmdir:function(parent, name) {2314var node = FS.lookupNode(parent, name);2315for (var i in node.contents) {2316throw new FS.ErrnoError(55);2317}2318delete parent.contents[name];2319},readdir:function(node) {2320var entries = ['.', '..'];2321for (var key in node.contents) {2322if (!node.contents.hasOwnProperty(key)) {2323continue;2324}2325entries.push(key);2326}2327return entries;2328},symlink:function(parent, newname, oldpath) {2329var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);2330node.link = oldpath;2331return node;2332},readlink:function(node) {2333if (!FS.isLink(node.mode)) {2334throw new FS.ErrnoError(28);2335}2336return node.link;2337}},stream_ops:{read:function(stream, buffer, offset, length, position) {2338var contents = stream.node.contents;2339if (position >= stream.node.usedBytes) return 0;2340var size = Math.min(stream.node.usedBytes - position, length);2341assert(size >= 0);2342if (size > 8 && contents.subarray) { // non-trivial, and typed array2343buffer.set(contents.subarray(position, position + size), offset);2344} else {2345for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];2346}2347return size;2348},write:function(stream, buffer, offset, length, position, canOwn) {2349// The data buffer should be a typed array view2350assert(!(buffer instanceof ArrayBuffer));23512352if (!length) return 0;2353var node = stream.node;2354node.timestamp = Date.now();23552356if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array?2357if (canOwn) {2358assert(position === 0, 'canOwn must imply no weird position inside the file');2359node.contents = buffer.subarray(offset, offset + length);2360node.usedBytes = length;2361return length;2362} else if (node.usedBytes === 0 && position === 0) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.2363node.contents = buffer.slice(offset, offset + length);2364node.usedBytes = length;2365return length;2366} else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file?2367node.contents.set(buffer.subarray(offset, offset + length), position);2368return length;2369}2370}23712372// Appending to an existing file and we need to reallocate, or source data did not come as a typed array.2373MEMFS.expandFileStorage(node, position+length);2374if (node.contents.subarray && buffer.subarray) node.contents.set(buffer.subarray(offset, offset + length), position); // Use typed array write if available.2375else {2376for (var i = 0; i < length; i++) {2377node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not.2378}2379}2380node.usedBytes = Math.max(node.usedBytes, position+length);2381return length;2382},llseek:function(stream, offset, whence) {2383var position = offset;2384if (whence === 1) {2385position += stream.position;2386} else if (whence === 2) {2387if (FS.isFile(stream.node.mode)) {2388position += stream.node.usedBytes;2389}2390}2391if (position < 0) {2392throw new FS.ErrnoError(28);2393}2394return position;2395},allocate:function(stream, offset, length) {2396MEMFS.expandFileStorage(stream.node, offset + length);2397stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length);2398},mmap:function(stream, buffer, offset, length, position, prot, flags) {2399// The data buffer should be a typed array view2400assert(!(buffer instanceof ArrayBuffer));2401if (!FS.isFile(stream.node.mode)) {2402throw new FS.ErrnoError(43);2403}2404var ptr;2405var allocated;2406var contents = stream.node.contents;2407// Only make a new copy when MAP_PRIVATE is specified.2408if ( !(flags & 2) &&2409contents.buffer === buffer.buffer ) {2410// We can't emulate MAP_SHARED when the file is not backed by the buffer2411// we're mapping to (e.g. the HEAP buffer).2412allocated = false;2413ptr = contents.byteOffset;2414} else {2415// Try to avoid unnecessary slices.2416if (position > 0 || position + length < contents.length) {2417if (contents.subarray) {2418contents = contents.subarray(position, position + length);2419} else {2420contents = Array.prototype.slice.call(contents, position, position + length);2421}2422}2423allocated = true;2424// malloc() can lead to growing the heap. If targeting the heap, we need to2425// re-acquire the heap buffer object in case growth had occurred.2426var fromHeap = (buffer.buffer == HEAP8.buffer);2427ptr = _malloc(length);2428if (!ptr) {2429throw new FS.ErrnoError(48);2430}2431(fromHeap ? HEAP8 : buffer).set(contents, ptr);2432}2433return { ptr: ptr, allocated: allocated };2434},msync:function(stream, buffer, offset, length, mmapFlags) {2435if (!FS.isFile(stream.node.mode)) {2436throw new FS.ErrnoError(43);2437}2438if (mmapFlags & 2) {2439// MAP_PRIVATE calls need not to be synced back to underlying fs2440return 0;2441}24422443var bytesWritten = MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);2444// should we check if bytesWritten and length are the same?2445return 0;2446}}};24472448var ERRNO_MESSAGES={0:"Success",1:"Arg list too long",2:"Permission denied",3:"Address already in use",4:"Address not available",5:"Address family not supported by protocol family",6:"No more processes",7:"Socket already connected",8:"Bad file number",9:"Trying to read unreadable message",10:"Mount device busy",11:"Operation canceled",12:"No children",13:"Connection aborted",14:"Connection refused",15:"Connection reset by peer",16:"File locking deadlock error",17:"Destination address required",18:"Math arg out of domain of func",19:"Quota exceeded",20:"File exists",21:"Bad address",22:"File too large",23:"Host is unreachable",24:"Identifier removed",25:"Illegal byte sequence",26:"Connection already in progress",27:"Interrupted system call",28:"Invalid argument",29:"I/O error",30:"Socket is already connected",31:"Is a directory",32:"Too many symbolic links",33:"Too many open files",34:"Too many links",35:"Message too long",36:"Multihop attempted",37:"File or path name too long",38:"Network interface is not configured",39:"Connection reset by network",40:"Network is unreachable",41:"Too many open files in system",42:"No buffer space available",43:"No such device",44:"No such file or directory",45:"Exec format error",46:"No record locks available",47:"The link has been severed",48:"Not enough core",49:"No message of desired type",50:"Protocol not available",51:"No space left on device",52:"Function not implemented",53:"Socket is not connected",54:"Not a directory",55:"Directory not empty",56:"State not recoverable",57:"Socket operation on non-socket",59:"Not a typewriter",60:"No such device or address",61:"Value too large for defined data type",62:"Previous owner died",63:"Not super-user",64:"Broken pipe",65:"Protocol error",66:"Unknown protocol",67:"Protocol wrong type for socket",68:"Math result not representable",69:"Read only file system",70:"Illegal seek",71:"No such process",72:"Stale file handle",73:"Connection timed out",74:"Text file busy",75:"Cross-device link",100:"Device not a stream",101:"Bad font file fmt",102:"Invalid slot",103:"Invalid request code",104:"No anode",105:"Block device required",106:"Channel number out of range",107:"Level 3 halted",108:"Level 3 reset",109:"Link number out of range",110:"Protocol driver not attached",111:"No CSI structure available",112:"Level 2 halted",113:"Invalid exchange",114:"Invalid request descriptor",115:"Exchange full",116:"No data (for no delay io)",117:"Timer expired",118:"Out of streams resources",119:"Machine is not on the network",120:"Package not installed",121:"The object is remote",122:"Advertise error",123:"Srmount error",124:"Communication error on send",125:"Cross mount point (not really error)",126:"Given log. name not unique",127:"f.d. invalid for this operation",128:"Remote address changed",129:"Can access a needed shared lib",130:"Accessing a corrupted shared lib",131:".lib section in a.out corrupted",132:"Attempting to link in too many libs",133:"Attempting to exec a shared library",135:"Streams pipe error",136:"Too many users",137:"Socket type not supported",138:"Not supported",139:"Protocol family not supported",140:"Can't send after socket shutdown",141:"Too many references",142:"Host is down",148:"No medium (in tape drive)",156:"Level 2 not synchronized"};24492450var ERRNO_CODES={EPERM:63,ENOENT:44,ESRCH:71,EINTR:27,EIO:29,ENXIO:60,E2BIG:1,ENOEXEC:45,EBADF:8,ECHILD:12,EAGAIN:6,EWOULDBLOCK:6,ENOMEM:48,EACCES:2,EFAULT:21,ENOTBLK:105,EBUSY:10,EEXIST:20,EXDEV:75,ENODEV:43,ENOTDIR:54,EISDIR:31,EINVAL:28,ENFILE:41,EMFILE:33,ENOTTY:59,ETXTBSY:74,EFBIG:22,ENOSPC:51,ESPIPE:70,EROFS:69,EMLINK:34,EPIPE:64,EDOM:18,ERANGE:68,ENOMSG:49,EIDRM:24,ECHRNG:106,EL2NSYNC:156,EL3HLT:107,EL3RST:108,ELNRNG:109,EUNATCH:110,ENOCSI:111,EL2HLT:112,EDEADLK:16,ENOLCK:46,EBADE:113,EBADR:114,EXFULL:115,ENOANO:104,EBADRQC:103,EBADSLT:102,EDEADLOCK:16,EBFONT:101,ENOSTR:100,ENODATA:116,ETIME:117,ENOSR:118,ENONET:119,ENOPKG:120,EREMOTE:121,ENOLINK:47,EADV:122,ESRMNT:123,ECOMM:124,EPROTO:65,EMULTIHOP:36,EDOTDOT:125,EBADMSG:9,ENOTUNIQ:126,EBADFD:127,EREMCHG:128,ELIBACC:129,ELIBBAD:130,ELIBSCN:131,ELIBMAX:132,ELIBEXEC:133,ENOSYS:52,ENOTEMPTY:55,ENAMETOOLONG:37,ELOOP:32,EOPNOTSUPP:138,EPFNOSUPPORT:139,ECONNRESET:15,ENOBUFS:42,EAFNOSUPPORT:5,EPROTOTYPE:67,ENOTSOCK:57,ENOPROTOOPT:50,ESHUTDOWN:140,ECONNREFUSED:14,EADDRINUSE:3,ECONNABORTED:13,ENETUNREACH:40,ENETDOWN:38,ETIMEDOUT:73,EHOSTDOWN:142,EHOSTUNREACH:23,EINPROGRESS:26,EALREADY:7,EDESTADDRREQ:17,EMSGSIZE:35,EPROTONOSUPPORT:66,ESOCKTNOSUPPORT:137,EADDRNOTAVAIL:4,ENETRESET:39,EISCONN:30,ENOTCONN:53,ETOOMANYREFS:141,EUSERS:136,EDQUOT:19,ESTALE:72,ENOTSUP:138,ENOMEDIUM:148,EILSEQ:25,EOVERFLOW:61,ECANCELED:11,ENOTRECOVERABLE:56,EOWNERDEAD:62,ESTRPIPE:135};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,trackingDelegate:{},tracking:{openFlags:{READ:1,WRITE:2}},ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,handleFSError:function(e) {2451if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace();2452return ___setErrNo(e.errno);2453},lookupPath:function(path, opts) {2454path = PATH_FS.resolve(FS.cwd(), path);2455opts = opts || {};24562457if (!path) return { path: '', node: null };24582459var defaults = {2460follow_mount: true,2461recurse_count: 02462};2463for (var key in defaults) {2464if (opts[key] === undefined) {2465opts[key] = defaults[key];2466}2467}24682469if (opts.recurse_count > 8) { // max recursive lookup of 82470throw new FS.ErrnoError(32);2471}24722473// split the path2474var parts = PATH.normalizeArray(path.split('/').filter(function(p) {2475return !!p;2476}), false);24772478// start at the root2479var current = FS.root;2480var current_path = '/';24812482for (var i = 0; i < parts.length; i++) {2483var islast = (i === parts.length-1);2484if (islast && opts.parent) {2485// stop resolving2486break;2487}24882489current = FS.lookupNode(current, parts[i]);2490current_path = PATH.join2(current_path, parts[i]);24912492// jump to the mount's root node if this is a mountpoint2493if (FS.isMountpoint(current)) {2494if (!islast || (islast && opts.follow_mount)) {2495current = current.mounted.root;2496}2497}24982499// by default, lookupPath will not follow a symlink if it is the final path component.2500// setting opts.follow = true will override this behavior.2501if (!islast || opts.follow) {2502var count = 0;2503while (FS.isLink(current.mode)) {2504var link = FS.readlink(current_path);2505current_path = PATH_FS.resolve(PATH.dirname(current_path), link);25062507var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });2508current = lookup.node;25092510if (count++ > 40) { // limit max consecutive symlinks to 40 (SYMLOOP_MAX).2511throw new FS.ErrnoError(32);2512}2513}2514}2515}25162517return { path: current_path, node: current };2518},getPath:function(node) {2519var path;2520while (true) {2521if (FS.isRoot(node)) {2522var mount = node.mount.mountpoint;2523if (!path) return mount;2524return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;2525}2526path = path ? node.name + '/' + path : node.name;2527node = node.parent;2528}2529},hashName:function(parentid, name) {2530var hash = 0;253125322533for (var i = 0; i < name.length; i++) {2534hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;2535}2536return ((parentid + hash) >>> 0) % FS.nameTable.length;2537},hashAddNode:function(node) {2538var hash = FS.hashName(node.parent.id, node.name);2539node.name_next = FS.nameTable[hash];2540FS.nameTable[hash] = node;2541},hashRemoveNode:function(node) {2542var hash = FS.hashName(node.parent.id, node.name);2543if (FS.nameTable[hash] === node) {2544FS.nameTable[hash] = node.name_next;2545} else {2546var current = FS.nameTable[hash];2547while (current) {2548if (current.name_next === node) {2549current.name_next = node.name_next;2550break;2551}2552current = current.name_next;2553}2554}2555},lookupNode:function(parent, name) {2556var errCode = FS.mayLookup(parent);2557if (errCode) {2558throw new FS.ErrnoError(errCode, parent);2559}2560var hash = FS.hashName(parent.id, name);2561for (var node = FS.nameTable[hash]; node; node = node.name_next) {2562var nodeName = node.name;2563if (node.parent.id === parent.id && nodeName === name) {2564return node;2565}2566}2567// if we failed to find it in the cache, call into the VFS2568return FS.lookup(parent, name);2569},createNode:function(parent, name, mode, rdev) {2570var node = new FS.FSNode(parent, name, mode, rdev);25712572FS.hashAddNode(node);25732574return node;2575},destroyNode:function(node) {2576FS.hashRemoveNode(node);2577},isRoot:function(node) {2578return node === node.parent;2579},isMountpoint:function(node) {2580return !!node.mounted;2581},isFile:function(mode) {2582return (mode & 61440) === 32768;2583},isDir:function(mode) {2584return (mode & 61440) === 16384;2585},isLink:function(mode) {2586return (mode & 61440) === 40960;2587},isChrdev:function(mode) {2588return (mode & 61440) === 8192;2589},isBlkdev:function(mode) {2590return (mode & 61440) === 24576;2591},isFIFO:function(mode) {2592return (mode & 61440) === 4096;2593},isSocket:function(mode) {2594return (mode & 49152) === 49152;2595},flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function(str) {2596var flags = FS.flagModes[str];2597if (typeof flags === 'undefined') {2598throw new Error('Unknown file open mode: ' + str);2599}2600return flags;2601},flagsToPermissionString:function(flag) {2602var perms = ['r', 'w', 'rw'][flag & 3];2603if ((flag & 512)) {2604perms += 'w';2605}2606return perms;2607},nodePermissions:function(node, perms) {2608if (FS.ignorePermissions) {2609return 0;2610}2611// return 0 if any user, group or owner bits are set.2612if (perms.indexOf('r') !== -1 && !(node.mode & 292)) {2613return 2;2614} else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) {2615return 2;2616} else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) {2617return 2;2618}2619return 0;2620},mayLookup:function(dir) {2621var errCode = FS.nodePermissions(dir, 'x');2622if (errCode) return errCode;2623if (!dir.node_ops.lookup) return 2;2624return 0;2625},mayCreate:function(dir, name) {2626try {2627var node = FS.lookupNode(dir, name);2628return 20;2629} catch (e) {2630}2631return FS.nodePermissions(dir, 'wx');2632},mayDelete:function(dir, name, isdir) {2633var node;2634try {2635node = FS.lookupNode(dir, name);2636} catch (e) {2637return e.errno;2638}2639var errCode = FS.nodePermissions(dir, 'wx');2640if (errCode) {2641return errCode;2642}2643if (isdir) {2644if (!FS.isDir(node.mode)) {2645return 54;2646}2647if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {2648return 10;2649}2650} else {2651if (FS.isDir(node.mode)) {2652return 31;2653}2654}2655return 0;2656},mayOpen:function(node, flags) {2657if (!node) {2658return 44;2659}2660if (FS.isLink(node.mode)) {2661return 32;2662} else if (FS.isDir(node.mode)) {2663if (FS.flagsToPermissionString(flags) !== 'r' || // opening for write2664(flags & 512)) { // TODO: check for O_SEARCH? (== search for dir only)2665return 31;2666}2667}2668return FS.nodePermissions(node, FS.flagsToPermissionString(flags));2669},MAX_OPEN_FDS:4096,nextfd:function(fd_start, fd_end) {2670fd_start = fd_start || 0;2671fd_end = fd_end || FS.MAX_OPEN_FDS;2672for (var fd = fd_start; fd <= fd_end; fd++) {2673if (!FS.streams[fd]) {2674return fd;2675}2676}2677throw new FS.ErrnoError(33);2678},getStream:function(fd) {2679return FS.streams[fd];2680},createStream:function(stream, fd_start, fd_end) {2681if (!FS.FSStream) {2682FS.FSStream = /** @constructor */ function(){};2683FS.FSStream.prototype = {2684object: {2685get: function() { return this.node; },2686set: function(val) { this.node = val; }2687},2688isRead: {2689get: function() { return (this.flags & 2097155) !== 1; }2690},2691isWrite: {2692get: function() { return (this.flags & 2097155) !== 0; }2693},2694isAppend: {2695get: function() { return (this.flags & 1024); }2696}2697};2698}2699// clone it, so we can return an instance of FSStream2700var newStream = new FS.FSStream();2701for (var p in stream) {2702newStream[p] = stream[p];2703}2704stream = newStream;2705var fd = FS.nextfd(fd_start, fd_end);2706stream.fd = fd;2707FS.streams[fd] = stream;2708return stream;2709},closeStream:function(fd) {2710FS.streams[fd] = null;2711},chrdev_stream_ops:{open:function(stream) {2712var device = FS.getDevice(stream.node.rdev);2713// override node's stream ops with the device's2714stream.stream_ops = device.stream_ops;2715// forward the open call2716if (stream.stream_ops.open) {2717stream.stream_ops.open(stream);2718}2719},llseek:function() {2720throw new FS.ErrnoError(70);2721}},major:function(dev) {2722return ((dev) >> 8);2723},minor:function(dev) {2724return ((dev) & 0xff);2725},makedev:function(ma, mi) {2726return ((ma) << 8 | (mi));2727},registerDevice:function(dev, ops) {2728FS.devices[dev] = { stream_ops: ops };2729},getDevice:function(dev) {2730return FS.devices[dev];2731},getMounts:function(mount) {2732var mounts = [];2733var check = [mount];27342735while (check.length) {2736var m = check.pop();27372738mounts.push(m);27392740check.push.apply(check, m.mounts);2741}27422743return mounts;2744},syncfs:function(populate, callback) {2745if (typeof(populate) === 'function') {2746callback = populate;2747populate = false;2748}27492750FS.syncFSRequests++;27512752if (FS.syncFSRequests > 1) {2753err('warning: ' + FS.syncFSRequests + ' FS.syncfs operations in flight at once, probably just doing extra work');2754}27552756var mounts = FS.getMounts(FS.root.mount);2757var completed = 0;27582759function doCallback(errCode) {2760assert(FS.syncFSRequests > 0);2761FS.syncFSRequests--;2762return callback(errCode);2763}27642765function done(errCode) {2766if (errCode) {2767if (!done.errored) {2768done.errored = true;2769return doCallback(errCode);2770}2771return;2772}2773if (++completed >= mounts.length) {2774doCallback(null);2775}2776};27772778// sync all mounts2779mounts.forEach(function (mount) {2780if (!mount.type.syncfs) {2781return done(null);2782}2783mount.type.syncfs(mount, populate, done);2784});2785},mount:function(type, opts, mountpoint) {2786if (typeof type === 'string') {2787// The filesystem was not included, and instead we have an error2788// message stored in the variable.2789throw type;2790}2791var root = mountpoint === '/';2792var pseudo = !mountpoint;2793var node;27942795if (root && FS.root) {2796throw new FS.ErrnoError(10);2797} else if (!root && !pseudo) {2798var lookup = FS.lookupPath(mountpoint, { follow_mount: false });27992800mountpoint = lookup.path; // use the absolute path2801node = lookup.node;28022803if (FS.isMountpoint(node)) {2804throw new FS.ErrnoError(10);2805}28062807if (!FS.isDir(node.mode)) {2808throw new FS.ErrnoError(54);2809}2810}28112812var mount = {2813type: type,2814opts: opts,2815mountpoint: mountpoint,2816mounts: []2817};28182819// create a root node for the fs2820var mountRoot = type.mount(mount);2821mountRoot.mount = mount;2822mount.root = mountRoot;28232824if (root) {2825FS.root = mountRoot;2826} else if (node) {2827// set as a mountpoint2828node.mounted = mount;28292830// add the new mount to the current mount's children2831if (node.mount) {2832node.mount.mounts.push(mount);2833}2834}28352836return mountRoot;2837},unmount:function (mountpoint) {2838var lookup = FS.lookupPath(mountpoint, { follow_mount: false });28392840if (!FS.isMountpoint(lookup.node)) {2841throw new FS.ErrnoError(28);2842}28432844// destroy the nodes for this mount, and all its child mounts2845var node = lookup.node;2846var mount = node.mounted;2847var mounts = FS.getMounts(mount);28482849Object.keys(FS.nameTable).forEach(function (hash) {2850var current = FS.nameTable[hash];28512852while (current) {2853var next = current.name_next;28542855if (mounts.indexOf(current.mount) !== -1) {2856FS.destroyNode(current);2857}28582859current = next;2860}2861});28622863// no longer a mountpoint2864node.mounted = null;28652866// remove this mount from the child mounts2867var idx = node.mount.mounts.indexOf(mount);2868assert(idx !== -1);2869node.mount.mounts.splice(idx, 1);2870},lookup:function(parent, name) {2871return parent.node_ops.lookup(parent, name);2872},mknod:function(path, mode, dev) {2873var lookup = FS.lookupPath(path, { parent: true });2874var parent = lookup.node;2875var name = PATH.basename(path);2876if (!name || name === '.' || name === '..') {2877throw new FS.ErrnoError(28);2878}2879var errCode = FS.mayCreate(parent, name);2880if (errCode) {2881throw new FS.ErrnoError(errCode);2882}2883if (!parent.node_ops.mknod) {2884throw new FS.ErrnoError(63);2885}2886return parent.node_ops.mknod(parent, name, mode, dev);2887},create:function(path, mode) {2888mode = mode !== undefined ? mode : 438 /* 0666 */;2889mode &= 4095;2890mode |= 32768;2891return FS.mknod(path, mode, 0);2892},mkdir:function(path, mode) {2893mode = mode !== undefined ? mode : 511 /* 0777 */;2894mode &= 511 | 512;2895mode |= 16384;2896return FS.mknod(path, mode, 0);2897},mkdirTree:function(path, mode) {2898var dirs = path.split('/');2899var d = '';2900for (var i = 0; i < dirs.length; ++i) {2901if (!dirs[i]) continue;2902d += '/' + dirs[i];2903try {2904FS.mkdir(d, mode);2905} catch(e) {2906if (e.errno != 20) throw e;2907}2908}2909},mkdev:function(path, mode, dev) {2910if (typeof(dev) === 'undefined') {2911dev = mode;2912mode = 438 /* 0666 */;2913}2914mode |= 8192;2915return FS.mknod(path, mode, dev);2916},symlink:function(oldpath, newpath) {2917if (!PATH_FS.resolve(oldpath)) {2918throw new FS.ErrnoError(44);2919}2920var lookup = FS.lookupPath(newpath, { parent: true });2921var parent = lookup.node;2922if (!parent) {2923throw new FS.ErrnoError(44);2924}2925var newname = PATH.basename(newpath);2926var errCode = FS.mayCreate(parent, newname);2927if (errCode) {2928throw new FS.ErrnoError(errCode);2929}2930if (!parent.node_ops.symlink) {2931throw new FS.ErrnoError(63);2932}2933return parent.node_ops.symlink(parent, newname, oldpath);2934},rename:function(old_path, new_path) {2935var old_dirname = PATH.dirname(old_path);2936var new_dirname = PATH.dirname(new_path);2937var old_name = PATH.basename(old_path);2938var new_name = PATH.basename(new_path);2939// parents must exist2940var lookup, old_dir, new_dir;2941try {2942lookup = FS.lookupPath(old_path, { parent: true });2943old_dir = lookup.node;2944lookup = FS.lookupPath(new_path, { parent: true });2945new_dir = lookup.node;2946} catch (e) {2947throw new FS.ErrnoError(10);2948}2949if (!old_dir || !new_dir) throw new FS.ErrnoError(44);2950// need to be part of the same mount2951if (old_dir.mount !== new_dir.mount) {2952throw new FS.ErrnoError(75);2953}2954// source must exist2955var old_node = FS.lookupNode(old_dir, old_name);2956// old path should not be an ancestor of the new path2957var relative = PATH_FS.relative(old_path, new_dirname);2958if (relative.charAt(0) !== '.') {2959throw new FS.ErrnoError(28);2960}2961// new path should not be an ancestor of the old path2962relative = PATH_FS.relative(new_path, old_dirname);2963if (relative.charAt(0) !== '.') {2964throw new FS.ErrnoError(55);2965}2966// see if the new path already exists2967var new_node;2968try {2969new_node = FS.lookupNode(new_dir, new_name);2970} catch (e) {2971// not fatal2972}2973// early out if nothing needs to change2974if (old_node === new_node) {2975return;2976}2977// we'll need to delete the old entry2978var isdir = FS.isDir(old_node.mode);2979var errCode = FS.mayDelete(old_dir, old_name, isdir);2980if (errCode) {2981throw new FS.ErrnoError(errCode);2982}2983// need delete permissions if we'll be overwriting.2984// need create permissions if new doesn't already exist.2985errCode = new_node ?2986FS.mayDelete(new_dir, new_name, isdir) :2987FS.mayCreate(new_dir, new_name);2988if (errCode) {2989throw new FS.ErrnoError(errCode);2990}2991if (!old_dir.node_ops.rename) {2992throw new FS.ErrnoError(63);2993}2994if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {2995throw new FS.ErrnoError(10);2996}2997// if we are going to change the parent, check write permissions2998if (new_dir !== old_dir) {2999errCode = FS.nodePermissions(old_dir, 'w');3000if (errCode) {3001throw new FS.ErrnoError(errCode);3002}3003}3004try {3005if (FS.trackingDelegate['willMovePath']) {3006FS.trackingDelegate['willMovePath'](old_path, new_path);3007}3008} catch(e) {3009err("FS.trackingDelegate['willMovePath']('"+old_path+"', '"+new_path+"') threw an exception: " + e.message);3010}3011// remove the node from the lookup hash3012FS.hashRemoveNode(old_node);3013// do the underlying fs rename3014try {3015old_dir.node_ops.rename(old_node, new_dir, new_name);3016} catch (e) {3017throw e;3018} finally {3019// add the node back to the hash (in case node_ops.rename3020// changed its name)3021FS.hashAddNode(old_node);3022}3023try {3024if (FS.trackingDelegate['onMovePath']) FS.trackingDelegate['onMovePath'](old_path, new_path);3025} catch(e) {3026err("FS.trackingDelegate['onMovePath']('"+old_path+"', '"+new_path+"') threw an exception: " + e.message);3027}3028},rmdir:function(path) {3029var lookup = FS.lookupPath(path, { parent: true });3030var parent = lookup.node;3031var name = PATH.basename(path);3032var node = FS.lookupNode(parent, name);3033var errCode = FS.mayDelete(parent, name, true);3034if (errCode) {3035throw new FS.ErrnoError(errCode);3036}3037if (!parent.node_ops.rmdir) {3038throw new FS.ErrnoError(63);3039}3040if (FS.isMountpoint(node)) {3041throw new FS.ErrnoError(10);3042}3043try {3044if (FS.trackingDelegate['willDeletePath']) {3045FS.trackingDelegate['willDeletePath'](path);3046}3047} catch(e) {3048err("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: " + e.message);3049}3050parent.node_ops.rmdir(parent, name);3051FS.destroyNode(node);3052try {3053if (FS.trackingDelegate['onDeletePath']) FS.trackingDelegate['onDeletePath'](path);3054} catch(e) {3055err("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: " + e.message);3056}3057},readdir:function(path) {3058var lookup = FS.lookupPath(path, { follow: true });3059var node = lookup.node;3060if (!node.node_ops.readdir) {3061throw new FS.ErrnoError(54);3062}3063return node.node_ops.readdir(node);3064},unlink:function(path) {3065var lookup = FS.lookupPath(path, { parent: true });3066var parent = lookup.node;3067var name = PATH.basename(path);3068var node = FS.lookupNode(parent, name);3069var errCode = FS.mayDelete(parent, name, false);3070if (errCode) {3071// According to POSIX, we should map EISDIR to EPERM, but3072// we instead do what Linux does (and we must, as we use3073// the musl linux libc).3074throw new FS.ErrnoError(errCode);3075}3076if (!parent.node_ops.unlink) {3077throw new FS.ErrnoError(63);3078}3079if (FS.isMountpoint(node)) {3080throw new FS.ErrnoError(10);3081}3082try {3083if (FS.trackingDelegate['willDeletePath']) {3084FS.trackingDelegate['willDeletePath'](path);3085}3086} catch(e) {3087err("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: " + e.message);3088}3089parent.node_ops.unlink(parent, name);3090FS.destroyNode(node);3091try {3092if (FS.trackingDelegate['onDeletePath']) FS.trackingDelegate['onDeletePath'](path);3093} catch(e) {3094err("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: " + e.message);3095}3096},readlink:function(path) {3097var lookup = FS.lookupPath(path);3098var link = lookup.node;3099if (!link) {3100throw new FS.ErrnoError(44);3101}3102if (!link.node_ops.readlink) {3103throw new FS.ErrnoError(28);3104}3105return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link));3106},stat:function(path, dontFollow) {3107var lookup = FS.lookupPath(path, { follow: !dontFollow });3108var node = lookup.node;3109if (!node) {3110throw new FS.ErrnoError(44);3111}3112if (!node.node_ops.getattr) {3113throw new FS.ErrnoError(63);3114}3115return node.node_ops.getattr(node);3116},lstat:function(path) {3117return FS.stat(path, true);3118},chmod:function(path, mode, dontFollow) {3119var node;3120if (typeof path === 'string') {3121var lookup = FS.lookupPath(path, { follow: !dontFollow });3122node = lookup.node;3123} else {3124node = path;3125}3126if (!node.node_ops.setattr) {3127throw new FS.ErrnoError(63);3128}3129node.node_ops.setattr(node, {3130mode: (mode & 4095) | (node.mode & ~4095),3131timestamp: Date.now()3132});3133},lchmod:function(path, mode) {3134FS.chmod(path, mode, true);3135},fchmod:function(fd, mode) {3136var stream = FS.getStream(fd);3137if (!stream) {3138throw new FS.ErrnoError(8);3139}3140FS.chmod(stream.node, mode);3141},chown:function(path, uid, gid, dontFollow) {3142var node;3143if (typeof path === 'string') {3144var lookup = FS.lookupPath(path, { follow: !dontFollow });3145node = lookup.node;3146} else {3147node = path;3148}3149if (!node.node_ops.setattr) {3150throw new FS.ErrnoError(63);3151}3152node.node_ops.setattr(node, {3153timestamp: Date.now()3154// we ignore the uid / gid for now3155});3156},lchown:function(path, uid, gid) {3157FS.chown(path, uid, gid, true);3158},fchown:function(fd, uid, gid) {3159var stream = FS.getStream(fd);3160if (!stream) {3161throw new FS.ErrnoError(8);3162}3163FS.chown(stream.node, uid, gid);3164},truncate:function(path, len) {3165if (len < 0) {3166throw new FS.ErrnoError(28);3167}3168var node;3169if (typeof path === 'string') {3170var lookup = FS.lookupPath(path, { follow: true });3171node = lookup.node;3172} else {3173node = path;3174}3175if (!node.node_ops.setattr) {3176throw new FS.ErrnoError(63);3177}3178if (FS.isDir(node.mode)) {3179throw new FS.ErrnoError(31);3180}3181if (!FS.isFile(node.mode)) {3182throw new FS.ErrnoError(28);3183}3184var errCode = FS.nodePermissions(node, 'w');3185if (errCode) {3186throw new FS.ErrnoError(errCode);3187}3188node.node_ops.setattr(node, {3189size: len,3190timestamp: Date.now()3191});3192},ftruncate:function(fd, len) {3193var stream = FS.getStream(fd);3194if (!stream) {3195throw new FS.ErrnoError(8);3196}3197if ((stream.flags & 2097155) === 0) {3198throw new FS.ErrnoError(28);3199}3200FS.truncate(stream.node, len);3201},utime:function(path, atime, mtime) {3202var lookup = FS.lookupPath(path, { follow: true });3203var node = lookup.node;3204node.node_ops.setattr(node, {3205timestamp: Math.max(atime, mtime)3206});3207},open:function(path, flags, mode, fd_start, fd_end) {3208if (path === "") {3209throw new FS.ErrnoError(44);3210}3211flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;3212mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode;3213if ((flags & 64)) {3214mode = (mode & 4095) | 32768;3215} else {3216mode = 0;3217}3218var node;3219if (typeof path === 'object') {3220node = path;3221} else {3222path = PATH.normalize(path);3223try {3224var lookup = FS.lookupPath(path, {3225follow: !(flags & 131072)3226});3227node = lookup.node;3228} catch (e) {3229// ignore3230}3231}3232// perhaps we need to create the node3233var created = false;3234if ((flags & 64)) {3235if (node) {3236// if O_CREAT and O_EXCL are set, error out if the node already exists3237if ((flags & 128)) {3238throw new FS.ErrnoError(20);3239}3240} else {3241// node doesn't exist, try to create it3242node = FS.mknod(path, mode, 0);3243created = true;3244}3245}3246if (!node) {3247throw new FS.ErrnoError(44);3248}3249// can't truncate a device3250if (FS.isChrdev(node.mode)) {3251flags &= ~512;3252}3253// if asked only for a directory, then this must be one3254if ((flags & 65536) && !FS.isDir(node.mode)) {3255throw new FS.ErrnoError(54);3256}3257// check permissions, if this is not a file we just created now (it is ok to3258// create and write to a file with read-only permissions; it is read-only3259// for later use)3260if (!created) {3261var errCode = FS.mayOpen(node, flags);3262if (errCode) {3263throw new FS.ErrnoError(errCode);3264}3265}3266// do truncation if necessary3267if ((flags & 512)) {3268FS.truncate(node, 0);3269}3270// we've already handled these, don't pass down to the underlying vfs3271flags &= ~(128 | 512);32723273// register the stream with the filesystem3274var stream = FS.createStream({3275node: node,3276path: FS.getPath(node), // we want the absolute path to the node3277flags: flags,3278seekable: true,3279position: 0,3280stream_ops: node.stream_ops,3281// used by the file family libc calls (fopen, fwrite, ferror, etc.)3282ungotten: [],3283error: false3284}, fd_start, fd_end);3285// call the new stream's open function3286if (stream.stream_ops.open) {3287stream.stream_ops.open(stream);3288}3289if (Module['logReadFiles'] && !(flags & 1)) {3290if (!FS.readFiles) FS.readFiles = {};3291if (!(path in FS.readFiles)) {3292FS.readFiles[path] = 1;3293err("FS.trackingDelegate error on read file: " + path);3294}3295}3296try {3297if (FS.trackingDelegate['onOpenFile']) {3298var trackingFlags = 0;3299if ((flags & 2097155) !== 1) {3300trackingFlags |= FS.tracking.openFlags.READ;3301}3302if ((flags & 2097155) !== 0) {3303trackingFlags |= FS.tracking.openFlags.WRITE;3304}3305FS.trackingDelegate['onOpenFile'](path, trackingFlags);3306}3307} catch(e) {3308err("FS.trackingDelegate['onOpenFile']('"+path+"', flags) threw an exception: " + e.message);3309}3310return stream;3311},close:function(stream) {3312if (FS.isClosed(stream)) {3313throw new FS.ErrnoError(8);3314}3315if (stream.getdents) stream.getdents = null; // free readdir state3316try {3317if (stream.stream_ops.close) {3318stream.stream_ops.close(stream);3319}3320} catch (e) {3321throw e;3322} finally {3323FS.closeStream(stream.fd);3324}3325stream.fd = null;3326},isClosed:function(stream) {3327return stream.fd === null;3328},llseek:function(stream, offset, whence) {3329if (FS.isClosed(stream)) {3330throw new FS.ErrnoError(8);3331}3332if (!stream.seekable || !stream.stream_ops.llseek) {3333throw new FS.ErrnoError(70);3334}3335if (whence != 0 && whence != 1 && whence != 2) {3336throw new FS.ErrnoError(28);3337}3338stream.position = stream.stream_ops.llseek(stream, offset, whence);3339stream.ungotten = [];3340return stream.position;3341},read:function(stream, buffer, offset, length, position) {3342if (length < 0 || position < 0) {3343throw new FS.ErrnoError(28);3344}3345if (FS.isClosed(stream)) {3346throw new FS.ErrnoError(8);3347}3348if ((stream.flags & 2097155) === 1) {3349throw new FS.ErrnoError(8);3350}3351if (FS.isDir(stream.node.mode)) {3352throw new FS.ErrnoError(31);3353}3354if (!stream.stream_ops.read) {3355throw new FS.ErrnoError(28);3356}3357var seeking = typeof position !== 'undefined';3358if (!seeking) {3359position = stream.position;3360} else if (!stream.seekable) {3361throw new FS.ErrnoError(70);3362}3363var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);3364if (!seeking) stream.position += bytesRead;3365return bytesRead;3366},write:function(stream, buffer, offset, length, position, canOwn) {3367if (length < 0 || position < 0) {3368throw new FS.ErrnoError(28);3369}3370if (FS.isClosed(stream)) {3371throw new FS.ErrnoError(8);3372}3373if ((stream.flags & 2097155) === 0) {3374throw new FS.ErrnoError(8);3375}3376if (FS.isDir(stream.node.mode)) {3377throw new FS.ErrnoError(31);3378}3379if (!stream.stream_ops.write) {3380throw new FS.ErrnoError(28);3381}3382if (stream.flags & 1024) {3383// seek to the end before writing in append mode3384FS.llseek(stream, 0, 2);3385}3386var seeking = typeof position !== 'undefined';3387if (!seeking) {3388position = stream.position;3389} else if (!stream.seekable) {3390throw new FS.ErrnoError(70);3391}3392var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);3393if (!seeking) stream.position += bytesWritten;3394try {3395if (stream.path && FS.trackingDelegate['onWriteToFile']) FS.trackingDelegate['onWriteToFile'](stream.path);3396} catch(e) {3397err("FS.trackingDelegate['onWriteToFile']('"+stream.path+"') threw an exception: " + e.message);3398}3399return bytesWritten;3400},allocate:function(stream, offset, length) {3401if (FS.isClosed(stream)) {3402throw new FS.ErrnoError(8);3403}3404if (offset < 0 || length <= 0) {3405throw new FS.ErrnoError(28);3406}3407if ((stream.flags & 2097155) === 0) {3408throw new FS.ErrnoError(8);3409}3410if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) {3411throw new FS.ErrnoError(43);3412}3413if (!stream.stream_ops.allocate) {3414throw new FS.ErrnoError(138);3415}3416stream.stream_ops.allocate(stream, offset, length);3417},mmap:function(stream, buffer, offset, length, position, prot, flags) {3418// User requests writing to file (prot & PROT_WRITE != 0).3419// Checking if we have permissions to write to the file unless3420// MAP_PRIVATE flag is set. According to POSIX spec it is possible3421// to write to file opened in read-only mode with MAP_PRIVATE flag,3422// as all modifications will be visible only in the memory of3423// the current process.3424if ((prot & 2) !== 03425&& (flags & 2) === 03426&& (stream.flags & 2097155) !== 2) {3427throw new FS.ErrnoError(2);3428}3429if ((stream.flags & 2097155) === 1) {3430throw new FS.ErrnoError(2);3431}3432if (!stream.stream_ops.mmap) {3433throw new FS.ErrnoError(43);3434}3435return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags);3436},msync:function(stream, buffer, offset, length, mmapFlags) {3437if (!stream || !stream.stream_ops.msync) {3438return 0;3439}3440return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags);3441},munmap:function(stream) {3442return 0;3443},ioctl:function(stream, cmd, arg) {3444if (!stream.stream_ops.ioctl) {3445throw new FS.ErrnoError(59);3446}3447return stream.stream_ops.ioctl(stream, cmd, arg);3448},readFile:function(path, opts) {3449opts = opts || {};3450opts.flags = opts.flags || 'r';3451opts.encoding = opts.encoding || 'binary';3452if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {3453throw new Error('Invalid encoding type "' + opts.encoding + '"');3454}3455var ret;3456var stream = FS.open(path, opts.flags);3457var stat = FS.stat(path);3458var length = stat.size;3459var buf = new Uint8Array(length);3460FS.read(stream, buf, 0, length, 0);3461if (opts.encoding === 'utf8') {3462ret = UTF8ArrayToString(buf, 0);3463} else if (opts.encoding === 'binary') {3464ret = buf;3465}3466FS.close(stream);3467return ret;3468},writeFile:function(path, data, opts) {3469opts = opts || {};3470opts.flags = opts.flags || 'w';3471var stream = FS.open(path, opts.flags, opts.mode);3472if (typeof data === 'string') {3473var buf = new Uint8Array(lengthBytesUTF8(data)+1);3474var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length);3475FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn);3476} else if (ArrayBuffer.isView(data)) {3477FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);3478} else {3479throw new Error('Unsupported data type');3480}3481FS.close(stream);3482},cwd:function() {3483return FS.currentPath;3484},chdir:function(path) {3485var lookup = FS.lookupPath(path, { follow: true });3486if (lookup.node === null) {3487throw new FS.ErrnoError(44);3488}3489if (!FS.isDir(lookup.node.mode)) {3490throw new FS.ErrnoError(54);3491}3492var errCode = FS.nodePermissions(lookup.node, 'x');3493if (errCode) {3494throw new FS.ErrnoError(errCode);3495}3496FS.currentPath = lookup.path;3497},createDefaultDirectories:function() {3498FS.mkdir('/tmp');3499FS.mkdir('/home');3500FS.mkdir('/home/web_user');3501},createDefaultDevices:function() {3502// create /dev3503FS.mkdir('/dev');3504// setup /dev/null3505FS.registerDevice(FS.makedev(1, 3), {3506read: function() { return 0; },3507write: function(stream, buffer, offset, length, pos) { return length; }3508});3509FS.mkdev('/dev/null', FS.makedev(1, 3));3510// setup /dev/tty and /dev/tty13511// stderr needs to print output using Module['printErr']3512// so we register a second tty just for it.3513TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);3514TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);3515FS.mkdev('/dev/tty', FS.makedev(5, 0));3516FS.mkdev('/dev/tty1', FS.makedev(6, 0));3517// setup /dev/[u]random3518var random_device;3519if (typeof crypto === 'object' && typeof crypto['getRandomValues'] === 'function') {3520// for modern web browsers3521var randomBuffer = new Uint8Array(1);3522random_device = function() { crypto.getRandomValues(randomBuffer); return randomBuffer[0]; };3523} else3524if (ENVIRONMENT_IS_NODE) {3525// for nodejs with or without crypto support included3526try {3527var crypto_module = require('crypto');3528// nodejs has crypto support3529random_device = function() { return crypto_module['randomBytes'](1)[0]; };3530} catch (e) {3531// nodejs doesn't have crypto support3532}3533} else3534{}3535if (!random_device) {3536// we couldn't find a proper implementation, as Math.random() is not suitable for /dev/random, see emscripten-core/emscripten/pull/70963537random_device = function() { abort("no cryptographic support found for random_device. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };"); };3538}3539FS.createDevice('/dev', 'random', random_device);3540FS.createDevice('/dev', 'urandom', random_device);3541// we're not going to emulate the actual shm device,3542// just create the tmp dirs that reside in it commonly3543FS.mkdir('/dev/shm');3544FS.mkdir('/dev/shm/tmp');3545},createSpecialDirectories:function() {3546// create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the name of the stream for fd 6 (see test_unistd_ttyname)3547FS.mkdir('/proc');3548FS.mkdir('/proc/self');3549FS.mkdir('/proc/self/fd');3550FS.mount({3551mount: function() {3552var node = FS.createNode('/proc/self', 'fd', 16384 | 511 /* 0777 */, 73);3553node.node_ops = {3554lookup: function(parent, name) {3555var fd = +name;3556var stream = FS.getStream(fd);3557if (!stream) throw new FS.ErrnoError(8);3558var ret = {3559parent: null,3560mount: { mountpoint: 'fake' },3561node_ops: { readlink: function() { return stream.path } }3562};3563ret.parent = ret; // make it look like a simple root node3564return ret;3565}3566};3567return node;3568}3569}, {}, '/proc/self/fd');3570},createStandardStreams:function() {3571// TODO deprecate the old functionality of a single3572// input / output callback and that utilizes FS.createDevice3573// and instead require a unique set of stream ops35743575// by default, we symlink the standard streams to the3576// default tty devices. however, if the standard streams3577// have been overwritten we create a unique device for3578// them instead.3579if (Module['stdin']) {3580FS.createDevice('/dev', 'stdin', Module['stdin']);3581} else {3582FS.symlink('/dev/tty', '/dev/stdin');3583}3584if (Module['stdout']) {3585FS.createDevice('/dev', 'stdout', null, Module['stdout']);3586} else {3587FS.symlink('/dev/tty', '/dev/stdout');3588}3589if (Module['stderr']) {3590FS.createDevice('/dev', 'stderr', null, Module['stderr']);3591} else {3592FS.symlink('/dev/tty1', '/dev/stderr');3593}35943595// open default streams for the stdin, stdout and stderr devices3596var stdin = FS.open('/dev/stdin', 'r');3597var stdout = FS.open('/dev/stdout', 'w');3598var stderr = FS.open('/dev/stderr', 'w');3599assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');3600assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');3601assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');3602},ensureErrnoError:function() {3603if (FS.ErrnoError) return;3604FS.ErrnoError = /** @this{Object} */ function ErrnoError(errno, node) {3605this.node = node;3606this.setErrno = /** @this{Object} */ function(errno) {3607this.errno = errno;3608for (var key in ERRNO_CODES) {3609if (ERRNO_CODES[key] === errno) {3610this.code = key;3611break;3612}3613}3614};3615this.setErrno(errno);3616this.message = ERRNO_MESSAGES[errno];36173618// Try to get a maximally helpful stack trace. On Node.js, getting Error.stack3619// now ensures it shows what we want.3620if (this.stack) {3621// Define the stack property for Node.js 4, which otherwise errors on the next line.3622Object.defineProperty(this, "stack", { value: (new Error).stack, writable: true });3623this.stack = demangleAll(this.stack);3624}3625};3626FS.ErrnoError.prototype = new Error();3627FS.ErrnoError.prototype.constructor = FS.ErrnoError;3628// Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)3629[44].forEach(function(code) {3630FS.genericErrors[code] = new FS.ErrnoError(code);3631FS.genericErrors[code].stack = '<generic error, no stack>';3632});3633},staticInit:function() {3634FS.ensureErrnoError();36353636FS.nameTable = new Array(4096);36373638FS.mount(MEMFS, {}, '/');36393640FS.createDefaultDirectories();3641FS.createDefaultDevices();3642FS.createSpecialDirectories();36433644FS.filesystems = {3645'MEMFS': MEMFS,3646};3647},init:function(input, output, error) {3648assert(!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)');3649FS.init.initialized = true;36503651FS.ensureErrnoError();36523653// Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here3654Module['stdin'] = input || Module['stdin'];3655Module['stdout'] = output || Module['stdout'];3656Module['stderr'] = error || Module['stderr'];36573658FS.createStandardStreams();3659},quit:function() {3660FS.init.initialized = false;3661// force-flush all streams, so we get musl std streams printed out3662var fflush = Module['_fflush'];3663if (fflush) fflush(0);3664// close all of our streams3665for (var i = 0; i < FS.streams.length; i++) {3666var stream = FS.streams[i];3667if (!stream) {3668continue;3669}3670FS.close(stream);3671}3672},getMode:function(canRead, canWrite) {3673var mode = 0;3674if (canRead) mode |= 292 | 73;3675if (canWrite) mode |= 146;3676return mode;3677},joinPath:function(parts, forceRelative) {3678var path = PATH.join.apply(null, parts);3679if (forceRelative && path[0] == '/') path = path.substr(1);3680return path;3681},absolutePath:function(relative, base) {3682return PATH_FS.resolve(base, relative);3683},standardizePath:function(path) {3684return PATH.normalize(path);3685},findObject:function(path, dontResolveLastLink) {3686var ret = FS.analyzePath(path, dontResolveLastLink);3687if (ret.exists) {3688return ret.object;3689} else {3690___setErrNo(ret.error);3691return null;3692}3693},analyzePath:function(path, dontResolveLastLink) {3694// operate from within the context of the symlink's target3695try {3696var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });3697path = lookup.path;3698} catch (e) {3699}3700var ret = {3701isRoot: false, exists: false, error: 0, name: null, path: null, object: null,3702parentExists: false, parentPath: null, parentObject: null3703};3704try {3705var lookup = FS.lookupPath(path, { parent: true });3706ret.parentExists = true;3707ret.parentPath = lookup.path;3708ret.parentObject = lookup.node;3709ret.name = PATH.basename(path);3710lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });3711ret.exists = true;3712ret.path = lookup.path;3713ret.object = lookup.node;3714ret.name = lookup.node.name;3715ret.isRoot = lookup.path === '/';3716} catch (e) {3717ret.error = e.errno;3718};3719return ret;3720},createFolder:function(parent, name, canRead, canWrite) {3721var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);3722var mode = FS.getMode(canRead, canWrite);3723return FS.mkdir(path, mode);3724},createPath:function(parent, path, canRead, canWrite) {3725parent = typeof parent === 'string' ? parent : FS.getPath(parent);3726var parts = path.split('/').reverse();3727while (parts.length) {3728var part = parts.pop();3729if (!part) continue;3730var current = PATH.join2(parent, part);3731try {3732FS.mkdir(current);3733} catch (e) {3734// ignore EEXIST3735}3736parent = current;3737}3738return current;3739},createFile:function(parent, name, properties, canRead, canWrite) {3740var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);3741var mode = FS.getMode(canRead, canWrite);3742return FS.create(path, mode);3743},createDataFile:function(parent, name, data, canRead, canWrite, canOwn) {3744var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent;3745var mode = FS.getMode(canRead, canWrite);3746var node = FS.create(path, mode);3747if (data) {3748if (typeof data === 'string') {3749var arr = new Array(data.length);3750for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);3751data = arr;3752}3753// make sure we can write to the file3754FS.chmod(node, mode | 146);3755var stream = FS.open(node, 'w');3756FS.write(stream, data, 0, data.length, 0, canOwn);3757FS.close(stream);3758FS.chmod(node, mode);3759}3760return node;3761},createDevice:function(parent, name, input, output) {3762var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);3763var mode = FS.getMode(!!input, !!output);3764if (!FS.createDevice.major) FS.createDevice.major = 64;3765var dev = FS.makedev(FS.createDevice.major++, 0);3766// Create a fake device that a set of stream ops to emulate3767// the old behavior.3768FS.registerDevice(dev, {3769open: function(stream) {3770stream.seekable = false;3771},3772close: function(stream) {3773// flush any pending line data3774if (output && output.buffer && output.buffer.length) {3775output(10);3776}3777},3778read: function(stream, buffer, offset, length, pos /* ignored */) {3779var bytesRead = 0;3780for (var i = 0; i < length; i++) {3781var result;3782try {3783result = input();3784} catch (e) {3785throw new FS.ErrnoError(29);3786}3787if (result === undefined && bytesRead === 0) {3788throw new FS.ErrnoError(6);3789}3790if (result === null || result === undefined) break;3791bytesRead++;3792buffer[offset+i] = result;3793}3794if (bytesRead) {3795stream.node.timestamp = Date.now();3796}3797return bytesRead;3798},3799write: function(stream, buffer, offset, length, pos) {3800for (var i = 0; i < length; i++) {3801try {3802output(buffer[offset+i]);3803} catch (e) {3804throw new FS.ErrnoError(29);3805}3806}3807if (length) {3808stream.node.timestamp = Date.now();3809}3810return i;3811}3812});3813return FS.mkdev(path, mode, dev);3814},createLink:function(parent, name, target, canRead, canWrite) {3815var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);3816return FS.symlink(target, path);3817},forceLoadFile:function(obj) {3818if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;3819var success = true;3820if (typeof XMLHttpRequest !== 'undefined') {3821throw 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.");3822} else if (read_) {3823// Command-line.3824try {3825// WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as3826// read() will try to parse UTF8.3827obj.contents = intArrayFromString(read_(obj.url), true);3828obj.usedBytes = obj.contents.length;3829} catch (e) {3830success = false;3831}3832} else {3833throw new Error('Cannot load without read() or XMLHttpRequest.');3834}3835if (!success) ___setErrNo(29);3836return success;3837},createLazyFile:function(parent, name, url, canRead, canWrite) {3838// Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.3839/** @constructor */3840function LazyUint8Array() {3841this.lengthKnown = false;3842this.chunks = []; // Loaded chunks. Index is the chunk number3843}3844LazyUint8Array.prototype.get = /** @this{Object} */ function LazyUint8Array_get(idx) {3845if (idx > this.length-1 || idx < 0) {3846return undefined;3847}3848var chunkOffset = idx % this.chunkSize;3849var chunkNum = (idx / this.chunkSize)|0;3850return this.getter(chunkNum)[chunkOffset];3851};3852LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {3853this.getter = getter;3854};3855LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {3856// Find length3857var xhr = new XMLHttpRequest();3858xhr.open('HEAD', url, false);3859xhr.send(null);3860if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);3861var datalength = Number(xhr.getResponseHeader("Content-length"));3862var header;3863var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";3864var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";38653866var chunkSize = 1024*1024; // Chunk size in bytes38673868if (!hasByteServing) chunkSize = datalength;38693870// Function to get a range from the remote URL.3871var doXHR = (function(from, to) {3872if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");3873if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");38743875// TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.3876var xhr = new XMLHttpRequest();3877xhr.open('GET', url, false);3878if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);38793880// Some hints to the browser that we want binary data.3881if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';3882if (xhr.overrideMimeType) {3883xhr.overrideMimeType('text/plain; charset=x-user-defined');3884}38853886xhr.send(null);3887if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);3888if (xhr.response !== undefined) {3889return new Uint8Array(/** @type{Array<number>} */(xhr.response || []));3890} else {3891return intArrayFromString(xhr.responseText || '', true);3892}3893});3894var lazyArray = this;3895lazyArray.setDataGetter(function(chunkNum) {3896var start = chunkNum * chunkSize;3897var end = (chunkNum+1) * chunkSize - 1; // including this byte3898end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block3899if (typeof(lazyArray.chunks[chunkNum]) === "undefined") {3900lazyArray.chunks[chunkNum] = doXHR(start, end);3901}3902if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!");3903return lazyArray.chunks[chunkNum];3904});39053906if (usesGzip || !datalength) {3907// if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length3908chunkSize = datalength = 1; // this will force getter(0)/doXHR do download the whole file3909datalength = this.getter(0).length;3910chunkSize = datalength;3911out("LazyFiles on gzip forces download of the whole file when length is accessed");3912}39133914this._length = datalength;3915this._chunkSize = chunkSize;3916this.lengthKnown = true;3917};3918if (typeof XMLHttpRequest !== 'undefined') {3919if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';3920var lazyArray = new LazyUint8Array();3921Object.defineProperties(lazyArray, {3922length: {3923get: /** @this{Object} */ function() {3924if(!this.lengthKnown) {3925this.cacheLength();3926}3927return this._length;3928}3929},3930chunkSize: {3931get: /** @this{Object} */ function() {3932if(!this.lengthKnown) {3933this.cacheLength();3934}3935return this._chunkSize;3936}3937}3938});39393940var properties = { isDevice: false, contents: lazyArray };3941} else {3942var properties = { isDevice: false, url: url };3943}39443945var node = FS.createFile(parent, name, properties, canRead, canWrite);3946// This is a total hack, but I want to get this lazy file code out of the3947// core of MEMFS. If we want to keep this lazy file concept I feel it should3948// be its own thin LAZYFS proxying calls to MEMFS.3949if (properties.contents) {3950node.contents = properties.contents;3951} else if (properties.url) {3952node.contents = null;3953node.url = properties.url;3954}3955// Add a function that defers querying the file size until it is asked the first time.3956Object.defineProperties(node, {3957usedBytes: {3958get: /** @this {FSNode} */ function() { return this.contents.length; }3959}3960});3961// override each stream op with one that tries to force load the lazy file first3962var stream_ops = {};3963var keys = Object.keys(node.stream_ops);3964keys.forEach(function(key) {3965var fn = node.stream_ops[key];3966stream_ops[key] = function forceLoadLazyFile() {3967if (!FS.forceLoadFile(node)) {3968throw new FS.ErrnoError(29);3969}3970return fn.apply(null, arguments);3971};3972});3973// use a custom read function3974stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) {3975if (!FS.forceLoadFile(node)) {3976throw new FS.ErrnoError(29);3977}3978var contents = stream.node.contents;3979if (position >= contents.length)3980return 0;3981var size = Math.min(contents.length - position, length);3982assert(size >= 0);3983if (contents.slice) { // normal array3984for (var i = 0; i < size; i++) {3985buffer[offset + i] = contents[position + i];3986}3987} else {3988for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR3989buffer[offset + i] = contents.get(position + i);3990}3991}3992return size;3993};3994node.stream_ops = stream_ops;3995return node;3996},createPreloadedFile:function(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) {3997Browser.init(); // XXX perhaps this method should move onto Browser?3998// TODO we should allow people to just pass in a complete filename instead3999// of parent and name being that we just join them anyways4000var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;4001var dep = getUniqueRunDependency('cp ' + fullname); // might have several active requests for the same fullname4002function processData(byteArray) {4003function finish(byteArray) {4004if (preFinish) preFinish();4005if (!dontCreateFile) {4006FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);4007}4008if (onload) onload();4009removeRunDependency(dep);4010}4011var handled = false;4012Module['preloadPlugins'].forEach(function(plugin) {4013if (handled) return;4014if (plugin['canHandle'](fullname)) {4015plugin['handle'](byteArray, fullname, finish, function() {4016if (onerror) onerror();4017removeRunDependency(dep);4018});4019handled = true;4020}4021});4022if (!handled) finish(byteArray);4023}4024addRunDependency(dep);4025if (typeof url == 'string') {4026Browser.asyncLoad(url, function(byteArray) {4027processData(byteArray);4028}, onerror);4029} else {4030processData(url);4031}4032},indexedDB:function() {4033return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;4034},DB_NAME:function() {4035return 'EM_FS_' + window.location.pathname;4036},DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function(paths, onload, onerror) {4037onload = onload || function(){};4038onerror = onerror || function(){};4039var indexedDB = FS.indexedDB();4040try {4041var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);4042} catch (e) {4043return onerror(e);4044}4045openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {4046out('creating db');4047var db = openRequest.result;4048db.createObjectStore(FS.DB_STORE_NAME);4049};4050openRequest.onsuccess = function openRequest_onsuccess() {4051var db = openRequest.result;4052var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');4053var files = transaction.objectStore(FS.DB_STORE_NAME);4054var ok = 0, fail = 0, total = paths.length;4055function finish() {4056if (fail == 0) onload(); else onerror();4057}4058paths.forEach(function(path) {4059var putRequest = files.put(FS.analyzePath(path).object.contents, path);4060putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() };4061putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() };4062});4063transaction.onerror = onerror;4064};4065openRequest.onerror = onerror;4066},loadFilesFromDB:function(paths, onload, onerror) {4067onload = onload || function(){};4068onerror = onerror || function(){};4069var indexedDB = FS.indexedDB();4070try {4071var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);4072} catch (e) {4073return onerror(e);4074}4075openRequest.onupgradeneeded = onerror; // no database to load from4076openRequest.onsuccess = function openRequest_onsuccess() {4077var db = openRequest.result;4078try {4079var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');4080} catch(e) {4081onerror(e);4082return;4083}4084var files = transaction.objectStore(FS.DB_STORE_NAME);4085var ok = 0, fail = 0, total = paths.length;4086function finish() {4087if (fail == 0) onload(); else onerror();4088}4089paths.forEach(function(path) {4090var getRequest = files.get(path);4091getRequest.onsuccess = function getRequest_onsuccess() {4092if (FS.analyzePath(path).exists) {4093FS.unlink(path);4094}4095FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);4096ok++;4097if (ok + fail == total) finish();4098};4099getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() };4100});4101transaction.onerror = onerror;4102};4103openRequest.onerror = onerror;4104}};var SYSCALLS={mappings:{},DEFAULT_POLLMASK:5,umask:511,calculateAt:function(dirfd, path) {4105if (path[0] !== '/') {4106// relative path4107var dir;4108if (dirfd === -100) {4109dir = FS.cwd();4110} else {4111var dirstream = FS.getStream(dirfd);4112if (!dirstream) throw new FS.ErrnoError(8);4113dir = dirstream.path;4114}4115path = PATH.join2(dir, path);4116}4117return path;4118},doStat:function(func, path, buf) {4119try {4120var stat = func(path);4121} catch (e) {4122if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) {4123// an error occurred while trying to look up the path; we should just report ENOTDIR4124return -54;4125}4126throw e;4127}4128HEAP32[((buf)>>2)]=stat.dev;4129HEAP32[(((buf)+(4))>>2)]=0;4130HEAP32[(((buf)+(8))>>2)]=stat.ino;4131HEAP32[(((buf)+(12))>>2)]=stat.mode;4132HEAP32[(((buf)+(16))>>2)]=stat.nlink;4133HEAP32[(((buf)+(20))>>2)]=stat.uid;4134HEAP32[(((buf)+(24))>>2)]=stat.gid;4135HEAP32[(((buf)+(28))>>2)]=stat.rdev;4136HEAP32[(((buf)+(32))>>2)]=0;4137(tempI64 = [stat.size>>>0,(tempDouble=stat.size,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(40))>>2)]=tempI64[0],HEAP32[(((buf)+(44))>>2)]=tempI64[1]);4138HEAP32[(((buf)+(48))>>2)]=4096;4139HEAP32[(((buf)+(52))>>2)]=stat.blocks;4140HEAP32[(((buf)+(56))>>2)]=(stat.atime.getTime() / 1000)|0;4141HEAP32[(((buf)+(60))>>2)]=0;4142HEAP32[(((buf)+(64))>>2)]=(stat.mtime.getTime() / 1000)|0;4143HEAP32[(((buf)+(68))>>2)]=0;4144HEAP32[(((buf)+(72))>>2)]=(stat.ctime.getTime() / 1000)|0;4145HEAP32[(((buf)+(76))>>2)]=0;4146(tempI64 = [stat.ino>>>0,(tempDouble=stat.ino,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(80))>>2)]=tempI64[0],HEAP32[(((buf)+(84))>>2)]=tempI64[1]);4147return 0;4148},doMsync:function(addr, stream, len, flags, offset) {4149var buffer = HEAPU8.slice(addr, addr + len);4150FS.msync(stream, buffer, offset, len, flags);4151},doMkdir:function(path, mode) {4152// remove a trailing slash, if one - /a/b/ has basename of '', but4153// we want to create b in the context of this function4154path = PATH.normalize(path);4155if (path[path.length-1] === '/') path = path.substr(0, path.length-1);4156FS.mkdir(path, mode, 0);4157return 0;4158},doMknod:function(path, mode, dev) {4159// we don't want this in the JS API as it uses mknod to create all nodes.4160switch (mode & 61440) {4161case 32768:4162case 8192:4163case 24576:4164case 4096:4165case 49152:4166break;4167default: return -28;4168}4169FS.mknod(path, mode, dev);4170return 0;4171},doReadlink:function(path, buf, bufsize) {4172if (bufsize <= 0) return -28;4173var ret = FS.readlink(path);41744175var len = Math.min(bufsize, lengthBytesUTF8(ret));4176var endChar = HEAP8[buf+len];4177stringToUTF8(ret, buf, bufsize+1);4178// readlink is one of the rare functions that write out a C string, but does never append a null to the output buffer(!)4179// stringToUTF8() always appends a null byte, so restore the character under the null byte after the write.4180HEAP8[buf+len] = endChar;41814182return len;4183},doAccess:function(path, amode) {4184if (amode & ~7) {4185// need a valid mode4186return -28;4187}4188var node;4189var lookup = FS.lookupPath(path, { follow: true });4190node = lookup.node;4191if (!node) {4192return -44;4193}4194var perms = '';4195if (amode & 4) perms += 'r';4196if (amode & 2) perms += 'w';4197if (amode & 1) perms += 'x';4198if (perms /* otherwise, they've just passed F_OK */ && FS.nodePermissions(node, perms)) {4199return -2;4200}4201return 0;4202},doDup:function(path, flags, suggestFD) {4203var suggest = FS.getStream(suggestFD);4204if (suggest) FS.close(suggest);4205return FS.open(path, flags, 0, suggestFD, suggestFD).fd;4206},doReadv:function(stream, iov, iovcnt, offset) {4207var ret = 0;4208for (var i = 0; i < iovcnt; i++) {4209var ptr = HEAP32[(((iov)+(i*8))>>2)];4210var len = HEAP32[(((iov)+(i*8 + 4))>>2)];4211var curr = FS.read(stream, HEAP8,ptr, len, offset);4212if (curr < 0) return -1;4213ret += curr;4214if (curr < len) break; // nothing more to read4215}4216return ret;4217},doWritev:function(stream, iov, iovcnt, offset) {4218var ret = 0;4219for (var i = 0; i < iovcnt; i++) {4220var ptr = HEAP32[(((iov)+(i*8))>>2)];4221var len = HEAP32[(((iov)+(i*8 + 4))>>2)];4222var curr = FS.write(stream, HEAP8,ptr, len, offset);4223if (curr < 0) return -1;4224ret += curr;4225}4226return ret;4227},varargs:undefined,get:function() {4228assert(SYSCALLS.varargs != undefined);4229SYSCALLS.varargs += 4;4230var ret = HEAP32[(((SYSCALLS.varargs)-(4))>>2)];4231return ret;4232},getStr:function(ptr) {4233var ret = UTF8ToString(ptr);4234return ret;4235},getStreamFromFD:function(fd) {4236var stream = FS.getStream(fd);4237if (!stream) throw new FS.ErrnoError(8);4238return stream;4239},get64:function(low, high) {4240if (low >= 0) assert(high === 0);4241else assert(high === -1);4242return low;4243}};function ___syscall221(fd, cmd, varargs) {SYSCALLS.varargs = varargs;4244try {4245// fcntl644246var stream = SYSCALLS.getStreamFromFD(fd);4247switch (cmd) {4248case 0: {4249var arg = SYSCALLS.get();4250if (arg < 0) {4251return -28;4252}4253var newStream;4254newStream = FS.open(stream.path, stream.flags, 0, arg);4255return newStream.fd;4256}4257case 1:4258case 2:4259return 0; // FD_CLOEXEC makes no sense for a single process.4260case 3:4261return stream.flags;4262case 4: {4263var arg = SYSCALLS.get();4264stream.flags |= arg;4265return 0;4266}4267case 12:4268/* case 12: Currently in musl F_GETLK64 has same value as F_GETLK, so omitted to avoid duplicate case blocks. If that changes, uncomment this */ {42694270var arg = SYSCALLS.get();4271var offset = 0;4272// We're always unlocked.4273HEAP16[(((arg)+(offset))>>1)]=2;4274return 0;4275}4276case 13:4277case 14:4278/* case 13: Currently in musl F_SETLK64 has same value as F_SETLK, so omitted to avoid duplicate case blocks. If that changes, uncomment this */4279/* case 14: Currently in musl F_SETLKW64 has same value as F_SETLKW, so omitted to avoid duplicate case blocks. If that changes, uncomment this */428042814282return 0; // Pretend that the locking is successful.4283case 16:4284case 8:4285return -28; // These are for sockets. We don't have them fully implemented yet.4286case 9:4287// musl trusts getown return values, due to a bug where they must be, as they overlap with errors. just return -1 here, so fnctl() returns that, and we set errno ourselves.4288___setErrNo(28);4289return -1;4290default: {4291return -28;4292}4293}4294} catch (e) {4295if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);4296return -e.errno;4297}4298}42994300function ___syscall5(path, flags, varargs) {SYSCALLS.varargs = varargs;4301try {4302// open4303var pathname = SYSCALLS.getStr(path);4304var mode = SYSCALLS.get();4305var stream = FS.open(pathname, flags, mode);4306return stream.fd;4307} catch (e) {4308if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);4309return -e.errno;4310}4311}43124313function ___syscall54(fd, op, varargs) {SYSCALLS.varargs = varargs;4314try {4315// ioctl4316var stream = SYSCALLS.getStreamFromFD(fd);4317switch (op) {4318case 21509:4319case 21505: {4320if (!stream.tty) return -59;4321return 0;4322}4323case 21510:4324case 21511:4325case 21512:4326case 21506:4327case 21507:4328case 21508: {4329if (!stream.tty) return -59;4330return 0; // no-op, not actually adjusting terminal settings4331}4332case 21519: {4333if (!stream.tty) return -59;4334var argp = SYSCALLS.get();4335HEAP32[((argp)>>2)]=0;4336return 0;4337}4338case 21520: {4339if (!stream.tty) return -59;4340return -28; // not supported4341}4342case 21531: {4343var argp = SYSCALLS.get();4344return FS.ioctl(stream, op, argp);4345}4346case 21523: {4347// TODO: in theory we should write to the winsize struct that gets4348// passed in, but for now musl doesn't read anything on it4349if (!stream.tty) return -59;4350return 0;4351}4352case 21524: {4353// TODO: technically, this ioctl call should change the window size.4354// but, since emscripten doesn't have any concept of a terminal window4355// yet, we'll just silently throw it away as we do TIOCGWINSZ4356if (!stream.tty) return -59;4357return 0;4358}4359default: abort('bad ioctl syscall ' + op);4360}4361} catch (e) {4362if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);4363return -e.errno;4364}4365}43664367function _abort() {4368abort();4369}43704371function _atexit(func, arg) {4372warnOnce('atexit() called, but EXIT_RUNTIME is not set, so atexits() will not be called. set EXIT_RUNTIME to 1 (see the FAQ)');4373__ATEXIT__.unshift({ func: func, arg: arg });4374}437543764377var _emscripten_get_now;if (ENVIRONMENT_IS_NODE) {4378_emscripten_get_now = function() {4379var t = process['hrtime']();4380return t[0] * 1e3 + t[1] / 1e6;4381};4382} else if (typeof dateNow !== 'undefined') {4383_emscripten_get_now = dateNow;4384} else _emscripten_get_now = function() { return performance.now(); }4385;43864387var _emscripten_get_now_is_monotonic=true;;function _clock_gettime(clk_id, tp) {4388// int clock_gettime(clockid_t clk_id, struct timespec *tp);4389var now;4390if (clk_id === 0) {4391now = Date.now();4392} else if ((clk_id === 1 || clk_id === 4) && _emscripten_get_now_is_monotonic) {4393now = _emscripten_get_now();4394} else {4395___setErrNo(28);4396return -1;4397}4398HEAP32[((tp)>>2)]=(now/1000)|0; // seconds4399HEAP32[(((tp)+(4))>>2)]=((now % 1000)*1000*1000)|0; // nanoseconds4400return 0;4401}44024403function _dlclose(handle) {4404abort("To use dlopen, you need to use Emscripten's linking support, see https://github.com/emscripten-core/emscripten/wiki/Linking");4405}44064407function _dlerror() {4408abort("To use dlopen, you need to use Emscripten's linking support, see https://github.com/emscripten-core/emscripten/wiki/Linking");4409}44104411function _dlsym(handle, symbol) {4412abort("To use dlopen, you need to use Emscripten's linking support, see https://github.com/emscripten-core/emscripten/wiki/Linking");4413}441444154416441744184419function _emscripten_set_main_loop_timing(mode, value) {4420Browser.mainLoop.timingMode = mode;4421Browser.mainLoop.timingValue = value;44224423if (!Browser.mainLoop.func) {4424console.error('emscripten_set_main_loop_timing: Cannot set timing mode for main loop since a main loop does not exist! Call emscripten_set_main_loop first to set one up.');4425return 1; // Return non-zero on failure, can't set timing mode when there is no main loop.4426}44274428if (mode == 0 /*EM_TIMING_SETTIMEOUT*/) {4429Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_setTimeout() {4430var timeUntilNextTick = Math.max(0, Browser.mainLoop.tickStartTime + value - _emscripten_get_now())|0;4431setTimeout(Browser.mainLoop.runner, timeUntilNextTick); // doing this each time means that on exception, we stop4432};4433Browser.mainLoop.method = 'timeout';4434} else if (mode == 1 /*EM_TIMING_RAF*/) {4435Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_rAF() {4436Browser.requestAnimationFrame(Browser.mainLoop.runner);4437};4438Browser.mainLoop.method = 'rAF';4439} else if (mode == 2 /*EM_TIMING_SETIMMEDIATE*/) {4440if (typeof setImmediate === 'undefined') {4441// Emulate setImmediate. (note: not a complete polyfill, we don't emulate clearImmediate() to keep code size to minimum, since not needed)4442var setImmediates = [];4443var emscriptenMainLoopMessageId = 'setimmediate';4444var Browser_setImmediate_messageHandler = function(event) {4445// When called in current thread or Worker, the main loop ID is structured slightly different to accommodate for --proxy-to-worker runtime listening to Worker events,4446// so check for both cases.4447if (event.data === emscriptenMainLoopMessageId || event.data.target === emscriptenMainLoopMessageId) {4448event.stopPropagation();4449setImmediates.shift()();4450}4451}4452addEventListener("message", Browser_setImmediate_messageHandler, true);4453setImmediate = /** @type{function(function(): ?, ...?): number} */(function Browser_emulated_setImmediate(func) {4454setImmediates.push(func);4455if (ENVIRONMENT_IS_WORKER) {4456if (Module['setImmediates'] === undefined) Module['setImmediates'] = [];4457Module['setImmediates'].push(func);4458postMessage({target: emscriptenMainLoopMessageId}); // In --proxy-to-worker, route the message via proxyClient.js4459} else postMessage(emscriptenMainLoopMessageId, "*"); // On the main thread, can just send the message to itself.4460})4461}4462Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_setImmediate() {4463setImmediate(Browser.mainLoop.runner);4464};4465Browser.mainLoop.method = 'immediate';4466}4467return 0;4468}/** @param {number|boolean=} noSetTiming */4469function _emscripten_set_main_loop(func, fps, simulateInfiniteLoop, arg, noSetTiming) {4470noExitRuntime = true;44714472assert(!Browser.mainLoop.func, 'emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.');44734474Browser.mainLoop.func = func;4475Browser.mainLoop.arg = arg;44764477var browserIterationFunc;4478if (typeof arg !== 'undefined') {4479browserIterationFunc = function() {4480Module['dynCall_vi'](func, arg);4481};4482} else {4483browserIterationFunc = function() {4484Module['dynCall_v'](func);4485};4486}44874488var thisMainLoopId = Browser.mainLoop.currentlyRunningMainloop;44894490Browser.mainLoop.runner = function Browser_mainLoop_runner() {4491if (ABORT) return;4492if (Browser.mainLoop.queue.length > 0) {4493var start = Date.now();4494var blocker = Browser.mainLoop.queue.shift();4495blocker.func(blocker.arg);4496if (Browser.mainLoop.remainingBlockers) {4497var remaining = Browser.mainLoop.remainingBlockers;4498var next = remaining%1 == 0 ? remaining-1 : Math.floor(remaining);4499if (blocker.counted) {4500Browser.mainLoop.remainingBlockers = next;4501} else {4502// not counted, but move the progress along a tiny bit4503next = next + 0.5; // do not steal all the next one's progress4504Browser.mainLoop.remainingBlockers = (8*remaining + next)/9;4505}4506}4507console.log('main loop blocker "' + blocker.name + '" took ' + (Date.now() - start) + ' ms'); //, left: ' + Browser.mainLoop.remainingBlockers);4508Browser.mainLoop.updateStatus();45094510// catches pause/resume main loop from blocker execution4511if (thisMainLoopId < Browser.mainLoop.currentlyRunningMainloop) return;45124513setTimeout(Browser.mainLoop.runner, 0);4514return;4515}45164517// catch pauses from non-main loop sources4518if (thisMainLoopId < Browser.mainLoop.currentlyRunningMainloop) return;45194520// Implement very basic swap interval control4521Browser.mainLoop.currentFrameNumber = Browser.mainLoop.currentFrameNumber + 1 | 0;4522if (Browser.mainLoop.timingMode == 1/*EM_TIMING_RAF*/ && Browser.mainLoop.timingValue > 1 && Browser.mainLoop.currentFrameNumber % Browser.mainLoop.timingValue != 0) {4523// Not the scheduled time to render this frame - skip.4524Browser.mainLoop.scheduler();4525return;4526} else if (Browser.mainLoop.timingMode == 0/*EM_TIMING_SETTIMEOUT*/) {4527Browser.mainLoop.tickStartTime = _emscripten_get_now();4528}45294530// Signal GL rendering layer that processing of a new frame is about to start. This helps it optimize4531// VBO double-buffering and reduce GPU stalls.4532453345344535if (Browser.mainLoop.method === 'timeout' && Module.ctx) {4536warnOnce('Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!');4537Browser.mainLoop.method = ''; // just warn once per call to set main loop4538}45394540Browser.mainLoop.runIter(browserIterationFunc);45414542checkStackCookie();45434544// catch pauses from the main loop itself4545if (thisMainLoopId < Browser.mainLoop.currentlyRunningMainloop) return;45464547// Queue new audio data. This is important to be right after the main loop invocation, so that we will immediately be able4548// to queue the newest produced audio samples.4549// TODO: Consider adding pre- and post- rAF callbacks so that GL.newRenderingFrameStarted() and SDL.audio.queueNewAudioData()4550// do not need to be hardcoded into this function, but can be more generic.4551if (typeof SDL === 'object' && SDL.audio && SDL.audio.queueNewAudioData) SDL.audio.queueNewAudioData();45524553Browser.mainLoop.scheduler();4554}45554556if (!noSetTiming) {4557if (fps && fps > 0) _emscripten_set_main_loop_timing(0/*EM_TIMING_SETTIMEOUT*/, 1000.0 / fps);4558else _emscripten_set_main_loop_timing(1/*EM_TIMING_RAF*/, 1); // Do rAF by rendering each frame (no decimating)45594560Browser.mainLoop.scheduler();4561}45624563if (simulateInfiniteLoop) {4564throw 'unwind';4565}4566}var Browser={mainLoop:{scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause:function() {4567Browser.mainLoop.scheduler = null;4568Browser.mainLoop.currentlyRunningMainloop++; // Incrementing this signals the previous main loop that it's now become old, and it must return.4569},resume:function() {4570Browser.mainLoop.currentlyRunningMainloop++;4571var timingMode = Browser.mainLoop.timingMode;4572var timingValue = Browser.mainLoop.timingValue;4573var func = Browser.mainLoop.func;4574Browser.mainLoop.func = null;4575_emscripten_set_main_loop(func, 0, false, Browser.mainLoop.arg, true /* do not set timing and call scheduler, we will do it on the next lines */);4576_emscripten_set_main_loop_timing(timingMode, timingValue);4577Browser.mainLoop.scheduler();4578},updateStatus:function() {4579if (Module['setStatus']) {4580var message = Module['statusMessage'] || 'Please wait...';4581var remaining = Browser.mainLoop.remainingBlockers;4582var expected = Browser.mainLoop.expectedBlockers;4583if (remaining) {4584if (remaining < expected) {4585Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')');4586} else {4587Module['setStatus'](message);4588}4589} else {4590Module['setStatus']('');4591}4592}4593},runIter:function(func) {4594if (ABORT) return;4595if (Module['preMainLoop']) {4596var preRet = Module['preMainLoop']();4597if (preRet === false) {4598return; // |return false| skips a frame4599}4600}4601try {4602func();4603} catch (e) {4604if (e instanceof ExitStatus) {4605return;4606} else {4607if (e && typeof e === 'object' && e.stack) err('exception thrown: ' + [e, e.stack]);4608throw e;4609}4610}4611if (Module['postMainLoop']) Module['postMainLoop']();4612}},isFullscreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function() {4613if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers46144615if (Browser.initted) return;4616Browser.initted = true;46174618try {4619new Blob();4620Browser.hasBlobConstructor = true;4621} catch(e) {4622Browser.hasBlobConstructor = false;4623console.log("warning: no blob constructor, cannot create blobs with mimetypes");4624}4625Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null));4626Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined;4627if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') {4628console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");4629Module.noImageDecoding = true;4630}46314632// Support for plugins that can process preloaded files. You can add more of these to4633// your app by creating and appending to Module.preloadPlugins.4634//4635// Each plugin is asked if it can handle a file based on the file's name. If it can,4636// it is given the file's raw data. When it is done, it calls a callback with the file's4637// (possibly modified) data. For example, a plugin might decompress a file, or it4638// might create some side data structure for use later (like an Image element, etc.).46394640var imagePlugin = {};4641imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {4642return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name);4643};4644imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {4645var b = null;4646if (Browser.hasBlobConstructor) {4647try {4648b = new Blob([byteArray], { type: Browser.getMimetype(name) });4649if (b.size !== byteArray.length) { // Safari bug #1186304650// Safari's Blob can only take an ArrayBuffer4651b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });4652}4653} catch(e) {4654warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder');4655}4656}4657if (!b) {4658var bb = new Browser.BlobBuilder();4659bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range4660b = bb.getBlob();4661}4662var url = Browser.URLObject.createObjectURL(b);4663assert(typeof url == 'string', 'createObjectURL must return a url as a string');4664var img = new Image();4665img.onload = function img_onload() {4666assert(img.complete, 'Image ' + name + ' could not be decoded');4667var canvas = document.createElement('canvas');4668canvas.width = img.width;4669canvas.height = img.height;4670var ctx = canvas.getContext('2d');4671ctx.drawImage(img, 0, 0);4672Module["preloadedImages"][name] = canvas;4673Browser.URLObject.revokeObjectURL(url);4674if (onload) onload(byteArray);4675};4676img.onerror = function img_onerror(event) {4677console.log('Image ' + url + ' could not be decoded');4678if (onerror) onerror();4679};4680img.src = url;4681};4682Module['preloadPlugins'].push(imagePlugin);46834684var audioPlugin = {};4685audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {4686return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };4687};4688audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {4689var done = false;4690function finish(audio) {4691if (done) return;4692done = true;4693Module["preloadedAudios"][name] = audio;4694if (onload) onload(byteArray);4695}4696function fail() {4697if (done) return;4698done = true;4699Module["preloadedAudios"][name] = new Audio(); // empty shim4700if (onerror) onerror();4701}4702if (Browser.hasBlobConstructor) {4703try {4704var b = new Blob([byteArray], { type: Browser.getMimetype(name) });4705} catch(e) {4706return fail();4707}4708var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this!4709assert(typeof url == 'string', 'createObjectURL must return a url as a string');4710var audio = new Audio();4711audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 1249264712audio.onerror = function audio_onerror(event) {4713if (done) return;4714console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach');4715function encode64(data) {4716var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';4717var PAD = '=';4718var ret = '';4719var leftchar = 0;4720var leftbits = 0;4721for (var i = 0; i < data.length; i++) {4722leftchar = (leftchar << 8) | data[i];4723leftbits += 8;4724while (leftbits >= 6) {4725var curr = (leftchar >> (leftbits-6)) & 0x3f;4726leftbits -= 6;4727ret += BASE[curr];4728}4729}4730if (leftbits == 2) {4731ret += BASE[(leftchar&3) << 4];4732ret += PAD + PAD;4733} else if (leftbits == 4) {4734ret += BASE[(leftchar&0xf) << 2];4735ret += PAD;4736}4737return ret;4738}4739audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);4740finish(audio); // we don't wait for confirmation this worked - but it's worth trying4741};4742audio.src = url;4743// workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror4744Browser.safeSetTimeout(function() {4745finish(audio); // try to use it even though it is not necessarily ready to play4746}, 10000);4747} else {4748return fail();4749}4750};4751Module['preloadPlugins'].push(audioPlugin);475247534754// Canvas event setup47554756function pointerLockChange() {4757Browser.pointerLock = document['pointerLockElement'] === Module['canvas'] ||4758document['mozPointerLockElement'] === Module['canvas'] ||4759document['webkitPointerLockElement'] === Module['canvas'] ||4760document['msPointerLockElement'] === Module['canvas'];4761}4762var canvas = Module['canvas'];4763if (canvas) {4764// forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module4765// Module['forcedAspectRatio'] = 4 / 3;47664767canvas.requestPointerLock = canvas['requestPointerLock'] ||4768canvas['mozRequestPointerLock'] ||4769canvas['webkitRequestPointerLock'] ||4770canvas['msRequestPointerLock'] ||4771function(){};4772canvas.exitPointerLock = document['exitPointerLock'] ||4773document['mozExitPointerLock'] ||4774document['webkitExitPointerLock'] ||4775document['msExitPointerLock'] ||4776function(){}; // no-op if function does not exist4777canvas.exitPointerLock = canvas.exitPointerLock.bind(document);47784779document.addEventListener('pointerlockchange', pointerLockChange, false);4780document.addEventListener('mozpointerlockchange', pointerLockChange, false);4781document.addEventListener('webkitpointerlockchange', pointerLockChange, false);4782document.addEventListener('mspointerlockchange', pointerLockChange, false);47834784if (Module['elementPointerLock']) {4785canvas.addEventListener("click", function(ev) {4786if (!Browser.pointerLock && Module['canvas'].requestPointerLock) {4787Module['canvas'].requestPointerLock();4788ev.preventDefault();4789}4790}, false);4791}4792}4793},createContext:function(canvas, useWebGL, setInModule, webGLContextAttributes) {4794if (useWebGL && Module.ctx && canvas == Module.canvas) return Module.ctx; // no need to recreate GL context if it's already been created for this canvas.47954796var ctx;4797var contextHandle;4798if (useWebGL) {4799// For GLES2/desktop GL compatibility, adjust a few defaults to be different to WebGL defaults, so that they align better with the desktop defaults.4800var contextAttributes = {4801antialias: false,4802alpha: false,4803majorVersion: 1,4804};48054806if (webGLContextAttributes) {4807for (var attribute in webGLContextAttributes) {4808contextAttributes[attribute] = webGLContextAttributes[attribute];4809}4810}48114812// This check of existence of GL is here to satisfy Closure compiler, which yells if variable GL is referenced below but GL object is not4813// actually compiled in because application is not doing any GL operations. TODO: Ideally if GL is not being used, this function4814// Browser.createContext() should not even be emitted.4815if (typeof GL !== 'undefined') {4816contextHandle = GL.createContext(canvas, contextAttributes);4817if (contextHandle) {4818ctx = GL.getContext(contextHandle).GLctx;4819}4820}4821} else {4822ctx = canvas.getContext('2d');4823}48244825if (!ctx) return null;48264827if (setInModule) {4828if (!useWebGL) assert(typeof GLctx === 'undefined', 'cannot set in module if GLctx is used, but we are a non-GL context that would replace it');48294830Module.ctx = ctx;4831if (useWebGL) GL.makeContextCurrent(contextHandle);4832Module.useWebGL = useWebGL;4833Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });4834Browser.init();4835}4836return ctx;4837},destroyContext:function(canvas, useWebGL, setInModule) {},fullscreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullscreen:function(lockPointer, resizeCanvas) {4838Browser.lockPointer = lockPointer;4839Browser.resizeCanvas = resizeCanvas;4840if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true;4841if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false;48424843var canvas = Module['canvas'];4844function fullscreenChange() {4845Browser.isFullscreen = false;4846var canvasContainer = canvas.parentNode;4847if ((document['fullscreenElement'] || document['mozFullScreenElement'] ||4848document['msFullscreenElement'] || document['webkitFullscreenElement'] ||4849document['webkitCurrentFullScreenElement']) === canvasContainer) {4850canvas.exitFullscreen = Browser.exitFullscreen;4851if (Browser.lockPointer) canvas.requestPointerLock();4852Browser.isFullscreen = true;4853if (Browser.resizeCanvas) {4854Browser.setFullscreenCanvasSize();4855} else {4856Browser.updateCanvasDimensions(canvas);4857}4858} else {4859// remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen4860canvasContainer.parentNode.insertBefore(canvas, canvasContainer);4861canvasContainer.parentNode.removeChild(canvasContainer);48624863if (Browser.resizeCanvas) {4864Browser.setWindowedCanvasSize();4865} else {4866Browser.updateCanvasDimensions(canvas);4867}4868}4869if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullscreen);4870if (Module['onFullscreen']) Module['onFullscreen'](Browser.isFullscreen);4871}48724873if (!Browser.fullscreenHandlersInstalled) {4874Browser.fullscreenHandlersInstalled = true;4875document.addEventListener('fullscreenchange', fullscreenChange, false);4876document.addEventListener('mozfullscreenchange', fullscreenChange, false);4877document.addEventListener('webkitfullscreenchange', fullscreenChange, false);4878document.addEventListener('MSFullscreenChange', fullscreenChange, false);4879}48804881// create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root4882var canvasContainer = document.createElement("div");4883canvas.parentNode.insertBefore(canvasContainer, canvas);4884canvasContainer.appendChild(canvas);48854886// use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)4887canvasContainer.requestFullscreen = canvasContainer['requestFullscreen'] ||4888canvasContainer['mozRequestFullScreen'] ||4889canvasContainer['msRequestFullscreen'] ||4890(canvasContainer['webkitRequestFullscreen'] ? function() { canvasContainer['webkitRequestFullscreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null) ||4891(canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null);48924893canvasContainer.requestFullscreen();4894},requestFullScreen:function() {4895abort('Module.requestFullScreen has been replaced by Module.requestFullscreen (without a capital S)');4896},exitFullscreen:function() {4897// This is workaround for chrome. Trying to exit from fullscreen4898// not in fullscreen state will cause "TypeError: Document not active"4899// in chrome. See https://github.com/emscripten-core/emscripten/pull/82364900if (!Browser.isFullscreen) {4901return false;4902}49034904var CFS = document['exitFullscreen'] ||4905document['cancelFullScreen'] ||4906document['mozCancelFullScreen'] ||4907document['msExitFullscreen'] ||4908document['webkitCancelFullScreen'] ||4909(function() {});4910CFS.apply(document, []);4911return true;4912},nextRAF:0,fakeRequestAnimationFrame:function(func) {4913// try to keep 60fps between calls to here4914var now = Date.now();4915if (Browser.nextRAF === 0) {4916Browser.nextRAF = now + 1000/60;4917} else {4918while (now + 2 >= Browser.nextRAF) { // fudge a little, to avoid timer jitter causing us to do lots of delay:04919Browser.nextRAF += 1000/60;4920}4921}4922var delay = Math.max(Browser.nextRAF - now, 0);4923setTimeout(func, delay);4924},requestAnimationFrame:function(func) {4925if (typeof requestAnimationFrame === 'function') {4926requestAnimationFrame(func);4927return;4928}4929var RAF = Browser.fakeRequestAnimationFrame;4930RAF(func);4931},safeCallback:function(func) {4932return function() {4933if (!ABORT) return func.apply(null, arguments);4934};4935},allowAsyncCallbacks:true,queuedAsyncCallbacks:[],pauseAsyncCallbacks:function() {4936Browser.allowAsyncCallbacks = false;4937},resumeAsyncCallbacks:function() { // marks future callbacks as ok to execute, and synchronously runs any remaining ones right now4938Browser.allowAsyncCallbacks = true;4939if (Browser.queuedAsyncCallbacks.length > 0) {4940var callbacks = Browser.queuedAsyncCallbacks;4941Browser.queuedAsyncCallbacks = [];4942callbacks.forEach(function(func) {4943func();4944});4945}4946},safeRequestAnimationFrame:function(func) {4947return Browser.requestAnimationFrame(function() {4948if (ABORT) return;4949if (Browser.allowAsyncCallbacks) {4950func();4951} else {4952Browser.queuedAsyncCallbacks.push(func);4953}4954});4955},safeSetTimeout:function(func, timeout) {4956noExitRuntime = true;4957return setTimeout(function() {4958if (ABORT) return;4959if (Browser.allowAsyncCallbacks) {4960func();4961} else {4962Browser.queuedAsyncCallbacks.push(func);4963}4964}, timeout);4965},safeSetInterval:function(func, timeout) {4966noExitRuntime = true;4967return setInterval(function() {4968if (ABORT) return;4969if (Browser.allowAsyncCallbacks) {4970func();4971} // drop it on the floor otherwise, next interval will kick in4972}, timeout);4973},getMimetype:function(name) {4974return {4975'jpg': 'image/jpeg',4976'jpeg': 'image/jpeg',4977'png': 'image/png',4978'bmp': 'image/bmp',4979'ogg': 'audio/ogg',4980'wav': 'audio/wav',4981'mp3': 'audio/mpeg'4982}[name.substr(name.lastIndexOf('.')+1)];4983},getUserMedia:function(func) {4984if(!window.getUserMedia) {4985window.getUserMedia = navigator['getUserMedia'] ||4986navigator['mozGetUserMedia'];4987}4988window.getUserMedia(func);4989},getMovementX:function(event) {4990return event['movementX'] ||4991event['mozMovementX'] ||4992event['webkitMovementX'] ||49930;4994},getMovementY:function(event) {4995return event['movementY'] ||4996event['mozMovementY'] ||4997event['webkitMovementY'] ||49980;4999},getMouseWheelDelta:function(event) {5000var delta = 0;5001switch (event.type) {5002case 'DOMMouseScroll':5003// 3 lines make up a step5004delta = event.detail / 3;5005break;5006case 'mousewheel':5007// 120 units make up a step5008delta = event.wheelDelta / 120;5009break;5010case 'wheel':5011delta = event.deltaY5012switch(event.deltaMode) {5013case 0:5014// DOM_DELTA_PIXEL: 100 pixels make up a step5015delta /= 100;5016break;5017case 1:5018// DOM_DELTA_LINE: 3 lines make up a step5019delta /= 3;5020break;5021case 2:5022// DOM_DELTA_PAGE: A page makes up 80 steps5023delta *= 80;5024break;5025default:5026throw 'unrecognized mouse wheel delta mode: ' + event.deltaMode;5027}5028break;5029default:5030throw 'unrecognized mouse wheel event: ' + event.type;5031}5032return delta;5033},mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:function(event) { // event should be mousemove, mousedown or mouseup5034if (Browser.pointerLock) {5035// When the pointer is locked, calculate the coordinates5036// based on the movement of the mouse.5037// Workaround for Firefox bug 7644985038if (event.type != 'mousemove' &&5039('mozMovementX' in event)) {5040Browser.mouseMovementX = Browser.mouseMovementY = 0;5041} else {5042Browser.mouseMovementX = Browser.getMovementX(event);5043Browser.mouseMovementY = Browser.getMovementY(event);5044}50455046// check if SDL is available5047if (typeof SDL != "undefined") {5048Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;5049Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;5050} else {5051// just add the mouse delta to the current absolut mouse position5052// FIXME: ideally this should be clamped against the canvas size and zero5053Browser.mouseX += Browser.mouseMovementX;5054Browser.mouseY += Browser.mouseMovementY;5055}5056} else {5057// Otherwise, calculate the movement based on the changes5058// in the coordinates.5059var rect = Module["canvas"].getBoundingClientRect();5060var cw = Module["canvas"].width;5061var ch = Module["canvas"].height;50625063// Neither .scrollX or .pageXOffset are defined in a spec, but5064// we prefer .scrollX because it is currently in a spec draft.5065// (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)5066var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset);5067var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset);5068// If this assert lands, it's likely because the browser doesn't support scrollX or pageXOffset5069// and we have no viable fallback.5070assert((typeof scrollX !== 'undefined') && (typeof scrollY !== 'undefined'), 'Unable to retrieve scroll position, mouse positions likely broken.');50715072if (event.type === 'touchstart' || event.type === 'touchend' || event.type === 'touchmove') {5073var touch = event.touch;5074if (touch === undefined) {5075return; // the "touch" property is only defined in SDL50765077}5078var adjustedX = touch.pageX - (scrollX + rect.left);5079var adjustedY = touch.pageY - (scrollY + rect.top);50805081adjustedX = adjustedX * (cw / rect.width);5082adjustedY = adjustedY * (ch / rect.height);50835084var coords = { x: adjustedX, y: adjustedY };50855086if (event.type === 'touchstart') {5087Browser.lastTouches[touch.identifier] = coords;5088Browser.touches[touch.identifier] = coords;5089} else if (event.type === 'touchend' || event.type === 'touchmove') {5090var last = Browser.touches[touch.identifier];5091if (!last) last = coords;5092Browser.lastTouches[touch.identifier] = last;5093Browser.touches[touch.identifier] = coords;5094}5095return;5096}50975098var x = event.pageX - (scrollX + rect.left);5099var y = event.pageY - (scrollY + rect.top);51005101// the canvas might be CSS-scaled compared to its backbuffer;5102// SDL-using content will want mouse coordinates in terms5103// of backbuffer units.5104x = x * (cw / rect.width);5105y = y * (ch / rect.height);51065107Browser.mouseMovementX = x - Browser.mouseX;5108Browser.mouseMovementY = y - Browser.mouseY;5109Browser.mouseX = x;5110Browser.mouseY = y;5111}5112},asyncLoad:function(url, onload, onerror, noRunDep) {5113var dep = !noRunDep ? getUniqueRunDependency('al ' + url) : '';5114readAsync(url, function(arrayBuffer) {5115assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');5116onload(new Uint8Array(arrayBuffer));5117if (dep) removeRunDependency(dep);5118}, function(event) {5119if (onerror) {5120onerror();5121} else {5122throw 'Loading data file "' + url + '" failed.';5123}5124});5125if (dep) addRunDependency(dep);5126},resizeListeners:[],updateResizeListeners:function() {5127var canvas = Module['canvas'];5128Browser.resizeListeners.forEach(function(listener) {5129listener(canvas.width, canvas.height);5130});5131},setCanvasSize:function(width, height, noUpdates) {5132var canvas = Module['canvas'];5133Browser.updateCanvasDimensions(canvas, width, height);5134if (!noUpdates) Browser.updateResizeListeners();5135},windowedWidth:0,windowedHeight:0,setFullscreenCanvasSize:function() {5136// check if SDL is available5137if (typeof SDL != "undefined") {5138var flags = HEAPU32[((SDL.screen)>>2)];5139flags = flags | 0x00800000; // set SDL_FULLSCREEN flag5140HEAP32[((SDL.screen)>>2)]=flags5141}5142Browser.updateCanvasDimensions(Module['canvas']);5143Browser.updateResizeListeners();5144},setWindowedCanvasSize:function() {5145// check if SDL is available5146if (typeof SDL != "undefined") {5147var flags = HEAPU32[((SDL.screen)>>2)];5148flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag5149HEAP32[((SDL.screen)>>2)]=flags5150}5151Browser.updateCanvasDimensions(Module['canvas']);5152Browser.updateResizeListeners();5153},updateCanvasDimensions:function(canvas, wNative, hNative) {5154if (wNative && hNative) {5155canvas.widthNative = wNative;5156canvas.heightNative = hNative;5157} else {5158wNative = canvas.widthNative;5159hNative = canvas.heightNative;5160}5161var w = wNative;5162var h = hNative;5163if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {5164if (w/h < Module['forcedAspectRatio']) {5165w = Math.round(h * Module['forcedAspectRatio']);5166} else {5167h = Math.round(w / Module['forcedAspectRatio']);5168}5169}5170if (((document['fullscreenElement'] || document['mozFullScreenElement'] ||5171document['msFullscreenElement'] || document['webkitFullscreenElement'] ||5172document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {5173var factor = Math.min(screen.width / w, screen.height / h);5174w = Math.round(w * factor);5175h = Math.round(h * factor);5176}5177if (Browser.resizeCanvas) {5178if (canvas.width != w) canvas.width = w;5179if (canvas.height != h) canvas.height = h;5180if (typeof canvas.style != 'undefined') {5181canvas.style.removeProperty( "width");5182canvas.style.removeProperty("height");5183}5184} else {5185if (canvas.width != wNative) canvas.width = wNative;5186if (canvas.height != hNative) canvas.height = hNative;5187if (typeof canvas.style != 'undefined') {5188if (w != wNative || h != hNative) {5189canvas.style.setProperty( "width", w + "px", "important");5190canvas.style.setProperty("height", h + "px", "important");5191} else {5192canvas.style.removeProperty( "width");5193canvas.style.removeProperty("height");5194}5195}5196}5197},wgetRequests:{},nextWgetRequestHandle:0,getNextWgetRequestHandle:function() {5198var handle = Browser.nextWgetRequestHandle;5199Browser.nextWgetRequestHandle++;5200return handle;5201}};var EGL={errorCode:12288,defaultDisplayInitialized:false,currentContext:0,currentReadSurface:0,currentDrawSurface:0,contextAttributes:{alpha:false,depth:false,stencil:false,antialias:false},stringCache:{},setErrorCode:function(code) {5202EGL.errorCode = code;5203},chooseConfig:function(display, attribList, config, config_size, numConfigs) {5204if (display != 62000 /* Magic ID for Emscripten 'default display' */) {5205EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);5206return 0;5207}52085209if (attribList) {5210// read attribList if it is non-null5211for(;;) {5212var param = HEAP32[((attribList)>>2)];5213if (param == 0x3021 /*EGL_ALPHA_SIZE*/) {5214var alphaSize = HEAP32[(((attribList)+(4))>>2)];5215EGL.contextAttributes.alpha = (alphaSize > 0);5216} else if (param == 0x3025 /*EGL_DEPTH_SIZE*/) {5217var depthSize = HEAP32[(((attribList)+(4))>>2)];5218EGL.contextAttributes.depth = (depthSize > 0);5219} else if (param == 0x3026 /*EGL_STENCIL_SIZE*/) {5220var stencilSize = HEAP32[(((attribList)+(4))>>2)];5221EGL.contextAttributes.stencil = (stencilSize > 0);5222} else if (param == 0x3031 /*EGL_SAMPLES*/) {5223var samples = HEAP32[(((attribList)+(4))>>2)];5224EGL.contextAttributes.antialias = (samples > 0);5225} else if (param == 0x3032 /*EGL_SAMPLE_BUFFERS*/) {5226var samples = HEAP32[(((attribList)+(4))>>2)];5227EGL.contextAttributes.antialias = (samples == 1);5228} else if (param == 0x3100 /*EGL_CONTEXT_PRIORITY_LEVEL_IMG*/) {5229var requestedPriority = HEAP32[(((attribList)+(4))>>2)];5230EGL.contextAttributes.lowLatency = (requestedPriority != 0x3103 /*EGL_CONTEXT_PRIORITY_LOW_IMG*/);5231} else if (param == 0x3038 /*EGL_NONE*/) {5232break;5233}5234attribList += 8;5235}5236}52375238if ((!config || !config_size) && !numConfigs) {5239EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);5240return 0;5241}5242if (numConfigs) {5243HEAP32[((numConfigs)>>2)]=1; // Total number of supported configs: 1.5244}5245if (config && config_size > 0) {5246HEAP32[((config)>>2)]=62002;5247}52485249EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);5250return 1;5251}};function _eglBindAPI(api) {5252if (api == 0x30A0 /* EGL_OPENGL_ES_API */) {5253EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);5254return 1;5255} else { // if (api == 0x30A1 /* EGL_OPENVG_API */ || api == 0x30A2 /* EGL_OPENGL_API */) {5256EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);5257return 0;5258}5259}52605261function _eglChooseConfig(display, attrib_list, configs, config_size, numConfigs) {5262return EGL.chooseConfig(display, attrib_list, configs, config_size, numConfigs);5263}5264526552665267function __webgl_acquireInstancedArraysExtension(ctx) {5268// Extension available in WebGL 1 from Firefox 26 and Google Chrome 30 onwards. Core feature in WebGL 2.5269var ext = ctx.getExtension('ANGLE_instanced_arrays');5270if (ext) {5271ctx['vertexAttribDivisor'] = function(index, divisor) { ext['vertexAttribDivisorANGLE'](index, divisor); };5272ctx['drawArraysInstanced'] = function(mode, first, count, primcount) { ext['drawArraysInstancedANGLE'](mode, first, count, primcount); };5273ctx['drawElementsInstanced'] = function(mode, count, type, indices, primcount) { ext['drawElementsInstancedANGLE'](mode, count, type, indices, primcount); };5274}5275}52765277function __webgl_acquireVertexArrayObjectExtension(ctx) {5278// Extension available in WebGL 1 from Firefox 25 and WebKit 536.28/desktop Safari 6.0.3 onwards. Core feature in WebGL 2.5279var ext = ctx.getExtension('OES_vertex_array_object');5280if (ext) {5281ctx['createVertexArray'] = function() { return ext['createVertexArrayOES'](); };5282ctx['deleteVertexArray'] = function(vao) { ext['deleteVertexArrayOES'](vao); };5283ctx['bindVertexArray'] = function(vao) { ext['bindVertexArrayOES'](vao); };5284ctx['isVertexArray'] = function(vao) { return ext['isVertexArrayOES'](vao); };5285}5286}52875288function __webgl_acquireDrawBuffersExtension(ctx) {5289// Extension available in WebGL 1 from Firefox 28 onwards. Core feature in WebGL 2.5290var ext = ctx.getExtension('WEBGL_draw_buffers');5291if (ext) {5292ctx['drawBuffers'] = function(n, bufs) { ext['drawBuffersWEBGL'](n, bufs); };5293}5294}var GL={counter:1,lastError:0,buffers:[],mappedBuffers:{},programs:[],framebuffers:[],renderbuffers:[],textures:[],uniforms:[],shaders:[],vaos:[],contexts:{},currentContext:null,offscreenCanvases:{},timerQueriesEXT:[],programInfos:{},stringCache:{},unpackAlignment:4,init:function() {5295var miniTempFloatBuffer = new Float32Array(GL.MINI_TEMP_BUFFER_SIZE);5296for (var i = 0; i < GL.MINI_TEMP_BUFFER_SIZE; i++) {5297GL.miniTempBufferFloatViews[i] = miniTempFloatBuffer.subarray(0, i+1);5298}52995300var miniTempIntBuffer = new Int32Array(GL.MINI_TEMP_BUFFER_SIZE);5301for (var i = 0; i < GL.MINI_TEMP_BUFFER_SIZE; i++) {5302GL.miniTempBufferIntViews[i] = miniTempIntBuffer.subarray(0, i+1);5303}5304},recordError:function recordError(errorCode) {5305if (!GL.lastError) {5306GL.lastError = errorCode;5307}5308},getNewId:function(table) {5309var ret = GL.counter++;5310for (var i = table.length; i < ret; i++) {5311table[i] = null;5312}5313return ret;5314},MINI_TEMP_BUFFER_SIZE:256,miniTempBufferFloatViews:[0],miniTempBufferIntViews:[0],getSource:function(shader, count, string, length) {5315var source = '';5316for (var i = 0; i < count; ++i) {5317var len = length ? HEAP32[(((length)+(i*4))>>2)] : -1;5318source += UTF8ToString(HEAP32[(((string)+(i*4))>>2)], len < 0 ? undefined : len);5319}5320return source;5321},createContext:function(canvas, webGLContextAttributes) {532253235324532553265327var ctx =5328(canvas.getContext("webgl", webGLContextAttributes)5329// https://caniuse.com/#feat=webgl5330);533153325333if (!ctx) return 0;53345335var handle = GL.registerContext(ctx, webGLContextAttributes);5336533753385339return handle;5340},registerContext:function(ctx, webGLContextAttributes) {5341var handle = _malloc(8); // Make space on the heap to store GL context attributes that need to be accessible as shared between threads.5342var context = {5343handle: handle,5344attributes: webGLContextAttributes,5345version: webGLContextAttributes.majorVersion,5346GLctx: ctx5347};534853495350// Store the created context object so that we can access the context given a canvas without having to pass the parameters again.5351if (ctx.canvas) ctx.canvas.GLctxObject = context;5352GL.contexts[handle] = context;5353if (typeof webGLContextAttributes.enableExtensionsByDefault === 'undefined' || webGLContextAttributes.enableExtensionsByDefault) {5354GL.initExtensions(context);5355}53565357535853595360return handle;5361},makeContextCurrent:function(contextHandle) {53625363GL.currentContext = GL.contexts[contextHandle]; // Active Emscripten GL layer context object.5364Module.ctx = GLctx = GL.currentContext && GL.currentContext.GLctx; // Active WebGL context object.5365return !(contextHandle && !GLctx);5366},getContext:function(contextHandle) {5367return GL.contexts[contextHandle];5368},deleteContext:function(contextHandle) {5369if (GL.currentContext === GL.contexts[contextHandle]) GL.currentContext = null;5370if (typeof JSEvents === 'object') JSEvents.removeAllHandlersOnTarget(GL.contexts[contextHandle].GLctx.canvas); // Release all JS event handlers on the DOM element that the GL context is associated with since the context is now deleted.5371if (GL.contexts[contextHandle] && GL.contexts[contextHandle].GLctx.canvas) GL.contexts[contextHandle].GLctx.canvas.GLctxObject = undefined; // Make sure the canvas object no longer refers to the context object so there are no GC surprises.5372_free(GL.contexts[contextHandle].handle);5373GL.contexts[contextHandle] = null;5374},initExtensions:function(context) {5375// If this function is called without a specific context object, init the extensions of the currently active context.5376if (!context) context = GL.currentContext;53775378if (context.initExtensionsDone) return;5379context.initExtensionsDone = true;53805381var GLctx = context.GLctx;53825383// Detect the presence of a few extensions manually, this GL interop layer itself will need to know if they exist.53845385if (context.version < 2) {5386__webgl_acquireInstancedArraysExtension(GLctx);5387__webgl_acquireVertexArrayObjectExtension(GLctx);5388__webgl_acquireDrawBuffersExtension(GLctx);5389}53905391GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query");53925393// These are the 'safe' feature-enabling extensions that don't add any performance impact related to e.g. debugging, and5394// should be enabled by default so that client GLES2/GL code will not need to go through extra hoops to get its stuff working.5395// As new extensions are ratified at http://www.khronos.org/registry/webgl/extensions/ , feel free to add your new extensions5396// here, as long as they don't produce a performance impact for users that might not be using those extensions.5397// E.g. debugging-related extensions should probably be off by default.5398var automaticallyEnabledExtensions = [ // Khronos ratified WebGL extensions ordered by number (no debug extensions):5399"OES_texture_float", "OES_texture_half_float", "OES_standard_derivatives",5400"OES_vertex_array_object", "WEBGL_compressed_texture_s3tc", "WEBGL_depth_texture",5401"OES_element_index_uint", "EXT_texture_filter_anisotropic", "EXT_frag_depth",5402"WEBGL_draw_buffers", "ANGLE_instanced_arrays", "OES_texture_float_linear",5403"OES_texture_half_float_linear", "EXT_blend_minmax", "EXT_shader_texture_lod",5404"EXT_texture_norm16",5405// Community approved WebGL extensions ordered by number:5406"WEBGL_compressed_texture_pvrtc", "EXT_color_buffer_half_float", "WEBGL_color_buffer_float",5407"EXT_sRGB", "WEBGL_compressed_texture_etc1", "EXT_disjoint_timer_query",5408"WEBGL_compressed_texture_etc", "WEBGL_compressed_texture_astc", "EXT_color_buffer_float",5409"WEBGL_compressed_texture_s3tc_srgb", "EXT_disjoint_timer_query_webgl2",5410// Old style prefixed forms of extensions (but still currently used on e.g. iPhone Xs as5411// tested on iOS 12.4.1):5412"WEBKIT_WEBGL_compressed_texture_pvrtc"];54135414function shouldEnableAutomatically(extension) {5415var ret = false;5416automaticallyEnabledExtensions.forEach(function(include) {5417if (extension.indexOf(include) != -1) {5418ret = true;5419}5420});5421return ret;5422}54235424var exts = GLctx.getSupportedExtensions() || []; // .getSupportedExtensions() can return null if context is lost, so coerce to empty array.5425exts.forEach(function(ext) {5426if (automaticallyEnabledExtensions.indexOf(ext) != -1) {5427GLctx.getExtension(ext); // Calling .getExtension enables that extension permanently, no need to store the return value to be enabled.5428}5429});5430},populateUniformTable:function(program) {5431var p = GL.programs[program];5432var ptable = GL.programInfos[program] = {5433uniforms: {},5434maxUniformLength: 0, // This is eagerly computed below, since we already enumerate all uniforms anyway.5435maxAttributeLength: -1, // This is lazily computed and cached, computed when/if first asked, "-1" meaning not computed yet.5436maxUniformBlockNameLength: -1 // Lazily computed as well5437};54385439var utable = ptable.uniforms;5440// A program's uniform table maps the string name of an uniform to an integer location of that uniform.5441// The global GL.uniforms map maps integer locations to WebGLUniformLocations.5442var numUniforms = GLctx.getProgramParameter(p, 0x8B86/*GL_ACTIVE_UNIFORMS*/);5443for (var i = 0; i < numUniforms; ++i) {5444var u = GLctx.getActiveUniform(p, i);54455446var name = u.name;5447ptable.maxUniformLength = Math.max(ptable.maxUniformLength, name.length+1);54485449// If we are dealing with an array, e.g. vec4 foo[3], strip off the array index part to canonicalize that "foo", "foo[]",5450// and "foo[0]" will mean the same. Loop below will populate foo[1] and foo[2].5451if (name.slice(-1) == ']') {5452name = name.slice(0, name.lastIndexOf('['));5453}54545455// Optimize memory usage slightly: If we have an array of uniforms, e.g. 'vec3 colors[3];', then5456// only store the string 'colors' in utable, and 'colors[0]', 'colors[1]' and 'colors[2]' will be parsed as 'colors'+i.5457// Note that for the GL.uniforms table, we still need to fetch the all WebGLUniformLocations for all the indices.5458var loc = GLctx.getUniformLocation(p, name);5459if (loc) {5460var id = GL.getNewId(GL.uniforms);5461utable[name] = [u.size, id];5462GL.uniforms[id] = loc;54635464for (var j = 1; j < u.size; ++j) {5465var n = name + '['+j+']';5466loc = GLctx.getUniformLocation(p, n);5467id = GL.getNewId(GL.uniforms);54685469GL.uniforms[id] = loc;5470}5471}5472}5473}};function _eglCreateContext(display, config, hmm, contextAttribs) {5474if (display != 62000 /* Magic ID for Emscripten 'default display' */) {5475EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);5476return 0;5477}54785479// EGL 1.4 spec says default EGL_CONTEXT_CLIENT_VERSION is GLES1, but this is not supported by Emscripten.5480// So user must pass EGL_CONTEXT_CLIENT_VERSION == 2 to initialize EGL.5481var glesContextVersion = 1;5482for(;;) {5483var param = HEAP32[((contextAttribs)>>2)];5484if (param == 0x3098 /*EGL_CONTEXT_CLIENT_VERSION*/) {5485glesContextVersion = HEAP32[(((contextAttribs)+(4))>>2)];5486} else if (param == 0x3038 /*EGL_NONE*/) {5487break;5488} else {5489/* EGL1.4 specifies only EGL_CONTEXT_CLIENT_VERSION as supported attribute */5490EGL.setErrorCode(0x3004 /*EGL_BAD_ATTRIBUTE*/);5491return 0;5492}5493contextAttribs += 8;5494}5495if (glesContextVersion != 2) {5496EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */);5497return 0; /* EGL_NO_CONTEXT */5498}54995500EGL.contextAttributes.majorVersion = glesContextVersion - 1; // WebGL 1 is GLES 2, WebGL2 is GLES35501EGL.contextAttributes.minorVersion = 0;55025503EGL.context = GL.createContext(Module['canvas'], EGL.contextAttributes);55045505if (EGL.context != 0) {5506EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);55075508// Run callbacks so that GL emulation works5509GL.makeContextCurrent(EGL.context);5510Module.useWebGL = true;5511Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });55125513// Note: This function only creates a context, but it shall not make it active.5514GL.makeContextCurrent(null);5515return 62004; // Magic ID for Emscripten EGLContext5516} else {5517EGL.setErrorCode(0x3009 /* EGL_BAD_MATCH */); // By the EGL 1.4 spec, an implementation that does not support GLES2 (WebGL in this case), this error code is set.5518return 0; /* EGL_NO_CONTEXT */5519}5520}55215522function _eglCreateWindowSurface(display, config, win, attrib_list) {5523if (display != 62000 /* Magic ID for Emscripten 'default display' */) {5524EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);5525return 0;5526}5527if (config != 62002 /* Magic ID for the only EGLConfig supported by Emscripten */) {5528EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */);5529return 0;5530}5531// TODO: Examine attrib_list! Parameters that can be present there are:5532// - EGL_RENDER_BUFFER (must be EGL_BACK_BUFFER)5533// - EGL_VG_COLORSPACE (can't be set)5534// - EGL_VG_ALPHA_FORMAT (can't be set)5535EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);5536return 62006; /* Magic ID for Emscripten 'default surface' */5537}55385539function _eglDestroyContext(display, context) {5540if (display != 62000 /* Magic ID for Emscripten 'default display' */) {5541EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);5542return 0;5543}5544if (context != 62004 /* Magic ID for Emscripten EGLContext */) {5545EGL.setErrorCode(0x3006 /* EGL_BAD_CONTEXT */);5546return 0;5547}55485549GL.deleteContext(EGL.context);5550EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);5551if (EGL.currentContext == context) {5552EGL.currentContext = 0;5553}5554return 1 /* EGL_TRUE */;5555}55565557function _eglDestroySurface(display, surface) {5558if (display != 62000 /* Magic ID for Emscripten 'default display' */) {5559EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);5560return 0;5561}5562if (surface != 62006 /* Magic ID for the only EGLSurface supported by Emscripten */) {5563EGL.setErrorCode(0x300D /* EGL_BAD_SURFACE */);5564return 1;5565}5566if (EGL.currentReadSurface == surface) {5567EGL.currentReadSurface = 0;5568}5569if (EGL.currentDrawSurface == surface) {5570EGL.currentDrawSurface = 0;5571}5572EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);5573return 1; /* Magic ID for Emscripten 'default surface' */5574}55755576function _eglGetConfigAttrib(display, config, attribute, value) {5577if (display != 62000 /* Magic ID for Emscripten 'default display' */) {5578EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);5579return 0;5580}5581if (config != 62002 /* Magic ID for the only EGLConfig supported by Emscripten */) {5582EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */);5583return 0;5584}5585if (!value) {5586EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);5587return 0;5588}5589EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);5590switch(attribute) {5591case 0x3020: // EGL_BUFFER_SIZE5592HEAP32[((value)>>2)]=EGL.contextAttributes.alpha ? 32 : 24;5593return 1;5594case 0x3021: // EGL_ALPHA_SIZE5595HEAP32[((value)>>2)]=EGL.contextAttributes.alpha ? 8 : 0;5596return 1;5597case 0x3022: // EGL_BLUE_SIZE5598HEAP32[((value)>>2)]=8;5599return 1;5600case 0x3023: // EGL_GREEN_SIZE5601HEAP32[((value)>>2)]=8;5602return 1;5603case 0x3024: // EGL_RED_SIZE5604HEAP32[((value)>>2)]=8;5605return 1;5606case 0x3025: // EGL_DEPTH_SIZE5607HEAP32[((value)>>2)]=EGL.contextAttributes.depth ? 24 : 0;5608return 1;5609case 0x3026: // EGL_STENCIL_SIZE5610HEAP32[((value)>>2)]=EGL.contextAttributes.stencil ? 8 : 0;5611return 1;5612case 0x3027: // EGL_CONFIG_CAVEAT5613// We can return here one of EGL_NONE (0x3038), EGL_SLOW_CONFIG (0x3050) or EGL_NON_CONFORMANT_CONFIG (0x3051).5614HEAP32[((value)>>2)]=0x3038;5615return 1;5616case 0x3028: // EGL_CONFIG_ID5617HEAP32[((value)>>2)]=62002;5618return 1;5619case 0x3029: // EGL_LEVEL5620HEAP32[((value)>>2)]=0;5621return 1;5622case 0x302A: // EGL_MAX_PBUFFER_HEIGHT5623HEAP32[((value)>>2)]=4096;5624return 1;5625case 0x302B: // EGL_MAX_PBUFFER_PIXELS5626HEAP32[((value)>>2)]=16777216;5627return 1;5628case 0x302C: // EGL_MAX_PBUFFER_WIDTH5629HEAP32[((value)>>2)]=4096;5630return 1;5631case 0x302D: // EGL_NATIVE_RENDERABLE5632HEAP32[((value)>>2)]=0;5633return 1;5634case 0x302E: // EGL_NATIVE_VISUAL_ID5635HEAP32[((value)>>2)]=0;5636return 1;5637case 0x302F: // EGL_NATIVE_VISUAL_TYPE5638HEAP32[((value)>>2)]=0x3038;5639return 1;5640case 0x3031: // EGL_SAMPLES5641HEAP32[((value)>>2)]=EGL.contextAttributes.antialias ? 4 : 0;5642return 1;5643case 0x3032: // EGL_SAMPLE_BUFFERS5644HEAP32[((value)>>2)]=EGL.contextAttributes.antialias ? 1 : 0;5645return 1;5646case 0x3033: // EGL_SURFACE_TYPE5647HEAP32[((value)>>2)]=0x4;5648return 1;5649case 0x3034: // EGL_TRANSPARENT_TYPE5650// If this returns EGL_TRANSPARENT_RGB (0x3052), transparency is used through color-keying. No such thing applies to Emscripten canvas.5651HEAP32[((value)>>2)]=0x3038;5652return 1;5653case 0x3035: // EGL_TRANSPARENT_BLUE_VALUE5654case 0x3036: // EGL_TRANSPARENT_GREEN_VALUE5655case 0x3037: // EGL_TRANSPARENT_RED_VALUE5656// "If EGL_TRANSPARENT_TYPE is EGL_NONE, then the values for EGL_TRANSPARENT_RED_VALUE, EGL_TRANSPARENT_GREEN_VALUE, and EGL_TRANSPARENT_BLUE_VALUE are undefined."5657HEAP32[((value)>>2)]=-1;5658return 1;5659case 0x3039: // EGL_BIND_TO_TEXTURE_RGB5660case 0x303A: // EGL_BIND_TO_TEXTURE_RGBA5661HEAP32[((value)>>2)]=0;5662return 1;5663case 0x303B: // EGL_MIN_SWAP_INTERVAL5664HEAP32[((value)>>2)]=0;5665return 1;5666case 0x303C: // EGL_MAX_SWAP_INTERVAL5667HEAP32[((value)>>2)]=1;5668return 1;5669case 0x303D: // EGL_LUMINANCE_SIZE5670case 0x303E: // EGL_ALPHA_MASK_SIZE5671HEAP32[((value)>>2)]=0;5672return 1;5673case 0x303F: // EGL_COLOR_BUFFER_TYPE5674// EGL has two types of buffers: EGL_RGB_BUFFER and EGL_LUMINANCE_BUFFER.5675HEAP32[((value)>>2)]=0x308E;5676return 1;5677case 0x3040: // EGL_RENDERABLE_TYPE5678// A bit combination of EGL_OPENGL_ES_BIT,EGL_OPENVG_BIT,EGL_OPENGL_ES2_BIT and EGL_OPENGL_BIT.5679HEAP32[((value)>>2)]=0x4;5680return 1;5681case 0x3042: // EGL_CONFORMANT5682// "EGL_CONFORMANT is a mask indicating if a client API context created with respect to the corresponding EGLConfig will pass the required conformance tests for that API."5683HEAP32[((value)>>2)]=0;5684return 1;5685default:5686EGL.setErrorCode(0x3004 /* EGL_BAD_ATTRIBUTE */);5687return 0;5688}5689}56905691function _eglGetDisplay(nativeDisplayType) {5692EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);5693// Note: As a 'conformant' implementation of EGL, we would prefer to init here only if the user5694// calls this function with EGL_DEFAULT_DISPLAY. Other display IDs would be preferred to be unsupported5695// and EGL_NO_DISPLAY returned. Uncomment the following code lines to do this.5696// Instead, an alternative route has been preferred, namely that the Emscripten EGL implementation5697// "emulates" X11, and eglGetDisplay is expected to accept/receive a pointer to an X11 Display object.5698// Therefore, be lax and allow anything to be passed in, and return the magic handle to our default EGLDisplay object.56995700// if (nativeDisplayType == 0 /* EGL_DEFAULT_DISPLAY */) {5701return 62000; // Magic ID for Emscripten 'default display'5702// }5703// else5704// return 0; // EGL_NO_DISPLAY5705}57065707function _eglGetError() {5708return EGL.errorCode;5709}57105711function _eglGetProcAddress(name_) {5712return _emscripten_GetProcAddress(name_);5713}57145715function _eglInitialize(display, majorVersion, minorVersion) {5716if (display == 62000 /* Magic ID for Emscripten 'default display' */) {5717if (majorVersion) {5718HEAP32[((majorVersion)>>2)]=1; // Advertise EGL Major version: '1'5719}5720if (minorVersion) {5721HEAP32[((minorVersion)>>2)]=4; // Advertise EGL Minor version: '4'5722}5723EGL.defaultDisplayInitialized = true;5724EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);5725return 1;5726}5727else {5728EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);5729return 0;5730}5731}57325733function _eglMakeCurrent(display, draw, read, context) {5734if (display != 62000 /* Magic ID for Emscripten 'default display' */) {5735EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);5736return 0 /* EGL_FALSE */;5737}5738//\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy.5739if (context != 0 && context != 62004 /* Magic ID for Emscripten EGLContext */) {5740EGL.setErrorCode(0x3006 /* EGL_BAD_CONTEXT */);5741return 0;5742}5743if ((read != 0 && read != 62006) || (draw != 0 && draw != 62006 /* Magic ID for Emscripten 'default surface' */)) {5744EGL.setErrorCode(0x300D /* EGL_BAD_SURFACE */);5745return 0;5746}57475748GL.makeContextCurrent(context ? EGL.context : null);57495750EGL.currentContext = context;5751EGL.currentDrawSurface = draw;5752EGL.currentReadSurface = read;5753EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);5754return 1 /* EGL_TRUE */;5755}57565757function _eglQueryString(display, name) {5758if (display != 62000 /* Magic ID for Emscripten 'default display' */) {5759EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);5760return 0;5761}5762//\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy.5763EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);5764if (EGL.stringCache[name]) return EGL.stringCache[name];5765var ret;5766switch(name) {5767case 0x3053 /* EGL_VENDOR */: ret = allocateUTF8("Emscripten"); break;5768case 0x3054 /* EGL_VERSION */: ret = allocateUTF8("1.4 Emscripten EGL"); break;5769case 0x3055 /* EGL_EXTENSIONS */: ret = allocateUTF8(""); break; // Currently not supporting any EGL extensions.5770case 0x308D /* EGL_CLIENT_APIS */: ret = allocateUTF8("OpenGL_ES"); break;5771default:5772EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);5773return 0;5774}5775EGL.stringCache[name] = ret;5776return ret;5777}57785779function _eglSwapBuffers() {57805781if (!EGL.defaultDisplayInitialized) {5782EGL.setErrorCode(0x3001 /* EGL_NOT_INITIALIZED */);5783} else if (!Module.ctx) {5784EGL.setErrorCode(0x3002 /* EGL_BAD_ACCESS */);5785} else if (Module.ctx.isContextLost()) {5786EGL.setErrorCode(0x300E /* EGL_CONTEXT_LOST */);5787} else {5788// According to documentation this does an implicit flush.5789// Due to discussion at https://github.com/emscripten-core/emscripten/pull/18715790// the flush was removed since this _may_ result in slowing code down.5791//_glFlush();5792EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);5793return 1 /* EGL_TRUE */;5794}5795return 0 /* EGL_FALSE */;5796}57975798function _eglSwapInterval(display, interval) {5799if (display != 62000 /* Magic ID for Emscripten 'default display' */) {5800EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);5801return 0;5802}5803if (interval == 0) _emscripten_set_main_loop_timing(0/*EM_TIMING_SETTIMEOUT*/, 0);5804else _emscripten_set_main_loop_timing(1/*EM_TIMING_RAF*/, interval);58055806EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);5807return 1;5808}58095810function _eglTerminate(display) {5811if (display != 62000 /* Magic ID for Emscripten 'default display' */) {5812EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);5813return 0;5814}5815EGL.currentContext = 0;5816EGL.currentReadSurface = 0;5817EGL.currentDrawSurface = 0;5818EGL.defaultDisplayInitialized = false;5819EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);5820return 1;5821}582258235824function _eglWaitClient() {5825EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);5826return 1;5827}function _eglWaitGL(5828) {5829return _eglWaitClient();5830}58315832function _eglWaitNative(nativeEngineId) {5833EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);5834return 1;5835}583658375838var JSEvents={keyEvent:0,mouseEvent:0,wheelEvent:0,uiEvent:0,focusEvent:0,deviceOrientationEvent:0,deviceMotionEvent:0,fullscreenChangeEvent:0,pointerlockChangeEvent:0,visibilityChangeEvent:0,touchEvent:0,previousFullscreenElement:null,previousScreenX:null,previousScreenY:null,removeEventListenersRegistered:false,removeAllEventListeners:function() {5839for(var i = JSEvents.eventHandlers.length-1; i >= 0; --i) {5840JSEvents._removeHandler(i);5841}5842JSEvents.eventHandlers = [];5843JSEvents.deferredCalls = [];5844},registerRemoveEventListeners:function() {5845if (!JSEvents.removeEventListenersRegistered) {5846__ATEXIT__.push(JSEvents.removeAllEventListeners);5847JSEvents.removeEventListenersRegistered = true;5848}5849},deferredCalls:[],deferCall:function(targetFunction, precedence, argsList) {5850function arraysHaveEqualContent(arrA, arrB) {5851if (arrA.length != arrB.length) return false;58525853for(var i in arrA) {5854if (arrA[i] != arrB[i]) return false;5855}5856return true;5857}5858// Test if the given call was already queued, and if so, don't add it again.5859for(var i in JSEvents.deferredCalls) {5860var call = JSEvents.deferredCalls[i];5861if (call.targetFunction == targetFunction && arraysHaveEqualContent(call.argsList, argsList)) {5862return;5863}5864}5865JSEvents.deferredCalls.push({5866targetFunction: targetFunction,5867precedence: precedence,5868argsList: argsList5869});58705871JSEvents.deferredCalls.sort(function(x,y) { return x.precedence < y.precedence; });5872},removeDeferredCalls:function(targetFunction) {5873for(var i = 0; i < JSEvents.deferredCalls.length; ++i) {5874if (JSEvents.deferredCalls[i].targetFunction == targetFunction) {5875JSEvents.deferredCalls.splice(i, 1);5876--i;5877}5878}5879},canPerformEventHandlerRequests:function() {5880return JSEvents.inEventHandler && JSEvents.currentEventHandler.allowsDeferredCalls;5881},runDeferredCalls:function() {5882if (!JSEvents.canPerformEventHandlerRequests()) {5883return;5884}5885for(var i = 0; i < JSEvents.deferredCalls.length; ++i) {5886var call = JSEvents.deferredCalls[i];5887JSEvents.deferredCalls.splice(i, 1);5888--i;5889call.targetFunction.apply(null, call.argsList);5890}5891},inEventHandler:0,currentEventHandler:null,eventHandlers:[],removeAllHandlersOnTarget:function(target, eventTypeString) {5892for(var i = 0; i < JSEvents.eventHandlers.length; ++i) {5893if (JSEvents.eventHandlers[i].target == target &&5894(!eventTypeString || eventTypeString == JSEvents.eventHandlers[i].eventTypeString)) {5895JSEvents._removeHandler(i--);5896}5897}5898},_removeHandler:function(i) {5899var h = JSEvents.eventHandlers[i];5900h.target.removeEventListener(h.eventTypeString, h.eventListenerFunc, h.useCapture);5901JSEvents.eventHandlers.splice(i, 1);5902},registerOrRemoveHandler:function(eventHandler) {5903var jsEventHandler = function jsEventHandler(event) {5904// Increment nesting count for the event handler.5905++JSEvents.inEventHandler;5906JSEvents.currentEventHandler = eventHandler;5907// Process any old deferred calls the user has placed.5908JSEvents.runDeferredCalls();5909// Process the actual event, calls back to user C code handler.5910eventHandler.handlerFunc(event);5911// Process any new deferred calls that were placed right now from this event handler.5912JSEvents.runDeferredCalls();5913// Out of event handler - restore nesting count.5914--JSEvents.inEventHandler;5915};59165917if (eventHandler.callbackfunc) {5918eventHandler.eventListenerFunc = jsEventHandler;5919eventHandler.target.addEventListener(eventHandler.eventTypeString, jsEventHandler, eventHandler.useCapture);5920JSEvents.eventHandlers.push(eventHandler);5921JSEvents.registerRemoveEventListeners();5922} else {5923for(var i = 0; i < JSEvents.eventHandlers.length; ++i) {5924if (JSEvents.eventHandlers[i].target == eventHandler.target5925&& JSEvents.eventHandlers[i].eventTypeString == eventHandler.eventTypeString) {5926JSEvents._removeHandler(i--);5927}5928}5929}5930},getNodeNameForTarget:function(target) {5931if (!target) return '';5932if (target == window) return '#window';5933if (target == screen) return '#screen';5934return (target && target.nodeName) ? target.nodeName : '';5935},fullscreenEnabled:function() {5936return document.fullscreenEnabled5937// Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitFullscreenEnabled.5938// TODO: If Safari at some point ships with unprefixed version, update the version check above.5939|| document.webkitFullscreenEnabled5940;5941}};59425943var __currentFullscreenStrategy={};594459455946594759485949595059515952function __maybeCStringToJsString(cString) {5953return cString === cString + 0 ? UTF8ToString(cString) : cString;5954}59555956var __specialEventTargets=[0, typeof document !== 'undefined' ? document : 0, typeof window !== 'undefined' ? window : 0];function __findEventTarget(target) {5957var domElement = __specialEventTargets[target] || (typeof document !== 'undefined' ? document.querySelector(__maybeCStringToJsString(target)) : undefined);5958return domElement;5959}function __findCanvasEventTarget(target) { return __findEventTarget(target); }function _emscripten_get_canvas_element_size(target, width, height) {5960var canvas = __findCanvasEventTarget(target);5961if (!canvas) return -4;5962HEAP32[((width)>>2)]=canvas.width;5963HEAP32[((height)>>2)]=canvas.height;5964}function __get_canvas_element_size(target) {5965var stackTop = stackSave();5966var w = stackAlloc(8);5967var h = w + 4;59685969var targetInt = stackAlloc(target.id.length+1);5970stringToUTF8(target.id, targetInt, target.id.length+1);5971var ret = _emscripten_get_canvas_element_size(targetInt, w, h);5972var size = [HEAP32[((w)>>2)], HEAP32[((h)>>2)]];5973stackRestore(stackTop);5974return size;5975}597659775978function _emscripten_set_canvas_element_size(target, width, height) {5979var canvas = __findCanvasEventTarget(target);5980if (!canvas) return -4;5981canvas.width = width;5982canvas.height = height;5983return 0;5984}function __set_canvas_element_size(target, width, height) {5985if (!target.controlTransferredOffscreen) {5986target.width = width;5987target.height = height;5988} else {5989// This function is being called from high-level JavaScript code instead of asm.js/Wasm,5990// and it needs to synchronously proxy over to another thread, so marshal the string onto the heap to do the call.5991var stackTop = stackSave();5992var targetInt = stackAlloc(target.id.length+1);5993stringToUTF8(target.id, targetInt, target.id.length+1);5994_emscripten_set_canvas_element_size(targetInt, width, height);5995stackRestore(stackTop);5996}5997}function __registerRestoreOldStyle(canvas) {5998var canvasSize = __get_canvas_element_size(canvas);5999var oldWidth = canvasSize[0];6000var oldHeight = canvasSize[1];6001var oldCssWidth = canvas.style.width;6002var oldCssHeight = canvas.style.height;6003var oldBackgroundColor = canvas.style.backgroundColor; // Chrome reads color from here.6004var oldDocumentBackgroundColor = document.body.style.backgroundColor; // IE11 reads color from here.6005// Firefox always has black background color.6006var oldPaddingLeft = canvas.style.paddingLeft; // Chrome, FF, Safari6007var oldPaddingRight = canvas.style.paddingRight;6008var oldPaddingTop = canvas.style.paddingTop;6009var oldPaddingBottom = canvas.style.paddingBottom;6010var oldMarginLeft = canvas.style.marginLeft; // IE116011var oldMarginRight = canvas.style.marginRight;6012var oldMarginTop = canvas.style.marginTop;6013var oldMarginBottom = canvas.style.marginBottom;6014var oldDocumentBodyMargin = document.body.style.margin;6015var oldDocumentOverflow = document.documentElement.style.overflow; // Chrome, Firefox6016var oldDocumentScroll = document.body.scroll; // IE6017var oldImageRendering = canvas.style.imageRendering;60186019function restoreOldStyle() {6020var fullscreenElement = document.fullscreenElement6021|| document.webkitFullscreenElement6022|| document.msFullscreenElement6023;6024if (!fullscreenElement) {6025document.removeEventListener('fullscreenchange', restoreOldStyle);602660276028// Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)6029// As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version.6030document.removeEventListener('webkitfullscreenchange', restoreOldStyle);603160326033__set_canvas_element_size(canvas, oldWidth, oldHeight);60346035canvas.style.width = oldCssWidth;6036canvas.style.height = oldCssHeight;6037canvas.style.backgroundColor = oldBackgroundColor; // Chrome6038// IE11 hack: assigning 'undefined' or an empty string to document.body.style.backgroundColor has no effect, so first assign back the default color6039// before setting the undefined value. Setting undefined value is also important, or otherwise we would later treat that as something that the user6040// had explicitly set so subsequent fullscreen transitions would not set background color properly.6041if (!oldDocumentBackgroundColor) document.body.style.backgroundColor = 'white';6042document.body.style.backgroundColor = oldDocumentBackgroundColor; // IE116043canvas.style.paddingLeft = oldPaddingLeft; // Chrome, FF, Safari6044canvas.style.paddingRight = oldPaddingRight;6045canvas.style.paddingTop = oldPaddingTop;6046canvas.style.paddingBottom = oldPaddingBottom;6047canvas.style.marginLeft = oldMarginLeft; // IE116048canvas.style.marginRight = oldMarginRight;6049canvas.style.marginTop = oldMarginTop;6050canvas.style.marginBottom = oldMarginBottom;6051document.body.style.margin = oldDocumentBodyMargin;6052document.documentElement.style.overflow = oldDocumentOverflow; // Chrome, Firefox6053document.body.scroll = oldDocumentScroll; // IE6054canvas.style.imageRendering = oldImageRendering;6055if (canvas.GLctxObject) canvas.GLctxObject.GLctx.viewport(0, 0, oldWidth, oldHeight);60566057if (__currentFullscreenStrategy.canvasResizedCallback) {6058dynCall_iiii(__currentFullscreenStrategy.canvasResizedCallback, 37, 0, __currentFullscreenStrategy.canvasResizedCallbackUserData);6059}6060}6061}6062document.addEventListener('fullscreenchange', restoreOldStyle);6063// Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)6064// As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version.6065document.addEventListener('webkitfullscreenchange', restoreOldStyle);6066return restoreOldStyle;6067}60686069function __setLetterbox(element, topBottom, leftRight) {6070// Cannot use margin to specify letterboxes in FF or Chrome, since those ignore margins in fullscreen mode.6071element.style.paddingLeft = element.style.paddingRight = leftRight + 'px';6072element.style.paddingTop = element.style.paddingBottom = topBottom + 'px';6073}60746075function __getBoundingClientRect(e) {6076return __specialEventTargets.indexOf(e) < 0 ? e.getBoundingClientRect() : {'left':0,'top':0};6077}function _JSEvents_resizeCanvasForFullscreen(target, strategy) {6078var restoreOldStyle = __registerRestoreOldStyle(target);6079var cssWidth = strategy.softFullscreen ? innerWidth : screen.width;6080var cssHeight = strategy.softFullscreen ? innerHeight : screen.height;6081var rect = __getBoundingClientRect(target);6082var windowedCssWidth = rect.width;6083var windowedCssHeight = rect.height;6084var canvasSize = __get_canvas_element_size(target);6085var windowedRttWidth = canvasSize[0];6086var windowedRttHeight = canvasSize[1];60876088if (strategy.scaleMode == 3) {6089__setLetterbox(target, (cssHeight - windowedCssHeight) / 2, (cssWidth - windowedCssWidth) / 2);6090cssWidth = windowedCssWidth;6091cssHeight = windowedCssHeight;6092} else if (strategy.scaleMode == 2) {6093if (cssWidth*windowedRttHeight < windowedRttWidth*cssHeight) {6094var desiredCssHeight = windowedRttHeight * cssWidth / windowedRttWidth;6095__setLetterbox(target, (cssHeight - desiredCssHeight) / 2, 0);6096cssHeight = desiredCssHeight;6097} else {6098var desiredCssWidth = windowedRttWidth * cssHeight / windowedRttHeight;6099__setLetterbox(target, 0, (cssWidth - desiredCssWidth) / 2);6100cssWidth = desiredCssWidth;6101}6102}61036104// If we are adding padding, must choose a background color or otherwise Chrome will give the6105// padding a default white color. Do it only if user has not customized their own background color.6106if (!target.style.backgroundColor) target.style.backgroundColor = 'black';6107// IE11 does the same, but requires the color to be set in the document body.6108if (!document.body.style.backgroundColor) document.body.style.backgroundColor = 'black'; // IE116109// Firefox always shows black letterboxes independent of style color.61106111target.style.width = cssWidth + 'px';6112target.style.height = cssHeight + 'px';61136114if (strategy.filteringMode == 1) {6115target.style.imageRendering = 'optimizeSpeed';6116target.style.imageRendering = '-moz-crisp-edges';6117target.style.imageRendering = '-o-crisp-edges';6118target.style.imageRendering = '-webkit-optimize-contrast';6119target.style.imageRendering = 'optimize-contrast';6120target.style.imageRendering = 'crisp-edges';6121target.style.imageRendering = 'pixelated';6122}61236124var dpiScale = (strategy.canvasResolutionScaleMode == 2) ? devicePixelRatio : 1;6125if (strategy.canvasResolutionScaleMode != 0) {6126var newWidth = (cssWidth * dpiScale)|0;6127var newHeight = (cssHeight * dpiScale)|0;6128__set_canvas_element_size(target, newWidth, newHeight);6129if (target.GLctxObject) target.GLctxObject.GLctx.viewport(0, 0, newWidth, newHeight);6130}6131return restoreOldStyle;6132}function _JSEvents_requestFullscreen(target, strategy) {6133// EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT + EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE is a mode where no extra logic is performed to the DOM elements.6134if (strategy.scaleMode != 0 || strategy.canvasResolutionScaleMode != 0) {6135_JSEvents_resizeCanvasForFullscreen(target, strategy);6136}61376138if (target.requestFullscreen) {6139target.requestFullscreen();6140} else if (target.webkitRequestFullscreen) {6141target.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);6142} else {6143return JSEvents.fullscreenEnabled() ? -3 : -1;6144}61456146if (strategy.canvasResizedCallback) {6147dynCall_iiii(strategy.canvasResizedCallback, 37, 0, strategy.canvasResizedCallbackUserData);6148}61496150return 0;6151}function _emscripten_exit_fullscreen() {6152if (!JSEvents.fullscreenEnabled()) return -1;6153// Make sure no queued up calls will fire after this.6154JSEvents.removeDeferredCalls(_JSEvents_requestFullscreen);61556156var d = __specialEventTargets[1];6157if (d.exitFullscreen) {6158d.fullscreenElement && d.exitFullscreen();6159} else if (d.webkitExitFullscreen) {6160d.webkitFullscreenElement && d.webkitExitFullscreen();6161} else {6162return -1;6163}61646165return 0;6166}616761686169function __requestPointerLock(target) {6170if (target.requestPointerLock) {6171target.requestPointerLock();6172} else if (target.msRequestPointerLock) {6173target.msRequestPointerLock();6174} else {6175// document.body is known to accept pointer lock, so use that to differentiate if the user passed a bad element,6176// or if the whole browser just doesn't support the feature.6177if (document.body.requestPointerLock6178|| document.body.msRequestPointerLock6179) {6180return -3;6181} else {6182return -1;6183}6184}6185return 0;6186}function _emscripten_exit_pointerlock() {6187// Make sure no queued up calls will fire after this.6188JSEvents.removeDeferredCalls(__requestPointerLock);61896190if (document.exitPointerLock) {6191document.exitPointerLock();6192} else if (document.msExitPointerLock) {6193document.msExitPointerLock();6194} else {6195return -1;6196}6197return 0;6198}61996200function _emscripten_get_device_pixel_ratio() {6201return (typeof devicePixelRatio === 'number' && devicePixelRatio) || 1.0;6202}62036204function _emscripten_get_element_css_size(target, width, height) {6205target = __findEventTarget(target);6206if (!target) return -4;62076208var rect = __getBoundingClientRect(target);6209HEAPF64[((width)>>3)]=rect.width;6210HEAPF64[((height)>>3)]=rect.height;62116212return 0;6213}621462156216function __fillGamepadEventData(eventStruct, e) {6217HEAPF64[((eventStruct)>>3)]=e.timestamp;6218for(var i = 0; i < e.axes.length; ++i) {6219HEAPF64[(((eventStruct+i*8)+(16))>>3)]=e.axes[i];6220}6221for(var i = 0; i < e.buttons.length; ++i) {6222if (typeof(e.buttons[i]) === 'object') {6223HEAPF64[(((eventStruct+i*8)+(528))>>3)]=e.buttons[i].value;6224} else {6225HEAPF64[(((eventStruct+i*8)+(528))>>3)]=e.buttons[i];6226}6227}6228for(var i = 0; i < e.buttons.length; ++i) {6229if (typeof(e.buttons[i]) === 'object') {6230HEAP32[(((eventStruct+i*4)+(1040))>>2)]=e.buttons[i].pressed;6231} else {6232// Assigning a boolean to HEAP32, that's ok, but Closure would like to warn about it:6233/** @suppress {checkTypes} */6234HEAP32[(((eventStruct+i*4)+(1040))>>2)]=e.buttons[i] == 1;6235}6236}6237HEAP32[(((eventStruct)+(1296))>>2)]=e.connected;6238HEAP32[(((eventStruct)+(1300))>>2)]=e.index;6239HEAP32[(((eventStruct)+(8))>>2)]=e.axes.length;6240HEAP32[(((eventStruct)+(12))>>2)]=e.buttons.length;6241stringToUTF8(e.id, eventStruct + 1304, 64);6242stringToUTF8(e.mapping, eventStruct + 1368, 64);6243}function _emscripten_get_gamepad_status(index, gamepadState) {6244if (!JSEvents.lastGamepadState) throw 'emscripten_get_gamepad_status() can only be called after having first called emscripten_sample_gamepad_data() and that function has returned EMSCRIPTEN_RESULT_SUCCESS!';62456246// INVALID_PARAM is returned on a Gamepad index that never was there.6247if (index < 0 || index >= JSEvents.lastGamepadState.length) return -5;62486249// NO_DATA is returned on a Gamepad index that was removed.6250// For previously disconnected gamepads there should be an empty slot (null/undefined/false) at the index.6251// This is because gamepads must keep their original position in the array.6252// For example, removing the first of two gamepads produces [null/undefined/false, gamepad].6253if (!JSEvents.lastGamepadState[index]) return -7;62546255__fillGamepadEventData(gamepadState, JSEvents.lastGamepadState[index]);6256return 0;6257}62586259function _emscripten_get_num_gamepads() {6260if (!JSEvents.lastGamepadState) throw 'emscripten_get_num_gamepads() can only be called after having first called emscripten_sample_gamepad_data() and that function has returned EMSCRIPTEN_RESULT_SUCCESS!';6261// N.B. Do not call emscripten_get_num_gamepads() unless having first called emscripten_sample_gamepad_data(), and that has returned EMSCRIPTEN_RESULT_SUCCESS.6262// Otherwise the following line will throw an exception.6263return JSEvents.lastGamepadState.length;6264}62656266function _emscripten_get_sbrk_ptr() {6267return 14350080;6268}62696270function _emscripten_glActiveTexture(x0) { GLctx['activeTexture'](x0) }62716272function _emscripten_glAttachShader(program, shader) {6273GLctx.attachShader(GL.programs[program],6274GL.shaders[shader]);6275}62766277function _emscripten_glBeginQueryEXT(target, id) {6278GLctx.disjointTimerQueryExt['beginQueryEXT'](target, GL.timerQueriesEXT[id]);6279}62806281function _emscripten_glBindAttribLocation(program, index, name) {6282GLctx.bindAttribLocation(GL.programs[program], index, UTF8ToString(name));6283}62846285function _emscripten_glBindBuffer(target, buffer) {62866287GLctx.bindBuffer(target, GL.buffers[buffer]);6288}62896290function _emscripten_glBindFramebuffer(target, framebuffer) {62916292GLctx.bindFramebuffer(target, GL.framebuffers[framebuffer]);62936294}62956296function _emscripten_glBindRenderbuffer(target, renderbuffer) {6297GLctx.bindRenderbuffer(target, GL.renderbuffers[renderbuffer]);6298}62996300function _emscripten_glBindTexture(target, texture) {6301GLctx.bindTexture(target, GL.textures[texture]);6302}63036304function _emscripten_glBindVertexArrayOES(vao) {6305GLctx['bindVertexArray'](GL.vaos[vao]);6306}63076308function _emscripten_glBlendColor(x0, x1, x2, x3) { GLctx['blendColor'](x0, x1, x2, x3) }63096310function _emscripten_glBlendEquation(x0) { GLctx['blendEquation'](x0) }63116312function _emscripten_glBlendEquationSeparate(x0, x1) { GLctx['blendEquationSeparate'](x0, x1) }63136314function _emscripten_glBlendFunc(x0, x1) { GLctx['blendFunc'](x0, x1) }63156316function _emscripten_glBlendFuncSeparate(x0, x1, x2, x3) { GLctx['blendFuncSeparate'](x0, x1, x2, x3) }63176318function _emscripten_glBufferData(target, size, data, usage) {6319// N.b. here first form specifies a heap subarray, second form an integer size, so the ?: code here is polymorphic. It is advised to avoid6320// randomly mixing both uses in calling code, to avoid any potential JS engine JIT issues.6321GLctx.bufferData(target, data ? HEAPU8.subarray(data, data+size) : size, usage);6322}63236324function _emscripten_glBufferSubData(target, offset, size, data) {6325GLctx.bufferSubData(target, offset, HEAPU8.subarray(data, data+size));6326}63276328function _emscripten_glCheckFramebufferStatus(x0) { return GLctx['checkFramebufferStatus'](x0) }63296330function _emscripten_glClear(x0) { GLctx['clear'](x0) }63316332function _emscripten_glClearColor(x0, x1, x2, x3) { GLctx['clearColor'](x0, x1, x2, x3) }63336334function _emscripten_glClearDepthf(x0) { GLctx['clearDepth'](x0) }63356336function _emscripten_glClearStencil(x0) { GLctx['clearStencil'](x0) }63376338function _emscripten_glColorMask(red, green, blue, alpha) {6339GLctx.colorMask(!!red, !!green, !!blue, !!alpha);6340}63416342function _emscripten_glCompileShader(shader) {6343GLctx.compileShader(GL.shaders[shader]);6344}63456346function _emscripten_glCompressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, data) {6347GLctx['compressedTexImage2D'](target, level, internalFormat, width, height, border, data ? HEAPU8.subarray((data),(data+imageSize)) : null);6348}63496350function _emscripten_glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data) {6351GLctx['compressedTexSubImage2D'](target, level, xoffset, yoffset, width, height, format, data ? HEAPU8.subarray((data),(data+imageSize)) : null);6352}63536354function _emscripten_glCopyTexImage2D(x0, x1, x2, x3, x4, x5, x6, x7) { GLctx['copyTexImage2D'](x0, x1, x2, x3, x4, x5, x6, x7) }63556356function _emscripten_glCopyTexSubImage2D(x0, x1, x2, x3, x4, x5, x6, x7) { GLctx['copyTexSubImage2D'](x0, x1, x2, x3, x4, x5, x6, x7) }63576358function _emscripten_glCreateProgram() {6359var id = GL.getNewId(GL.programs);6360var program = GLctx.createProgram();6361program.name = id;6362GL.programs[id] = program;6363return id;6364}63656366function _emscripten_glCreateShader(shaderType) {6367var id = GL.getNewId(GL.shaders);6368GL.shaders[id] = GLctx.createShader(shaderType);6369return id;6370}63716372function _emscripten_glCullFace(x0) { GLctx['cullFace'](x0) }63736374function _emscripten_glDeleteBuffers(n, buffers) {6375for (var i = 0; i < n; i++) {6376var id = HEAP32[(((buffers)+(i*4))>>2)];6377var buffer = GL.buffers[id];63786379// From spec: "glDeleteBuffers silently ignores 0's and names that do not6380// correspond to existing buffer objects."6381if (!buffer) continue;63826383GLctx.deleteBuffer(buffer);6384buffer.name = 0;6385GL.buffers[id] = null;63866387if (id == GL.currArrayBuffer) GL.currArrayBuffer = 0;6388if (id == GL.currElementArrayBuffer) GL.currElementArrayBuffer = 0;6389}6390}63916392function _emscripten_glDeleteFramebuffers(n, framebuffers) {6393for (var i = 0; i < n; ++i) {6394var id = HEAP32[(((framebuffers)+(i*4))>>2)];6395var framebuffer = GL.framebuffers[id];6396if (!framebuffer) continue; // GL spec: "glDeleteFramebuffers silently ignores 0s and names that do not correspond to existing framebuffer objects".6397GLctx.deleteFramebuffer(framebuffer);6398framebuffer.name = 0;6399GL.framebuffers[id] = null;6400}6401}64026403function _emscripten_glDeleteProgram(id) {6404if (!id) return;6405var program = GL.programs[id];6406if (!program) { // glDeleteProgram actually signals an error when deleting a nonexisting object, unlike some other GL delete functions.6407GL.recordError(0x501 /* GL_INVALID_VALUE */);6408return;6409}6410GLctx.deleteProgram(program);6411program.name = 0;6412GL.programs[id] = null;6413GL.programInfos[id] = null;6414}64156416function _emscripten_glDeleteQueriesEXT(n, ids) {6417for (var i = 0; i < n; i++) {6418var id = HEAP32[(((ids)+(i*4))>>2)];6419var query = GL.timerQueriesEXT[id];6420if (!query) continue; // GL spec: "unused names in ids are ignored, as is the name zero."6421GLctx.disjointTimerQueryExt['deleteQueryEXT'](query);6422GL.timerQueriesEXT[id] = null;6423}6424}64256426function _emscripten_glDeleteRenderbuffers(n, renderbuffers) {6427for (var i = 0; i < n; i++) {6428var id = HEAP32[(((renderbuffers)+(i*4))>>2)];6429var renderbuffer = GL.renderbuffers[id];6430if (!renderbuffer) continue; // GL spec: "glDeleteRenderbuffers silently ignores 0s and names that do not correspond to existing renderbuffer objects".6431GLctx.deleteRenderbuffer(renderbuffer);6432renderbuffer.name = 0;6433GL.renderbuffers[id] = null;6434}6435}64366437function _emscripten_glDeleteShader(id) {6438if (!id) return;6439var shader = GL.shaders[id];6440if (!shader) { // glDeleteShader actually signals an error when deleting a nonexisting object, unlike some other GL delete functions.6441GL.recordError(0x501 /* GL_INVALID_VALUE */);6442return;6443}6444GLctx.deleteShader(shader);6445GL.shaders[id] = null;6446}64476448function _emscripten_glDeleteTextures(n, textures) {6449for (var i = 0; i < n; i++) {6450var id = HEAP32[(((textures)+(i*4))>>2)];6451var texture = GL.textures[id];6452if (!texture) continue; // GL spec: "glDeleteTextures silently ignores 0s and names that do not correspond to existing textures".6453GLctx.deleteTexture(texture);6454texture.name = 0;6455GL.textures[id] = null;6456}6457}64586459function _emscripten_glDeleteVertexArraysOES(n, vaos) {6460for (var i = 0; i < n; i++) {6461var id = HEAP32[(((vaos)+(i*4))>>2)];6462GLctx['deleteVertexArray'](GL.vaos[id]);6463GL.vaos[id] = null;6464}6465}64666467function _emscripten_glDepthFunc(x0) { GLctx['depthFunc'](x0) }64686469function _emscripten_glDepthMask(flag) {6470GLctx.depthMask(!!flag);6471}64726473function _emscripten_glDepthRangef(x0, x1) { GLctx['depthRange'](x0, x1) }64746475function _emscripten_glDetachShader(program, shader) {6476GLctx.detachShader(GL.programs[program],6477GL.shaders[shader]);6478}64796480function _emscripten_glDisable(x0) { GLctx['disable'](x0) }64816482function _emscripten_glDisableVertexAttribArray(index) {6483GLctx.disableVertexAttribArray(index);6484}64856486function _emscripten_glDrawArrays(mode, first, count) {64876488GLctx.drawArrays(mode, first, count);64896490}64916492function _emscripten_glDrawArraysInstancedANGLE(mode, first, count, primcount) {6493GLctx['drawArraysInstanced'](mode, first, count, primcount);6494}649564966497var __tempFixedLengthArray=[];function _emscripten_glDrawBuffersWEBGL(n, bufs) {64986499var bufArray = __tempFixedLengthArray[n];6500for (var i = 0; i < n; i++) {6501bufArray[i] = HEAP32[(((bufs)+(i*4))>>2)];6502}65036504GLctx['drawBuffers'](bufArray);6505}65066507function _emscripten_glDrawElements(mode, count, type, indices) {65086509GLctx.drawElements(mode, count, type, indices);65106511}65126513function _emscripten_glDrawElementsInstancedANGLE(mode, count, type, indices, primcount) {6514GLctx['drawElementsInstanced'](mode, count, type, indices, primcount);6515}65166517function _emscripten_glEnable(x0) { GLctx['enable'](x0) }65186519function _emscripten_glEnableVertexAttribArray(index) {6520GLctx.enableVertexAttribArray(index);6521}65226523function _emscripten_glEndQueryEXT(target) {6524GLctx.disjointTimerQueryExt['endQueryEXT'](target);6525}65266527function _emscripten_glFinish() { GLctx['finish']() }65286529function _emscripten_glFlush() { GLctx['flush']() }65306531function _emscripten_glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer) {6532GLctx.framebufferRenderbuffer(target, attachment, renderbuffertarget,6533GL.renderbuffers[renderbuffer]);6534}65356536function _emscripten_glFramebufferTexture2D(target, attachment, textarget, texture, level) {6537GLctx.framebufferTexture2D(target, attachment, textarget,6538GL.textures[texture], level);6539}65406541function _emscripten_glFrontFace(x0) { GLctx['frontFace'](x0) }654265436544function __glGenObject(n, buffers, createFunction, objectTable6545) {6546for (var i = 0; i < n; i++) {6547var buffer = GLctx[createFunction]();6548var id = buffer && GL.getNewId(objectTable);6549if (buffer) {6550buffer.name = id;6551objectTable[id] = buffer;6552} else {6553GL.recordError(0x502 /* GL_INVALID_OPERATION */);6554}6555HEAP32[(((buffers)+(i*4))>>2)]=id;6556}6557}function _emscripten_glGenBuffers(n, buffers) {6558__glGenObject(n, buffers, 'createBuffer', GL.buffers6559);6560}65616562function _emscripten_glGenFramebuffers(n, ids) {6563__glGenObject(n, ids, 'createFramebuffer', GL.framebuffers6564);6565}65666567function _emscripten_glGenQueriesEXT(n, ids) {6568for (var i = 0; i < n; i++) {6569var query = GLctx.disjointTimerQueryExt['createQueryEXT']();6570if (!query) {6571GL.recordError(0x502 /* GL_INVALID_OPERATION */);6572while(i < n) HEAP32[(((ids)+(i++*4))>>2)]=0;6573return;6574}6575var id = GL.getNewId(GL.timerQueriesEXT);6576query.name = id;6577GL.timerQueriesEXT[id] = query;6578HEAP32[(((ids)+(i*4))>>2)]=id;6579}6580}65816582function _emscripten_glGenRenderbuffers(n, renderbuffers) {6583__glGenObject(n, renderbuffers, 'createRenderbuffer', GL.renderbuffers6584);6585}65866587function _emscripten_glGenTextures(n, textures) {6588__glGenObject(n, textures, 'createTexture', GL.textures6589);6590}65916592function _emscripten_glGenVertexArraysOES(n, arrays) {6593__glGenObject(n, arrays, 'createVertexArray', GL.vaos6594);6595}65966597function _emscripten_glGenerateMipmap(x0) { GLctx['generateMipmap'](x0) }65986599function _emscripten_glGetActiveAttrib(program, index, bufSize, length, size, type, name) {6600program = GL.programs[program];6601var info = GLctx.getActiveAttrib(program, index);6602if (!info) return; // If an error occurs, nothing will be written to length, size and type and name.66036604var numBytesWrittenExclNull = (bufSize > 0 && name) ? stringToUTF8(info.name, name, bufSize) : 0;6605if (length) HEAP32[((length)>>2)]=numBytesWrittenExclNull;6606if (size) HEAP32[((size)>>2)]=info.size;6607if (type) HEAP32[((type)>>2)]=info.type;6608}66096610function _emscripten_glGetActiveUniform(program, index, bufSize, length, size, type, name) {6611program = GL.programs[program];6612var info = GLctx.getActiveUniform(program, index);6613if (!info) return; // If an error occurs, nothing will be written to length, size, type and name.66146615var numBytesWrittenExclNull = (bufSize > 0 && name) ? stringToUTF8(info.name, name, bufSize) : 0;6616if (length) HEAP32[((length)>>2)]=numBytesWrittenExclNull;6617if (size) HEAP32[((size)>>2)]=info.size;6618if (type) HEAP32[((type)>>2)]=info.type;6619}66206621function _emscripten_glGetAttachedShaders(program, maxCount, count, shaders) {6622var result = GLctx.getAttachedShaders(GL.programs[program]);6623var len = result.length;6624if (len > maxCount) {6625len = maxCount;6626}6627HEAP32[((count)>>2)]=len;6628for (var i = 0; i < len; ++i) {6629var id = GL.shaders.indexOf(result[i]);6630HEAP32[(((shaders)+(i*4))>>2)]=id;6631}6632}66336634function _emscripten_glGetAttribLocation(program, name) {6635return GLctx.getAttribLocation(GL.programs[program], UTF8ToString(name));6636}66376638663966406641function readI53FromI64(ptr) {6642return HEAPU32[ptr>>2] + HEAP32[ptr+4>>2] * 4294967296;6643}66446645function readI53FromU64(ptr) {6646return HEAPU32[ptr>>2] + HEAPU32[ptr+4>>2] * 4294967296;6647}function writeI53ToI64(ptr, num) {6648HEAPU32[ptr>>2] = num;6649HEAPU32[ptr+4>>2] = (num - HEAPU32[ptr>>2])/4294967296;6650var deserialized = (num >= 0) ? readI53FromU64(ptr) : readI53FromI64(ptr);6651if (deserialized != num) warnOnce('writeI53ToI64() out of range: serialized JS Number ' + num + ' to Wasm heap as bytes lo=0x' + HEAPU32[ptr>>2].toString(16) + ', hi=0x' + HEAPU32[ptr+4>>2].toString(16) + ', which deserializes back to ' + deserialized + ' instead!');6652}function emscriptenWebGLGet(name_, p, type) {6653// Guard against user passing a null pointer.6654// Note that GLES2 spec does not say anything about how passing a null pointer should be treated.6655// Testing on desktop core GL 3, the application crashes on glGetIntegerv to a null pointer, but6656// better to report an error instead of doing anything random.6657if (!p) {6658GL.recordError(0x501 /* GL_INVALID_VALUE */);6659return;6660}6661var ret = undefined;6662switch(name_) { // Handle a few trivial GLES values6663case 0x8DFA: // GL_SHADER_COMPILER6664ret = 1;6665break;6666case 0x8DF8: // GL_SHADER_BINARY_FORMATS6667if (type != 0 && type != 1) {6668GL.recordError(0x500); // GL_INVALID_ENUM6669}6670return; // Do not write anything to the out pointer, since no binary formats are supported.6671case 0x8DF9: // GL_NUM_SHADER_BINARY_FORMATS6672ret = 0;6673break;6674case 0x86A2: // GL_NUM_COMPRESSED_TEXTURE_FORMATS6675// WebGL doesn't have GL_NUM_COMPRESSED_TEXTURE_FORMATS (it's obsolete since GL_COMPRESSED_TEXTURE_FORMATS returns a JS array that can be queried for length),6676// so implement it ourselves to allow C++ GLES2 code get the length.6677var formats = GLctx.getParameter(0x86A3 /*GL_COMPRESSED_TEXTURE_FORMATS*/);6678ret = formats ? formats.length : 0;6679break;6680}66816682if (ret === undefined) {6683var result = GLctx.getParameter(name_);6684switch (typeof(result)) {6685case "number":6686ret = result;6687break;6688case "boolean":6689ret = result ? 1 : 0;6690break;6691case "string":6692GL.recordError(0x500); // GL_INVALID_ENUM6693return;6694case "object":6695if (result === null) {6696// null is a valid result for some (e.g., which buffer is bound - perhaps nothing is bound), but otherwise6697// can mean an invalid name_, which we need to report as an error6698switch(name_) {6699case 0x8894: // ARRAY_BUFFER_BINDING6700case 0x8B8D: // CURRENT_PROGRAM6701case 0x8895: // ELEMENT_ARRAY_BUFFER_BINDING6702case 0x8CA6: // FRAMEBUFFER_BINDING6703case 0x8CA7: // RENDERBUFFER_BINDING6704case 0x8069: // TEXTURE_BINDING_2D6705case 0x85B5: // WebGL 2 GL_VERTEX_ARRAY_BINDING, or WebGL 1 extension OES_vertex_array_object GL_VERTEX_ARRAY_BINDING_OES6706case 0x8514: { // TEXTURE_BINDING_CUBE_MAP6707ret = 0;6708break;6709}6710default: {6711GL.recordError(0x500); // GL_INVALID_ENUM6712return;6713}6714}6715} else if (result instanceof Float32Array ||6716result instanceof Uint32Array ||6717result instanceof Int32Array ||6718result instanceof Array) {6719for (var i = 0; i < result.length; ++i) {6720switch (type) {6721case 0: HEAP32[(((p)+(i*4))>>2)]=result[i]; break;6722case 2: HEAPF32[(((p)+(i*4))>>2)]=result[i]; break;6723case 4: HEAP8[(((p)+(i))>>0)]=result[i] ? 1 : 0; break;6724}6725}6726return;6727} else {6728try {6729ret = result.name | 0;6730} catch(e) {6731GL.recordError(0x500); // GL_INVALID_ENUM6732err('GL_INVALID_ENUM in glGet' + type + 'v: Unknown object returned from WebGL getParameter(' + name_ + ')! (error: ' + e + ')');6733return;6734}6735}6736break;6737default:6738GL.recordError(0x500); // GL_INVALID_ENUM6739err('GL_INVALID_ENUM in glGet' + type + 'v: Native code calling glGet' + type + 'v(' + name_ + ') and it returns ' + result + ' of type ' + typeof(result) + '!');6740return;6741}6742}67436744switch (type) {6745case 1: writeI53ToI64(p, ret); break;6746case 0: HEAP32[((p)>>2)]=ret; break;6747case 2: HEAPF32[((p)>>2)]=ret; break;6748case 4: HEAP8[((p)>>0)]=ret ? 1 : 0; break;6749}6750}function _emscripten_glGetBooleanv(name_, p) {6751emscriptenWebGLGet(name_, p, 4);6752}67536754function _emscripten_glGetBufferParameteriv(target, value, data) {6755if (!data) {6756// GLES2 specification does not specify how to behave if data is a null pointer. Since calling this function does not make sense6757// if data == null, issue a GL error to notify user about it.6758GL.recordError(0x501 /* GL_INVALID_VALUE */);6759return;6760}6761HEAP32[((data)>>2)]=GLctx.getBufferParameter(target, value);6762}67636764function _emscripten_glGetError() {6765var error = GLctx.getError() || GL.lastError;6766GL.lastError = 0/*GL_NO_ERROR*/;6767return error;6768}67696770function _emscripten_glGetFloatv(name_, p) {6771emscriptenWebGLGet(name_, p, 2);6772}67736774function _emscripten_glGetFramebufferAttachmentParameteriv(target, attachment, pname, params) {6775var result = GLctx.getFramebufferAttachmentParameter(target, attachment, pname);6776if (result instanceof WebGLRenderbuffer ||6777result instanceof WebGLTexture) {6778result = result.name | 0;6779}6780HEAP32[((params)>>2)]=result;6781}67826783function _emscripten_glGetIntegerv(name_, p) {6784emscriptenWebGLGet(name_, p, 0);6785}67866787function _emscripten_glGetProgramInfoLog(program, maxLength, length, infoLog) {6788var log = GLctx.getProgramInfoLog(GL.programs[program]);6789if (log === null) log = '(unknown error)';6790var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0;6791if (length) HEAP32[((length)>>2)]=numBytesWrittenExclNull;6792}67936794function _emscripten_glGetProgramiv(program, pname, p) {6795if (!p) {6796// GLES2 specification does not specify how to behave if p is a null pointer. Since calling this function does not make sense6797// if p == null, issue a GL error to notify user about it.6798GL.recordError(0x501 /* GL_INVALID_VALUE */);6799return;6800}68016802if (program >= GL.counter) {6803GL.recordError(0x501 /* GL_INVALID_VALUE */);6804return;6805}68066807var ptable = GL.programInfos[program];6808if (!ptable) {6809GL.recordError(0x502 /* GL_INVALID_OPERATION */);6810return;6811}68126813if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH6814var log = GLctx.getProgramInfoLog(GL.programs[program]);6815if (log === null) log = '(unknown error)';6816HEAP32[((p)>>2)]=log.length + 1;6817} else if (pname == 0x8B87 /* GL_ACTIVE_UNIFORM_MAX_LENGTH */) {6818HEAP32[((p)>>2)]=ptable.maxUniformLength;6819} else if (pname == 0x8B8A /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */) {6820if (ptable.maxAttributeLength == -1) {6821program = GL.programs[program];6822var numAttribs = GLctx.getProgramParameter(program, 0x8B89/*GL_ACTIVE_ATTRIBUTES*/);6823ptable.maxAttributeLength = 0; // Spec says if there are no active attribs, 0 must be returned.6824for (var i = 0; i < numAttribs; ++i) {6825var activeAttrib = GLctx.getActiveAttrib(program, i);6826ptable.maxAttributeLength = Math.max(ptable.maxAttributeLength, activeAttrib.name.length+1);6827}6828}6829HEAP32[((p)>>2)]=ptable.maxAttributeLength;6830} else if (pname == 0x8A35 /* GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */) {6831if (ptable.maxUniformBlockNameLength == -1) {6832program = GL.programs[program];6833var numBlocks = GLctx.getProgramParameter(program, 0x8A36/*GL_ACTIVE_UNIFORM_BLOCKS*/);6834ptable.maxUniformBlockNameLength = 0;6835for (var i = 0; i < numBlocks; ++i) {6836var activeBlockName = GLctx.getActiveUniformBlockName(program, i);6837ptable.maxUniformBlockNameLength = Math.max(ptable.maxUniformBlockNameLength, activeBlockName.length+1);6838}6839}6840HEAP32[((p)>>2)]=ptable.maxUniformBlockNameLength;6841} else {6842HEAP32[((p)>>2)]=GLctx.getProgramParameter(GL.programs[program], pname);6843}6844}68456846function _emscripten_glGetQueryObjecti64vEXT(id, pname, params) {6847if (!params) {6848// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense6849// if p == null, issue a GL error to notify user about it.6850GL.recordError(0x501 /* GL_INVALID_VALUE */);6851return;6852}6853var query = GL.timerQueriesEXT[id];6854var param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname);6855var ret;6856if (typeof param == 'boolean') {6857ret = param ? 1 : 0;6858} else {6859ret = param;6860}6861writeI53ToI64(params, ret);6862}68636864function _emscripten_glGetQueryObjectivEXT(id, pname, params) {6865if (!params) {6866// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense6867// if p == null, issue a GL error to notify user about it.6868GL.recordError(0x501 /* GL_INVALID_VALUE */);6869return;6870}6871var query = GL.timerQueriesEXT[id];6872var param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname);6873var ret;6874if (typeof param == 'boolean') {6875ret = param ? 1 : 0;6876} else {6877ret = param;6878}6879HEAP32[((params)>>2)]=ret;6880}68816882function _emscripten_glGetQueryObjectui64vEXT(id, pname, params) {6883if (!params) {6884// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense6885// if p == null, issue a GL error to notify user about it.6886GL.recordError(0x501 /* GL_INVALID_VALUE */);6887return;6888}6889var query = GL.timerQueriesEXT[id];6890var param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname);6891var ret;6892if (typeof param == 'boolean') {6893ret = param ? 1 : 0;6894} else {6895ret = param;6896}6897writeI53ToI64(params, ret);6898}68996900function _emscripten_glGetQueryObjectuivEXT(id, pname, params) {6901if (!params) {6902// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense6903// if p == null, issue a GL error to notify user about it.6904GL.recordError(0x501 /* GL_INVALID_VALUE */);6905return;6906}6907var query = GL.timerQueriesEXT[id];6908var param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname);6909var ret;6910if (typeof param == 'boolean') {6911ret = param ? 1 : 0;6912} else {6913ret = param;6914}6915HEAP32[((params)>>2)]=ret;6916}69176918function _emscripten_glGetQueryivEXT(target, pname, params) {6919if (!params) {6920// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense6921// if p == null, issue a GL error to notify user about it.6922GL.recordError(0x501 /* GL_INVALID_VALUE */);6923return;6924}6925HEAP32[((params)>>2)]=GLctx.disjointTimerQueryExt['getQueryEXT'](target, pname);6926}69276928function _emscripten_glGetRenderbufferParameteriv(target, pname, params) {6929if (!params) {6930// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense6931// if params == null, issue a GL error to notify user about it.6932GL.recordError(0x501 /* GL_INVALID_VALUE */);6933return;6934}6935HEAP32[((params)>>2)]=GLctx.getRenderbufferParameter(target, pname);6936}69376938function _emscripten_glGetShaderInfoLog(shader, maxLength, length, infoLog) {6939var log = GLctx.getShaderInfoLog(GL.shaders[shader]);6940if (log === null) log = '(unknown error)';6941var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0;6942if (length) HEAP32[((length)>>2)]=numBytesWrittenExclNull;6943}69446945function _emscripten_glGetShaderPrecisionFormat(shaderType, precisionType, range, precision) {6946var result = GLctx.getShaderPrecisionFormat(shaderType, precisionType);6947HEAP32[((range)>>2)]=result.rangeMin;6948HEAP32[(((range)+(4))>>2)]=result.rangeMax;6949HEAP32[((precision)>>2)]=result.precision;6950}69516952function _emscripten_glGetShaderSource(shader, bufSize, length, source) {6953var result = GLctx.getShaderSource(GL.shaders[shader]);6954if (!result) return; // If an error occurs, nothing will be written to length or source.6955var numBytesWrittenExclNull = (bufSize > 0 && source) ? stringToUTF8(result, source, bufSize) : 0;6956if (length) HEAP32[((length)>>2)]=numBytesWrittenExclNull;6957}69586959function _emscripten_glGetShaderiv(shader, pname, p) {6960if (!p) {6961// GLES2 specification does not specify how to behave if p is a null pointer. Since calling this function does not make sense6962// if p == null, issue a GL error to notify user about it.6963GL.recordError(0x501 /* GL_INVALID_VALUE */);6964return;6965}6966if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH6967var log = GLctx.getShaderInfoLog(GL.shaders[shader]);6968if (log === null) log = '(unknown error)';6969HEAP32[((p)>>2)]=log.length + 1;6970} else if (pname == 0x8B88) { // GL_SHADER_SOURCE_LENGTH6971var source = GLctx.getShaderSource(GL.shaders[shader]);6972var sourceLength = (source === null || source.length == 0) ? 0 : source.length + 1;6973HEAP32[((p)>>2)]=sourceLength;6974} else {6975HEAP32[((p)>>2)]=GLctx.getShaderParameter(GL.shaders[shader], pname);6976}6977}697869796980function stringToNewUTF8(jsString) {6981var length = lengthBytesUTF8(jsString)+1;6982var cString = _malloc(length);6983stringToUTF8(jsString, cString, length);6984return cString;6985}function _emscripten_glGetString(name_) {6986if (GL.stringCache[name_]) return GL.stringCache[name_];6987var ret;6988switch(name_) {6989case 0x1F03 /* GL_EXTENSIONS */:6990var exts = GLctx.getSupportedExtensions() || []; // .getSupportedExtensions() can return null if context is lost, so coerce to empty array.6991exts = exts.concat(exts.map(function(e) { return "GL_" + e; }));6992ret = stringToNewUTF8(exts.join(' '));6993break;6994case 0x1F00 /* GL_VENDOR */:6995case 0x1F01 /* GL_RENDERER */:6996case 0x9245 /* UNMASKED_VENDOR_WEBGL */:6997case 0x9246 /* UNMASKED_RENDERER_WEBGL */:6998var s = GLctx.getParameter(name_);6999if (!s) {7000GL.recordError(0x500/*GL_INVALID_ENUM*/);7001}7002ret = stringToNewUTF8(s);7003break;70047005case 0x1F02 /* GL_VERSION */:7006var glVersion = GLctx.getParameter(0x1F02 /*GL_VERSION*/);7007// return GLES version string corresponding to the version of the WebGL context7008{7009glVersion = 'OpenGL ES 2.0 (' + glVersion + ')';7010}7011ret = stringToNewUTF8(glVersion);7012break;7013case 0x8B8C /* GL_SHADING_LANGUAGE_VERSION */:7014var glslVersion = GLctx.getParameter(0x8B8C /*GL_SHADING_LANGUAGE_VERSION*/);7015// extract the version number 'N.M' from the string 'WebGL GLSL ES N.M ...'7016var ver_re = /^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;7017var ver_num = glslVersion.match(ver_re);7018if (ver_num !== null) {7019if (ver_num[1].length == 3) ver_num[1] = ver_num[1] + '0'; // ensure minor version has 2 digits7020glslVersion = 'OpenGL ES GLSL ES ' + ver_num[1] + ' (' + glslVersion + ')';7021}7022ret = stringToNewUTF8(glslVersion);7023break;7024default:7025GL.recordError(0x500/*GL_INVALID_ENUM*/);7026return 0;7027}7028GL.stringCache[name_] = ret;7029return ret;7030}70317032function _emscripten_glGetTexParameterfv(target, pname, params) {7033if (!params) {7034// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense7035// if p == null, issue a GL error to notify user about it.7036GL.recordError(0x501 /* GL_INVALID_VALUE */);7037return;7038}7039HEAPF32[((params)>>2)]=GLctx.getTexParameter(target, pname);7040}70417042function _emscripten_glGetTexParameteriv(target, pname, params) {7043if (!params) {7044// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense7045// if p == null, issue a GL error to notify user about it.7046GL.recordError(0x501 /* GL_INVALID_VALUE */);7047return;7048}7049HEAP32[((params)>>2)]=GLctx.getTexParameter(target, pname);7050}705170527053function jstoi_q(str) {7054// TODO: If issues below are resolved, add a suitable suppression or remove this comment.7055return parseInt(str, undefined /* https://github.com/google/closure-compiler/issues/3230 / https://github.com/google/closure-compiler/issues/3548 */);7056}function _emscripten_glGetUniformLocation(program, name) {7057name = UTF8ToString(name);70587059var arrayIndex = 0;7060// If user passed an array accessor "[index]", parse the array index off the accessor.7061if (name[name.length - 1] == ']') {7062var leftBrace = name.lastIndexOf('[');7063arrayIndex = name[leftBrace+1] != ']' ? jstoi_q(name.slice(leftBrace + 1)) : 0; // "index]", parseInt will ignore the ']' at the end; but treat "foo[]" as "foo[0]"7064name = name.slice(0, leftBrace);7065}70667067var uniformInfo = GL.programInfos[program] && GL.programInfos[program].uniforms[name]; // returns pair [ dimension_of_uniform_array, uniform_location ]7068if (uniformInfo && arrayIndex >= 0 && arrayIndex < uniformInfo[0]) { // Check if user asked for an out-of-bounds element, i.e. for 'vec4 colors[3];' user could ask for 'colors[10]' which should return -1.7069return uniformInfo[1] + arrayIndex;7070} else {7071return -1;7072}7073}707470757076/** @suppress{checkTypes} */7077function emscriptenWebGLGetUniform(program, location, params, type) {7078if (!params) {7079// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense7080// if params == null, issue a GL error to notify user about it.7081GL.recordError(0x501 /* GL_INVALID_VALUE */);7082return;7083}7084var data = GLctx.getUniform(GL.programs[program], GL.uniforms[location]);7085if (typeof data == 'number' || typeof data == 'boolean') {7086switch (type) {7087case 0: HEAP32[((params)>>2)]=data; break;7088case 2: HEAPF32[((params)>>2)]=data; break;7089default: throw 'internal emscriptenWebGLGetUniform() error, bad type: ' + type;7090}7091} else {7092for (var i = 0; i < data.length; i++) {7093switch (type) {7094case 0: HEAP32[(((params)+(i*4))>>2)]=data[i]; break;7095case 2: HEAPF32[(((params)+(i*4))>>2)]=data[i]; break;7096default: throw 'internal emscriptenWebGLGetUniform() error, bad type: ' + type;7097}7098}7099}7100}function _emscripten_glGetUniformfv(program, location, params) {7101emscriptenWebGLGetUniform(program, location, params, 2);7102}71037104function _emscripten_glGetUniformiv(program, location, params) {7105emscriptenWebGLGetUniform(program, location, params, 0);7106}71077108function _emscripten_glGetVertexAttribPointerv(index, pname, pointer) {7109if (!pointer) {7110// GLES2 specification does not specify how to behave if pointer is a null pointer. Since calling this function does not make sense7111// if pointer == null, issue a GL error to notify user about it.7112GL.recordError(0x501 /* GL_INVALID_VALUE */);7113return;7114}7115HEAP32[((pointer)>>2)]=GLctx.getVertexAttribOffset(index, pname);7116}711771187119/** @suppress{checkTypes} */7120function emscriptenWebGLGetVertexAttrib(index, pname, params, type) {7121if (!params) {7122// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense7123// if params == null, issue a GL error to notify user about it.7124GL.recordError(0x501 /* GL_INVALID_VALUE */);7125return;7126}7127var data = GLctx.getVertexAttrib(index, pname);7128if (pname == 0x889F/*VERTEX_ATTRIB_ARRAY_BUFFER_BINDING*/) {7129HEAP32[((params)>>2)]=data["name"];7130} else if (typeof data == 'number' || typeof data == 'boolean') {7131switch (type) {7132case 0: HEAP32[((params)>>2)]=data; break;7133case 2: HEAPF32[((params)>>2)]=data; break;7134case 5: HEAP32[((params)>>2)]=Math.fround(data); break;7135default: throw 'internal emscriptenWebGLGetVertexAttrib() error, bad type: ' + type;7136}7137} else {7138for (var i = 0; i < data.length; i++) {7139switch (type) {7140case 0: HEAP32[(((params)+(i*4))>>2)]=data[i]; break;7141case 2: HEAPF32[(((params)+(i*4))>>2)]=data[i]; break;7142case 5: HEAP32[(((params)+(i*4))>>2)]=Math.fround(data[i]); break;7143default: throw 'internal emscriptenWebGLGetVertexAttrib() error, bad type: ' + type;7144}7145}7146}7147}function _emscripten_glGetVertexAttribfv(index, pname, params) {7148// N.B. This function may only be called if the vertex attribute was specified using the function glVertexAttrib*f(),7149// otherwise the results are undefined. (GLES3 spec 6.1.12)7150emscriptenWebGLGetVertexAttrib(index, pname, params, 2);7151}71527153function _emscripten_glGetVertexAttribiv(index, pname, params) {7154// N.B. This function may only be called if the vertex attribute was specified using the function glVertexAttrib*f(),7155// otherwise the results are undefined. (GLES3 spec 6.1.12)7156emscriptenWebGLGetVertexAttrib(index, pname, params, 5);7157}71587159function _emscripten_glHint(x0, x1) { GLctx['hint'](x0, x1) }71607161function _emscripten_glIsBuffer(buffer) {7162var b = GL.buffers[buffer];7163if (!b) return 0;7164return GLctx.isBuffer(b);7165}71667167function _emscripten_glIsEnabled(x0) { return GLctx['isEnabled'](x0) }71687169function _emscripten_glIsFramebuffer(framebuffer) {7170var fb = GL.framebuffers[framebuffer];7171if (!fb) return 0;7172return GLctx.isFramebuffer(fb);7173}71747175function _emscripten_glIsProgram(program) {7176program = GL.programs[program];7177if (!program) return 0;7178return GLctx.isProgram(program);7179}71807181function _emscripten_glIsQueryEXT(id) {7182var query = GL.timerQueriesEXT[id];7183if (!query) return 0;7184return GLctx.disjointTimerQueryExt['isQueryEXT'](query);7185}71867187function _emscripten_glIsRenderbuffer(renderbuffer) {7188var rb = GL.renderbuffers[renderbuffer];7189if (!rb) return 0;7190return GLctx.isRenderbuffer(rb);7191}71927193function _emscripten_glIsShader(shader) {7194var s = GL.shaders[shader];7195if (!s) return 0;7196return GLctx.isShader(s);7197}71987199function _emscripten_glIsTexture(id) {7200var texture = GL.textures[id];7201if (!texture) return 0;7202return GLctx.isTexture(texture);7203}72047205function _emscripten_glIsVertexArrayOES(array) {72067207var vao = GL.vaos[array];7208if (!vao) return 0;7209return GLctx['isVertexArray'](vao);7210}72117212function _emscripten_glLineWidth(x0) { GLctx['lineWidth'](x0) }72137214function _emscripten_glLinkProgram(program) {7215GLctx.linkProgram(GL.programs[program]);7216GL.populateUniformTable(program);7217}72187219function _emscripten_glPixelStorei(pname, param) {7220if (pname == 0xCF5 /* GL_UNPACK_ALIGNMENT */) {7221GL.unpackAlignment = param;7222}7223GLctx.pixelStorei(pname, param);7224}72257226function _emscripten_glPolygonOffset(x0, x1) { GLctx['polygonOffset'](x0, x1) }72277228function _emscripten_glQueryCounterEXT(id, target) {7229GLctx.disjointTimerQueryExt['queryCounterEXT'](GL.timerQueriesEXT[id], target);7230}7231723272337234function __computeUnpackAlignedImageSize(width, height, sizePerPixel, alignment) {7235function roundedToNextMultipleOf(x, y) {7236return (x + y - 1) & -y;7237}7238var plainRowSize = width * sizePerPixel;7239var alignedRowSize = roundedToNextMultipleOf(plainRowSize, alignment);7240return height * alignedRowSize;7241}72427243function __colorChannelsInGlTextureFormat(format) {7244// Micro-optimizations for size: map format to size by subtracting smallest enum value (0x1902) from all values first.7245// Also omit the most common size value (1) from the list, which is assumed by formats not on the list.7246var colorChannels = {7247// 0x1902 /* GL_DEPTH_COMPONENT */ - 0x1902: 1,7248// 0x1906 /* GL_ALPHA */ - 0x1902: 1,72495: 3,72506: 4,7251// 0x1909 /* GL_LUMINANCE */ - 0x1902: 1,72528: 2,725329502: 3,725429504: 4,7255};7256return colorChannels[format - 0x1902]||1;7257}72587259function __heapObjectForWebGLType(type) {7260// Micro-optimization for size: Subtract lowest GL enum number (0x1400/* GL_BYTE */) from type to compare7261// smaller values for the heap, for shorter generated code size.7262// Also the type HEAPU16 is not tested for explicitly, but any unrecognized type will return out HEAPU16.7263// (since most types are HEAPU16)7264type -= 0x1400;72657266if (type == 1) return HEAPU8;726772687269if (type == 4) return HEAP32;72707271if (type == 6) return HEAPF32;72727273if (type == 57274|| type == 289227275)7276return HEAPU32;72777278return HEAPU16;7279}72807281function __heapAccessShiftForWebGLHeap(heap) {7282return 31 - Math.clz32(heap.BYTES_PER_ELEMENT);7283}function emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) {7284var heap = __heapObjectForWebGLType(type);7285var shift = __heapAccessShiftForWebGLHeap(heap);7286var byteSize = 1<<shift;7287var sizePerPixel = __colorChannelsInGlTextureFormat(format) * byteSize;7288var bytes = __computeUnpackAlignedImageSize(width, height, sizePerPixel, GL.unpackAlignment);7289return heap.subarray(pixels >> shift, pixels + bytes >> shift);7290}function _emscripten_glReadPixels(x, y, width, height, format, type, pixels) {7291var pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, format);7292if (!pixelData) {7293GL.recordError(0x500/*GL_INVALID_ENUM*/);7294return;7295}7296GLctx.readPixels(x, y, width, height, format, type, pixelData);7297}72987299function _emscripten_glReleaseShaderCompiler() {7300// NOP (as allowed by GLES 2.0 spec)7301}73027303function _emscripten_glRenderbufferStorage(x0, x1, x2, x3) { GLctx['renderbufferStorage'](x0, x1, x2, x3) }73047305function _emscripten_glSampleCoverage(value, invert) {7306GLctx.sampleCoverage(value, !!invert);7307}73087309function _emscripten_glScissor(x0, x1, x2, x3) { GLctx['scissor'](x0, x1, x2, x3) }73107311function _emscripten_glShaderBinary() {7312GL.recordError(0x500/*GL_INVALID_ENUM*/);7313}73147315function _emscripten_glShaderSource(shader, count, string, length) {7316var source = GL.getSource(shader, count, string, length);731773187319GLctx.shaderSource(GL.shaders[shader], source);7320}73217322function _emscripten_glStencilFunc(x0, x1, x2) { GLctx['stencilFunc'](x0, x1, x2) }73237324function _emscripten_glStencilFuncSeparate(x0, x1, x2, x3) { GLctx['stencilFuncSeparate'](x0, x1, x2, x3) }73257326function _emscripten_glStencilMask(x0) { GLctx['stencilMask'](x0) }73277328function _emscripten_glStencilMaskSeparate(x0, x1) { GLctx['stencilMaskSeparate'](x0, x1) }73297330function _emscripten_glStencilOp(x0, x1, x2) { GLctx['stencilOp'](x0, x1, x2) }73317332function _emscripten_glStencilOpSeparate(x0, x1, x2, x3) { GLctx['stencilOpSeparate'](x0, x1, x2, x3) }73337334function _emscripten_glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels) {7335GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) : null);7336}73377338function _emscripten_glTexParameterf(x0, x1, x2) { GLctx['texParameterf'](x0, x1, x2) }73397340function _emscripten_glTexParameterfv(target, pname, params) {7341var param = HEAPF32[((params)>>2)];7342GLctx.texParameterf(target, pname, param);7343}73447345function _emscripten_glTexParameteri(x0, x1, x2) { GLctx['texParameteri'](x0, x1, x2) }73467347function _emscripten_glTexParameteriv(target, pname, params) {7348var param = HEAP32[((params)>>2)];7349GLctx.texParameteri(target, pname, param);7350}73517352function _emscripten_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels) {7353var pixelData = null;7354if (pixels) pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, 0);7355GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixelData);7356}73577358function _emscripten_glUniform1f(location, v0) {7359GLctx.uniform1f(GL.uniforms[location], v0);7360}73617362function _emscripten_glUniform1fv(location, count, value) {736373647365if (count <= GL.MINI_TEMP_BUFFER_SIZE) {7366// avoid allocation when uploading few enough uniforms7367var view = GL.miniTempBufferFloatViews[count-1];7368for (var i = 0; i < count; ++i) {7369view[i] = HEAPF32[(((value)+(4*i))>>2)];7370}7371} else7372{7373var view = HEAPF32.subarray((value)>>2,(value+count*4)>>2);7374}7375GLctx.uniform1fv(GL.uniforms[location], view);7376}73777378function _emscripten_glUniform1i(location, v0) {7379GLctx.uniform1i(GL.uniforms[location], v0);7380}73817382function _emscripten_glUniform1iv(location, count, value) {738373847385if (count <= GL.MINI_TEMP_BUFFER_SIZE) {7386// avoid allocation when uploading few enough uniforms7387var view = GL.miniTempBufferIntViews[count-1];7388for (var i = 0; i < count; ++i) {7389view[i] = HEAP32[(((value)+(4*i))>>2)];7390}7391} else7392{7393var view = HEAP32.subarray((value)>>2,(value+count*4)>>2);7394}7395GLctx.uniform1iv(GL.uniforms[location], view);7396}73977398function _emscripten_glUniform2f(location, v0, v1) {7399GLctx.uniform2f(GL.uniforms[location], v0, v1);7400}74017402function _emscripten_glUniform2fv(location, count, value) {740374047405if (2*count <= GL.MINI_TEMP_BUFFER_SIZE) {7406// avoid allocation when uploading few enough uniforms7407var view = GL.miniTempBufferFloatViews[2*count-1];7408for (var i = 0; i < 2*count; i += 2) {7409view[i] = HEAPF32[(((value)+(4*i))>>2)];7410view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];7411}7412} else7413{7414var view = HEAPF32.subarray((value)>>2,(value+count*8)>>2);7415}7416GLctx.uniform2fv(GL.uniforms[location], view);7417}74187419function _emscripten_glUniform2i(location, v0, v1) {7420GLctx.uniform2i(GL.uniforms[location], v0, v1);7421}74227423function _emscripten_glUniform2iv(location, count, value) {742474257426if (2*count <= GL.MINI_TEMP_BUFFER_SIZE) {7427// avoid allocation when uploading few enough uniforms7428var view = GL.miniTempBufferIntViews[2*count-1];7429for (var i = 0; i < 2*count; i += 2) {7430view[i] = HEAP32[(((value)+(4*i))>>2)];7431view[i+1] = HEAP32[(((value)+(4*i+4))>>2)];7432}7433} else7434{7435var view = HEAP32.subarray((value)>>2,(value+count*8)>>2);7436}7437GLctx.uniform2iv(GL.uniforms[location], view);7438}74397440function _emscripten_glUniform3f(location, v0, v1, v2) {7441GLctx.uniform3f(GL.uniforms[location], v0, v1, v2);7442}74437444function _emscripten_glUniform3fv(location, count, value) {744574467447if (3*count <= GL.MINI_TEMP_BUFFER_SIZE) {7448// avoid allocation when uploading few enough uniforms7449var view = GL.miniTempBufferFloatViews[3*count-1];7450for (var i = 0; i < 3*count; i += 3) {7451view[i] = HEAPF32[(((value)+(4*i))>>2)];7452view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];7453view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];7454}7455} else7456{7457var view = HEAPF32.subarray((value)>>2,(value+count*12)>>2);7458}7459GLctx.uniform3fv(GL.uniforms[location], view);7460}74617462function _emscripten_glUniform3i(location, v0, v1, v2) {7463GLctx.uniform3i(GL.uniforms[location], v0, v1, v2);7464}74657466function _emscripten_glUniform3iv(location, count, value) {746774687469if (3*count <= GL.MINI_TEMP_BUFFER_SIZE) {7470// avoid allocation when uploading few enough uniforms7471var view = GL.miniTempBufferIntViews[3*count-1];7472for (var i = 0; i < 3*count; i += 3) {7473view[i] = HEAP32[(((value)+(4*i))>>2)];7474view[i+1] = HEAP32[(((value)+(4*i+4))>>2)];7475view[i+2] = HEAP32[(((value)+(4*i+8))>>2)];7476}7477} else7478{7479var view = HEAP32.subarray((value)>>2,(value+count*12)>>2);7480}7481GLctx.uniform3iv(GL.uniforms[location], view);7482}74837484function _emscripten_glUniform4f(location, v0, v1, v2, v3) {7485GLctx.uniform4f(GL.uniforms[location], v0, v1, v2, v3);7486}74877488function _emscripten_glUniform4fv(location, count, value) {748974907491if (4*count <= GL.MINI_TEMP_BUFFER_SIZE) {7492// avoid allocation when uploading few enough uniforms7493var view = GL.miniTempBufferFloatViews[4*count-1];7494// hoist the heap out of the loop for size and for pthreads+growth.7495var heap = HEAPF32;7496value >>= 2;7497for (var i = 0; i < 4 * count; i += 4) {7498var dst = value + i;7499view[i] = heap[dst];7500view[i + 1] = heap[dst + 1];7501view[i + 2] = heap[dst + 2];7502view[i + 3] = heap[dst + 3];7503}7504} else7505{7506var view = HEAPF32.subarray((value)>>2,(value+count*16)>>2);7507}7508GLctx.uniform4fv(GL.uniforms[location], view);7509}75107511function _emscripten_glUniform4i(location, v0, v1, v2, v3) {7512GLctx.uniform4i(GL.uniforms[location], v0, v1, v2, v3);7513}75147515function _emscripten_glUniform4iv(location, count, value) {751675177518if (4*count <= GL.MINI_TEMP_BUFFER_SIZE) {7519// avoid allocation when uploading few enough uniforms7520var view = GL.miniTempBufferIntViews[4*count-1];7521for (var i = 0; i < 4*count; i += 4) {7522view[i] = HEAP32[(((value)+(4*i))>>2)];7523view[i+1] = HEAP32[(((value)+(4*i+4))>>2)];7524view[i+2] = HEAP32[(((value)+(4*i+8))>>2)];7525view[i+3] = HEAP32[(((value)+(4*i+12))>>2)];7526}7527} else7528{7529var view = HEAP32.subarray((value)>>2,(value+count*16)>>2);7530}7531GLctx.uniform4iv(GL.uniforms[location], view);7532}75337534function _emscripten_glUniformMatrix2fv(location, count, transpose, value) {753575367537if (4*count <= GL.MINI_TEMP_BUFFER_SIZE) {7538// avoid allocation when uploading few enough uniforms7539var view = GL.miniTempBufferFloatViews[4*count-1];7540for (var i = 0; i < 4*count; i += 4) {7541view[i] = HEAPF32[(((value)+(4*i))>>2)];7542view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];7543view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];7544view[i+3] = HEAPF32[(((value)+(4*i+12))>>2)];7545}7546} else7547{7548var view = HEAPF32.subarray((value)>>2,(value+count*16)>>2);7549}7550GLctx.uniformMatrix2fv(GL.uniforms[location], !!transpose, view);7551}75527553function _emscripten_glUniformMatrix3fv(location, count, transpose, value) {755475557556if (9*count <= GL.MINI_TEMP_BUFFER_SIZE) {7557// avoid allocation when uploading few enough uniforms7558var view = GL.miniTempBufferFloatViews[9*count-1];7559for (var i = 0; i < 9*count; i += 9) {7560view[i] = HEAPF32[(((value)+(4*i))>>2)];7561view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];7562view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];7563view[i+3] = HEAPF32[(((value)+(4*i+12))>>2)];7564view[i+4] = HEAPF32[(((value)+(4*i+16))>>2)];7565view[i+5] = HEAPF32[(((value)+(4*i+20))>>2)];7566view[i+6] = HEAPF32[(((value)+(4*i+24))>>2)];7567view[i+7] = HEAPF32[(((value)+(4*i+28))>>2)];7568view[i+8] = HEAPF32[(((value)+(4*i+32))>>2)];7569}7570} else7571{7572var view = HEAPF32.subarray((value)>>2,(value+count*36)>>2);7573}7574GLctx.uniformMatrix3fv(GL.uniforms[location], !!transpose, view);7575}75767577function _emscripten_glUniformMatrix4fv(location, count, transpose, value) {757875797580if (16*count <= GL.MINI_TEMP_BUFFER_SIZE) {7581// avoid allocation when uploading few enough uniforms7582var view = GL.miniTempBufferFloatViews[16*count-1];7583// hoist the heap out of the loop for size and for pthreads+growth.7584var heap = HEAPF32;7585value >>= 2;7586for (var i = 0; i < 16 * count; i += 16) {7587var dst = value + i;7588view[i] = heap[dst];7589view[i + 1] = heap[dst + 1];7590view[i + 2] = heap[dst + 2];7591view[i + 3] = heap[dst + 3];7592view[i + 4] = heap[dst + 4];7593view[i + 5] = heap[dst + 5];7594view[i + 6] = heap[dst + 6];7595view[i + 7] = heap[dst + 7];7596view[i + 8] = heap[dst + 8];7597view[i + 9] = heap[dst + 9];7598view[i + 10] = heap[dst + 10];7599view[i + 11] = heap[dst + 11];7600view[i + 12] = heap[dst + 12];7601view[i + 13] = heap[dst + 13];7602view[i + 14] = heap[dst + 14];7603view[i + 15] = heap[dst + 15];7604}7605} else7606{7607var view = HEAPF32.subarray((value)>>2,(value+count*64)>>2);7608}7609GLctx.uniformMatrix4fv(GL.uniforms[location], !!transpose, view);7610}76117612function _emscripten_glUseProgram(program) {7613GLctx.useProgram(GL.programs[program]);7614}76157616function _emscripten_glValidateProgram(program) {7617GLctx.validateProgram(GL.programs[program]);7618}76197620function _emscripten_glVertexAttrib1f(x0, x1) { GLctx['vertexAttrib1f'](x0, x1) }76217622function _emscripten_glVertexAttrib1fv(index, v) {76237624GLctx.vertexAttrib1f(index, HEAPF32[v>>2]);7625}76267627function _emscripten_glVertexAttrib2f(x0, x1, x2) { GLctx['vertexAttrib2f'](x0, x1, x2) }76287629function _emscripten_glVertexAttrib2fv(index, v) {76307631GLctx.vertexAttrib2f(index, HEAPF32[v>>2], HEAPF32[v+4>>2]);7632}76337634function _emscripten_glVertexAttrib3f(x0, x1, x2, x3) { GLctx['vertexAttrib3f'](x0, x1, x2, x3) }76357636function _emscripten_glVertexAttrib3fv(index, v) {76377638GLctx.vertexAttrib3f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2]);7639}76407641function _emscripten_glVertexAttrib4f(x0, x1, x2, x3, x4) { GLctx['vertexAttrib4f'](x0, x1, x2, x3, x4) }76427643function _emscripten_glVertexAttrib4fv(index, v) {76447645GLctx.vertexAttrib4f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2], HEAPF32[v+12>>2]);7646}76477648function _emscripten_glVertexAttribDivisorANGLE(index, divisor) {7649GLctx['vertexAttribDivisor'](index, divisor);7650}76517652function _emscripten_glVertexAttribPointer(index, size, type, normalized, stride, ptr) {7653GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr);7654}76557656function _emscripten_glViewport(x0, x1, x2, x3) { GLctx['viewport'](x0, x1, x2, x3) }76577658function _emscripten_has_asyncify() {7659return 0;7660}76617662function _emscripten_memcpy_big(dest, src, num) {7663HEAPU8.copyWithin(dest, src, src + num);7664}766576667667function __emscripten_do_request_fullscreen(target, strategy) {7668if (!JSEvents.fullscreenEnabled()) return -1;7669target = __findEventTarget(target);7670if (!target) return -4;76717672if (!target.requestFullscreen7673&& !target.webkitRequestFullscreen7674) {7675return -3;7676}76777678var canPerformRequests = JSEvents.canPerformEventHandlerRequests();76797680// Queue this function call if we're not currently in an event handler and the user saw it appropriate to do so.7681if (!canPerformRequests) {7682if (strategy.deferUntilInEventHandler) {7683JSEvents.deferCall(_JSEvents_requestFullscreen, 1 /* priority over pointer lock */, [target, strategy]);7684return 1;7685} else {7686return -2;7687}7688}76897690return _JSEvents_requestFullscreen(target, strategy);7691}function _emscripten_request_fullscreen_strategy(target, deferUntilInEventHandler, fullscreenStrategy) {7692var strategy = {7693scaleMode: HEAP32[((fullscreenStrategy)>>2)],7694canvasResolutionScaleMode: HEAP32[(((fullscreenStrategy)+(4))>>2)],7695filteringMode: HEAP32[(((fullscreenStrategy)+(8))>>2)],7696deferUntilInEventHandler: deferUntilInEventHandler,7697canvasResizedCallback: HEAP32[(((fullscreenStrategy)+(12))>>2)],7698canvasResizedCallbackUserData: HEAP32[(((fullscreenStrategy)+(16))>>2)]7699};7700__currentFullscreenStrategy = strategy;77017702return __emscripten_do_request_fullscreen(target, strategy);7703}77047705function _emscripten_request_pointerlock(target, deferUntilInEventHandler) {7706target = __findEventTarget(target);7707if (!target) return -4;7708if (!target.requestPointerLock7709&& !target.msRequestPointerLock7710) {7711return -1;7712}77137714var canPerformRequests = JSEvents.canPerformEventHandlerRequests();77157716// Queue this function call if we're not currently in an event handler and the user saw it appropriate to do so.7717if (!canPerformRequests) {7718if (deferUntilInEventHandler) {7719JSEvents.deferCall(__requestPointerLock, 2 /* priority below fullscreen */, [target]);7720return 1;7721} else {7722return -2;7723}7724}77257726return __requestPointerLock(target);7727}772877297730function _emscripten_get_heap_size() {7731return HEAPU8.length;7732}77337734function abortOnCannotGrowMemory(requestedSize) {7735abort('Cannot enlarge memory arrays to size ' + requestedSize + ' bytes (OOM). Either (1) compile with -s INITIAL_MEMORY=X with X higher than the current value ' + HEAP8.length + ', (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ');7736}function _emscripten_resize_heap(requestedSize) {7737abortOnCannotGrowMemory(requestedSize);7738}77397740function _emscripten_sample_gamepad_data() {7741return (JSEvents.lastGamepadState = (navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : null)))7742? 0 : -1;7743}774477457746function __registerBeforeUnloadEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString) {7747var beforeUnloadEventHandlerFunc = function(ev) {7748var e = ev || event;77497750// Note: This is always called on the main browser thread, since it needs synchronously return a value!7751var confirmationMessage = dynCall_iiii(callbackfunc, eventTypeId, 0, userData);77527753if (confirmationMessage) {7754confirmationMessage = UTF8ToString(confirmationMessage);7755}7756if (confirmationMessage) {7757e.preventDefault();7758e.returnValue = confirmationMessage;7759return confirmationMessage;7760}7761};77627763var eventHandler = {7764target: __findEventTarget(target),7765eventTypeString: eventTypeString,7766callbackfunc: callbackfunc,7767handlerFunc: beforeUnloadEventHandlerFunc,7768useCapture: useCapture7769};7770JSEvents.registerOrRemoveHandler(eventHandler);7771}function _emscripten_set_beforeunload_callback_on_thread(userData, callbackfunc, targetThread) {7772if (typeof onbeforeunload === 'undefined') return -1;7773// beforeunload callback can only be registered on the main browser thread, because the page will go away immediately after returning from the handler,7774// and there is no time to start proxying it anywhere.7775if (targetThread !== 1) return -5;7776__registerBeforeUnloadEventCallback(2, userData, true, callbackfunc, 28, "beforeunload");7777return 0;7778}777977807781function __registerFocusEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {7782if (!JSEvents.focusEvent) JSEvents.focusEvent = _malloc( 256 );77837784var focusEventHandlerFunc = function(ev) {7785var e = ev || event;77867787var nodeName = JSEvents.getNodeNameForTarget(e.target);7788var id = e.target.id ? e.target.id : '';77897790var focusEvent = JSEvents.focusEvent;7791stringToUTF8(nodeName, focusEvent + 0, 128);7792stringToUTF8(id, focusEvent + 128, 128);77937794if (dynCall_iiii(callbackfunc, eventTypeId, focusEvent, userData)) e.preventDefault();7795};77967797var eventHandler = {7798target: __findEventTarget(target),7799eventTypeString: eventTypeString,7800callbackfunc: callbackfunc,7801handlerFunc: focusEventHandlerFunc,7802useCapture: useCapture7803};7804JSEvents.registerOrRemoveHandler(eventHandler);7805}function _emscripten_set_blur_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {7806__registerFocusEventCallback(target, userData, useCapture, callbackfunc, 12, "blur", targetThread);7807return 0;7808}780978107811function _emscripten_set_element_css_size(target, width, height) {7812target = __findEventTarget(target);7813if (!target) return -4;78147815target.style.width = width + "px";7816target.style.height = height + "px";78177818return 0;7819}78207821function _emscripten_set_focus_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {7822__registerFocusEventCallback(target, userData, useCapture, callbackfunc, 13, "focus", targetThread);7823return 0;7824}7825782678277828function __fillFullscreenChangeEventData(eventStruct) {7829var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;7830var isFullscreen = !!fullscreenElement;7831/** @suppress{checkTypes} */7832HEAP32[((eventStruct)>>2)]=isFullscreen;7833HEAP32[(((eventStruct)+(4))>>2)]=JSEvents.fullscreenEnabled();7834// If transitioning to fullscreen, report info about the element that is now fullscreen.7835// If transitioning to windowed mode, report info about the element that just was fullscreen.7836var reportedElement = isFullscreen ? fullscreenElement : JSEvents.previousFullscreenElement;7837var nodeName = JSEvents.getNodeNameForTarget(reportedElement);7838var id = (reportedElement && reportedElement.id) ? reportedElement.id : '';7839stringToUTF8(nodeName, eventStruct + 8, 128);7840stringToUTF8(id, eventStruct + 136, 128);7841HEAP32[(((eventStruct)+(264))>>2)]=reportedElement ? reportedElement.clientWidth : 0;7842HEAP32[(((eventStruct)+(268))>>2)]=reportedElement ? reportedElement.clientHeight : 0;7843HEAP32[(((eventStruct)+(272))>>2)]=screen.width;7844HEAP32[(((eventStruct)+(276))>>2)]=screen.height;7845if (isFullscreen) {7846JSEvents.previousFullscreenElement = fullscreenElement;7847}7848}function __registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {7849if (!JSEvents.fullscreenChangeEvent) JSEvents.fullscreenChangeEvent = _malloc( 280 );78507851var fullscreenChangeEventhandlerFunc = function(ev) {7852var e = ev || event;78537854var fullscreenChangeEvent = JSEvents.fullscreenChangeEvent;78557856__fillFullscreenChangeEventData(fullscreenChangeEvent);78577858if (dynCall_iiii(callbackfunc, eventTypeId, fullscreenChangeEvent, userData)) e.preventDefault();7859};78607861var eventHandler = {7862target: target,7863eventTypeString: eventTypeString,7864callbackfunc: callbackfunc,7865handlerFunc: fullscreenChangeEventhandlerFunc,7866useCapture: useCapture7867};7868JSEvents.registerOrRemoveHandler(eventHandler);7869}function _emscripten_set_fullscreenchange_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {7870if (!JSEvents.fullscreenEnabled()) return -1;7871target = __findEventTarget(target);7872if (!target) return -4;7873__registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "fullscreenchange", targetThread);787478757876// Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)7877// As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version.7878__registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "webkitfullscreenchange", targetThread);78797880return 0;7881}788278837884function __registerGamepadEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {7885if (!JSEvents.gamepadEvent) JSEvents.gamepadEvent = _malloc( 1432 );78867887var gamepadEventHandlerFunc = function(ev) {7888var e = ev || event;78897890var gamepadEvent = JSEvents.gamepadEvent;7891__fillGamepadEventData(gamepadEvent, e["gamepad"]);78927893if (dynCall_iiii(callbackfunc, eventTypeId, gamepadEvent, userData)) e.preventDefault();7894};78957896var eventHandler = {7897target: __findEventTarget(target),7898allowsDeferredCalls: true,7899eventTypeString: eventTypeString,7900callbackfunc: callbackfunc,7901handlerFunc: gamepadEventHandlerFunc,7902useCapture: useCapture7903};7904JSEvents.registerOrRemoveHandler(eventHandler);7905}function _emscripten_set_gamepadconnected_callback_on_thread(userData, useCapture, callbackfunc, targetThread) {7906if (!navigator.getGamepads && !navigator.webkitGetGamepads) return -1;7907__registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 26, "gamepadconnected", targetThread);7908return 0;7909}79107911function _emscripten_set_gamepaddisconnected_callback_on_thread(userData, useCapture, callbackfunc, targetThread) {7912if (!navigator.getGamepads && !navigator.webkitGetGamepads) return -1;7913__registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 27, "gamepaddisconnected", targetThread);7914return 0;7915}791679177918function __registerKeyEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {7919if (!JSEvents.keyEvent) JSEvents.keyEvent = _malloc( 164 );79207921var keyEventHandlerFunc = function(ev) {7922var e = ev || event;79237924var keyEventData = JSEvents.keyEvent;7925stringToUTF8(e.key ? e.key : "", keyEventData + 0, 32);7926stringToUTF8(e.code ? e.code : "", keyEventData + 32, 32);7927HEAP32[(((keyEventData)+(64))>>2)]=e.location;7928HEAP32[(((keyEventData)+(68))>>2)]=e.ctrlKey;7929HEAP32[(((keyEventData)+(72))>>2)]=e.shiftKey;7930HEAP32[(((keyEventData)+(76))>>2)]=e.altKey;7931HEAP32[(((keyEventData)+(80))>>2)]=e.metaKey;7932HEAP32[(((keyEventData)+(84))>>2)]=e.repeat;7933stringToUTF8(e.locale ? e.locale : "", keyEventData + 88, 32);7934stringToUTF8(e.char ? e.char : "", keyEventData + 120, 32);7935HEAP32[(((keyEventData)+(152))>>2)]=e.charCode;7936HEAP32[(((keyEventData)+(156))>>2)]=e.keyCode;7937HEAP32[(((keyEventData)+(160))>>2)]=e.which;79387939if (dynCall_iiii(callbackfunc, eventTypeId, keyEventData, userData)) e.preventDefault();7940};79417942var eventHandler = {7943target: __findEventTarget(target),7944allowsDeferredCalls: true,7945eventTypeString: eventTypeString,7946callbackfunc: callbackfunc,7947handlerFunc: keyEventHandlerFunc,7948useCapture: useCapture7949};7950JSEvents.registerOrRemoveHandler(eventHandler);7951}function _emscripten_set_keydown_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {7952__registerKeyEventCallback(target, userData, useCapture, callbackfunc, 2, "keydown", targetThread);7953return 0;7954}79557956function _emscripten_set_keypress_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {7957__registerKeyEventCallback(target, userData, useCapture, callbackfunc, 1, "keypress", targetThread);7958return 0;7959}79607961function _emscripten_set_keyup_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {7962__registerKeyEventCallback(target, userData, useCapture, callbackfunc, 3, "keyup", targetThread);7963return 0;7964}79657966796779687969function __fillMouseEventData(eventStruct, e, target) {7970HEAP32[((eventStruct)>>2)]=e.screenX;7971HEAP32[(((eventStruct)+(4))>>2)]=e.screenY;7972HEAP32[(((eventStruct)+(8))>>2)]=e.clientX;7973HEAP32[(((eventStruct)+(12))>>2)]=e.clientY;7974HEAP32[(((eventStruct)+(16))>>2)]=e.ctrlKey;7975HEAP32[(((eventStruct)+(20))>>2)]=e.shiftKey;7976HEAP32[(((eventStruct)+(24))>>2)]=e.altKey;7977HEAP32[(((eventStruct)+(28))>>2)]=e.metaKey;7978HEAP16[(((eventStruct)+(32))>>1)]=e.button;7979HEAP16[(((eventStruct)+(34))>>1)]=e.buttons;7980var movementX = e["movementX"]7981|| (e.screenX-JSEvents.previousScreenX)7982;7983var movementY = e["movementY"]7984|| (e.screenY-JSEvents.previousScreenY)7985;79867987HEAP32[(((eventStruct)+(36))>>2)]=movementX;7988HEAP32[(((eventStruct)+(40))>>2)]=movementY;79897990var rect = __getBoundingClientRect(target);7991HEAP32[(((eventStruct)+(44))>>2)]=e.clientX - rect.left;7992HEAP32[(((eventStruct)+(48))>>2)]=e.clientY - rect.top;79937994// wheel and mousewheel events contain wrong screenX/screenY on chrome/opera7995// https://github.com/emscripten-core/emscripten/pull/49977996// https://bugs.chromium.org/p/chromium/issues/detail?id=6999567997if (e.type !== 'wheel' && e.type !== 'mousewheel') {7998JSEvents.previousScreenX = e.screenX;7999JSEvents.previousScreenY = e.screenY;8000}8001}function __registerMouseEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {8002if (!JSEvents.mouseEvent) JSEvents.mouseEvent = _malloc( 64 );8003target = __findEventTarget(target);80048005var mouseEventHandlerFunc = function(ev) {8006var e = ev || event;80078008// TODO: Make this access thread safe, or this could update live while app is reading it.8009__fillMouseEventData(JSEvents.mouseEvent, e, target);80108011if (dynCall_iiii(callbackfunc, eventTypeId, JSEvents.mouseEvent, userData)) e.preventDefault();8012};80138014var eventHandler = {8015target: target,8016allowsDeferredCalls: eventTypeString != 'mousemove' && eventTypeString != 'mouseenter' && eventTypeString != 'mouseleave', // Mouse move events do not allow fullscreen/pointer lock requests to be handled in them!8017eventTypeString: eventTypeString,8018callbackfunc: callbackfunc,8019handlerFunc: mouseEventHandlerFunc,8020useCapture: useCapture8021};8022JSEvents.registerOrRemoveHandler(eventHandler);8023}function _emscripten_set_mousedown_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {8024__registerMouseEventCallback(target, userData, useCapture, callbackfunc, 5, "mousedown", targetThread);8025return 0;8026}80278028function _emscripten_set_mouseenter_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {8029__registerMouseEventCallback(target, userData, useCapture, callbackfunc, 33, "mouseenter", targetThread);8030return 0;8031}80328033function _emscripten_set_mouseleave_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {8034__registerMouseEventCallback(target, userData, useCapture, callbackfunc, 34, "mouseleave", targetThread);8035return 0;8036}80378038function _emscripten_set_mousemove_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {8039__registerMouseEventCallback(target, userData, useCapture, callbackfunc, 8, "mousemove", targetThread);8040return 0;8041}80428043function _emscripten_set_mouseup_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {8044__registerMouseEventCallback(target, userData, useCapture, callbackfunc, 6, "mouseup", targetThread);8045return 0;8046}8047804880498050function __fillPointerlockChangeEventData(eventStruct) {8051var pointerLockElement = document.pointerLockElement || document.mozPointerLockElement || document.webkitPointerLockElement || document.msPointerLockElement;8052var isPointerlocked = !!pointerLockElement;8053/** @suppress {checkTypes} */8054HEAP32[((eventStruct)>>2)]=isPointerlocked;8055var nodeName = JSEvents.getNodeNameForTarget(pointerLockElement);8056var id = (pointerLockElement && pointerLockElement.id) ? pointerLockElement.id : '';8057stringToUTF8(nodeName, eventStruct + 4, 128);8058stringToUTF8(id, eventStruct + 132, 128);8059}function __registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {8060if (!JSEvents.pointerlockChangeEvent) JSEvents.pointerlockChangeEvent = _malloc( 260 );80618062var pointerlockChangeEventHandlerFunc = function(ev) {8063var e = ev || event;80648065var pointerlockChangeEvent = JSEvents.pointerlockChangeEvent;8066__fillPointerlockChangeEventData(pointerlockChangeEvent);80678068if (dynCall_iiii(callbackfunc, eventTypeId, pointerlockChangeEvent, userData)) e.preventDefault();8069};80708071var eventHandler = {8072target: target,8073eventTypeString: eventTypeString,8074callbackfunc: callbackfunc,8075handlerFunc: pointerlockChangeEventHandlerFunc,8076useCapture: useCapture8077};8078JSEvents.registerOrRemoveHandler(eventHandler);8079}/** @suppress {missingProperties} */8080function _emscripten_set_pointerlockchange_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {8081// TODO: Currently not supported in pthreads or in --proxy-to-worker mode. (In pthreads mode, document object is not defined)8082if (!document || !document.body || (!document.body.requestPointerLock && !document.body.mozRequestPointerLock && !document.body.webkitRequestPointerLock && !document.body.msRequestPointerLock)) {8083return -1;8084}80858086target = __findEventTarget(target);8087if (!target) return -4;8088__registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "pointerlockchange", targetThread);8089__registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "mozpointerlockchange", targetThread);8090__registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "webkitpointerlockchange", targetThread);8091__registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "mspointerlockchange", targetThread);8092return 0;8093}809480958096function __registerUiEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {8097if (!JSEvents.uiEvent) JSEvents.uiEvent = _malloc( 36 );80988099target = __findEventTarget(target);81008101var uiEventHandlerFunc = function(ev) {8102var e = ev || event;8103if (e.target != target) {8104// Never take ui events such as scroll via a 'bubbled' route, but always from the direct element that8105// was targeted. Otherwise e.g. if app logs a message in response to a page scroll, the Emscripten log8106// message box could cause to scroll, generating a new (bubbled) scroll message, causing a new log print,8107// causing a new scroll, etc..8108return;8109}8110var uiEvent = JSEvents.uiEvent;8111var b = document.body; // Take document.body to a variable, Closure compiler does not outline access to it on its own.8112HEAP32[((uiEvent)>>2)]=e.detail;8113HEAP32[(((uiEvent)+(4))>>2)]=b.clientWidth;8114HEAP32[(((uiEvent)+(8))>>2)]=b.clientHeight;8115HEAP32[(((uiEvent)+(12))>>2)]=innerWidth;8116HEAP32[(((uiEvent)+(16))>>2)]=innerHeight;8117HEAP32[(((uiEvent)+(20))>>2)]=outerWidth;8118HEAP32[(((uiEvent)+(24))>>2)]=outerHeight;8119HEAP32[(((uiEvent)+(28))>>2)]=pageXOffset;8120HEAP32[(((uiEvent)+(32))>>2)]=pageYOffset;8121if (dynCall_iiii(callbackfunc, eventTypeId, uiEvent, userData)) e.preventDefault();8122};81238124var eventHandler = {8125target: target,8126eventTypeString: eventTypeString,8127callbackfunc: callbackfunc,8128handlerFunc: uiEventHandlerFunc,8129useCapture: useCapture8130};8131JSEvents.registerOrRemoveHandler(eventHandler);8132}function _emscripten_set_resize_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {8133__registerUiEventCallback(target, userData, useCapture, callbackfunc, 10, "resize", targetThread);8134return 0;8135}813681378138function __registerTouchEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {8139if (!JSEvents.touchEvent) JSEvents.touchEvent = _malloc( 1684 );81408141target = __findEventTarget(target);81428143var touchEventHandlerFunc = function(ev) {8144var e = ev || event;81458146var touches = {};8147for(var i = 0; i < e.touches.length; ++i) {8148var touch = e.touches[i];8149touch.changed = false;8150touches[touch.identifier] = touch;8151}8152for(var i = 0; i < e.changedTouches.length; ++i) {8153var touch = e.changedTouches[i];8154touches[touch.identifier] = touch;8155touch.changed = true;8156}8157for(var i = 0; i < e.targetTouches.length; ++i) {8158var touch = e.targetTouches[i];8159touches[touch.identifier].onTarget = true;8160}81618162var touchEvent = JSEvents.touchEvent;8163var ptr = touchEvent;8164HEAP32[(((ptr)+(4))>>2)]=e.ctrlKey;8165HEAP32[(((ptr)+(8))>>2)]=e.shiftKey;8166HEAP32[(((ptr)+(12))>>2)]=e.altKey;8167HEAP32[(((ptr)+(16))>>2)]=e.metaKey;8168ptr += 20; // Advance to the start of the touch array.8169var targetRect = __getBoundingClientRect(target);8170var numTouches = 0;8171for(var i in touches) {8172var t = touches[i];8173HEAP32[((ptr)>>2)]=t.identifier;8174HEAP32[(((ptr)+(4))>>2)]=t.screenX;8175HEAP32[(((ptr)+(8))>>2)]=t.screenY;8176HEAP32[(((ptr)+(12))>>2)]=t.clientX;8177HEAP32[(((ptr)+(16))>>2)]=t.clientY;8178HEAP32[(((ptr)+(20))>>2)]=t.pageX;8179HEAP32[(((ptr)+(24))>>2)]=t.pageY;8180HEAP32[(((ptr)+(28))>>2)]=t.changed;8181HEAP32[(((ptr)+(32))>>2)]=t.onTarget;8182HEAP32[(((ptr)+(36))>>2)]=t.clientX - targetRect.left;8183HEAP32[(((ptr)+(40))>>2)]=t.clientY - targetRect.top;81848185ptr += 52;81868187if (++numTouches >= 32) {8188break;8189}8190}8191HEAP32[((touchEvent)>>2)]=numTouches;81928193if (dynCall_iiii(callbackfunc, eventTypeId, touchEvent, userData)) e.preventDefault();8194};81958196var eventHandler = {8197target: target,8198allowsDeferredCalls: eventTypeString == 'touchstart' || eventTypeString == 'touchend',8199eventTypeString: eventTypeString,8200callbackfunc: callbackfunc,8201handlerFunc: touchEventHandlerFunc,8202useCapture: useCapture8203};8204JSEvents.registerOrRemoveHandler(eventHandler);8205}function _emscripten_set_touchcancel_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {8206__registerTouchEventCallback(target, userData, useCapture, callbackfunc, 25, "touchcancel", targetThread);8207return 0;8208}82098210function _emscripten_set_touchend_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {8211__registerTouchEventCallback(target, userData, useCapture, callbackfunc, 23, "touchend", targetThread);8212return 0;8213}82148215function _emscripten_set_touchmove_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {8216__registerTouchEventCallback(target, userData, useCapture, callbackfunc, 24, "touchmove", targetThread);8217return 0;8218}82198220function _emscripten_set_touchstart_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {8221__registerTouchEventCallback(target, userData, useCapture, callbackfunc, 22, "touchstart", targetThread);8222return 0;8223}8224822582268227function __fillVisibilityChangeEventData(eventStruct) {8228var visibilityStates = [ "hidden", "visible", "prerender", "unloaded" ];8229var visibilityState = visibilityStates.indexOf(document.visibilityState);82308231// Assigning a boolean to HEAP32 with expected type coercion.8232/** @suppress {checkTypes} */8233HEAP32[((eventStruct)>>2)]=document.hidden;8234HEAP32[(((eventStruct)+(4))>>2)]=visibilityState;8235}function __registerVisibilityChangeEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {8236if (!JSEvents.visibilityChangeEvent) JSEvents.visibilityChangeEvent = _malloc( 8 );82378238var visibilityChangeEventHandlerFunc = function(ev) {8239var e = ev || event;82408241var visibilityChangeEvent = JSEvents.visibilityChangeEvent;82428243__fillVisibilityChangeEventData(visibilityChangeEvent);82448245if (dynCall_iiii(callbackfunc, eventTypeId, visibilityChangeEvent, userData)) e.preventDefault();8246};82478248var eventHandler = {8249target: target,8250eventTypeString: eventTypeString,8251callbackfunc: callbackfunc,8252handlerFunc: visibilityChangeEventHandlerFunc,8253useCapture: useCapture8254};8255JSEvents.registerOrRemoveHandler(eventHandler);8256}function _emscripten_set_visibilitychange_callback_on_thread(userData, useCapture, callbackfunc, targetThread) {8257if (!__specialEventTargets[1]) {8258return -4;8259}8260__registerVisibilityChangeEventCallback(__specialEventTargets[1], userData, useCapture, callbackfunc, 21, "visibilitychange", targetThread);8261return 0;8262}826382648265function __registerWheelEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {8266if (!JSEvents.wheelEvent) JSEvents.wheelEvent = _malloc( 96 );82678268// The DOM Level 3 events spec event 'wheel'8269var wheelHandlerFunc = function(ev) {8270var e = ev || event;8271var wheelEvent = JSEvents.wheelEvent;8272__fillMouseEventData(wheelEvent, e, target);8273HEAPF64[(((wheelEvent)+(64))>>3)]=e["deltaX"];8274HEAPF64[(((wheelEvent)+(72))>>3)]=e["deltaY"];8275HEAPF64[(((wheelEvent)+(80))>>3)]=e["deltaZ"];8276HEAP32[(((wheelEvent)+(88))>>2)]=e["deltaMode"];8277if (dynCall_iiii(callbackfunc, eventTypeId, wheelEvent, userData)) e.preventDefault();8278};8279// The 'mousewheel' event as implemented in Safari 6.0.58280var mouseWheelHandlerFunc = function(ev) {8281var e = ev || event;8282__fillMouseEventData(JSEvents.wheelEvent, e, target);8283HEAPF64[(((JSEvents.wheelEvent)+(64))>>3)]=e["wheelDeltaX"] || 0;8284/* 1. Invert to unify direction with the DOM Level 3 wheel event. 2. MSIE does not provide wheelDeltaY, so wheelDelta is used as a fallback. */8285var wheelDeltaY = -(e["wheelDeltaY"] || e["wheelDelta"])8286HEAPF64[(((JSEvents.wheelEvent)+(72))>>3)]=wheelDeltaY;8287HEAPF64[(((JSEvents.wheelEvent)+(80))>>3)]=0 /* Not available */;8288HEAP32[(((JSEvents.wheelEvent)+(88))>>2)]=0 /* DOM_DELTA_PIXEL */;8289var shouldCancel = dynCall_iiii(callbackfunc, eventTypeId, JSEvents.wheelEvent, userData);8290if (shouldCancel) {8291e.preventDefault();8292}8293};82948295var eventHandler = {8296target: target,8297allowsDeferredCalls: true,8298eventTypeString: eventTypeString,8299callbackfunc: callbackfunc,8300handlerFunc: (eventTypeString == 'wheel') ? wheelHandlerFunc : mouseWheelHandlerFunc,8301useCapture: useCapture8302};8303JSEvents.registerOrRemoveHandler(eventHandler);8304}function _emscripten_set_wheel_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {8305target = __findEventTarget(target);8306if (typeof target.onwheel !== 'undefined') {8307__registerWheelEventCallback(target, userData, useCapture, callbackfunc, 9, "wheel", targetThread);8308return 0;8309} else if (typeof target.onmousewheel !== 'undefined') {8310__registerWheelEventCallback(target, userData, useCapture, callbackfunc, 9, "mousewheel", targetThread);8311return 0;8312} else {8313return -1;8314}8315}83168317function _emscripten_sleep() {8318throw 'Please compile your program with async support in order to use asynchronous operations like emscripten_sleep';8319}8320832183228323var ENV={};83248325function __getExecutableName() {8326return thisProgram || './this.program';8327}function _emscripten_get_environ() {8328if (!_emscripten_get_environ.strings) {8329// Default values.8330var env = {8331'USER': 'web_user',8332'LOGNAME': 'web_user',8333'PATH': '/',8334'PWD': '/',8335'HOME': '/home/web_user',8336// Browser language detection #87518337'LANG': ((typeof navigator === 'object' && navigator.languages && navigator.languages[0]) || 'C').replace('-', '_') + '.UTF-8',8338'_': __getExecutableName()8339};8340// Apply the user-provided values, if any.8341for (var x in ENV) {8342env[x] = ENV[x];8343}8344var strings = [];8345for (var x in env) {8346strings.push(x + '=' + env[x]);8347}8348_emscripten_get_environ.strings = strings;8349}8350return _emscripten_get_environ.strings;8351}function _environ_get(__environ, environ_buf) {8352var strings = _emscripten_get_environ();8353var bufSize = 0;8354strings.forEach(function(string, i) {8355var ptr = environ_buf + bufSize;8356HEAP32[(((__environ)+(i * 4))>>2)]=ptr;8357writeAsciiToMemory(string, ptr);8358bufSize += string.length + 1;8359});8360return 0;8361}83628363function _environ_sizes_get(penviron_count, penviron_buf_size) {8364var strings = _emscripten_get_environ();8365HEAP32[((penviron_count)>>2)]=strings.length;8366var bufSize = 0;8367strings.forEach(function(string) {8368bufSize += string.length + 1;8369});8370HEAP32[((penviron_buf_size)>>2)]=bufSize;8371return 0;8372}83738374function _exit(status) {8375// void _exit(int status);8376// http://pubs.opengroup.org/onlinepubs/000095399/functions/exit.html8377exit(status);8378}83798380function _fd_close(fd) {try {83818382var stream = SYSCALLS.getStreamFromFD(fd);8383FS.close(stream);8384return 0;8385} catch (e) {8386if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);8387return e.errno;8388}8389}83908391function _fd_read(fd, iov, iovcnt, pnum) {try {83928393var stream = SYSCALLS.getStreamFromFD(fd);8394var num = SYSCALLS.doReadv(stream, iov, iovcnt);8395HEAP32[((pnum)>>2)]=num8396return 0;8397} catch (e) {8398if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);8399return e.errno;8400}8401}84028403function _fd_seek(fd, offset_low, offset_high, whence, newOffset) {try {84048405var stream = SYSCALLS.getStreamFromFD(fd);8406var HIGH_OFFSET = 0x100000000; // 2^328407// use an unsigned operator on low and shift high by 32-bits8408var offset = offset_high * HIGH_OFFSET + (offset_low >>> 0);84098410var DOUBLE_LIMIT = 0x20000000000000; // 2^538411// we also check for equality since DOUBLE_LIMIT + 1 == DOUBLE_LIMIT8412if (offset <= -DOUBLE_LIMIT || offset >= DOUBLE_LIMIT) {8413return -61;8414}84158416FS.llseek(stream, offset, whence);8417(tempI64 = [stream.position>>>0,(tempDouble=stream.position,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((newOffset)>>2)]=tempI64[0],HEAP32[(((newOffset)+(4))>>2)]=tempI64[1]);8418if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; // reset readdir state8419return 0;8420} catch (e) {8421if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);8422return e.errno;8423}8424}84258426function _fd_write(fd, iov, iovcnt, pnum) {try {84278428var stream = SYSCALLS.getStreamFromFD(fd);8429var num = SYSCALLS.doWritev(stream, iov, iovcnt);8430HEAP32[((pnum)>>2)]=num8431return 0;8432} catch (e) {8433if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);8434return e.errno;8435}8436}84378438function _gettimeofday(ptr) {8439var now = Date.now();8440HEAP32[((ptr)>>2)]=(now/1000)|0; // seconds8441HEAP32[(((ptr)+(4))>>2)]=((now % 1000)*1000)|0; // microseconds8442return 0;8443}84448445function _glActiveTexture(x0) { GLctx['activeTexture'](x0) }84468447function _glAttachShader(program, shader) {8448GLctx.attachShader(GL.programs[program],8449GL.shaders[shader]);8450}84518452function _glBindBuffer(target, buffer) {84538454GLctx.bindBuffer(target, GL.buffers[buffer]);8455}84568457function _glBindTexture(target, texture) {8458GLctx.bindTexture(target, GL.textures[texture]);8459}84608461function _glBlendFunc(x0, x1) { GLctx['blendFunc'](x0, x1) }84628463function _glBufferData(target, size, data, usage) {8464// N.b. here first form specifies a heap subarray, second form an integer size, so the ?: code here is polymorphic. It is advised to avoid8465// randomly mixing both uses in calling code, to avoid any potential JS engine JIT issues.8466GLctx.bufferData(target, data ? HEAPU8.subarray(data, data+size) : size, usage);8467}84688469function _glClear(x0) { GLctx['clear'](x0) }84708471function _glClearColor(x0, x1, x2, x3) { GLctx['clearColor'](x0, x1, x2, x3) }84728473function _glCompileShader(shader) {8474GLctx.compileShader(GL.shaders[shader]);8475}84768477function _glCreateProgram() {8478var id = GL.getNewId(GL.programs);8479var program = GLctx.createProgram();8480program.name = id;8481GL.programs[id] = program;8482return id;8483}84848485function _glCreateShader(shaderType) {8486var id = GL.getNewId(GL.shaders);8487GL.shaders[id] = GLctx.createShader(shaderType);8488return id;8489}84908491function _glDepthFunc(x0) { GLctx['depthFunc'](x0) }84928493function _glDepthMask(flag) {8494GLctx.depthMask(!!flag);8495}84968497function _glDisable(x0) { GLctx['disable'](x0) }84988499function _glDisableVertexAttribArray(index) {8500GLctx.disableVertexAttribArray(index);8501}85028503function _glDrawArrays(mode, first, count) {85048505GLctx.drawArrays(mode, first, count);85068507}85088509function _glEnable(x0) { GLctx['enable'](x0) }85108511function _glEnableVertexAttribArray(index) {8512GLctx.enableVertexAttribArray(index);8513}85148515function _glGenBuffers(n, buffers) {8516__glGenObject(n, buffers, 'createBuffer', GL.buffers8517);8518}85198520function _glGenTextures(n, textures) {8521__glGenObject(n, textures, 'createTexture', GL.textures8522);8523}85248525function _glGetAttribLocation(program, name) {8526return GLctx.getAttribLocation(GL.programs[program], UTF8ToString(name));8527}85288529function _glGetShaderInfoLog(shader, maxLength, length, infoLog) {8530var log = GLctx.getShaderInfoLog(GL.shaders[shader]);8531if (log === null) log = '(unknown error)';8532var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0;8533if (length) HEAP32[((length)>>2)]=numBytesWrittenExclNull;8534}85358536function _glGetShaderiv(shader, pname, p) {8537if (!p) {8538// GLES2 specification does not specify how to behave if p is a null pointer. Since calling this function does not make sense8539// if p == null, issue a GL error to notify user about it.8540GL.recordError(0x501 /* GL_INVALID_VALUE */);8541return;8542}8543if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH8544var log = GLctx.getShaderInfoLog(GL.shaders[shader]);8545if (log === null) log = '(unknown error)';8546HEAP32[((p)>>2)]=log.length + 1;8547} else if (pname == 0x8B88) { // GL_SHADER_SOURCE_LENGTH8548var source = GLctx.getShaderSource(GL.shaders[shader]);8549var sourceLength = (source === null || source.length == 0) ? 0 : source.length + 1;8550HEAP32[((p)>>2)]=sourceLength;8551} else {8552HEAP32[((p)>>2)]=GLctx.getShaderParameter(GL.shaders[shader], pname);8553}8554}85558556function _glGetUniformLocation(program, name) {8557name = UTF8ToString(name);85588559var arrayIndex = 0;8560// If user passed an array accessor "[index]", parse the array index off the accessor.8561if (name[name.length - 1] == ']') {8562var leftBrace = name.lastIndexOf('[');8563arrayIndex = name[leftBrace+1] != ']' ? jstoi_q(name.slice(leftBrace + 1)) : 0; // "index]", parseInt will ignore the ']' at the end; but treat "foo[]" as "foo[0]"8564name = name.slice(0, leftBrace);8565}85668567var uniformInfo = GL.programInfos[program] && GL.programInfos[program].uniforms[name]; // returns pair [ dimension_of_uniform_array, uniform_location ]8568if (uniformInfo && arrayIndex >= 0 && arrayIndex < uniformInfo[0]) { // Check if user asked for an out-of-bounds element, i.e. for 'vec4 colors[3];' user could ask for 'colors[10]' which should return -1.8569return uniformInfo[1] + arrayIndex;8570} else {8571return -1;8572}8573}85748575function _glLinkProgram(program) {8576GLctx.linkProgram(GL.programs[program]);8577GL.populateUniformTable(program);8578}85798580function _glPolygonOffset(x0, x1) { GLctx['polygonOffset'](x0, x1) }85818582function _glScissor(x0, x1, x2, x3) { GLctx['scissor'](x0, x1, x2, x3) }85838584function _glShaderSource(shader, count, string, length) {8585var source = GL.getSource(shader, count, string, length);858685878588GLctx.shaderSource(GL.shaders[shader], source);8589}85908591function _glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels) {8592GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) : null);8593}85948595function _glTexParameteri(x0, x1, x2) { GLctx['texParameteri'](x0, x1, x2) }85968597function _glUniform1i(location, v0) {8598GLctx.uniform1i(GL.uniforms[location], v0);8599}86008601function _glUseProgram(program) {8602GLctx.useProgram(GL.programs[program]);8603}86048605function _glVertexAttribPointer(index, size, type, normalized, stride, ptr) {8606GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr);8607}86088609function _glViewport(x0, x1, x2, x3) { GLctx['viewport'](x0, x1, x2, x3) }861086118612function _usleep(useconds) {8613// int usleep(useconds_t useconds);8614// http://pubs.opengroup.org/onlinepubs/000095399/functions/usleep.html8615// We're single-threaded, so use a busy loop. Super-ugly.8616var start = _emscripten_get_now();8617while (_emscripten_get_now() - start < useconds / 1000) {8618// Do nothing.8619}8620}function _nanosleep(rqtp, rmtp) {8621// int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);8622if (rqtp === 0) {8623___setErrNo(28);8624return -1;8625}8626var seconds = HEAP32[((rqtp)>>2)];8627var nanoseconds = HEAP32[(((rqtp)+(4))>>2)];8628if (nanoseconds < 0 || nanoseconds > 999999999 || seconds < 0) {8629___setErrNo(28);8630return -1;8631}8632if (rmtp !== 0) {8633HEAP32[((rmtp)>>2)]=0;8634HEAP32[(((rmtp)+(4))>>2)]=0;8635}8636return _usleep((seconds * 1e6) + (nanoseconds / 1000));8637}86388639function _setTempRet0($i) {8640setTempRet0(($i) | 0);8641}86428643function _sigaction(signum, act, oldact) {8644//int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);8645err('Calling stub instead of sigaction()');8646return 0;8647}864886498650var __sigalrm_handler=0;function _signal(sig, func) {8651if (sig == 14 /*SIGALRM*/) {8652__sigalrm_handler = func;8653} else {8654err('Calling stub instead of signal()');8655}8656return 0;8657}86588659function readAsmConstArgs(sigPtr, buf) {8660if (!readAsmConstArgs.array) {8661readAsmConstArgs.array = [];8662}8663var args = readAsmConstArgs.array;8664args.length = 0;8665var ch;8666while (ch = HEAPU8[sigPtr++]) {8667if (ch === 100/*'d'*/ || ch === 102/*'f'*/) {8668buf = (buf + 7) & ~7;8669args.push(HEAPF64[(buf >> 3)]);8670buf += 8;8671} else8672if (ch === 105 /*'i'*/)8673{8674buf = (buf + 3) & ~3;8675args.push(HEAP32[(buf >> 2)]);8676buf += 4;8677}8678else abort("unexpected char in asm const signature " + ch);8679}8680return args;8681}8682var FSNode = /** @constructor */ function(parent, name, mode, rdev) {8683if (!parent) {8684parent = this; // root node sets parent to itself8685}8686this.parent = parent;8687this.mount = parent.mount;8688this.mounted = null;8689this.id = FS.nextInode++;8690this.name = name;8691this.mode = mode;8692this.node_ops = {};8693this.stream_ops = {};8694this.rdev = rdev;8695};8696var readMode = 292/*292*/ | 73/*73*/;8697var writeMode = 146/*146*/;8698Object.defineProperties(FSNode.prototype, {8699read: {8700get: /** @this{FSNode} */function() {8701return (this.mode & readMode) === readMode;8702},8703set: /** @this{FSNode} */function(val) {8704val ? this.mode |= readMode : this.mode &= ~readMode;8705}8706},8707write: {8708get: /** @this{FSNode} */function() {8709return (this.mode & writeMode) === writeMode;8710},8711set: /** @this{FSNode} */function(val) {8712val ? this.mode |= writeMode : this.mode &= ~writeMode;8713}8714},8715isFolder: {8716get: /** @this{FSNode} */function() {8717return FS.isDir(this.mode);8718}8719},8720isDevice: {8721get: /** @this{FSNode} */function() {8722return FS.isChrdev(this.mode);8723}8724}8725});8726FS.FSNode = FSNode;8727FS.staticInit();;8728Module["requestFullscreen"] = function Module_requestFullscreen(lockPointer, resizeCanvas) { Browser.requestFullscreen(lockPointer, resizeCanvas) };8729Module["requestFullScreen"] = function Module_requestFullScreen() { Browser.requestFullScreen() };8730Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };8731Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };8732Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };8733Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() };8734Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }8735Module["createContext"] = function Module_createContext(canvas, useWebGL, setInModule, webGLContextAttributes) { return Browser.createContext(canvas, useWebGL, setInModule, webGLContextAttributes) };8736var GLctx; GL.init();8737for (var i = 0; i < 32; i++) __tempFixedLengthArray.push(new Array(i));;8738var ASSERTIONS = true;87398740// Copyright 2017 The Emscripten Authors. All rights reserved.8741// Emscripten is available under two separate licenses, the MIT license and the8742// University of Illinois/NCSA Open Source License. Both these licenses can be8743// found in the LICENSE file.87448745/** @type {function(string, boolean=, number=)} */8746function intArrayFromString(stringy, dontAddNull, length) {8747var len = length > 0 ? length : lengthBytesUTF8(stringy)+1;8748var u8array = new Array(len);8749var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);8750if (dontAddNull) u8array.length = numBytesWritten;8751return u8array;8752}87538754function intArrayToString(array) {8755var ret = [];8756for (var i = 0; i < array.length; i++) {8757var chr = array[i];8758if (chr > 0xFF) {8759if (ASSERTIONS) {8760assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.');8761}8762chr &= 0xFF;8763}8764ret.push(String.fromCharCode(chr));8765}8766return ret.join('');8767}876887698770var asmGlobalArg = {};8771var asmLibraryArg = { "__assert_fail": ___assert_fail, "__handle_stack_overflow": ___handle_stack_overflow, "__syscall221": ___syscall221, "__syscall5": ___syscall5, "__syscall54": ___syscall54, "abort": _abort, "atexit": _atexit, "clock_gettime": _clock_gettime, "dlclose": _dlclose, "dlerror": _dlerror, "dlsym": _dlsym, "eglBindAPI": _eglBindAPI, "eglChooseConfig": _eglChooseConfig, "eglCreateContext": _eglCreateContext, "eglCreateWindowSurface": _eglCreateWindowSurface, "eglDestroyContext": _eglDestroyContext, "eglDestroySurface": _eglDestroySurface, "eglGetConfigAttrib": _eglGetConfigAttrib, "eglGetDisplay": _eglGetDisplay, "eglGetError": _eglGetError, "eglGetProcAddress": _eglGetProcAddress, "eglInitialize": _eglInitialize, "eglMakeCurrent": _eglMakeCurrent, "eglQueryString": _eglQueryString, "eglSwapBuffers": _eglSwapBuffers, "eglSwapInterval": _eglSwapInterval, "eglTerminate": _eglTerminate, "eglWaitGL": _eglWaitGL, "eglWaitNative": _eglWaitNative, "emscripten_asm_const_iii": _emscripten_asm_const_iii, "emscripten_exit_fullscreen": _emscripten_exit_fullscreen, "emscripten_exit_pointerlock": _emscripten_exit_pointerlock, "emscripten_get_device_pixel_ratio": _emscripten_get_device_pixel_ratio, "emscripten_get_element_css_size": _emscripten_get_element_css_size, "emscripten_get_gamepad_status": _emscripten_get_gamepad_status, "emscripten_get_num_gamepads": _emscripten_get_num_gamepads, "emscripten_get_sbrk_ptr": _emscripten_get_sbrk_ptr, "emscripten_glActiveTexture": _emscripten_glActiveTexture, "emscripten_glAttachShader": _emscripten_glAttachShader, "emscripten_glBeginQueryEXT": _emscripten_glBeginQueryEXT, "emscripten_glBindAttribLocation": _emscripten_glBindAttribLocation, "emscripten_glBindBuffer": _emscripten_glBindBuffer, "emscripten_glBindFramebuffer": _emscripten_glBindFramebuffer, "emscripten_glBindRenderbuffer": _emscripten_glBindRenderbuffer, "emscripten_glBindTexture": _emscripten_glBindTexture, "emscripten_glBindVertexArrayOES": _emscripten_glBindVertexArrayOES, "emscripten_glBlendColor": _emscripten_glBlendColor, "emscripten_glBlendEquation": _emscripten_glBlendEquation, "emscripten_glBlendEquationSeparate": _emscripten_glBlendEquationSeparate, "emscripten_glBlendFunc": _emscripten_glBlendFunc, "emscripten_glBlendFuncSeparate": _emscripten_glBlendFuncSeparate, "emscripten_glBufferData": _emscripten_glBufferData, "emscripten_glBufferSubData": _emscripten_glBufferSubData, "emscripten_glCheckFramebufferStatus": _emscripten_glCheckFramebufferStatus, "emscripten_glClear": _emscripten_glClear, "emscripten_glClearColor": _emscripten_glClearColor, "emscripten_glClearDepthf": _emscripten_glClearDepthf, "emscripten_glClearStencil": _emscripten_glClearStencil, "emscripten_glColorMask": _emscripten_glColorMask, "emscripten_glCompileShader": _emscripten_glCompileShader, "emscripten_glCompressedTexImage2D": _emscripten_glCompressedTexImage2D, "emscripten_glCompressedTexSubImage2D": _emscripten_glCompressedTexSubImage2D, "emscripten_glCopyTexImage2D": _emscripten_glCopyTexImage2D, "emscripten_glCopyTexSubImage2D": _emscripten_glCopyTexSubImage2D, "emscripten_glCreateProgram": _emscripten_glCreateProgram, "emscripten_glCreateShader": _emscripten_glCreateShader, "emscripten_glCullFace": _emscripten_glCullFace, "emscripten_glDeleteBuffers": _emscripten_glDeleteBuffers, "emscripten_glDeleteFramebuffers": _emscripten_glDeleteFramebuffers, "emscripten_glDeleteProgram": _emscripten_glDeleteProgram, "emscripten_glDeleteQueriesEXT": _emscripten_glDeleteQueriesEXT, "emscripten_glDeleteRenderbuffers": _emscripten_glDeleteRenderbuffers, "emscripten_glDeleteShader": _emscripten_glDeleteShader, "emscripten_glDeleteTextures": _emscripten_glDeleteTextures, "emscripten_glDeleteVertexArraysOES": _emscripten_glDeleteVertexArraysOES, "emscripten_glDepthFunc": _emscripten_glDepthFunc, "emscripten_glDepthMask": _emscripten_glDepthMask, "emscripten_glDepthRangef": _emscripten_glDepthRangef, "emscripten_glDetachShader": _emscripten_glDetachShader, "emscripten_glDisable": _emscripten_glDisable, "emscripten_glDisableVertexAttribArray": _emscripten_glDisableVertexAttribArray, "emscripten_glDrawArrays": _emscripten_glDrawArrays, "emscripten_glDrawArraysInstancedANGLE": _emscripten_glDrawArraysInstancedANGLE, "emscripten_glDrawBuffersWEBGL": _emscripten_glDrawBuffersWEBGL, "emscripten_glDrawElements": _emscripten_glDrawElements, "emscripten_glDrawElementsInstancedANGLE": _emscripten_glDrawElementsInstancedANGLE, "emscripten_glEnable": _emscripten_glEnable, "emscripten_glEnableVertexAttribArray": _emscripten_glEnableVertexAttribArray, "emscripten_glEndQueryEXT": _emscripten_glEndQueryEXT, "emscripten_glFinish": _emscripten_glFinish, "emscripten_glFlush": _emscripten_glFlush, "emscripten_glFramebufferRenderbuffer": _emscripten_glFramebufferRenderbuffer, "emscripten_glFramebufferTexture2D": _emscripten_glFramebufferTexture2D, "emscripten_glFrontFace": _emscripten_glFrontFace, "emscripten_glGenBuffers": _emscripten_glGenBuffers, "emscripten_glGenFramebuffers": _emscripten_glGenFramebuffers, "emscripten_glGenQueriesEXT": _emscripten_glGenQueriesEXT, "emscripten_glGenRenderbuffers": _emscripten_glGenRenderbuffers, "emscripten_glGenTextures": _emscripten_glGenTextures, "emscripten_glGenVertexArraysOES": _emscripten_glGenVertexArraysOES, "emscripten_glGenerateMipmap": _emscripten_glGenerateMipmap, "emscripten_glGetActiveAttrib": _emscripten_glGetActiveAttrib, "emscripten_glGetActiveUniform": _emscripten_glGetActiveUniform, "emscripten_glGetAttachedShaders": _emscripten_glGetAttachedShaders, "emscripten_glGetAttribLocation": _emscripten_glGetAttribLocation, "emscripten_glGetBooleanv": _emscripten_glGetBooleanv, "emscripten_glGetBufferParameteriv": _emscripten_glGetBufferParameteriv, "emscripten_glGetError": _emscripten_glGetError, "emscripten_glGetFloatv": _emscripten_glGetFloatv, "emscripten_glGetFramebufferAttachmentParameteriv": _emscripten_glGetFramebufferAttachmentParameteriv, "emscripten_glGetIntegerv": _emscripten_glGetIntegerv, "emscripten_glGetProgramInfoLog": _emscripten_glGetProgramInfoLog, "emscripten_glGetProgramiv": _emscripten_glGetProgramiv, "emscripten_glGetQueryObjecti64vEXT": _emscripten_glGetQueryObjecti64vEXT, "emscripten_glGetQueryObjectivEXT": _emscripten_glGetQueryObjectivEXT, "emscripten_glGetQueryObjectui64vEXT": _emscripten_glGetQueryObjectui64vEXT, "emscripten_glGetQueryObjectuivEXT": _emscripten_glGetQueryObjectuivEXT, "emscripten_glGetQueryivEXT": _emscripten_glGetQueryivEXT, "emscripten_glGetRenderbufferParameteriv": _emscripten_glGetRenderbufferParameteriv, "emscripten_glGetShaderInfoLog": _emscripten_glGetShaderInfoLog, "emscripten_glGetShaderPrecisionFormat": _emscripten_glGetShaderPrecisionFormat, "emscripten_glGetShaderSource": _emscripten_glGetShaderSource, "emscripten_glGetShaderiv": _emscripten_glGetShaderiv, "emscripten_glGetString": _emscripten_glGetString, "emscripten_glGetTexParameterfv": _emscripten_glGetTexParameterfv, "emscripten_glGetTexParameteriv": _emscripten_glGetTexParameteriv, "emscripten_glGetUniformLocation": _emscripten_glGetUniformLocation, "emscripten_glGetUniformfv": _emscripten_glGetUniformfv, "emscripten_glGetUniformiv": _emscripten_glGetUniformiv, "emscripten_glGetVertexAttribPointerv": _emscripten_glGetVertexAttribPointerv, "emscripten_glGetVertexAttribfv": _emscripten_glGetVertexAttribfv, "emscripten_glGetVertexAttribiv": _emscripten_glGetVertexAttribiv, "emscripten_glHint": _emscripten_glHint, "emscripten_glIsBuffer": _emscripten_glIsBuffer, "emscripten_glIsEnabled": _emscripten_glIsEnabled, "emscripten_glIsFramebuffer": _emscripten_glIsFramebuffer, "emscripten_glIsProgram": _emscripten_glIsProgram, "emscripten_glIsQueryEXT": _emscripten_glIsQueryEXT, "emscripten_glIsRenderbuffer": _emscripten_glIsRenderbuffer, "emscripten_glIsShader": _emscripten_glIsShader, "emscripten_glIsTexture": _emscripten_glIsTexture, "emscripten_glIsVertexArrayOES": _emscripten_glIsVertexArrayOES, "emscripten_glLineWidth": _emscripten_glLineWidth, "emscripten_glLinkProgram": _emscripten_glLinkProgram, "emscripten_glPixelStorei": _emscripten_glPixelStorei, "emscripten_glPolygonOffset": _emscripten_glPolygonOffset, "emscripten_glQueryCounterEXT": _emscripten_glQueryCounterEXT, "emscripten_glReadPixels": _emscripten_glReadPixels, "emscripten_glReleaseShaderCompiler": _emscripten_glReleaseShaderCompiler, "emscripten_glRenderbufferStorage": _emscripten_glRenderbufferStorage, "emscripten_glSampleCoverage": _emscripten_glSampleCoverage, "emscripten_glScissor": _emscripten_glScissor, "emscripten_glShaderBinary": _emscripten_glShaderBinary, "emscripten_glShaderSource": _emscripten_glShaderSource, "emscripten_glStencilFunc": _emscripten_glStencilFunc, "emscripten_glStencilFuncSeparate": _emscripten_glStencilFuncSeparate, "emscripten_glStencilMask": _emscripten_glStencilMask, "emscripten_glStencilMaskSeparate": _emscripten_glStencilMaskSeparate, "emscripten_glStencilOp": _emscripten_glStencilOp, "emscripten_glStencilOpSeparate": _emscripten_glStencilOpSeparate, "emscripten_glTexImage2D": _emscripten_glTexImage2D, "emscripten_glTexParameterf": _emscripten_glTexParameterf, "emscripten_glTexParameterfv": _emscripten_glTexParameterfv, "emscripten_glTexParameteri": _emscripten_glTexParameteri, "emscripten_glTexParameteriv": _emscripten_glTexParameteriv, "emscripten_glTexSubImage2D": _emscripten_glTexSubImage2D, "emscripten_glUniform1f": _emscripten_glUniform1f, "emscripten_glUniform1fv": _emscripten_glUniform1fv, "emscripten_glUniform1i": _emscripten_glUniform1i, "emscripten_glUniform1iv": _emscripten_glUniform1iv, "emscripten_glUniform2f": _emscripten_glUniform2f, "emscripten_glUniform2fv": _emscripten_glUniform2fv, "emscripten_glUniform2i": _emscripten_glUniform2i, "emscripten_glUniform2iv": _emscripten_glUniform2iv, "emscripten_glUniform3f": _emscripten_glUniform3f, "emscripten_glUniform3fv": _emscripten_glUniform3fv, "emscripten_glUniform3i": _emscripten_glUniform3i, "emscripten_glUniform3iv": _emscripten_glUniform3iv, "emscripten_glUniform4f": _emscripten_glUniform4f, "emscripten_glUniform4fv": _emscripten_glUniform4fv, "emscripten_glUniform4i": _emscripten_glUniform4i, "emscripten_glUniform4iv": _emscripten_glUniform4iv, "emscripten_glUniformMatrix2fv": _emscripten_glUniformMatrix2fv, "emscripten_glUniformMatrix3fv": _emscripten_glUniformMatrix3fv, "emscripten_glUniformMatrix4fv": _emscripten_glUniformMatrix4fv, "emscripten_glUseProgram": _emscripten_glUseProgram, "emscripten_glValidateProgram": _emscripten_glValidateProgram, "emscripten_glVertexAttrib1f": _emscripten_glVertexAttrib1f, "emscripten_glVertexAttrib1fv": _emscripten_glVertexAttrib1fv, "emscripten_glVertexAttrib2f": _emscripten_glVertexAttrib2f, "emscripten_glVertexAttrib2fv": _emscripten_glVertexAttrib2fv, "emscripten_glVertexAttrib3f": _emscripten_glVertexAttrib3f, "emscripten_glVertexAttrib3fv": _emscripten_glVertexAttrib3fv, "emscripten_glVertexAttrib4f": _emscripten_glVertexAttrib4f, "emscripten_glVertexAttrib4fv": _emscripten_glVertexAttrib4fv, "emscripten_glVertexAttribDivisorANGLE": _emscripten_glVertexAttribDivisorANGLE, "emscripten_glVertexAttribPointer": _emscripten_glVertexAttribPointer, "emscripten_glViewport": _emscripten_glViewport, "emscripten_has_asyncify": _emscripten_has_asyncify, "emscripten_memcpy_big": _emscripten_memcpy_big, "emscripten_request_fullscreen_strategy": _emscripten_request_fullscreen_strategy, "emscripten_request_pointerlock": _emscripten_request_pointerlock, "emscripten_resize_heap": _emscripten_resize_heap, "emscripten_sample_gamepad_data": _emscripten_sample_gamepad_data, "emscripten_set_beforeunload_callback_on_thread": _emscripten_set_beforeunload_callback_on_thread, "emscripten_set_blur_callback_on_thread": _emscripten_set_blur_callback_on_thread, "emscripten_set_canvas_element_size": _emscripten_set_canvas_element_size, "emscripten_set_element_css_size": _emscripten_set_element_css_size, "emscripten_set_focus_callback_on_thread": _emscripten_set_focus_callback_on_thread, "emscripten_set_fullscreenchange_callback_on_thread": _emscripten_set_fullscreenchange_callback_on_thread, "emscripten_set_gamepadconnected_callback_on_thread": _emscripten_set_gamepadconnected_callback_on_thread, "emscripten_set_gamepaddisconnected_callback_on_thread": _emscripten_set_gamepaddisconnected_callback_on_thread, "emscripten_set_keydown_callback_on_thread": _emscripten_set_keydown_callback_on_thread, "emscripten_set_keypress_callback_on_thread": _emscripten_set_keypress_callback_on_thread, "emscripten_set_keyup_callback_on_thread": _emscripten_set_keyup_callback_on_thread, "emscripten_set_main_loop": _emscripten_set_main_loop, "emscripten_set_mousedown_callback_on_thread": _emscripten_set_mousedown_callback_on_thread, "emscripten_set_mouseenter_callback_on_thread": _emscripten_set_mouseenter_callback_on_thread, "emscripten_set_mouseleave_callback_on_thread": _emscripten_set_mouseleave_callback_on_thread, "emscripten_set_mousemove_callback_on_thread": _emscripten_set_mousemove_callback_on_thread, "emscripten_set_mouseup_callback_on_thread": _emscripten_set_mouseup_callback_on_thread, "emscripten_set_pointerlockchange_callback_on_thread": _emscripten_set_pointerlockchange_callback_on_thread, "emscripten_set_resize_callback_on_thread": _emscripten_set_resize_callback_on_thread, "emscripten_set_touchcancel_callback_on_thread": _emscripten_set_touchcancel_callback_on_thread, "emscripten_set_touchend_callback_on_thread": _emscripten_set_touchend_callback_on_thread, "emscripten_set_touchmove_callback_on_thread": _emscripten_set_touchmove_callback_on_thread, "emscripten_set_touchstart_callback_on_thread": _emscripten_set_touchstart_callback_on_thread, "emscripten_set_visibilitychange_callback_on_thread": _emscripten_set_visibilitychange_callback_on_thread, "emscripten_set_wheel_callback_on_thread": _emscripten_set_wheel_callback_on_thread, "emscripten_sleep": _emscripten_sleep, "environ_get": _environ_get, "environ_sizes_get": _environ_sizes_get, "exit": _exit, "fd_close": _fd_close, "fd_read": _fd_read, "fd_seek": _fd_seek, "fd_write": _fd_write, "gettimeofday": _gettimeofday, "glActiveTexture": _glActiveTexture, "glAttachShader": _glAttachShader, "glBindBuffer": _glBindBuffer, "glBindTexture": _glBindTexture, "glBlendFunc": _glBlendFunc, "glBufferData": _glBufferData, "glClear": _glClear, "glClearColor": _glClearColor, "glCompileShader": _glCompileShader, "glCreateProgram": _glCreateProgram, "glCreateShader": _glCreateShader, "glDepthFunc": _glDepthFunc, "glDepthMask": _glDepthMask, "glDisable": _glDisable, "glDisableVertexAttribArray": _glDisableVertexAttribArray, "glDrawArrays": _glDrawArrays, "glEnable": _glEnable, "glEnableVertexAttribArray": _glEnableVertexAttribArray, "glGenBuffers": _glGenBuffers, "glGenTextures": _glGenTextures, "glGetAttribLocation": _glGetAttribLocation, "glGetShaderInfoLog": _glGetShaderInfoLog, "glGetShaderiv": _glGetShaderiv, "glGetUniformLocation": _glGetUniformLocation, "glLinkProgram": _glLinkProgram, "glPolygonOffset": _glPolygonOffset, "glScissor": _glScissor, "glShaderSource": _glShaderSource, "glTexImage2D": _glTexImage2D, "glTexParameteri": _glTexParameteri, "glUniform1i": _glUniform1i, "glUseProgram": _glUseProgram, "glVertexAttribPointer": _glVertexAttribPointer, "glViewport": _glViewport, "memory": wasmMemory, "nanosleep": _nanosleep, "setTempRet0": _setTempRet0, "sigaction": _sigaction, "signal": _signal, "table": wasmTable };8772var asm = createWasm();8773Module["asm"] = asm;8774/** @type {function(...*):?} */8775var ___wasm_call_ctors = Module["___wasm_call_ctors"] = function() {8776assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8777assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8778return Module["asm"]["__wasm_call_ctors"].apply(null, arguments)8779};87808781/** @type {function(...*):?} */8782var _memcpy = Module["_memcpy"] = function() {8783assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8784assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8785return Module["asm"]["memcpy"].apply(null, arguments)8786};87878788/** @type {function(...*):?} */8789var _memset = Module["_memset"] = function() {8790assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8791assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8792return Module["asm"]["memset"].apply(null, arguments)8793};87948795/** @type {function(...*):?} */8796var _malloc = Module["_malloc"] = function() {8797assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8798assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8799return Module["asm"]["malloc"].apply(null, arguments)8800};88018802/** @type {function(...*):?} */8803var _free = Module["_free"] = function() {8804assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8805assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8806return Module["asm"]["free"].apply(null, arguments)8807};88088809/** @type {function(...*):?} */8810var _main = Module["_main"] = function() {8811assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8812assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8813return Module["asm"]["main"].apply(null, arguments)8814};88158816/** @type {function(...*):?} */8817var _strstr = Module["_strstr"] = function() {8818assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8819assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8820return Module["asm"]["strstr"].apply(null, arguments)8821};88228823/** @type {function(...*):?} */8824var ___errno_location = Module["___errno_location"] = function() {8825assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8826assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8827return Module["asm"]["__errno_location"].apply(null, arguments)8828};88298830/** @type {function(...*):?} */8831var _fflush = Module["_fflush"] = function() {8832assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8833assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8834return Module["asm"]["fflush"].apply(null, arguments)8835};88368837/** @type {function(...*):?} */8838var _emscripten_GetProcAddress = Module["_emscripten_GetProcAddress"] = function() {8839assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8840assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8841return Module["asm"]["emscripten_GetProcAddress"].apply(null, arguments)8842};88438844/** @type {function(...*):?} */8845var ___set_stack_limit = Module["___set_stack_limit"] = function() {8846assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8847assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8848return Module["asm"]["__set_stack_limit"].apply(null, arguments)8849};88508851/** @type {function(...*):?} */8852var stackSave = Module["stackSave"] = function() {8853assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8854assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8855return Module["asm"]["stackSave"].apply(null, arguments)8856};88578858/** @type {function(...*):?} */8859var stackAlloc = Module["stackAlloc"] = function() {8860assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8861assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8862return Module["asm"]["stackAlloc"].apply(null, arguments)8863};88648865/** @type {function(...*):?} */8866var stackRestore = Module["stackRestore"] = function() {8867assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8868assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8869return Module["asm"]["stackRestore"].apply(null, arguments)8870};88718872/** @type {function(...*):?} */8873var __growWasmMemory = Module["__growWasmMemory"] = function() {8874assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8875assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8876return Module["asm"]["__growWasmMemory"].apply(null, arguments)8877};88788879/** @type {function(...*):?} */8880var dynCall_i = Module["dynCall_i"] = function() {8881assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8882assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8883return Module["asm"]["dynCall_i"].apply(null, arguments)8884};88858886/** @type {function(...*):?} */8887var dynCall_v = Module["dynCall_v"] = function() {8888assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8889assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8890return Module["asm"]["dynCall_v"].apply(null, arguments)8891};88928893/** @type {function(...*):?} */8894var dynCall_iiii = Module["dynCall_iiii"] = function() {8895assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8896assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8897return Module["asm"]["dynCall_iiii"].apply(null, arguments)8898};88998900/** @type {function(...*):?} */8901var dynCall_vi = Module["dynCall_vi"] = function() {8902assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8903assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8904return Module["asm"]["dynCall_vi"].apply(null, arguments)8905};89068907/** @type {function(...*):?} */8908var dynCall_iii = Module["dynCall_iii"] = function() {8909assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8910assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8911return Module["asm"]["dynCall_iii"].apply(null, arguments)8912};89138914/** @type {function(...*):?} */8915var dynCall_vd = Module["dynCall_vd"] = function() {8916assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8917assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8918return Module["asm"]["dynCall_vd"].apply(null, arguments)8919};89208921/** @type {function(...*):?} */8922var dynCall_ii = Module["dynCall_ii"] = function() {8923assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8924assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8925return Module["asm"]["dynCall_ii"].apply(null, arguments)8926};89278928/** @type {function(...*):?} */8929var dynCall_viii = Module["dynCall_viii"] = function() {8930assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8931assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8932return Module["asm"]["dynCall_viii"].apply(null, arguments)8933};89348935/** @type {function(...*):?} */8936var dynCall_vii = Module["dynCall_vii"] = function() {8937assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8938assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8939return Module["asm"]["dynCall_vii"].apply(null, arguments)8940};89418942/** @type {function(...*):?} */8943var dynCall_viiii = Module["dynCall_viiii"] = function() {8944assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8945assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8946return Module["asm"]["dynCall_viiii"].apply(null, arguments)8947};89488949/** @type {function(...*):?} */8950var dynCall_d = Module["dynCall_d"] = function() {8951assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8952assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8953return Module["asm"]["dynCall_d"].apply(null, arguments)8954};89558956/** @type {function(...*):?} */8957var dynCall_iiiii = Module["dynCall_iiiii"] = function() {8958assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8959assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8960return Module["asm"]["dynCall_iiiii"].apply(null, arguments)8961};89628963/** @type {function(...*):?} */8964var dynCall_iiiiii = Module["dynCall_iiiiii"] = function() {8965assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8966assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8967return Module["asm"]["dynCall_iiiiii"].apply(null, arguments)8968};89698970/** @type {function(...*):?} */8971var dynCall_jiji = Module["dynCall_jiji"] = function() {8972assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8973assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8974return Module["asm"]["dynCall_jiji"].apply(null, arguments)8975};89768977/** @type {function(...*):?} */8978var dynCall_ji = Module["dynCall_ji"] = function() {8979assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8980assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8981return Module["asm"]["dynCall_ji"].apply(null, arguments)8982};89838984/** @type {function(...*):?} */8985var dynCall_iiiiidii = Module["dynCall_iiiiidii"] = function() {8986assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8987assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8988return Module["asm"]["dynCall_iiiiidii"].apply(null, arguments)8989};89908991/** @type {function(...*):?} */8992var dynCall_iiiiiiiiii = Module["dynCall_iiiiiiiiii"] = function() {8993assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');8994assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');8995return Module["asm"]["dynCall_iiiiiiiiii"].apply(null, arguments)8996};89978998/** @type {function(...*):?} */8999var dynCall_iiiiiiiii = Module["dynCall_iiiiiiiii"] = function() {9000assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9001assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9002return Module["asm"]["dynCall_iiiiiiiii"].apply(null, arguments)9003};90049005/** @type {function(...*):?} */9006var dynCall_viiiiiii = Module["dynCall_viiiiiii"] = function() {9007assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9008assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9009return Module["asm"]["dynCall_viiiiiii"].apply(null, arguments)9010};90119012/** @type {function(...*):?} */9013var dynCall_viiiiiiiiiii = Module["dynCall_viiiiiiiiiii"] = function() {9014assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9015assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9016return Module["asm"]["dynCall_viiiiiiiiiii"].apply(null, arguments)9017};90189019/** @type {function(...*):?} */9020var dynCall_iiiiiiii = Module["dynCall_iiiiiiii"] = function() {9021assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9022assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9023return Module["asm"]["dynCall_iiiiiiii"].apply(null, arguments)9024};90259026/** @type {function(...*):?} */9027var dynCall_iidiiii = Module["dynCall_iidiiii"] = function() {9028assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9029assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9030return Module["asm"]["dynCall_iidiiii"].apply(null, arguments)9031};90329033/** @type {function(...*):?} */9034var dynCall_viiiii = Module["dynCall_viiiii"] = function() {9035assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9036assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9037return Module["asm"]["dynCall_viiiii"].apply(null, arguments)9038};90399040/** @type {function(...*):?} */9041var dynCall_vffff = Module["dynCall_vffff"] = function() {9042assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9043assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9044return Module["asm"]["dynCall_vffff"].apply(null, arguments)9045};90469047/** @type {function(...*):?} */9048var dynCall_vf = Module["dynCall_vf"] = function() {9049assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9050assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9051return Module["asm"]["dynCall_vf"].apply(null, arguments)9052};90539054/** @type {function(...*):?} */9055var dynCall_viiiiiiii = Module["dynCall_viiiiiiii"] = function() {9056assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9057assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9058return Module["asm"]["dynCall_viiiiiiii"].apply(null, arguments)9059};90609061/** @type {function(...*):?} */9062var dynCall_viiiiiiiii = Module["dynCall_viiiiiiiii"] = function() {9063assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9064assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9065return Module["asm"]["dynCall_viiiiiiiii"].apply(null, arguments)9066};90679068/** @type {function(...*):?} */9069var dynCall_vff = Module["dynCall_vff"] = function() {9070assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9071assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9072return Module["asm"]["dynCall_vff"].apply(null, arguments)9073};90749075/** @type {function(...*):?} */9076var dynCall_vfi = Module["dynCall_vfi"] = function() {9077assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9078assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9079return Module["asm"]["dynCall_vfi"].apply(null, arguments)9080};90819082/** @type {function(...*):?} */9083var dynCall_viif = Module["dynCall_viif"] = function() {9084assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9085assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9086return Module["asm"]["dynCall_viif"].apply(null, arguments)9087};90889089/** @type {function(...*):?} */9090var dynCall_vif = Module["dynCall_vif"] = function() {9091assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9092assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9093return Module["asm"]["dynCall_vif"].apply(null, arguments)9094};90959096/** @type {function(...*):?} */9097var dynCall_viff = Module["dynCall_viff"] = function() {9098assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9099assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9100return Module["asm"]["dynCall_viff"].apply(null, arguments)9101};91029103/** @type {function(...*):?} */9104var dynCall_vifff = Module["dynCall_vifff"] = function() {9105assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9106assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9107return Module["asm"]["dynCall_vifff"].apply(null, arguments)9108};91099110/** @type {function(...*):?} */9111var dynCall_viffff = Module["dynCall_viffff"] = function() {9112assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9113assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9114return Module["asm"]["dynCall_viffff"].apply(null, arguments)9115};91169117/** @type {function(...*):?} */9118var dynCall_viiiiii = Module["dynCall_viiiiii"] = function() {9119assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)');9120assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)');9121return Module["asm"]["dynCall_viiiiii"].apply(null, arguments)9122};91239124912591269127// === Auto-generated postamble setup entry stuff ===91289129Module['asm'] = asm;91309131if (!Object.getOwnPropertyDescriptor(Module, "intArrayFromString")) Module["intArrayFromString"] = function() { abort("'intArrayFromString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9132if (!Object.getOwnPropertyDescriptor(Module, "intArrayToString")) Module["intArrayToString"] = function() { abort("'intArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9133if (!Object.getOwnPropertyDescriptor(Module, "ccall")) Module["ccall"] = function() { abort("'ccall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9134if (!Object.getOwnPropertyDescriptor(Module, "cwrap")) Module["cwrap"] = function() { abort("'cwrap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9135if (!Object.getOwnPropertyDescriptor(Module, "setValue")) Module["setValue"] = function() { abort("'setValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9136if (!Object.getOwnPropertyDescriptor(Module, "getValue")) Module["getValue"] = function() { abort("'getValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9137if (!Object.getOwnPropertyDescriptor(Module, "allocate")) Module["allocate"] = function() { abort("'allocate' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9138if (!Object.getOwnPropertyDescriptor(Module, "getMemory")) Module["getMemory"] = function() { abort("'getMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };9139if (!Object.getOwnPropertyDescriptor(Module, "UTF8ArrayToString")) Module["UTF8ArrayToString"] = function() { abort("'UTF8ArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9140if (!Object.getOwnPropertyDescriptor(Module, "UTF8ToString")) Module["UTF8ToString"] = function() { abort("'UTF8ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9141if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8Array")) Module["stringToUTF8Array"] = function() { abort("'stringToUTF8Array' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9142if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8")) Module["stringToUTF8"] = function() { abort("'stringToUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9143if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF8")) Module["lengthBytesUTF8"] = function() { abort("'lengthBytesUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9144if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9145if (!Object.getOwnPropertyDescriptor(Module, "addOnPreRun")) Module["addOnPreRun"] = function() { abort("'addOnPreRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9146if (!Object.getOwnPropertyDescriptor(Module, "addOnInit")) Module["addOnInit"] = function() { abort("'addOnInit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9147if (!Object.getOwnPropertyDescriptor(Module, "addOnPreMain")) Module["addOnPreMain"] = function() { abort("'addOnPreMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9148if (!Object.getOwnPropertyDescriptor(Module, "addOnExit")) Module["addOnExit"] = function() { abort("'addOnExit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9149if (!Object.getOwnPropertyDescriptor(Module, "addOnPostRun")) Module["addOnPostRun"] = function() { abort("'addOnPostRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9150if (!Object.getOwnPropertyDescriptor(Module, "writeStringToMemory")) Module["writeStringToMemory"] = function() { abort("'writeStringToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9151if (!Object.getOwnPropertyDescriptor(Module, "writeArrayToMemory")) Module["writeArrayToMemory"] = function() { abort("'writeArrayToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9152if (!Object.getOwnPropertyDescriptor(Module, "writeAsciiToMemory")) Module["writeAsciiToMemory"] = function() { abort("'writeAsciiToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9153if (!Object.getOwnPropertyDescriptor(Module, "addRunDependency")) Module["addRunDependency"] = function() { abort("'addRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };9154if (!Object.getOwnPropertyDescriptor(Module, "removeRunDependency")) Module["removeRunDependency"] = function() { abort("'removeRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };9155if (!Object.getOwnPropertyDescriptor(Module, "FS_createFolder")) Module["FS_createFolder"] = function() { abort("'FS_createFolder' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };9156if (!Object.getOwnPropertyDescriptor(Module, "FS_createPath")) Module["FS_createPath"] = function() { abort("'FS_createPath' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };9157if (!Object.getOwnPropertyDescriptor(Module, "FS_createDataFile")) Module["FS_createDataFile"] = function() { abort("'FS_createDataFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };9158if (!Object.getOwnPropertyDescriptor(Module, "FS_createPreloadedFile")) Module["FS_createPreloadedFile"] = function() { abort("'FS_createPreloadedFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };9159if (!Object.getOwnPropertyDescriptor(Module, "FS_createLazyFile")) Module["FS_createLazyFile"] = function() { abort("'FS_createLazyFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };9160if (!Object.getOwnPropertyDescriptor(Module, "FS_createLink")) Module["FS_createLink"] = function() { abort("'FS_createLink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };9161if (!Object.getOwnPropertyDescriptor(Module, "FS_createDevice")) Module["FS_createDevice"] = function() { abort("'FS_createDevice' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };9162if (!Object.getOwnPropertyDescriptor(Module, "FS_unlink")) Module["FS_unlink"] = function() { abort("'FS_unlink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };9163if (!Object.getOwnPropertyDescriptor(Module, "dynamicAlloc")) Module["dynamicAlloc"] = function() { abort("'dynamicAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9164if (!Object.getOwnPropertyDescriptor(Module, "loadDynamicLibrary")) Module["loadDynamicLibrary"] = function() { abort("'loadDynamicLibrary' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9165if (!Object.getOwnPropertyDescriptor(Module, "loadWebAssemblyModule")) Module["loadWebAssemblyModule"] = function() { abort("'loadWebAssemblyModule' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9166if (!Object.getOwnPropertyDescriptor(Module, "getLEB")) Module["getLEB"] = function() { abort("'getLEB' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9167if (!Object.getOwnPropertyDescriptor(Module, "getFunctionTables")) Module["getFunctionTables"] = function() { abort("'getFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9168if (!Object.getOwnPropertyDescriptor(Module, "alignFunctionTables")) Module["alignFunctionTables"] = function() { abort("'alignFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9169if (!Object.getOwnPropertyDescriptor(Module, "registerFunctions")) Module["registerFunctions"] = function() { abort("'registerFunctions' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9170if (!Object.getOwnPropertyDescriptor(Module, "addFunction")) Module["addFunction"] = function() { abort("'addFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9171if (!Object.getOwnPropertyDescriptor(Module, "removeFunction")) Module["removeFunction"] = function() { abort("'removeFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9172if (!Object.getOwnPropertyDescriptor(Module, "getFuncWrapper")) Module["getFuncWrapper"] = function() { abort("'getFuncWrapper' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9173if (!Object.getOwnPropertyDescriptor(Module, "prettyPrint")) Module["prettyPrint"] = function() { abort("'prettyPrint' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9174if (!Object.getOwnPropertyDescriptor(Module, "makeBigInt")) Module["makeBigInt"] = function() { abort("'makeBigInt' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9175if (!Object.getOwnPropertyDescriptor(Module, "dynCall")) Module["dynCall"] = function() { abort("'dynCall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9176if (!Object.getOwnPropertyDescriptor(Module, "getCompilerSetting")) Module["getCompilerSetting"] = function() { abort("'getCompilerSetting' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9177if (!Object.getOwnPropertyDescriptor(Module, "print")) Module["print"] = function() { abort("'print' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9178if (!Object.getOwnPropertyDescriptor(Module, "printErr")) Module["printErr"] = function() { abort("'printErr' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9179if (!Object.getOwnPropertyDescriptor(Module, "getTempRet0")) Module["getTempRet0"] = function() { abort("'getTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9180if (!Object.getOwnPropertyDescriptor(Module, "setTempRet0")) Module["setTempRet0"] = function() { abort("'setTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9181Module["callMain"] = callMain;9182if (!Object.getOwnPropertyDescriptor(Module, "abort")) Module["abort"] = function() { abort("'abort' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9183if (!Object.getOwnPropertyDescriptor(Module, "stringToNewUTF8")) Module["stringToNewUTF8"] = function() { abort("'stringToNewUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9184if (!Object.getOwnPropertyDescriptor(Module, "abortOnCannotGrowMemory")) Module["abortOnCannotGrowMemory"] = function() { abort("'abortOnCannotGrowMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9185if (!Object.getOwnPropertyDescriptor(Module, "emscripten_realloc_buffer")) Module["emscripten_realloc_buffer"] = function() { abort("'emscripten_realloc_buffer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9186if (!Object.getOwnPropertyDescriptor(Module, "ENV")) Module["ENV"] = function() { abort("'ENV' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9187if (!Object.getOwnPropertyDescriptor(Module, "setjmpId")) Module["setjmpId"] = function() { abort("'setjmpId' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9188if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_CODES")) Module["ERRNO_CODES"] = function() { abort("'ERRNO_CODES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9189if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_MESSAGES")) Module["ERRNO_MESSAGES"] = function() { abort("'ERRNO_MESSAGES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9190if (!Object.getOwnPropertyDescriptor(Module, "DNS")) Module["DNS"] = function() { abort("'DNS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9191if (!Object.getOwnPropertyDescriptor(Module, "GAI_ERRNO_MESSAGES")) Module["GAI_ERRNO_MESSAGES"] = function() { abort("'GAI_ERRNO_MESSAGES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9192if (!Object.getOwnPropertyDescriptor(Module, "Protocols")) Module["Protocols"] = function() { abort("'Protocols' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9193if (!Object.getOwnPropertyDescriptor(Module, "Sockets")) Module["Sockets"] = function() { abort("'Sockets' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9194if (!Object.getOwnPropertyDescriptor(Module, "UNWIND_CACHE")) Module["UNWIND_CACHE"] = function() { abort("'UNWIND_CACHE' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9195if (!Object.getOwnPropertyDescriptor(Module, "readAsmConstArgs")) Module["readAsmConstArgs"] = function() { abort("'readAsmConstArgs' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9196if (!Object.getOwnPropertyDescriptor(Module, "jstoi_q")) Module["jstoi_q"] = function() { abort("'jstoi_q' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9197if (!Object.getOwnPropertyDescriptor(Module, "jstoi_s")) Module["jstoi_s"] = function() { abort("'jstoi_s' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9198if (!Object.getOwnPropertyDescriptor(Module, "PATH")) Module["PATH"] = function() { abort("'PATH' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9199if (!Object.getOwnPropertyDescriptor(Module, "PATH_FS")) Module["PATH_FS"] = function() { abort("'PATH_FS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9200if (!Object.getOwnPropertyDescriptor(Module, "SYSCALLS")) Module["SYSCALLS"] = function() { abort("'SYSCALLS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9201if (!Object.getOwnPropertyDescriptor(Module, "syscallMmap2")) Module["syscallMmap2"] = function() { abort("'syscallMmap2' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9202if (!Object.getOwnPropertyDescriptor(Module, "syscallMunmap")) Module["syscallMunmap"] = function() { abort("'syscallMunmap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9203if (!Object.getOwnPropertyDescriptor(Module, "JSEvents")) Module["JSEvents"] = function() { abort("'JSEvents' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9204if (!Object.getOwnPropertyDescriptor(Module, "demangle")) Module["demangle"] = function() { abort("'demangle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9205if (!Object.getOwnPropertyDescriptor(Module, "demangleAll")) Module["demangleAll"] = function() { abort("'demangleAll' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9206if (!Object.getOwnPropertyDescriptor(Module, "jsStackTrace")) Module["jsStackTrace"] = function() { abort("'jsStackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9207if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9208if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64")) Module["writeI53ToI64"] = function() { abort("'writeI53ToI64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9209if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Clamped")) Module["writeI53ToI64Clamped"] = function() { abort("'writeI53ToI64Clamped' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9210if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Signaling")) Module["writeI53ToI64Signaling"] = function() { abort("'writeI53ToI64Signaling' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9211if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Clamped")) Module["writeI53ToU64Clamped"] = function() { abort("'writeI53ToU64Clamped' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9212if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Signaling")) Module["writeI53ToU64Signaling"] = function() { abort("'writeI53ToU64Signaling' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9213if (!Object.getOwnPropertyDescriptor(Module, "readI53FromI64")) Module["readI53FromI64"] = function() { abort("'readI53FromI64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9214if (!Object.getOwnPropertyDescriptor(Module, "readI53FromU64")) Module["readI53FromU64"] = function() { abort("'readI53FromU64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9215if (!Object.getOwnPropertyDescriptor(Module, "convertI32PairToI53")) Module["convertI32PairToI53"] = function() { abort("'convertI32PairToI53' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9216if (!Object.getOwnPropertyDescriptor(Module, "convertU32PairToI53")) Module["convertU32PairToI53"] = function() { abort("'convertU32PairToI53' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9217if (!Object.getOwnPropertyDescriptor(Module, "Browser")) Module["Browser"] = function() { abort("'Browser' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9218if (!Object.getOwnPropertyDescriptor(Module, "FS")) Module["FS"] = function() { abort("'FS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9219if (!Object.getOwnPropertyDescriptor(Module, "MEMFS")) Module["MEMFS"] = function() { abort("'MEMFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9220if (!Object.getOwnPropertyDescriptor(Module, "TTY")) Module["TTY"] = function() { abort("'TTY' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9221if (!Object.getOwnPropertyDescriptor(Module, "PIPEFS")) Module["PIPEFS"] = function() { abort("'PIPEFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9222if (!Object.getOwnPropertyDescriptor(Module, "SOCKFS")) Module["SOCKFS"] = function() { abort("'SOCKFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9223if (!Object.getOwnPropertyDescriptor(Module, "GL")) Module["GL"] = function() { abort("'GL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9224if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGet")) Module["emscriptenWebGLGet"] = function() { abort("'emscriptenWebGLGet' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9225if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetTexPixelData")) Module["emscriptenWebGLGetTexPixelData"] = function() { abort("'emscriptenWebGLGetTexPixelData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9226if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetUniform")) Module["emscriptenWebGLGetUniform"] = function() { abort("'emscriptenWebGLGetUniform' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9227if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetVertexAttrib")) Module["emscriptenWebGLGetVertexAttrib"] = function() { abort("'emscriptenWebGLGetVertexAttrib' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9228if (!Object.getOwnPropertyDescriptor(Module, "AL")) Module["AL"] = function() { abort("'AL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9229if (!Object.getOwnPropertyDescriptor(Module, "SDL")) Module["SDL"] = function() { abort("'SDL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9230if (!Object.getOwnPropertyDescriptor(Module, "SDL_gfx")) Module["SDL_gfx"] = function() { abort("'SDL_gfx' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9231if (!Object.getOwnPropertyDescriptor(Module, "GLUT")) Module["GLUT"] = function() { abort("'GLUT' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9232if (!Object.getOwnPropertyDescriptor(Module, "EGL")) Module["EGL"] = function() { abort("'EGL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9233if (!Object.getOwnPropertyDescriptor(Module, "GLFW_Window")) Module["GLFW_Window"] = function() { abort("'GLFW_Window' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9234if (!Object.getOwnPropertyDescriptor(Module, "GLFW")) Module["GLFW"] = function() { abort("'GLFW' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9235if (!Object.getOwnPropertyDescriptor(Module, "GLEW")) Module["GLEW"] = function() { abort("'GLEW' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9236if (!Object.getOwnPropertyDescriptor(Module, "IDBStore")) Module["IDBStore"] = function() { abort("'IDBStore' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9237if (!Object.getOwnPropertyDescriptor(Module, "runAndAbortIfError")) Module["runAndAbortIfError"] = function() { abort("'runAndAbortIfError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9238if (!Object.getOwnPropertyDescriptor(Module, "warnOnce")) Module["warnOnce"] = function() { abort("'warnOnce' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9239if (!Object.getOwnPropertyDescriptor(Module, "stackSave")) Module["stackSave"] = function() { abort("'stackSave' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9240if (!Object.getOwnPropertyDescriptor(Module, "stackRestore")) Module["stackRestore"] = function() { abort("'stackRestore' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9241if (!Object.getOwnPropertyDescriptor(Module, "stackAlloc")) Module["stackAlloc"] = function() { abort("'stackAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9242if (!Object.getOwnPropertyDescriptor(Module, "AsciiToString")) Module["AsciiToString"] = function() { abort("'AsciiToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9243if (!Object.getOwnPropertyDescriptor(Module, "stringToAscii")) Module["stringToAscii"] = function() { abort("'stringToAscii' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9244if (!Object.getOwnPropertyDescriptor(Module, "UTF16ToString")) Module["UTF16ToString"] = function() { abort("'UTF16ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9245if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF16")) Module["stringToUTF16"] = function() { abort("'stringToUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9246if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF16")) Module["lengthBytesUTF16"] = function() { abort("'lengthBytesUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9247if (!Object.getOwnPropertyDescriptor(Module, "UTF32ToString")) Module["UTF32ToString"] = function() { abort("'UTF32ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9248if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF32")) Module["stringToUTF32"] = function() { abort("'stringToUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9249if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF32")) Module["lengthBytesUTF32"] = function() { abort("'lengthBytesUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9250if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8")) Module["allocateUTF8"] = function() { abort("'allocateUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9251if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8OnStack")) Module["allocateUTF8OnStack"] = function() { abort("'allocateUTF8OnStack' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };9252Module["writeStackCookie"] = writeStackCookie;9253Module["checkStackCookie"] = checkStackCookie;9254Module["abortStackOverflow"] = abortStackOverflow;if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_NORMAL")) Object.defineProperty(Module, "ALLOC_NORMAL", { configurable: true, get: function() { abort("'ALLOC_NORMAL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } });9255if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_STACK")) Object.defineProperty(Module, "ALLOC_STACK", { configurable: true, get: function() { abort("'ALLOC_STACK' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } });9256if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_DYNAMIC")) Object.defineProperty(Module, "ALLOC_DYNAMIC", { configurable: true, get: function() { abort("'ALLOC_DYNAMIC' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } });9257if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_NONE")) Object.defineProperty(Module, "ALLOC_NONE", { configurable: true, get: function() { abort("'ALLOC_NONE' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } });9258925992609261var calledRun;926292639264/**9265* @constructor9266* @this {ExitStatus}9267*/9268function ExitStatus(status) {9269this.name = "ExitStatus";9270this.message = "Program terminated with exit(" + status + ")";9271this.status = status;9272}92739274var calledMain = false;927592769277dependenciesFulfilled = function runCaller() {9278// If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)9279if (!calledRun) run();9280if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled9281};92829283function callMain(args) {9284assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])');9285assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');92869287var entryFunction = Module['_main'];928892899290args = args || [];92919292var argc = args.length+1;9293var argv = stackAlloc((argc + 1) * 4);9294HEAP32[argv >> 2] = allocateUTF8OnStack(thisProgram);9295for (var i = 1; i < argc; i++) {9296HEAP32[(argv >> 2) + i] = allocateUTF8OnStack(args[i - 1]);9297}9298HEAP32[(argv >> 2) + argc] = 0;929993009301try {93029303Module['___set_stack_limit'](STACK_MAX);93049305var ret = entryFunction(argc, argv);930693079308// In PROXY_TO_PTHREAD builds, we should never exit the runtime below, as execution is asynchronously handed9309// off to a pthread.9310// if we're not running an evented main loop, it's time to exit9311exit(ret, /* implicit = */ true);9312}9313catch(e) {9314if (e instanceof ExitStatus) {9315// exit() throws this once it's done to make sure execution9316// has been stopped completely9317return;9318} else if (e == 'unwind') {9319// running an evented main loop, don't immediately exit9320noExitRuntime = true;9321return;9322} else {9323var toLog = e;9324if (e && typeof e === 'object' && e.stack) {9325toLog = [e, e.stack];9326}9327err('exception thrown: ' + toLog);9328quit_(1, e);9329}9330} finally {9331calledMain = true;9332}9333}93349335933693379338/** @type {function(Array=)} */9339function run(args) {9340args = args || arguments_;93419342if (runDependencies > 0) {9343return;9344}93459346writeStackCookie();93479348preRun();93499350if (runDependencies > 0) return; // a preRun added a dependency, run will be called later93519352function doRun() {9353// run may have just been called through dependencies being fulfilled just in this very frame,9354// or while the async setStatus time below was happening9355if (calledRun) return;9356calledRun = true;9357Module['calledRun'] = true;93589359if (ABORT) return;93609361initRuntime();93629363preMain();93649365if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();93669367if (shouldRunNow) callMain(args);93689369postRun();9370}93719372if (Module['setStatus']) {9373Module['setStatus']('Running...');9374setTimeout(function() {9375setTimeout(function() {9376Module['setStatus']('');9377}, 1);9378doRun();9379}, 1);9380} else9381{9382doRun();9383}9384checkStackCookie();9385}9386Module['run'] = run;93879388function checkUnflushedContent() {9389// Compiler settings do not allow exiting the runtime, so flushing9390// the streams is not possible. but in ASSERTIONS mode we check9391// if there was something to flush, and if so tell the user they9392// should request that the runtime be exitable.9393// Normally we would not even include flush() at all, but in ASSERTIONS9394// builds we do so just for this check, and here we see if there is any9395// content to flush, that is, we check if there would have been9396// something a non-ASSERTIONS build would have not seen.9397// How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=09398// mode (which has its own special function for this; otherwise, all9399// the code is inside libc)9400var print = out;9401var printErr = err;9402var has = false;9403out = err = function(x) {9404has = true;9405}9406try { // it doesn't matter if it fails9407var flush = Module['_fflush'];9408if (flush) flush(0);9409// also flush in the JS FS layer9410['stdout', 'stderr'].forEach(function(name) {9411var info = FS.analyzePath('/dev/' + name);9412if (!info) return;9413var stream = info.object;9414var rdev = stream.rdev;9415var tty = TTY.ttys[rdev];9416if (tty && tty.output && tty.output.length) {9417has = true;9418}9419});9420} catch(e) {}9421out = print;9422err = printErr;9423if (has) {9424warnOnce('stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the FAQ), or make sure to emit a newline when you printf etc.');9425}9426}94279428/** @param {boolean|number=} implicit */9429function exit(status, implicit) {9430checkUnflushedContent();94319432// if this is just main exit-ing implicitly, and the status is 0, then we9433// don't need to do anything here and can just leave. if the status is9434// non-zero, though, then we need to report it.9435// (we may have warned about this earlier, if a situation justifies doing so)9436if (implicit && noExitRuntime && status === 0) {9437return;9438}94399440if (noExitRuntime) {9441// if exit() was called, we may warn the user if the runtime isn't actually being shut down9442if (!implicit) {9443err('program exited (with status: ' + status + '), but EXIT_RUNTIME is not set, so halting execution but not exiting the runtime or preventing further async execution (build with EXIT_RUNTIME=1, if you want a true shutdown)');9444}9445} else {94469447ABORT = true;9448EXITSTATUS = status;94499450exitRuntime();94519452if (Module['onExit']) Module['onExit'](status);9453}94549455quit_(status, new ExitStatus(status));9456}94579458if (Module['preInit']) {9459if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];9460while (Module['preInit'].length > 0) {9461Module['preInit'].pop()();9462}9463}94649465// shouldRunNow refers to calling main(), not run().9466var shouldRunNow = true;94679468if (Module['noInitialRun']) shouldRunNow = false;946994709471noExitRuntime = true;94729473run();947494759476947794789479// {{MODULE_ADDITIONS}}948094819482948394849485