diff --git a/examples/audio-worklet-webassembly.mjs b/examples/audio-worklet-webassembly.mjs new file mode 100644 index 0000000..9eb0b8d --- /dev/null +++ b/examples/audio-worklet-webassembly.mjs @@ -0,0 +1,16 @@ +// https://github.com/GoogleChromeLabs/web-audio-samples/tree/main/src/audio-worklet/design-pattern/wasm +// +// Copyright (c) 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import { AudioContext, OscillatorNode, AudioWorkletNode } from '../index.mjs'; + +const audioContext = new AudioContext(); + +await audioContext.audioWorklet.addModule('./worklets/wasm-worklet-processor.mjs'); +const oscillator = new OscillatorNode(audioContext); +const bypasser = new AudioWorkletNode(audioContext, 'wasm-worklet-processor'); +oscillator.connect(bypasser).connect(audioContext.destination); +oscillator.start(); + diff --git a/examples/worklets/Makefile b/examples/worklets/Makefile new file mode 100644 index 0000000..59bfc70 --- /dev/null +++ b/examples/worklets/Makefile @@ -0,0 +1,15 @@ +DEPS = SimpleKernel.cc + +build: $(DEPS) + @emcc --bind -O1 \ + -s WASM=1 \ + -s BINARYEN_ASYNC_COMPILATION=0 \ + -s SINGLE_FILE=1 \ + -s ENVIRONMENT=node \ + -s EXPORT_ES6=1 \ + -s EXPORTED_FUNCTIONS="['_malloc']" \ + SimpleKernel.cc \ + -o simple-kernel.wasmmodule.mjs + +clean: + @rm -f simple-kernel.wasmmodule.js diff --git a/examples/worklets/SimpleKernel.cc b/examples/worklets/SimpleKernel.cc new file mode 100644 index 0000000..84535a0 --- /dev/null +++ b/examples/worklets/SimpleKernel.cc @@ -0,0 +1,65 @@ +// adapted from https://github.com/GoogleChromeLabs/web-audio-samples/tree/main/src/audio-worklet/design-pattern/wasm + +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +#include "emscripten/bind.h" + +using namespace emscripten; + +const unsigned kRenderQuantumFrames = 128; +const unsigned kBytesPerChannel = kRenderQuantumFrames * sizeof(float); + +// The "kernel" is an object that processes a audio stream, which contains +// one or more channels. It is supposed to obtain the frame data from an +// |input|, process and fill an |output| of the AudioWorkletProcessor. +// +// AudioWorkletProcessor Input(multi-channel, 128-frames) +// | +// V +// Kernel +// | +// V +// AudioWorkletProcessor Output(multi-channel, 128-frames) +// +// In this implementation, the kernel operates based on 128-frames, which is +// the render quantum size of Web Audio API. +class SimpleKernel { + public: + SimpleKernel() {} + + void Process(uintptr_t input_ptr, uintptr_t output_ptr, + unsigned channel_count) { + float* input_buffer = reinterpret_cast(input_ptr); + float* output_buffer = reinterpret_cast(output_ptr); + + // Bypasses the data. By design, the channel count will always be the same + // for |input_buffer| and |output_buffer|. + for (unsigned channel = 0; channel < channel_count; ++channel) { + float* destination = output_buffer + channel * kRenderQuantumFrames; + float* source = input_buffer + channel * kRenderQuantumFrames; + memcpy(destination, source, kBytesPerChannel); + } + } +}; + +EMSCRIPTEN_BINDINGS(CLASS_SimpleKernel) { + class_("SimpleKernel") + .constructor() + .function("process", + &SimpleKernel::Process, + allow_raw_pointers()); +} diff --git a/examples/worklets/a.out.js b/examples/worklets/a.out.js new file mode 100644 index 0000000..1243a09 --- /dev/null +++ b/examples/worklets/a.out.js @@ -0,0 +1,1488 @@ + +import { createRequire } from 'module'; +const require = createRequire(import.meta.url); + +var Module = (() => { + var _scriptName = import.meta.url; + + return ( +function(moduleArg = {}) { + var moduleRtn; + +// include: shell.js +// The Module object: Our interface to the outside world. We import +// and export values on it. There are various ways Module can be used: +// 1. Not defined. We create it here +// 2. A function parameter, function(moduleArg) => Promise +// 3. pre-run appended it, var Module = {}; ..generated code.. +// 4. External script tag defines var Module. +// We need to check if Module already exists (e.g. case 3 above). +// Substitution will be replaced with actual code on later stage of the build, +// this way Closure Compiler will not mangle it (e.g. case 4. above). +// Note that if you want to run closure, and also to use Module +// after the generated code, you will need to define var Module = {}; +// before the code. Then that object will be used in the code, and you +// can continue to use Module afterwards as well. +var Module = moduleArg; + +// Set up the promise that indicates the Module is initialized +var readyPromiseResolve, readyPromiseReject; +var readyPromise = new Promise((resolve, reject) => { + readyPromiseResolve = resolve; + readyPromiseReject = reject; +}); + +// Determine the runtime environment we are in. You can customize this by +// setting the ENVIRONMENT setting at compile time (see settings.js). + +var ENVIRONMENT_IS_WEB = false; +var ENVIRONMENT_IS_WORKER = false; +var ENVIRONMENT_IS_NODE = true; +var ENVIRONMENT_IS_SHELL = false; + +if (ENVIRONMENT_IS_NODE) { + // `require()` is no-op in an ESM module, use `createRequire()` to construct + // the require()` function. This is only necessary for multi-environment + // builds, `-sENVIRONMENT=node` emits a static import declaration instead. + // TODO: Swap all `require()`'s with `import()`'s? + +} + +// --pre-jses are emitted after the Module integration code, so that they can +// refer to Module (if they choose; they can also define Module) + + +// Sometimes an existing Module object exists with properties +// meant to overwrite the default module functionality. Here +// we collect those properties and reapply _after_ we configure +// the current environment's defaults to avoid having to be so +// defensive during initialization. +var moduleOverrides = Object.assign({}, Module); + +var arguments_ = []; +var thisProgram = './this.program'; +var quit_ = (status, toThrow) => { + throw toThrow; +}; + +// `/` should be present at the end if `scriptDirectory` is not empty +var scriptDirectory = ''; +function locateFile(path) { + if (Module['locateFile']) { + return Module['locateFile'](path, scriptDirectory); + } + return scriptDirectory + path; +} + +// Hooks that are implemented differently in different runtime environments. +var readAsync, readBinary; + +if (ENVIRONMENT_IS_NODE) { + + // These modules will usually be used on Node.js. Load them eagerly to avoid + // the complexity of lazy-loading. + var fs = require('fs'); + var nodePath = require('path'); + + // EXPORT_ES6 + ENVIRONMENT_IS_NODE always requires use of import.meta.url, + // since there's no way getting the current absolute path of the module when + // support for that is not available. + if (!import.meta.url.startsWith('data:')) { + scriptDirectory = nodePath.dirname(require('url').fileURLToPath(import.meta.url)) + '/'; + } + +// include: node_shell_read.js +readBinary = (filename) => { + // We need to re-wrap `file://` strings to URLs. + filename = isFileURI(filename) ? new URL(filename) : filename; + var ret = fs.readFileSync(filename); + return ret; +}; + +readAsync = async (filename, binary = true) => { + // See the comment in the `readBinary` function. + filename = isFileURI(filename) ? new URL(filename) : filename; + var ret = fs.readFileSync(filename, binary ? undefined : 'utf8'); + return ret; +}; +// end include: node_shell_read.js + if (!Module['thisProgram'] && process.argv.length > 1) { + thisProgram = process.argv[1].replace(/\\/g, '/'); + } + + arguments_ = process.argv.slice(2); + + // MODULARIZE will export the module in the proper place outside, we don't need to export here + + quit_ = (status, toThrow) => { + process.exitCode = status; + throw toThrow; + }; + +} else + +// Note that this includes Node.js workers when relevant (pthreads is enabled). +// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and +// ENVIRONMENT_IS_NODE. +{ +} + +var out = Module['print'] || console.log.bind(console); +var err = Module['printErr'] || console.error.bind(console); + +// Merge back in the overrides +Object.assign(Module, moduleOverrides); +// Free the object hierarchy contained in the overrides, this lets the GC +// reclaim data used. +moduleOverrides = null; + +// Emit code to handle expected values on the Module object. This applies Module.x +// to the proper local x. This has two benefits: first, we only emit it if it is +// expected to arrive, and second, by using a local everywhere else that can be +// minified. + +if (Module['arguments']) arguments_ = Module['arguments']; + +if (Module['thisProgram']) thisProgram = Module['thisProgram']; + +// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message +// end include: shell.js + +// include: preamble.js +// === Preamble library stuff === + +// Documentation for the public APIs defined in this file must be updated in: +// site/source/docs/api_reference/preamble.js.rst +// A prebuilt local version of the documentation is available at: +// site/build/text/docs/api_reference/preamble.js.txt +// You can also build docs locally as HTML or other formats in site/ +// An online HTML version (which may be of a different version of Emscripten) +// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html + +var wasmBinary = Module['wasmBinary']; + +// include: base64Utils.js +// Converts a string of base64 into a byte array (Uint8Array). +function intArrayFromBase64(s) { + if (typeof ENVIRONMENT_IS_NODE != 'undefined' && ENVIRONMENT_IS_NODE) { + var buf = Buffer.from(s, 'base64'); + return new Uint8Array(buf.buffer, buf.byteOffset, buf.length); + } + + var decoded = atob(s); + var bytes = new Uint8Array(decoded.length); + for (var i = 0 ; i < decoded.length ; ++i) { + bytes[i] = decoded.charCodeAt(i); + } + return bytes; +} + +// If filename is a base64 data URI, parses and returns data (Buffer on node, +// Uint8Array otherwise). If filename is not a base64 data URI, returns undefined. +function tryParseAsDataURI(filename) { + if (!isDataURI(filename)) { + return; + } + + return intArrayFromBase64(filename.slice(dataURIPrefix.length)); +} +// end include: base64Utils.js +// Wasm globals + +var wasmMemory; + +//======================================== +// Runtime essentials +//======================================== + +// whether we are quitting the application. no code should run after this. +// set in exit() and abort() +var ABORT = false; + +// set by exit() and abort(). Passed to 'onExit' handler. +// NOTE: This is also used as the process return code code in shell environments +// but only when noExitRuntime is false. +var EXITSTATUS; + +// In STRICT mode, we only define assert() when ASSERTIONS is set. i.e. we +// don't define it at all in release modes. This matches the behaviour of +// MINIMAL_RUNTIME. +// TODO(sbc): Make this the default even without STRICT enabled. +/** @type {function(*, string=)} */ +function assert(condition, text) { + if (!condition) { + // This build was created without ASSERTIONS defined. `assert()` should not + // ever be called in this configuration but in case there are callers in + // the wild leave this simple abort() implementation here for now. + abort(text); + } +} + +// Memory management + +var HEAP, +/** @type {!Int8Array} */ + HEAP8, +/** @type {!Uint8Array} */ + HEAPU8, +/** @type {!Int16Array} */ + HEAP16, +/** @type {!Uint16Array} */ + HEAPU16, +/** @type {!Int32Array} */ + HEAP32, +/** @type {!Uint32Array} */ + HEAPU32, +/** @type {!Float32Array} */ + HEAPF32, +/** @type {!Float64Array} */ + HEAPF64; + +// include: runtime_shared.js +function updateMemoryViews() { + var b = wasmMemory.buffer; + Module['HEAP8'] = HEAP8 = new Int8Array(b); + Module['HEAP16'] = HEAP16 = new Int16Array(b); + Module['HEAPU8'] = HEAPU8 = new Uint8Array(b); + Module['HEAPU16'] = HEAPU16 = new Uint16Array(b); + Module['HEAP32'] = HEAP32 = new Int32Array(b); + Module['HEAPU32'] = HEAPU32 = new Uint32Array(b); + Module['HEAPF32'] = HEAPF32 = new Float32Array(b); + Module['HEAPF64'] = HEAPF64 = new Float64Array(b); +} + +// end include: runtime_shared.js +// include: runtime_stack_check.js +// end include: runtime_stack_check.js +var __ATPRERUN__ = []; // functions called before the runtime is initialized +var __ATINIT__ = []; // functions called during startup +var __ATEXIT__ = []; // functions called during shutdown +var __ATPOSTRUN__ = []; // functions called after the main() is called + +var runtimeInitialized = false; + +function preRun() { + if (Module['preRun']) { + if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']]; + while (Module['preRun'].length) { + addOnPreRun(Module['preRun'].shift()); + } + } + callRuntimeCallbacks(__ATPRERUN__); +} + +function initRuntime() { + runtimeInitialized = true; + + + callRuntimeCallbacks(__ATINIT__); +} + +function postRun() { + + if (Module['postRun']) { + if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']]; + while (Module['postRun'].length) { + addOnPostRun(Module['postRun'].shift()); + } + } + + callRuntimeCallbacks(__ATPOSTRUN__); +} + +function addOnPreRun(cb) { + __ATPRERUN__.unshift(cb); +} + +function addOnInit(cb) { + __ATINIT__.unshift(cb); +} + +function addOnExit(cb) { +} + +function addOnPostRun(cb) { + __ATPOSTRUN__.unshift(cb); +} + +// include: runtime_math.js +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc + +// end include: runtime_math.js +// A counter of dependencies for calling run(). If we need to +// do asynchronous work before running, increment this and +// decrement it. Incrementing must happen in a place like +// Module.preRun (used by emcc to add file preloading). +// Note that you can add dependencies in preRun, even though +// it happens right before run - run will be postponed until +// the dependencies are met. +var runDependencies = 0; +var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled + +function getUniqueRunDependency(id) { + return id; +} + +function addRunDependency(id) { + runDependencies++; + + Module['monitorRunDependencies']?.(runDependencies); + +} + +function removeRunDependency(id) { + runDependencies--; + + Module['monitorRunDependencies']?.(runDependencies); + + if (runDependencies == 0) { + if (dependenciesFulfilled) { + var callback = dependenciesFulfilled; + dependenciesFulfilled = null; + callback(); // can add another dependenciesFulfilled + } + } +} + +/** @param {string|number=} what */ +function abort(what) { + Module['onAbort']?.(what); + + what = 'Aborted(' + what + ')'; + // TODO(sbc): Should we remove printing and leave it up to whoever + // catches the exception? + err(what); + + ABORT = true; + + what += '. Build with -sASSERTIONS for more info.'; + + // Use a wasm runtime error, because a JS error might be seen as a foreign + // exception, which means we'd run destructors on it. We need the error to + // simply make the program stop. + // FIXME This approach does not work in Wasm EH because it currently does not assume + // all RuntimeErrors are from traps; it decides whether a RuntimeError is from + // a trap or not based on a hidden field within the object. So at the moment + // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that + // allows this in the wasm spec. + + // Suppress closure compiler warning here. Closure compiler's builtin extern + // definition for WebAssembly.RuntimeError claims it takes no arguments even + // though it can. + // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed. + /** @suppress {checkTypes} */ + var e = new WebAssembly.RuntimeError(what); + + readyPromiseReject(e); + // Throw the error whether or not MODULARIZE is set because abort is used + // in code paths apart from instantiation where an exception is expected + // to be thrown when abort is called. + throw e; +} + +// include: memoryprofiler.js +// end include: memoryprofiler.js +// include: URIUtils.js +// Prefix of data URIs emitted by SINGLE_FILE and related options. +var dataURIPrefix = 'data:application/octet-stream;base64,'; + +/** + * Indicates whether filename is a base64 data URI. + * @noinline + */ +var isDataURI = (filename) => filename.startsWith(dataURIPrefix); + +/** + * Indicates whether filename is delivered via file protocol (as opposed to http/https) + * @noinline + */ +var isFileURI = (filename) => filename.startsWith('file://'); +// end include: URIUtils.js +// include: runtime_exceptions.js +// end include: runtime_exceptions.js +function findWasmBinary() { + var f = 'data:application/octet-stream;base64,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AkACQAJAIAYoAigOAgABAgsgBigCGEEAIAYoAiRBAUYbQQAgBigCIEEBRhtBACAGKAIsQQFGGyEFDAELAkAgBigCHEEBRg0AIAYoAiwNASAGKAIgQQFHDQEgBigCJEEBRw0BCyAGKAIUIQULIAZBwABqJAAgBQt3AQF/AkAgASgCJCIEDQAgASADNgIYIAEgAjYCECABQQE2AiQgASABKAI4NgIUDwsCQAJAIAEoAhQgASgCOEcNACABKAIQIAJHDQAgASgCGEECRw0BIAEgAzYCGA8LIAFBAToANiABQQI2AhggASAEQQFqNgIkCwsdAAJAIAAgASgCCEEAECZFDQAgASABIAIgAxAuCws2AAJAIAAgASgCCEEAECZFDQAgASABIAIgAxAuDwsgACgCCCIAIAEgAiADIAAoAgAoAhwRAgALnwEAIAFBAToANQJAIAMgASgCBEcNACABQQE6ADQCQAJAIAEoAhAiAw0AIAFBATYCJCABIAQ2AhggASACNgIQIARBAUcNAiABKAIwQQFGDQEMAgsCQCADIAJHDQACQCABKAIYIgNBAkcNACABIAQ2AhggBCEDCyABKAIwQQFHDQIgA0EBRg0BDAILIAEgASgCJEEBajYCJAsgAUEBOgA2CwsgAAJAIAIgASgCBEcNACABKAIcQQFGDQAgASADNgIcCwuBAgACQCAAIAEoAgggBBAmRQ0AIAEgASACIAMQMg8LAkACQCAAIAEoAgAgBBAmRQ0AAkACQCACIAEoAhBGDQAgAiABKAIURw0BCyADQQFHDQIgAUEBNgIgDwsgASADNgIgAkAgASgCLEEERg0AIAFBADsBNCAAKAIIIgAgASACIAJBASAEIAAoAgAoAhQRBQACQCABLQA1QQFHDQAgAUEDNgIsIAEtADRFDQEMAwsgAUEENgIsCyABIAI2AhQgASABKAIoQQFqNgIoIAEoAiRBAUcNASABKAIYQQJHDQEgAUEBOgA2DwsgACgCCCIAIAEgAiADIAQgACgCACgCGBEDAAsLmAEAAkAgACABKAIIIAQQJkUNACABIAEgAiADEDIPCwJAIAAgASgCACAEECZFDQACQAJAIAIgASgCEEYNACACIAEoAhRHDQELIANBAUcNASABQQE2AiAPCyABIAI2AhQgASADNgIgIAEgASgCKEEBajYCKAJAIAEoAiRBAUcNACABKAIYQQJHDQAgAUEBOgA2CyABQQQ2AiwLCzwAAkAgACABKAIIIAUQJkUNACABIAEgAiADIAQQMQ8LIAAoAggiACABIAIgAyAEIAUgACgCACgCFBEFAAsfAAJAIAAgASgCCCAFECZFDQAgASABIAIgAyAEEDELCwkAIAAoAgQQGgvaAwBByAlBhw0QAkHUCUG2DEEBQQAQA0HgCUGxDEEBQYB/Qf8AEARB+AlBqgxBAUGAf0H/ABAEQewJQagMQQFBAEH/ARAEQYQKQYYMQQJBgIB+Qf//ARAEQZAKQf0LQQJBAEH//wMQBEGcCkGVDEEEQYCAgIB4Qf////8HEARBqApBjAxBBEEAQX8QBEG0CkHEDEEEQYCAgIB4Qf////8HEARBwApBuwxBBEEAQX8QBEHMCkGgDEEIQoCAgICAgICAgH9C////////////ABA6QdgKQZ8MQQhCAEJ/EDpB5ApBmQxBBBAFQfAKQYANQQgQBUGQEkHWDBAGQdgSQQRByQwQB0GgE0ECQeIMEAdB7BNBBEHxDBAHQbgUEAhB1BRBAEG/EBAJQfwUQQBBhBEQCUGkFUEBQd0QEAlBzBVBAkGMDRAJQfQVQQNBqw0QCUGcFkEEQdMNEAlBxBZBBUHwDRAJQewWQQRBqREQCUGUF0EFQccREAlB/BRBAEHWDhAJQaQVQQFBtQ4QCUHMFUECQZgPEAlB9BVBA0H2DhAJQZwWQQRBnhAQCUHEFkEFQfwPEAlBvBdBCEHbDxAJQeQXQQlBuQ8QCUGMGEEGQZYOEAlBtBhBB0HuERAJCykAQQBBDzYC2BxBAEEANgLcHBA4QQBBACgC1Bw2AtwcQQBB2Bw2AtQcCxwAIAAgASACIAOnIANCIIinIASnIARCIIinEAoLC+0QAgBBgAgL2xCEBQAACAQAAFN0OXR5cGVfaW5mbwAAAACsBQAAJAQAAAAEAABOMTBfX2N4eGFiaXYxMTZfX3NoaW1fdHlwZV9pbmZvRQAAAACsBQAAVAQAABgEAABOMTBfX2N4eGFiaXYxMTdfX2NsYXNzX3R5cGVfaW5mb0UAAAAAAAAAlAQAAAEAAAACAAAAAwAAAAQAAAAFAAAArAUAAKAEAAAYBAAATjEwX19jeHhhYml2MTIzX19mdW5kYW1lbnRhbF90eXBlX2luZm9FAIAEAADQBAAAdgAAAIAEAADcBAAAYgAAAIAEAADoBAAAYwAAAIAEAAD0BAAAaAAAAIAEAAAABQAAYQAAAIAEAAAMBQAAcwAAAIAEAAAYBQAAdAAAAIAEAAAkBQAAaQAAAIAEAAAwBQAAagAAAIAEAAA8BQAAbAAAAIAEAABIBQAAbQAAAIAEAABUBQAAeAAAAIAEAABgBQAAeQAAAIAEAABsBQAAZgAAAIAEAAB4BQAAZAAAAAAAAABIBAAAAQAAAAYAAAADAAAABAAAAAcAAAAIAAAACQAAAAoAAAAAAAAAzAUAAAEAAAALAAAAAwAAAAQAAAAHAAAADAAAAA0AAAAOAAAArAUAANgFAABIBAAATjEwX19jeHhhYml2MTIwX19zaV9jbGFzc190eXBlX2luZm9FAHVuc2lnbmVkIHNob3J0AHVuc2lnbmVkIGludABmbG9hdAB1aW50NjRfdAB1bnNpZ25lZCBjaGFyAGJvb2wAdW5zaWduZWQgbG9uZwBzdGQ6OndzdHJpbmcAc3RkOjpzdHJpbmcAc3RkOjp1MTZzdHJpbmcAc3RkOjp1MzJzdHJpbmcAZG91YmxlAHZvaWQAZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8c2hvcnQ+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVuc2lnbmVkIHNob3J0PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxpbnQ+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVuc2lnbmVkIGludD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8ZmxvYXQ+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVpbnQ4X3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludDhfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDE2X3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludDE2X3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVpbnQ2NF90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxpbnQ2NF90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1aW50MzJfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50MzJfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8Y2hhcj4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgY2hhcj4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8c2lnbmVkIGNoYXI+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGxvbmc+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVuc2lnbmVkIGxvbmc+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGRvdWJsZT4AAACEBQAAGAkAAE5TdDNfXzIxMmJhc2ljX3N0cmluZ0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVOU185YWxsb2NhdG9ySWNFRUVFAACEBQAAYAkAAE5TdDNfXzIxMmJhc2ljX3N0cmluZ0l3TlNfMTFjaGFyX3RyYWl0c0l3RUVOU185YWxsb2NhdG9ySXdFRUVFAACEBQAAqAkAAE5TdDNfXzIxMmJhc2ljX3N0cmluZ0lEc05TXzExY2hhcl90cmFpdHNJRHNFRU5TXzlhbGxvY2F0b3JJRHNFRUVFAAAAhAUAAPQJAABOU3QzX18yMTJiYXNpY19zdHJpbmdJRGlOU18xMWNoYXJfdHJhaXRzSURpRUVOU185YWxsb2NhdG9ySURpRUVFRQAAAIQFAABACgAATjEwZW1zY3JpcHRlbjN2YWxFAACEBQAAXAoAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWNFRQAAhAUAAIQKAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lhRUUAAIQFAACsCgAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJaEVFAACEBQAA1AoAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SXNFRQAAhAUAAPwKAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0l0RUUAAIQFAAAkCwAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJaUVFAACEBQAATAsAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWpFRQAAhAUAAHQLAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lsRUUAAIQFAACcCwAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJbUVFAACEBQAAxAsAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SXhFRQAAhAUAAOwLAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0l5RUUAAIQFAAAUDAAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJZkVFAACEBQAAPAwAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWRFRQAAQdwYCwRgDgEAAEkPdGFyZ2V0X2ZlYXR1cmVzBCsPbXV0YWJsZS1nbG9iYWxzKwhzaWduLWV4dCsPcmVmZXJlbmNlLXR5cGVzKwptdWx0aXZhbHVl'; + return f; +} + +var wasmBinaryFile; + +function getBinarySync(file) { + if (file == wasmBinaryFile && wasmBinary) { + return new Uint8Array(wasmBinary); + } + var binary = tryParseAsDataURI(file); + if (binary) { + return binary; + } + if (readBinary) { + return readBinary(file); + } + throw 'sync fetching of the wasm failed: you can preload it to Module["wasmBinary"] manually, or emcc.py will do that for you when generating HTML (but not JS)'; +} + +async function getWasmBinary(binaryFile) { + + // Otherwise, getBinarySync should be able to get it synchronously + return getBinarySync(binaryFile); +} + +function instantiateSync(file, info) { + var module; + var binary = getBinarySync(file); + module = new WebAssembly.Module(binary); + var instance = new WebAssembly.Instance(module, info); + return [instance, module]; +} + +function getWasmImports() { + // prepare imports + return { + 'env': wasmImports, + 'wasi_snapshot_preview1': wasmImports, + } +} + +// Create the wasm instance. +// Receives the wasm imports, returns the exports. + function createWasm() { + // Load the wasm module and create an instance of using native support in the JS engine. + // handle a generated wasm instance, receiving its exports and + // performing other necessary setup + /** @param {WebAssembly.Module=} module*/ + function receiveInstance(instance, module) { + wasmExports = instance.exports; + + + + wasmMemory = wasmExports['memory']; + + updateMemoryViews(); + + addOnInit(wasmExports['__wasm_call_ctors']); + + removeRunDependency('wasm-instantiate'); + return wasmExports; + } + // wait for the pthread pool (if any) + addRunDependency('wasm-instantiate'); + + // Prefer streaming instantiation if available. + + var info = getWasmImports(); + + // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback + // to manually instantiate the Wasm module themselves. This allows pages to + // run the instantiation parallel to any other async startup actions they are + // performing. + // Also pthreads and wasm workers initialize the wasm instance through this + // path. + if (Module['instantiateWasm']) { + try { + return Module['instantiateWasm'](info, receiveInstance); + } catch(e) { + err(`Module.instantiateWasm callback failed with error: ${e}`); + // If instantiation fails, reject the module ready promise. + readyPromiseReject(e); + } + } + + wasmBinaryFile ??= findWasmBinary(); + + var result = instantiateSync(wasmBinaryFile, info); + // 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. + // When the regression is fixed, we can remove this if/else. + return receiveInstance(result[0]); +} + +// Globals used by JS i64 conversions (see makeSetValue) +var tempDouble; +var tempI64; + +// include: runtime_debug.js +// end include: runtime_debug.js +// === Body === +// end include: preamble.js + + + class ExitStatus { + name = 'ExitStatus'; + constructor(status) { + this.message = `Program terminated with exit(${status})`; + this.status = status; + } + } + + var callRuntimeCallbacks = (callbacks) => { + while (callbacks.length > 0) { + // Pass the module as the first argument. + callbacks.shift()(Module); + } + }; + + + /** + * @param {number} ptr + * @param {string} type + */ + function getValue(ptr, type = 'i8') { + if (type.endsWith('*')) type = '*'; + switch (type) { + case 'i1': return HEAP8[ptr]; + case 'i8': return HEAP8[ptr]; + case 'i16': return HEAP16[((ptr)>>1)]; + case 'i32': return HEAP32[((ptr)>>2)]; + case 'i64': abort('to do getValue(i64) use WASM_BIGINT'); + case 'float': return HEAPF32[((ptr)>>2)]; + case 'double': return HEAPF64[((ptr)>>3)]; + case '*': return HEAPU32[((ptr)>>2)]; + default: abort(`invalid type for getValue: ${type}`); + } + } + + var noExitRuntime = Module['noExitRuntime'] || true; + + + /** + * @param {number} ptr + * @param {number} value + * @param {string} type + */ + function setValue(ptr, value, type = 'i8') { + if (type.endsWith('*')) type = '*'; + switch (type) { + case 'i1': HEAP8[ptr] = value; break; + case 'i8': HEAP8[ptr] = value; break; + case 'i16': HEAP16[((ptr)>>1)] = value; break; + case 'i32': HEAP32[((ptr)>>2)] = value; break; + case 'i64': abort('to do setValue(i64) use WASM_BIGINT'); + case 'float': HEAPF32[((ptr)>>2)] = value; break; + case 'double': HEAPF64[((ptr)>>3)] = value; break; + case '*': HEAPU32[((ptr)>>2)] = value; break; + default: abort(`invalid type for setValue: ${type}`); + } + } + + var stackRestore = (val) => __emscripten_stack_restore(val); + + var stackSave = () => _emscripten_stack_get_current(); + + var __embind_register_bigint = (primitiveType, name, size, minRange, maxRange) => {}; + + var embind_init_charCodes = () => { + var codes = new Array(256); + for (var i = 0; i < 256; ++i) { + codes[i] = String.fromCharCode(i); + } + embind_charCodes = codes; + }; + var embind_charCodes; + var readLatin1String = (ptr) => { + var ret = ""; + var c = ptr; + while (HEAPU8[c]) { + ret += embind_charCodes[HEAPU8[c++]]; + } + return ret; + }; + + var awaitingDependencies = { + }; + + var registeredTypes = { + }; + + var typeDependencies = { + }; + + var BindingError; + var throwBindingError = (message) => { throw new BindingError(message); }; + + + + + var InternalError; + var throwInternalError = (message) => { throw new InternalError(message); }; + var whenDependentTypesAreResolved = (myTypes, dependentTypes, getTypeConverters) => { + myTypes.forEach((type) => typeDependencies[type] = dependentTypes); + + function onComplete(typeConverters) { + var myTypeConverters = getTypeConverters(typeConverters); + if (myTypeConverters.length !== myTypes.length) { + throwInternalError('Mismatched type converter count'); + } + for (var i = 0; i < myTypes.length; ++i) { + registerType(myTypes[i], myTypeConverters[i]); + } + } + + var typeConverters = new Array(dependentTypes.length); + var unregisteredTypes = []; + var registered = 0; + dependentTypes.forEach((dt, i) => { + if (registeredTypes.hasOwnProperty(dt)) { + typeConverters[i] = registeredTypes[dt]; + } else { + unregisteredTypes.push(dt); + if (!awaitingDependencies.hasOwnProperty(dt)) { + awaitingDependencies[dt] = []; + } + awaitingDependencies[dt].push(() => { + typeConverters[i] = registeredTypes[dt]; + ++registered; + if (registered === unregisteredTypes.length) { + onComplete(typeConverters); + } + }); + } + }); + if (0 === unregisteredTypes.length) { + onComplete(typeConverters); + } + }; + /** @param {Object=} options */ + function sharedRegisterType(rawType, registeredInstance, options = {}) { + var name = registeredInstance.name; + if (!rawType) { + throwBindingError(`type "${name}" must have a positive integer typeid pointer`); + } + if (registeredTypes.hasOwnProperty(rawType)) { + if (options.ignoreDuplicateRegistrations) { + return; + } else { + throwBindingError(`Cannot register type '${name}' twice`); + } + } + + registeredTypes[rawType] = registeredInstance; + delete typeDependencies[rawType]; + + if (awaitingDependencies.hasOwnProperty(rawType)) { + var callbacks = awaitingDependencies[rawType]; + delete awaitingDependencies[rawType]; + callbacks.forEach((cb) => cb()); + } + } + /** @param {Object=} options */ + function registerType(rawType, registeredInstance, options = {}) { + return sharedRegisterType(rawType, registeredInstance, options); + } + + var GenericWireTypeSize = 8; + /** @suppress {globalThis} */ + var __embind_register_bool = (rawType, name, trueValue, falseValue) => { + name = readLatin1String(name); + registerType(rawType, { + name, + 'fromWireType': function(wt) { + // ambiguous emscripten ABI: sometimes return values are + // true or false, and sometimes integers (0 or 1) + return !!wt; + }, + 'toWireType': function(destructors, o) { + return o ? trueValue : falseValue; + }, + argPackAdvance: GenericWireTypeSize, + 'readValueFromPointer': function(pointer) { + return this['fromWireType'](HEAPU8[pointer]); + }, + destructorFunction: null, // This type does not need a destructor + }); + }; + + + var emval_freelist = []; + + var emval_handles = []; + var __emval_decref = (handle) => { + if (handle > 9 && 0 === --emval_handles[handle + 1]) { + emval_handles[handle] = undefined; + emval_freelist.push(handle); + } + }; + + + + + + var count_emval_handles = () => { + return emval_handles.length / 2 - 5 - emval_freelist.length; + }; + + var init_emval = () => { + // reserve 0 and some special values. These never get de-allocated. + emval_handles.push( + 0, 1, + undefined, 1, + null, 1, + true, 1, + false, 1, + ); + Module['count_emval_handles'] = count_emval_handles; + }; + var Emval = { + toValue:(handle) => { + if (!handle) { + throwBindingError('Cannot use deleted val. handle = ' + handle); + } + return emval_handles[handle]; + }, + toHandle:(value) => { + switch (value) { + case undefined: return 2; + case null: return 4; + case true: return 6; + case false: return 8; + default:{ + const handle = emval_freelist.pop() || emval_handles.length; + emval_handles[handle] = value; + emval_handles[handle + 1] = 1; + return handle; + } + } + }, + }; + + /** @suppress {globalThis} */ + function readPointer(pointer) { + return this['fromWireType'](HEAPU32[((pointer)>>2)]); + } + + var EmValType = { + name: 'emscripten::val', + 'fromWireType': (handle) => { + var rv = Emval.toValue(handle); + __emval_decref(handle); + return rv; + }, + 'toWireType': (destructors, value) => Emval.toHandle(value), + argPackAdvance: GenericWireTypeSize, + 'readValueFromPointer': readPointer, + destructorFunction: null, // This type does not need a destructor + + // TODO: do we need a deleteObject here? write a test where + // emval is passed into JS via an interface + }; + var __embind_register_emval = (rawType) => registerType(rawType, EmValType); + + var embindRepr = (v) => { + if (v === null) { + return 'null'; + } + var t = typeof v; + if (t === 'object' || t === 'array' || t === 'function') { + return v.toString(); + } else { + return '' + v; + } + }; + + var floatReadValueFromPointer = (name, width) => { + switch (width) { + case 4: return function(pointer) { + return this['fromWireType'](HEAPF32[((pointer)>>2)]); + }; + case 8: return function(pointer) { + return this['fromWireType'](HEAPF64[((pointer)>>3)]); + }; + default: + throw new TypeError(`invalid float width (${width}): ${name}`); + } + }; + + + var __embind_register_float = (rawType, name, size) => { + name = readLatin1String(name); + registerType(rawType, { + name, + 'fromWireType': (value) => value, + 'toWireType': (destructors, value) => { + // The VM will perform JS to Wasm value conversion, according to the spec: + // https://www.w3.org/TR/wasm-js-api-1/#towebassemblyvalue + return value; + }, + argPackAdvance: GenericWireTypeSize, + 'readValueFromPointer': floatReadValueFromPointer(name, size), + destructorFunction: null, // This type does not need a destructor + }); + }; + + + var integerReadValueFromPointer = (name, width, signed) => { + // integers are quite common, so generate very specialized functions + switch (width) { + case 1: return signed ? + (pointer) => HEAP8[pointer] : + (pointer) => HEAPU8[pointer]; + case 2: return signed ? + (pointer) => HEAP16[((pointer)>>1)] : + (pointer) => HEAPU16[((pointer)>>1)] + case 4: return signed ? + (pointer) => HEAP32[((pointer)>>2)] : + (pointer) => HEAPU32[((pointer)>>2)] + default: + throw new TypeError(`invalid integer width (${width}): ${name}`); + } + }; + + + /** @suppress {globalThis} */ + var __embind_register_integer = (primitiveType, name, size, minRange, maxRange) => { + name = readLatin1String(name); + // LLVM doesn't have signed and unsigned 32-bit types, so u32 literals come + // out as 'i32 -1'. Always treat those as max u32. + if (maxRange === -1) { + maxRange = 4294967295; + } + + var fromWireType = (value) => value; + + if (minRange === 0) { + var bitshift = 32 - 8*size; + fromWireType = (value) => (value << bitshift) >>> bitshift; + } + + var isUnsignedType = (name.includes('unsigned')); + var checkAssertions = (value, toTypeName) => { + } + var toWireType; + if (isUnsignedType) { + toWireType = function(destructors, value) { + checkAssertions(value, this.name); + return value >>> 0; + } + } else { + toWireType = function(destructors, value) { + checkAssertions(value, this.name); + // The VM will perform JS to Wasm value conversion, according to the spec: + // https://www.w3.org/TR/wasm-js-api-1/#towebassemblyvalue + return value; + } + } + registerType(primitiveType, { + name, + 'fromWireType': fromWireType, + 'toWireType': toWireType, + argPackAdvance: GenericWireTypeSize, + 'readValueFromPointer': integerReadValueFromPointer(name, size, minRange !== 0), + destructorFunction: null, // This type does not need a destructor + }); + }; + + + var __embind_register_memory_view = (rawType, dataTypeIndex, name) => { + var typeMapping = [ + Int8Array, + Uint8Array, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + Float32Array, + Float64Array, + ]; + + var TA = typeMapping[dataTypeIndex]; + + function decodeMemoryView(handle) { + var size = HEAPU32[((handle)>>2)]; + var data = HEAPU32[(((handle)+(4))>>2)]; + return new TA(HEAP8.buffer, data, size); + } + + name = readLatin1String(name); + registerType(rawType, { + name, + 'fromWireType': decodeMemoryView, + argPackAdvance: GenericWireTypeSize, + 'readValueFromPointer': decodeMemoryView, + }, { + ignoreDuplicateRegistrations: true, + }); + }; + + + + + + var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => { + // Parameter maxBytesToWrite is not optional. Negative values, 0, null, + // undefined and false each don't write out any bytes. + if (!(maxBytesToWrite > 0)) + return 0; + + var startIdx = outIdx; + var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator. + for (var i = 0; i < str.length; ++i) { + // 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. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + // 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/rfc3629 + var u = str.charCodeAt(i); // possibly a lead surrogate + if (u >= 0xD800 && u <= 0xDFFF) { + var u1 = str.charCodeAt(++i); + u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF); + } + if (u <= 0x7F) { + if (outIdx >= endIdx) break; + heap[outIdx++] = u; + } else if (u <= 0x7FF) { + if (outIdx + 1 >= endIdx) break; + heap[outIdx++] = 0xC0 | (u >> 6); + heap[outIdx++] = 0x80 | (u & 63); + } else if (u <= 0xFFFF) { + if (outIdx + 2 >= endIdx) break; + heap[outIdx++] = 0xE0 | (u >> 12); + heap[outIdx++] = 0x80 | ((u >> 6) & 63); + heap[outIdx++] = 0x80 | (u & 63); + } else { + if (outIdx + 3 >= endIdx) break; + heap[outIdx++] = 0xF0 | (u >> 18); + heap[outIdx++] = 0x80 | ((u >> 12) & 63); + heap[outIdx++] = 0x80 | ((u >> 6) & 63); + heap[outIdx++] = 0x80 | (u & 63); + } + } + // Null-terminate the pointer to the buffer. + heap[outIdx] = 0; + return outIdx - startIdx; + }; + var stringToUTF8 = (str, outPtr, maxBytesToWrite) => { + return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite); + }; + + var lengthBytesUTF8 = (str) => { + var len = 0; + for (var i = 0; i < str.length; ++i) { + // 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. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var c = str.charCodeAt(i); // possibly a lead surrogate + if (c <= 0x7F) { + len++; + } else if (c <= 0x7FF) { + len += 2; + } else if (c >= 0xD800 && c <= 0xDFFF) { + len += 4; ++i; + } else { + len += 3; + } + } + return len; + }; + + + + var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder() : undefined; + + /** + * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given + * array that contains uint8 values, returns a copy of that string as a + * Javascript String object. + * heapOrArray is either a regular array, or a JavaScript typed array view. + * @param {number=} idx + * @param {number=} maxBytesToRead + * @return {string} + */ + var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead = NaN) => { + var endIdx = idx + maxBytesToRead; + var endPtr = idx; + // TextDecoder needs to know the byte length in advance, it doesn't stop on + // null terminator by itself. Also, use the length info to avoid running tiny + // strings through TextDecoder, since .subarray() allocates garbage. + // (As a tiny code save trick, compare endPtr against endIdx using a negation, + // so that undefined/NaN means Infinity) + while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr; + + if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) { + return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr)); + } + var str = ''; + // If building with TextDecoder, we have already computed the string length + // above, so test loop end condition against that + while (idx < endPtr) { + // For UTF8 byte structure, see: + // http://en.wikipedia.org/wiki/UTF-8#Description + // https://www.ietf.org/rfc/rfc2279.txt + // https://tools.ietf.org/html/rfc3629 + var u0 = heapOrArray[idx++]; + if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; } + var u1 = heapOrArray[idx++] & 63; + if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; } + var u2 = heapOrArray[idx++] & 63; + if ((u0 & 0xF0) == 0xE0) { + u0 = ((u0 & 15) << 12) | (u1 << 6) | u2; + } else { + u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63); + } + + if (u0 < 0x10000) { + str += String.fromCharCode(u0); + } else { + var ch = u0 - 0x10000; + str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); + } + } + return str; + }; + + /** + * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the + * emscripten HEAP, returns a copy of that string as a Javascript String object. + * + * @param {number} ptr + * @param {number=} maxBytesToRead - An optional length that specifies the + * maximum number of bytes to read. You can omit this parameter to scan the + * string until the first 0 byte. If maxBytesToRead is passed, and the string + * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the + * string will cut short at that byte index (i.e. maxBytesToRead will not + * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing + * frequent uses of UTF8ToString() with and without maxBytesToRead may throw + * JS JIT optimizations off, so it is worth to consider consistently using one + * @return {string} + */ + var UTF8ToString = (ptr, maxBytesToRead) => { + return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ''; + }; + var __embind_register_std_string = (rawType, name) => { + name = readLatin1String(name); + var stdStringIsUTF8 + = true; + + registerType(rawType, { + name, + // For some method names we use string keys here since they are part of + // the public/external API and/or used by the runtime-generated code. + 'fromWireType'(value) { + var length = HEAPU32[((value)>>2)]; + var payload = value + 4; + + var str; + if (stdStringIsUTF8) { + var decodeStartPtr = payload; + // Looping here to support possible embedded '0' bytes + for (var i = 0; i <= length; ++i) { + var currentBytePtr = payload + i; + if (i == length || HEAPU8[currentBytePtr] == 0) { + var maxRead = currentBytePtr - decodeStartPtr; + var stringSegment = UTF8ToString(decodeStartPtr, maxRead); + if (str === undefined) { + str = stringSegment; + } else { + str += String.fromCharCode(0); + str += stringSegment; + } + decodeStartPtr = currentBytePtr + 1; + } + } + } else { + var a = new Array(length); + for (var i = 0; i < length; ++i) { + a[i] = String.fromCharCode(HEAPU8[payload + i]); + } + str = a.join(''); + } + + _free(value); + + return str; + }, + 'toWireType'(destructors, value) { + if (value instanceof ArrayBuffer) { + value = new Uint8Array(value); + } + + var length; + var valueIsOfTypeString = (typeof value == 'string'); + + if (!(valueIsOfTypeString || value instanceof Uint8Array || value instanceof Uint8ClampedArray || value instanceof Int8Array)) { + throwBindingError('Cannot pass non-string to std::string'); + } + if (stdStringIsUTF8 && valueIsOfTypeString) { + length = lengthBytesUTF8(value); + } else { + length = value.length; + } + + // assumes POINTER_SIZE alignment + var base = _malloc(4 + length + 1); + var ptr = base + 4; + HEAPU32[((base)>>2)] = length; + if (stdStringIsUTF8 && valueIsOfTypeString) { + stringToUTF8(value, ptr, length + 1); + } else { + if (valueIsOfTypeString) { + for (var i = 0; i < length; ++i) { + var charCode = value.charCodeAt(i); + if (charCode > 255) { + _free(ptr); + throwBindingError('String has UTF-16 code units that do not fit in 8 bits'); + } + HEAPU8[ptr + i] = charCode; + } + } else { + for (var i = 0; i < length; ++i) { + HEAPU8[ptr + i] = value[i]; + } + } + } + + if (destructors !== null) { + destructors.push(_free, base); + } + return base; + }, + argPackAdvance: GenericWireTypeSize, + 'readValueFromPointer': readPointer, + destructorFunction(ptr) { + _free(ptr); + }, + }); + }; + + + + + var UTF16Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf-16le') : undefined;; + var UTF16ToString = (ptr, maxBytesToRead) => { + var endPtr = ptr; + // TextDecoder needs to know the byte length in advance, it doesn't stop on + // null terminator by itself. + // Also, use the length info to avoid running tiny strings through + // TextDecoder, since .subarray() allocates garbage. + var idx = endPtr >> 1; + var maxIdx = idx + maxBytesToRead / 2; + // If maxBytesToRead is not passed explicitly, it will be undefined, and this + // will always evaluate to true. This saves on code size. + while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx; + endPtr = idx << 1; + + if (endPtr - ptr > 32 && UTF16Decoder) + return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr)); + + // Fallback: decode without UTF16Decoder + var str = ''; + + // If maxBytesToRead is not passed explicitly, it will be undefined, and the + // for-loop's condition will always evaluate to true. The loop is then + // terminated on the first null char. + for (var i = 0; !(i >= maxBytesToRead / 2); ++i) { + var codeUnit = HEAP16[(((ptr)+(i*2))>>1)]; + if (codeUnit == 0) break; + // fromCharCode constructs a character from a UTF-16 code unit, so we can + // pass the UTF16 string right through. + str += String.fromCharCode(codeUnit); + } + + return str; + }; + + var stringToUTF16 = (str, outPtr, maxBytesToWrite) => { + // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. + maxBytesToWrite ??= 0x7FFFFFFF; + if (maxBytesToWrite < 2) return 0; + maxBytesToWrite -= 2; // Null terminator. + var startPtr = outPtr; + var numCharsToWrite = (maxBytesToWrite < str.length*2) ? (maxBytesToWrite / 2) : str.length; + for (var i = 0; i < numCharsToWrite; ++i) { + // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP. + var codeUnit = str.charCodeAt(i); // possibly a lead surrogate + HEAP16[((outPtr)>>1)] = codeUnit; + outPtr += 2; + } + // Null-terminate the pointer to the HEAP. + HEAP16[((outPtr)>>1)] = 0; + return outPtr - startPtr; + }; + + var lengthBytesUTF16 = (str) => str.length*2; + + var UTF32ToString = (ptr, maxBytesToRead) => { + var i = 0; + + var str = ''; + // If maxBytesToRead is not passed explicitly, it will be undefined, and this + // will always evaluate to true. This saves on code size. + while (!(i >= maxBytesToRead / 4)) { + var utf32 = HEAP32[(((ptr)+(i*4))>>2)]; + if (utf32 == 0) break; + ++i; + // 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. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + if (utf32 >= 0x10000) { + var ch = utf32 - 0x10000; + str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); + } else { + str += String.fromCharCode(utf32); + } + } + return str; + }; + + var stringToUTF32 = (str, outPtr, maxBytesToWrite) => { + // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. + maxBytesToWrite ??= 0x7FFFFFFF; + if (maxBytesToWrite < 4) return 0; + var startPtr = outPtr; + var endPtr = startPtr + maxBytesToWrite - 4; + for (var i = 0; i < str.length; ++i) { + // 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. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var codeUnit = str.charCodeAt(i); // possibly a lead surrogate + if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) { + var trailSurrogate = str.charCodeAt(++i); + codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF); + } + HEAP32[((outPtr)>>2)] = codeUnit; + outPtr += 4; + if (outPtr + 4 > endPtr) break; + } + // Null-terminate the pointer to the HEAP. + HEAP32[((outPtr)>>2)] = 0; + return outPtr - startPtr; + }; + + var lengthBytesUTF32 = (str) => { + var len = 0; + for (var i = 0; i < str.length; ++i) { + // 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. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var codeUnit = str.charCodeAt(i); + if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) ++i; // possibly a lead surrogate, so skip over the tail surrogate. + len += 4; + } + + return len; + }; + var __embind_register_std_wstring = (rawType, charSize, name) => { + name = readLatin1String(name); + var decodeString, encodeString, readCharAt, lengthBytesUTF; + if (charSize === 2) { + decodeString = UTF16ToString; + encodeString = stringToUTF16; + lengthBytesUTF = lengthBytesUTF16; + readCharAt = (pointer) => HEAPU16[((pointer)>>1)]; + } else if (charSize === 4) { + decodeString = UTF32ToString; + encodeString = stringToUTF32; + lengthBytesUTF = lengthBytesUTF32; + readCharAt = (pointer) => HEAPU32[((pointer)>>2)]; + } + registerType(rawType, { + name, + 'fromWireType': (value) => { + // Code mostly taken from _embind_register_std_string fromWireType + var length = HEAPU32[((value)>>2)]; + var str; + + var decodeStartPtr = value + 4; + // Looping here to support possible embedded '0' bytes + for (var i = 0; i <= length; ++i) { + var currentBytePtr = value + 4 + i * charSize; + if (i == length || readCharAt(currentBytePtr) == 0) { + var maxReadBytes = currentBytePtr - decodeStartPtr; + var stringSegment = decodeString(decodeStartPtr, maxReadBytes); + if (str === undefined) { + str = stringSegment; + } else { + str += String.fromCharCode(0); + str += stringSegment; + } + decodeStartPtr = currentBytePtr + charSize; + } + } + + _free(value); + + return str; + }, + 'toWireType': (destructors, value) => { + if (!(typeof value == 'string')) { + throwBindingError(`Cannot pass non-string to C++ string type ${name}`); + } + + // assumes POINTER_SIZE alignment + var length = lengthBytesUTF(value); + var ptr = _malloc(4 + length + charSize); + HEAPU32[((ptr)>>2)] = length / charSize; + + encodeString(value, ptr + 4, length + charSize); + + if (destructors !== null) { + destructors.push(_free, ptr); + } + return ptr; + }, + argPackAdvance: GenericWireTypeSize, + 'readValueFromPointer': readPointer, + destructorFunction(ptr) { + _free(ptr); + } + }); + }; + + + var __embind_register_void = (rawType, name) => { + name = readLatin1String(name); + registerType(rawType, { + isVoid: true, // void return values can be optimized out sometimes + name, + argPackAdvance: 0, + 'fromWireType': () => undefined, + // TODO: assert if anything else is given? + 'toWireType': (destructors, o) => undefined, + }); + }; + + var __emscripten_memcpy_js = (dest, src, num) => HEAPU8.copyWithin(dest, src, src + num); + + var getHeapMax = () => + HEAPU8.length; + + var alignMemory = (size, alignment) => { + return Math.ceil(size / alignment) * alignment; + }; + + var abortOnCannotGrowMemory = (requestedSize) => { + abort('OOM'); + }; + var _emscripten_resize_heap = (requestedSize) => { + var oldSize = HEAPU8.length; + // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned. + requestedSize >>>= 0; + abortOnCannotGrowMemory(requestedSize); + }; +embind_init_charCodes(); +BindingError = Module['BindingError'] = class BindingError extends Error { constructor(message) { super(message); this.name = 'BindingError'; }}; +InternalError = Module['InternalError'] = class InternalError extends Error { constructor(message) { super(message); this.name = 'InternalError'; }}; +init_emval();; +var wasmImports = { + /** @export */ + _embind_register_bigint: __embind_register_bigint, + /** @export */ + _embind_register_bool: __embind_register_bool, + /** @export */ + _embind_register_emval: __embind_register_emval, + /** @export */ + _embind_register_float: __embind_register_float, + /** @export */ + _embind_register_integer: __embind_register_integer, + /** @export */ + _embind_register_memory_view: __embind_register_memory_view, + /** @export */ + _embind_register_std_string: __embind_register_std_string, + /** @export */ + _embind_register_std_wstring: __embind_register_std_wstring, + /** @export */ + _embind_register_void: __embind_register_void, + /** @export */ + _emscripten_memcpy_js: __emscripten_memcpy_js, + /** @export */ + emscripten_resize_heap: _emscripten_resize_heap +}; +var wasmExports = createWasm(); +var ___wasm_call_ctors = wasmExports['__wasm_call_ctors'] +var ___getTypeName = wasmExports['__getTypeName'] +var _malloc = Module['_malloc'] = wasmExports['malloc'] +var _free = wasmExports['free'] +var __emscripten_stack_restore = wasmExports['_emscripten_stack_restore'] +var __emscripten_stack_alloc = wasmExports['_emscripten_stack_alloc'] +var _emscripten_stack_get_current = wasmExports['emscripten_stack_get_current'] + + +// include: postamble.js +// === Auto-generated postamble setup entry stuff === + + + + +var calledRun; + +dependenciesFulfilled = function runCaller() { + // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false) + if (!calledRun) run(); + if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled +}; + +function run() { + + if (runDependencies > 0) { + return; + } + + preRun(); + + // a preRun added a dependency, run will be called later + if (runDependencies > 0) { + return; + } + + function doRun() { + // run may have just been called through dependencies being fulfilled just in this very frame, + // or while the async setStatus time below was happening + if (calledRun) return; + calledRun = true; + Module['calledRun'] = true; + + if (ABORT) return; + + initRuntime(); + + readyPromiseResolve(Module); + Module['onRuntimeInitialized']?.(); + + postRun(); + } + + if (Module['setStatus']) { + Module['setStatus']('Running...'); + setTimeout(() => { + setTimeout(() => Module['setStatus'](''), 1); + doRun(); + }, 1); + } else + { + doRun(); + } +} + +if (Module['preInit']) { + if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']]; + while (Module['preInit'].length > 0) { + Module['preInit'].pop()(); + } +} + +run(); + +// end include: postamble.js + +// include: postamble_modularize.js +// In MODULARIZE mode we wrap the generated code in a factory function +// and return either the Module itself, or a promise of the module. +// +// We assign to the `moduleRtn` global here and configure closure to see +// this as and extern so it won't get minified. + +moduleRtn = Module; + +// end include: postamble_modularize.js + + + + return moduleRtn; +} +); +})(); +export default Module; diff --git a/examples/worklets/free-queue.mjs b/examples/worklets/free-queue.mjs new file mode 100644 index 0000000..04409b6 --- /dev/null +++ b/examples/worklets/free-queue.mjs @@ -0,0 +1,254 @@ +// ported from https://github.com/GoogleChromeLabs/web-audio-samples/tree/main/src/audio-worklet/design-pattern/wasm + +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +// Byte per audio sample. (32 bit float) +const BYTES_PER_SAMPLE = Float32Array.BYTES_PER_ELEMENT; + +// Basic byte unit of WASM heap. (16 bit = 2 bytes) +const BYTES_PER_UNIT = Uint16Array.BYTES_PER_ELEMENT; + +// The max audio channel on Chrome is 32. +const MAX_CHANNEL_COUNT = 32; + +// WebAudio's render quantum size. +const RENDER_QUANTUM_FRAMES = 128; + + +/** + * A WASM HEAP wrapper for AudioBuffer class. This breaks down the AudioBuffer + * into an Array of Float32Array for the convinient WASM opearion. + * + * @class + * @dependency Module A WASM module generated by the emscripten glue code. + */ +class FreeQueue { + /** + * @constructor + * @param {object} wasmModule WASM module generated by Emscripten. + * @param {number} length Buffer frame length. + * @param {number} channelCount Number of channels. + * @param {number=} maxChannelCount Maximum number of channels. + */ + constructor(wasmModule, length, channelCount, maxChannelCount) { + // HeapAudioBuffer initialization + // The |channelCount| must be greater than 0, and less than or equal to + // the maximum channel count. + this._isInitialized = false; + this._module = wasmModule; + this._length = length; + this._maxChannelCount = maxChannelCount ? + Math.min(maxChannelCount, MAX_CHANNEL_COUNT) : channelCount; + this._channelCount = channelCount; + this._allocateHeap(); + this._isInitialized = true; + + + // RingBuffer initialization + this._readIndex = 0; + this._writeIndex = 0; + this._framesAvailable = 0; + this._channelDataLocal = []; + for (let i = 0; i < this._channelCount; ++i) { + this._channelDataLocal[i] = new Float32Array(length); + } + } + + /** + * Allocates memory in the WASM heap and set up Float32Array views for the + * channel data. + * + * @private + */ + _allocateHeap() { + const channelByteSize = this._length * BYTES_PER_SAMPLE; + const dataByteSize = this._channelCount * channelByteSize; + this._dataPtr = this._module._malloc(dataByteSize); + this._channelData = []; + for (let i = 0; i < this._channelCount; ++i) { + const startByteOffset = this._dataPtr + i * channelByteSize; + const endByteOffset = startByteOffset + channelByteSize; + // Get the actual array index by dividing the byte offset by 2 bytes. + this._channelData[i] = + this._module.HEAPF32.subarray( + startByteOffset >> BYTES_PER_UNIT, + endByteOffset >> BYTES_PER_UNIT); + } + } + + /** + * Adapt the current channel count to the new input buffer. + * + * @param {number} newChannelCount The new channel count. + */ + adaptChannel(newChannelCount) { + if (newChannelCount < this._maxChannelCount) { + this._channelCount = newChannelCount; + } + } + + /** + * Getter for the buffer length in frames. + * + * @return {?number} Buffer length in frames. + */ + get length() { + return this._isInitialized ? this._length : null; + } + + /** + * Getter for the number of channels. + * + * @return {?number} Buffer length in frames. + */ + get numberOfChannels() { + return this._isInitialized ? this._channelCount : null; + } + + /** + * Getter for the maxixmum number of channels allowed for the instance. + * + * @return {?number} Buffer length in frames. + */ + get maxChannelCount() { + return this._isInitialized ? this._maxChannelCount : null; + } + + /** + * Returns a Float32Array object for a given channel index. If the channel + * index is undefined, it returns the reference to the entire array of channel + * data. + * + * @param {number|undefined} channelIndex Channel index. + * @return {?Array} a channel data array or an + * array of channel data. + */ + getChannelData(channelIndex) { + if (channelIndex >= this._channelCount) { + return null; + } + + return typeof channelIndex === 'undefined' ? + this._channelData : this._channelData[channelIndex]; + } + + /** + * Returns the base address of the allocated memory space in the WASM heap. + * + * @return {number} WASM Heap address. + */ + getHeapAddress() { + return this._dataPtr; + } + + /** + * Returns the base address of the allocated memory space in the WASM heap. + * + * @return {number} WASM Heap address. + */ + getPointer() { + return this._dataPtr; + } + + /** + * Frees the allocated memory space in the WASM heap. + */ + free() { + this._isInitialized = false; + this._module._free(this._dataPtr); + this._module._free(this._pointerArrayPtr); + this._channelData = null; + } + + /** + * Getter for Available frames in buffer. + * + * @return {number} Available frames in buffer. + */ + get framesAvailable() { + return this._framesAvailable; + } + + /** + * Push a sequence of Float32Arrays to buffer. + * + * @param {array} arraySequence A sequence of Float32Arrays. + */ + push(arraySequence) { + // The channel count of arraySequence and the length of each channel must + // match with this buffer obejct. + + if (arraySequence.length !== this._channelCount) { + throw new Error(`Channel count mismatch: expected ${this._channelCount}, but got ${arraySequence.length}.`); + } + + // Transfer data from the |arraySequence| storage to the internal buffer. + const sourceLength = arraySequence[0].length; + for (let i = 0; i < sourceLength; ++i) { + for (let channel = 0; channel < this._channelCount; ++channel) { + this._channelDataLocal[channel][this._writeIndex] = arraySequence[channel][i]; + } + this._writeIndex = (this._writeIndex + 1) % this._length; + } + + // For excessive frames, the buffer will be overwritten. + this._framesAvailable += sourceLength; + if (this._framesAvailable > this._length) { + this._framesAvailable = this._length; + } + } + + /** + * Pull data out of buffer and fill a given sequence of Float32Arrays. + * + * @param {array} arraySequence An array of Float32Arrays. + */ + pull(arraySequence) { + // The channel count of arraySequence and the length of each channel must + // match with this buffer obejct. + + if (arraySequence.length !== this._channelCount) { + throw new Error(`Channel count mismatch: expected ${this._channelCount}, but got ${arraySequence.length}.`); + } + + // If the FIFO is completely empty, do nothing. + if (this._framesAvailable === 0) { + return; + } + + const destinationLength = arraySequence[0].length; + + // Transfer data from the internal buffer to the |arraySequence| storage. + for (let i = 0; i < destinationLength; ++i) { + for (let channel = 0; channel < this._channelCount; ++channel) { + arraySequence[channel][i] = this._channelDataLocal[channel][this._readIndex]; + } + this._readIndex = (this._readIndex + 1) % this._length; + } + + this._framesAvailable -= destinationLength; + if (this._framesAvailable < 0) { + this._framesAvailable = 0; + } + } +} // class FreeQueue + +export { + MAX_CHANNEL_COUNT, + RENDER_QUANTUM_FRAMES, + FreeQueue +}; diff --git a/examples/worklets/simple-kernel.wasmmodule.mjs b/examples/worklets/simple-kernel.wasmmodule.mjs new file mode 100644 index 0000000..cdfc4a3 --- /dev/null +++ b/examples/worklets/simple-kernel.wasmmodule.mjs @@ -0,0 +1,2603 @@ + +import { createRequire } from 'module'; +const require = createRequire(import.meta.url); + +var Module = (() => { + var _scriptName = import.meta.url; + + return ( +function(moduleArg = {}) { + var moduleRtn; + +// include: shell.js +// The Module object: Our interface to the outside world. We import +// and export values on it. There are various ways Module can be used: +// 1. Not defined. We create it here +// 2. A function parameter, function(moduleArg) => Promise +// 3. pre-run appended it, var Module = {}; ..generated code.. +// 4. External script tag defines var Module. +// We need to check if Module already exists (e.g. case 3 above). +// Substitution will be replaced with actual code on later stage of the build, +// this way Closure Compiler will not mangle it (e.g. case 4. above). +// Note that if you want to run closure, and also to use Module +// after the generated code, you will need to define var Module = {}; +// before the code. Then that object will be used in the code, and you +// can continue to use Module afterwards as well. +var Module = moduleArg; + +// Set up the promise that indicates the Module is initialized +var readyPromiseResolve, readyPromiseReject; +var readyPromise = new Promise((resolve, reject) => { + readyPromiseResolve = resolve; + readyPromiseReject = reject; +}); + +// Determine the runtime environment we are in. You can customize this by +// setting the ENVIRONMENT setting at compile time (see settings.js). + +var ENVIRONMENT_IS_WEB = false; +var ENVIRONMENT_IS_WORKER = false; +var ENVIRONMENT_IS_NODE = true; +var ENVIRONMENT_IS_SHELL = false; + +if (ENVIRONMENT_IS_NODE) { + // `require()` is no-op in an ESM module, use `createRequire()` to construct + // the require()` function. This is only necessary for multi-environment + // builds, `-sENVIRONMENT=node` emits a static import declaration instead. + // TODO: Swap all `require()`'s with `import()`'s? + +} + +// --pre-jses are emitted after the Module integration code, so that they can +// refer to Module (if they choose; they can also define Module) + + +// Sometimes an existing Module object exists with properties +// meant to overwrite the default module functionality. Here +// we collect those properties and reapply _after_ we configure +// the current environment's defaults to avoid having to be so +// defensive during initialization. +var moduleOverrides = Object.assign({}, Module); + +var arguments_ = []; +var thisProgram = './this.program'; +var quit_ = (status, toThrow) => { + throw toThrow; +}; + +// `/` should be present at the end if `scriptDirectory` is not empty +var scriptDirectory = ''; +function locateFile(path) { + if (Module['locateFile']) { + return Module['locateFile'](path, scriptDirectory); + } + return scriptDirectory + path; +} + +// Hooks that are implemented differently in different runtime environments. +var readAsync, readBinary; + +if (ENVIRONMENT_IS_NODE) { + + // These modules will usually be used on Node.js. Load them eagerly to avoid + // the complexity of lazy-loading. + var fs = require('fs'); + var nodePath = require('path'); + + // EXPORT_ES6 + ENVIRONMENT_IS_NODE always requires use of import.meta.url, + // since there's no way getting the current absolute path of the module when + // support for that is not available. + if (!import.meta.url.startsWith('data:')) { + scriptDirectory = nodePath.dirname(require('url').fileURLToPath(import.meta.url)) + '/'; + } + +// include: node_shell_read.js +readBinary = (filename) => { + // We need to re-wrap `file://` strings to URLs. + filename = isFileURI(filename) ? new URL(filename) : filename; + var ret = fs.readFileSync(filename); + return ret; +}; + +readAsync = async (filename, binary = true) => { + // See the comment in the `readBinary` function. + filename = isFileURI(filename) ? new URL(filename) : filename; + var ret = fs.readFileSync(filename, binary ? undefined : 'utf8'); + return ret; +}; +// end include: node_shell_read.js + if (!Module['thisProgram'] && process.argv.length > 1) { + thisProgram = process.argv[1].replace(/\\/g, '/'); + } + + arguments_ = process.argv.slice(2); + + // MODULARIZE will export the module in the proper place outside, we don't need to export here + + quit_ = (status, toThrow) => { + process.exitCode = status; + throw toThrow; + }; + +} else + +// Note that this includes Node.js workers when relevant (pthreads is enabled). +// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and +// ENVIRONMENT_IS_NODE. +{ +} + +var out = Module['print'] || console.log.bind(console); +var err = Module['printErr'] || console.error.bind(console); + +// Merge back in the overrides +Object.assign(Module, moduleOverrides); +// Free the object hierarchy contained in the overrides, this lets the GC +// reclaim data used. +moduleOverrides = null; + +// Emit code to handle expected values on the Module object. This applies Module.x +// to the proper local x. This has two benefits: first, we only emit it if it is +// expected to arrive, and second, by using a local everywhere else that can be +// minified. + +if (Module['arguments']) arguments_ = Module['arguments']; + +if (Module['thisProgram']) thisProgram = Module['thisProgram']; + +// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message +// end include: shell.js + +// include: preamble.js +// === Preamble library stuff === + +// Documentation for the public APIs defined in this file must be updated in: +// site/source/docs/api_reference/preamble.js.rst +// A prebuilt local version of the documentation is available at: +// site/build/text/docs/api_reference/preamble.js.txt +// You can also build docs locally as HTML or other formats in site/ +// An online HTML version (which may be of a different version of Emscripten) +// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html + +var wasmBinary = Module['wasmBinary']; + +// include: base64Utils.js +// Converts a string of base64 into a byte array (Uint8Array). +function intArrayFromBase64(s) { + if (typeof ENVIRONMENT_IS_NODE != 'undefined' && ENVIRONMENT_IS_NODE) { + var buf = Buffer.from(s, 'base64'); + return new Uint8Array(buf.buffer, buf.byteOffset, buf.length); + } + + var decoded = atob(s); + var bytes = new Uint8Array(decoded.length); + for (var i = 0 ; i < decoded.length ; ++i) { + bytes[i] = decoded.charCodeAt(i); + } + return bytes; +} + +// If filename is a base64 data URI, parses and returns data (Buffer on node, +// Uint8Array otherwise). If filename is not a base64 data URI, returns undefined. +function tryParseAsDataURI(filename) { + if (!isDataURI(filename)) { + return; + } + + return intArrayFromBase64(filename.slice(dataURIPrefix.length)); +} +// end include: base64Utils.js +// Wasm globals + +var wasmMemory; + +//======================================== +// Runtime essentials +//======================================== + +// whether we are quitting the application. no code should run after this. +// set in exit() and abort() +var ABORT = false; + +// set by exit() and abort(). Passed to 'onExit' handler. +// NOTE: This is also used as the process return code code in shell environments +// but only when noExitRuntime is false. +var EXITSTATUS; + +// In STRICT mode, we only define assert() when ASSERTIONS is set. i.e. we +// don't define it at all in release modes. This matches the behaviour of +// MINIMAL_RUNTIME. +// TODO(sbc): Make this the default even without STRICT enabled. +/** @type {function(*, string=)} */ +function assert(condition, text) { + if (!condition) { + // This build was created without ASSERTIONS defined. `assert()` should not + // ever be called in this configuration but in case there are callers in + // the wild leave this simple abort() implementation here for now. + abort(text); + } +} + +// Memory management + +var HEAP, +/** @type {!Int8Array} */ + HEAP8, +/** @type {!Uint8Array} */ + HEAPU8, +/** @type {!Int16Array} */ + HEAP16, +/** @type {!Uint16Array} */ + HEAPU16, +/** @type {!Int32Array} */ + HEAP32, +/** @type {!Uint32Array} */ + HEAPU32, +/** @type {!Float32Array} */ + HEAPF32, +/** @type {!Float64Array} */ + HEAPF64; + +// include: runtime_shared.js +function updateMemoryViews() { + var b = wasmMemory.buffer; + Module['HEAP8'] = HEAP8 = new Int8Array(b); + Module['HEAP16'] = HEAP16 = new Int16Array(b); + Module['HEAPU8'] = HEAPU8 = new Uint8Array(b); + Module['HEAPU16'] = HEAPU16 = new Uint16Array(b); + Module['HEAP32'] = HEAP32 = new Int32Array(b); + Module['HEAPU32'] = HEAPU32 = new Uint32Array(b); + Module['HEAPF32'] = HEAPF32 = new Float32Array(b); + Module['HEAPF64'] = HEAPF64 = new Float64Array(b); +} + +// end include: runtime_shared.js +// include: runtime_stack_check.js +// end include: runtime_stack_check.js +var __ATPRERUN__ = []; // functions called before the runtime is initialized +var __ATINIT__ = []; // functions called during startup +var __ATEXIT__ = []; // functions called during shutdown +var __ATPOSTRUN__ = []; // functions called after the main() is called + +var runtimeInitialized = false; + +function preRun() { + if (Module['preRun']) { + if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']]; + while (Module['preRun'].length) { + addOnPreRun(Module['preRun'].shift()); + } + } + callRuntimeCallbacks(__ATPRERUN__); +} + +function initRuntime() { + runtimeInitialized = true; + + + callRuntimeCallbacks(__ATINIT__); +} + +function postRun() { + + if (Module['postRun']) { + if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']]; + while (Module['postRun'].length) { + addOnPostRun(Module['postRun'].shift()); + } + } + + callRuntimeCallbacks(__ATPOSTRUN__); +} + +function addOnPreRun(cb) { + __ATPRERUN__.unshift(cb); +} + +function addOnInit(cb) { + __ATINIT__.unshift(cb); +} + +function addOnExit(cb) { +} + +function addOnPostRun(cb) { + __ATPOSTRUN__.unshift(cb); +} + +// include: runtime_math.js +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc + +// end include: runtime_math.js +// A counter of dependencies for calling run(). If we need to +// do asynchronous work before running, increment this and +// decrement it. Incrementing must happen in a place like +// Module.preRun (used by emcc to add file preloading). +// Note that you can add dependencies in preRun, even though +// it happens right before run - run will be postponed until +// the dependencies are met. +var runDependencies = 0; +var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled + +function getUniqueRunDependency(id) { + return id; +} + +function addRunDependency(id) { + runDependencies++; + + Module['monitorRunDependencies']?.(runDependencies); + +} + +function removeRunDependency(id) { + runDependencies--; + + Module['monitorRunDependencies']?.(runDependencies); + + if (runDependencies == 0) { + if (dependenciesFulfilled) { + var callback = dependenciesFulfilled; + dependenciesFulfilled = null; + callback(); // can add another dependenciesFulfilled + } + } +} + +/** @param {string|number=} what */ +function abort(what) { + Module['onAbort']?.(what); + + what = 'Aborted(' + what + ')'; + // TODO(sbc): Should we remove printing and leave it up to whoever + // catches the exception? + err(what); + + ABORT = true; + + what += '. Build with -sASSERTIONS for more info.'; + + // Use a wasm runtime error, because a JS error might be seen as a foreign + // exception, which means we'd run destructors on it. We need the error to + // simply make the program stop. + // FIXME This approach does not work in Wasm EH because it currently does not assume + // all RuntimeErrors are from traps; it decides whether a RuntimeError is from + // a trap or not based on a hidden field within the object. So at the moment + // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that + // allows this in the wasm spec. + + // Suppress closure compiler warning here. Closure compiler's builtin extern + // definition for WebAssembly.RuntimeError claims it takes no arguments even + // though it can. + // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed. + /** @suppress {checkTypes} */ + var e = new WebAssembly.RuntimeError(what); + + readyPromiseReject(e); + // Throw the error whether or not MODULARIZE is set because abort is used + // in code paths apart from instantiation where an exception is expected + // to be thrown when abort is called. + throw e; +} + +// include: memoryprofiler.js +// end include: memoryprofiler.js +// include: URIUtils.js +// Prefix of data URIs emitted by SINGLE_FILE and related options. +var dataURIPrefix = 'data:application/octet-stream;base64,'; + +/** + * Indicates whether filename is a base64 data URI. + * @noinline + */ +var isDataURI = (filename) => filename.startsWith(dataURIPrefix); + +/** + * Indicates whether filename is delivered via file protocol (as opposed to http/https) + * @noinline + */ +var isFileURI = (filename) => filename.startsWith('file://'); +// end include: URIUtils.js +// include: runtime_exceptions.js +// end include: runtime_exceptions.js +function findWasmBinary() { + var f = 'data:application/octet-stream;base64,AGFzbQEAAAABiwESYAF/AX9gAX8AYAR/f39/AGAAAGADf39/AX9gBn9/f39/fwBgBX9/f39/AGAAAX9gAn9/AGADf39/AGACf38Bf2AGf39/f39/AX9gDX9/f39/f39/f39/f38AYAp/f39/f39/f39/AGAEf39/fwF/YAV/f39/fwF/YAV/f39+fgBgB39/f39/f38AAs0DDwNlbnYWX2VtYmluZF9yZWdpc3Rlcl9jbGFzcwAMA2VudiJfZW1iaW5kX3JlZ2lzdGVyX2NsYXNzX2NvbnN0cnVjdG9yAAUDZW52H19lbWJpbmRfcmVnaXN0ZXJfY2xhc3NfZnVuY3Rpb24ADQNlbnYVX2VtYmluZF9yZWdpc3Rlcl92b2lkAAgDZW52FV9lbWJpbmRfcmVnaXN0ZXJfYm9vbAACA2VudhhfZW1iaW5kX3JlZ2lzdGVyX2ludGVnZXIABgNlbnYWX2VtYmluZF9yZWdpc3Rlcl9mbG9hdAAJA2VudhtfZW1iaW5kX3JlZ2lzdGVyX3N0ZF9zdHJpbmcACANlbnYcX2VtYmluZF9yZWdpc3Rlcl9zdGRfd3N0cmluZwAJA2VudhZfZW1iaW5kX3JlZ2lzdGVyX2VtdmFsAAEDZW52HF9lbWJpbmRfcmVnaXN0ZXJfbWVtb3J5X3ZpZXcACQNlbnYVX2Vtc2NyaXB0ZW5fbWVtY3B5X2pzAAkDZW52FmVtc2NyaXB0ZW5fcmVzaXplX2hlYXAAAANlbnYJX2Fib3J0X2pzAAMDZW52F19lbWJpbmRfcmVnaXN0ZXJfYmlnaW50ABEDRkUDAAEDAwMAAQAHAgYDBAQAAAcABAEHAAAAAwEIAwMABwoAAQEBAQEBBAQABA4ICw8LAgICBAQKCgYCBgYFBQABBwEABxAEBQFwARkZBQYBAYICggIGDQJ/AUGQoAQLfwFBAAsHrwEJBm1lbW9yeQIAEV9fd2FzbV9jYWxsX2N0b3JzAA8NX19nZXRUeXBlTmFtZQAQGV9faW5kaXJlY3RfZnVuY3Rpb25fdGFibGUBAAZtYWxsb2MAIQRmcmVlACMZX2Vtc2NyaXB0ZW5fc3RhY2tfcmVzdG9yZQBQF19lbXNjcmlwdGVuX3N0YWNrX2FsbG9jAFEcZW1zY3JpcHRlbl9zdGFja19nZXRfY3VycmVudABSCR4BAEEBCxgSFRYXGBkaFDAzMTI3NDpMSkE1S0lCNkQK4F5FBgAQExAbCwkAIAAoAgQQHgsVACAAQQAoAvgbNgIEQQAgADYC+BsL2gMAQfwYQZ8JEANBlBlBwQhBAUEAEARBoBlBvAhBAUGAf0H/ABAFQbgZQbUIQQFBgH9B/wAQBUGsGUGzCEEBQQBB/wEQBUHEGUGJCEECQYCAfkH//wEQBUHQGUGACEECQQBB//8DEAVB3BlBmAhBBEGAgICAeEH/////BxAFQegZQY8IQQRBAEF/EAVB9BlB3AhBBEGAgICAeEH/////BxAFQYAaQdMIQQRBAEF/EAVBjBpBowhBCEKAgICAgICAgIB/Qv///////////wAQU0GYGkGiCEEIQgBCfxBTQaQaQZwIQQQQBkGwGkGYCUEIEAZBqA5B7ggQB0HwDkEEQeEIEAhBuA9BAkH6CBAIQYQQQQRBiQkQCEHQEBAJQewQQQBB1wwQCkGUEUEAQZwNEApBvBFBAUH1DBAKQeQRQQJBpAkQCkGMEkEDQcMJEApBtBJBBEHrCRAKQdwSQQVBiAoQCkGEE0EEQcENEApBrBNBBUHfDRAKQZQRQQBB7goQCkG8EUEBQc0KEApB5BFBAkGwCxAKQYwSQQNBjgsQCkG0EkEEQbYMEApB3BJBBUGUDBAKQdQTQQhB8wsQCkH8E0EJQdELEApBpBRBBkGuChAKQcwUQQdBhg4QCgspAEEAQQE2AvwbQQBBADYCgBwQEkEAQQAoAvgbNgKAHEEAQfwbNgL4GwtlAQF/QfQUQYwVQawVQQBBzRVBAkHQFUEAQdAVQQBBxghB0hVBAxAAQfQUQQFB2BVBzRVBBEEFEAFBCBAmIgBBADYCBCAAQQY2AgBB9BRBqwhBBUHgFUH0FUEHIABBAEEAQQAQAgsFAEH0FAsQAAJAIABFDQAgAEEBECoLCwcAIAARBwALBgBBARAmCzoBAn8CQCADRQ0AQQAhBANAIAIgBCIEQQl0IgVqIAEgBWpBgAQQHBogBEEBaiIFIQQgBSADRw0ACwsLSAEBfyABIAAoAgQiBUEBdWohASAAKAIAIQACQAJAIAVBAXFFDQAgASgCACAAaigCACEADAELIAAhAAsgASACIAMgBCAAEQIAC3oBAX9BAEEINgKEHEEAQQA2AogcQfQUQYwVQawVQQBBzRVBAkHQFUEAQdAVQQBBxghB0hVBAxAAQfQUQQFB2BVBzRVBBEEFEAFBCBAmIgBBADYCBCAAQQY2AgBB9BRBqwhBBUHgFUH0FUEHIABBAEEAQQAQAkGEHBARC5AEAQN/AkAgAkGABEkNACAAIAEgAhALIAAPCyAAIAJqIQMCQAJAIAEgAHNBA3ENAAJAAkAgAEEDcQ0AIAAhAgwBCwJAIAINACAAIQIMAQsgACECA0AgAiABLQAAOgAAIAFBAWohASACQQFqIgJBA3FFDQEgAiADSQ0ACwsgA0F8cSEEAkAgA0HAAEkNACACIARBQGoiBUsNAANAIAIgASgCADYCACACIAEoAgQ2AgQgAiABKAIINgIIIAIgASgCDDYCDCACIAEoAhA2AhAgAiABKAIUNgIUIAIgASgCGDYCGCACIAEoAhw2AhwgAiABKAIgNgIgIAIgASgCJDYCJCACIAEoAig2AiggAiABKAIsNgIsIAIgASgCMDYCMCACIAEoAjQ2AjQgAiABKAI4NgI4IAIgASgCPDYCPCABQcAAaiEBIAJBwABqIgIgBU0NAAsLIAIgBE8NAQNAIAIgASgCADYCACABQQRqIQEgAkEEaiICIARJDQAMAgsACwJAIANBBE8NACAAIQIMAQsCQCAAIANBfGoiBE0NACAAIQIMAQsgACECA0AgAiABLQAAOgAAIAIgAS0AAToAASACIAEtAAI6AAIgAiABLQADOgADIAFBBGohASACQQRqIgIgBE0NAAsLAkAgAiADTw0AA0AgAiABLQAAOgAAIAFBAWohASACQQFqIgIgA0cNAAsLIAAL8gICA38BfgJAIAJFDQAgACABOgAAIAAgAmoiA0F/aiABOgAAIAJBA0kNACAAIAE6AAIgACABOgABIANBfWogAToAACADQX5qIAE6AAAgAkEHSQ0AIAAgAToAAyADQXxqIAE6AAAgAkEJSQ0AIABBACAAa0EDcSIEaiIDIAFB/wFxQYGChAhsIgE2AgAgAyACIARrQXxxIgRqIgJBfGogATYCACAEQQlJDQAgAyABNgIIIAMgATYCBCACQXhqIAE2AgAgAkF0aiABNgIAIARBGUkNACADIAE2AhggAyABNgIUIAMgATYCECADIAE2AgwgAkFwaiABNgIAIAJBbGogATYCACACQWhqIAE2AgAgAkFkaiABNgIAIAQgA0EEcUEYciIFayICQSBJDQAgAa1CgYCAgBB+IQYgAyAFaiEBA0AgASAGNwMYIAEgBjcDECABIAY3AwggASAGNwMAIAFBIGohASACQWBqIgJBH0sNAAsLIAALIQECfwJAIAAQH0EBaiIBECEiAg0AQQAPCyACIAAgARAcC4gBAQN/IAAhAQJAAkAgAEEDcUUNAAJAIAAtAAANACAAIABrDwsgACEBA0AgAUEBaiIBQQNxRQ0BIAEtAAANAAwCCwALA0AgASICQQRqIQFBgIKECCACKAIAIgNrIANyQYCBgoR4cUGAgYKEeEYNAAsDQCACIgFBAWohAiABLQAADQALCyABIABrCwUAQYwcC+8hAQt/IwBBEGsiASQAAkACQAJAAkACQAJAAkACQAJAAkACQCAAQfQBSw0AAkBBACgCkBwiAkEQIABBC2pB+ANxIABBC0kbIgNBA3YiBHYiAEEDcUUNAAJAAkAgAEF/c0EBcSAEaiIDQQN0IgRBuBxqIgAgBEHAHGooAgAiBCgCCCIFRw0AQQAgAkF+IAN3cTYCkBwMAQsgBSAANgIMIAAgBTYCCAsgBEEIaiEAIAQgA0EDdCIDQQNyNgIEIAQgA2oiBCAEKAIEQQFyNgIEDAsLIANBACgCmBwiBk0NAQJAIABFDQACQAJAIAAgBHRBAiAEdCIAQQAgAGtycWgiBEEDdCIAQbgcaiIFIABBwBxqKAIAIgAoAggiB0cNAEEAIAJBfiAEd3EiAjYCkBwMAQsgByAFNgIMIAUgBzYCCAsgACADQQNyNgIEIAAgA2oiByAEQQN0IgQgA2siA0EBcjYCBCAAIARqIAM2AgACQCAGRQ0AIAZBeHFBuBxqIQVBACgCpBwhBAJAAkAgAkEBIAZBA3Z0IghxDQBBACACIAhyNgKQHCAFIQgMAQsgBSgCCCEICyAFIAQ2AgggCCAENgIMIAQgBTYCDCAEIAg2AggLIABBCGohAEEAIAc2AqQcQQAgAzYCmBwMCwtBACgClBwiCUUNASAJaEECdEHAHmooAgAiBygCBEF4cSADayEEIAchBQJAA0ACQCAFKAIQIgANACAFKAIUIgBFDQILIAAoAgRBeHEgA2siBSAEIAUgBEkiBRshBCAAIAcgBRshByAAIQUMAAsACyAHKAIYIQoCQCAHKAIMIgAgB0YNACAHKAIIIgUgADYCDCAAIAU2AggMCgsCQAJAIAcoAhQiBUUNACAHQRRqIQgMAQsgBygCECIFRQ0DIAdBEGohCAsDQCAIIQsgBSIAQRRqIQggACgCFCIFDQAgAEEQaiEIIAAoAhAiBQ0ACyALQQA2AgAMCQtBfyEDIABBv39LDQAgAEELaiIEQXhxIQNBACgClBwiCkUNAEEfIQYCQCAAQfT//wdLDQAgA0EmIARBCHZnIgBrdkEBcSAAQQF0a0E+aiEGC0EAIANrIQQCQAJAAkACQCAGQQJ0QcAeaigCACIFDQBBACEAQQAhCAwBC0EAIQAgA0EAQRkgBkEBdmsgBkEfRht0IQdBACEIA0ACQCAFKAIEQXhxIANrIgIgBE8NACACIQQgBSEIIAINAEEAIQQgBSEIIAUhAAwDCyAAIAUoAhQiAiACIAUgB0EddkEEcWooAhAiC0YbIAAgAhshACAHQQF0IQcgCyEFIAsNAAsLAkAgACAIcg0AQQAhCEECIAZ0IgBBACAAa3IgCnEiAEUNAyAAaEECdEHAHmooAgAhAAsgAEUNAQsDQCAAKAIEQXhxIANrIgIgBEkhBwJAIAAoAhAiBQ0AIAAoAhQhBQsgAiAEIAcbIQQgACAIIAcbIQggBSEAIAUNAAsLIAhFDQAgBEEAKAKYHCADa08NACAIKAIYIQsCQCAIKAIMIgAgCEYNACAIKAIIIgUgADYCDCAAIAU2AggMCAsCQAJAIAgoAhQiBUUNACAIQRRqIQcMAQsgCCgCECIFRQ0DIAhBEGohBwsDQCAHIQIgBSIAQRRqIQcgACgCFCIFDQAgAEEQaiEHIAAoAhAiBQ0ACyACQQA2AgAMBwsCQEEAKAKYHCIAIANJDQBBACgCpBwhBAJAAkAgACADayIFQRBJDQAgBCADaiIHIAVBAXI2AgQgBCAAaiAFNgIAIAQgA0EDcjYCBAwBCyAEIABBA3I2AgQgBCAAaiIAIAAoAgRBAXI2AgRBACEHQQAhBQtBACAFNgKYHEEAIAc2AqQcIARBCGohAAwJCwJAQQAoApwcIgcgA00NAEEAIAcgA2siBDYCnBxBAEEAKAKoHCIAIANqIgU2AqgcIAUgBEEBcjYCBCAAIANBA3I2AgQgAEEIaiEADAkLAkACQEEAKALoH0UNAEEAKALwHyEEDAELQQBCfzcC9B9BAEKAoICAgIAENwLsH0EAIAFBDGpBcHFB2KrVqgVzNgLoH0EAQQA2AvwfQQBBADYCzB9BgCAhBAtBACEAIAQgA0EvaiIGaiICQQAgBGsiC3EiCCADTQ0IQQAhAAJAQQAoAsgfIgRFDQBBACgCwB8iBSAIaiIKIAVNDQkgCiAESw0JCwJAAkBBAC0AzB9BBHENAAJAAkACQAJAAkBBACgCqBwiBEUNAEHQHyEAA0ACQCAEIAAoAgAiBUkNACAEIAUgACgCBGpJDQMLIAAoAggiAA0ACwtBABAlIgdBf0YNAyAIIQICQEEAKALsHyIAQX9qIgQgB3FFDQAgCCAHayAEIAdqQQAgAGtxaiECCyACIANNDQMCQEEAKALIHyIARQ0AQQAoAsAfIgQgAmoiBSAETQ0EIAUgAEsNBAsgAhAlIgAgB0cNAQwFCyACIAdrIAtxIgIQJSIHIAAoAgAgACgCBGpGDQEgByEACyAAQX9GDQECQCACIANBMGpJDQAgACEHDAQLIAYgAmtBACgC8B8iBGpBACAEa3EiBBAlQX9GDQEgBCACaiECIAAhBwwDCyAHQX9HDQILQQBBACgCzB9BBHI2AswfCyAIECUhB0EAECUhACAHQX9GDQUgAEF/Rg0FIAcgAE8NBSAAIAdrIgIgA0Eoak0NBQtBAEEAKALAHyACaiIANgLAHwJAIABBACgCxB9NDQBBACAANgLEHwsCQAJAQQAoAqgcIgRFDQBB0B8hAANAIAcgACgCACIFIAAoAgQiCGpGDQIgACgCCCIADQAMBQsACwJAAkBBACgCoBwiAEUNACAHIABPDQELQQAgBzYCoBwLQQAhAEEAIAI2AtQfQQAgBzYC0B9BAEF/NgKwHEEAQQAoAugfNgK0HEEAQQA2AtwfA0AgAEEDdCIEQcAcaiAEQbgcaiIFNgIAIARBxBxqIAU2AgAgAEEBaiIAQSBHDQALQQAgAkFYaiIAQXggB2tBB3EiBGsiBTYCnBxBACAHIARqIgQ2AqgcIAQgBUEBcjYCBCAHIABqQSg2AgRBAEEAKAL4HzYCrBwMBAsgBCAHTw0CIAQgBUkNAiAAKAIMQQhxDQIgACAIIAJqNgIEQQAgBEF4IARrQQdxIgBqIgU2AqgcQQBBACgCnBwgAmoiByAAayIANgKcHCAFIABBAXI2AgQgBCAHakEoNgIEQQBBACgC+B82AqwcDAMLQQAhAAwGC0EAIQAMBAsCQCAHQQAoAqAcTw0AQQAgBzYCoBwLIAcgAmohBUHQHyEAAkACQANAIAAoAgAiCCAFRg0BIAAoAggiAA0ADAILAAsgAC0ADEEIcUUNAwtB0B8hAAJAA0ACQCAEIAAoAgAiBUkNACAEIAUgACgCBGoiBUkNAgsgACgCCCEADAALAAtBACACQVhqIgBBeCAHa0EHcSIIayILNgKcHEEAIAcgCGoiCDYCqBwgCCALQQFyNgIEIAcgAGpBKDYCBEEAQQAoAvgfNgKsHCAEIAVBJyAFa0EHcWpBUWoiACAAIARBEGpJGyIIQRs2AgQgCEEQakEAKQLYHzcCACAIQQApAtAfNwIIQQAgCEEIajYC2B9BACACNgLUH0EAIAc2AtAfQQBBADYC3B8gCEEYaiEAA0AgAEEHNgIEIABBCGohByAAQQRqIQAgByAFSQ0ACyAIIARGDQAgCCAIKAIEQX5xNgIEIAQgCCAEayIHQQFyNgIEIAggBzYCAAJAAkAgB0H/AUsNACAHQXhxQbgcaiEAAkACQEEAKAKQHCIFQQEgB0EDdnQiB3ENAEEAIAUgB3I2ApAcIAAhBQwBCyAAKAIIIQULIAAgBDYCCCAFIAQ2AgxBDCEHQQghCAwBC0EfIQACQCAHQf///wdLDQAgB0EmIAdBCHZnIgBrdkEBcSAAQQF0a0E+aiEACyAEIAA2AhwgBEIANwIQIABBAnRBwB5qIQUCQAJAAkBBACgClBwiCEEBIAB0IgJxDQBBACAIIAJyNgKUHCAFIAQ2AgAgBCAFNgIYDAELIAdBAEEZIABBAXZrIABBH0YbdCEAIAUoAgAhCANAIAgiBSgCBEF4cSAHRg0CIABBHXYhCCAAQQF0IQAgBSAIQQRxaiICKAIQIggNAAsgAkEQaiAENgIAIAQgBTYCGAtBCCEHQQwhCCAEIQUgBCEADAELIAUoAggiACAENgIMIAUgBDYCCCAEIAA2AghBACEAQRghB0EMIQgLIAQgCGogBTYCACAEIAdqIAA2AgALQQAoApwcIgAgA00NAEEAIAAgA2siBDYCnBxBAEEAKAKoHCIAIANqIgU2AqgcIAUgBEEBcjYCBCAAIANBA3I2AgQgAEEIaiEADAQLECBBMDYCAEEAIQAMAwsgACAHNgIAIAAgACgCBCACajYCBCAHIAggAxAiIQAMAgsCQCALRQ0AAkACQCAIIAgoAhwiB0ECdEHAHmoiBSgCAEcNACAFIAA2AgAgAA0BQQAgCkF+IAd3cSIKNgKUHAwCCwJAAkAgCygCECAIRw0AIAsgADYCEAwBCyALIAA2AhQLIABFDQELIAAgCzYCGAJAIAgoAhAiBUUNACAAIAU2AhAgBSAANgIYCyAIKAIUIgVFDQAgACAFNgIUIAUgADYCGAsCQAJAIARBD0sNACAIIAQgA2oiAEEDcjYCBCAIIABqIgAgACgCBEEBcjYCBAwBCyAIIANBA3I2AgQgCCADaiIHIARBAXI2AgQgByAEaiAENgIAAkAgBEH/AUsNACAEQXhxQbgcaiEAAkACQEEAKAKQHCIDQQEgBEEDdnQiBHENAEEAIAMgBHI2ApAcIAAhBAwBCyAAKAIIIQQLIAAgBzYCCCAEIAc2AgwgByAANgIMIAcgBDYCCAwBC0EfIQACQCAEQf///wdLDQAgBEEmIARBCHZnIgBrdkEBcSAAQQF0a0E+aiEACyAHIAA2AhwgB0IANwIQIABBAnRBwB5qIQMCQAJAAkAgCkEBIAB0IgVxDQBBACAKIAVyNgKUHCADIAc2AgAgByADNgIYDAELIARBAEEZIABBAXZrIABBH0YbdCEAIAMoAgAhBQNAIAUiAygCBEF4cSAERg0CIABBHXYhBSAAQQF0IQAgAyAFQQRxaiICKAIQIgUNAAsgAkEQaiAHNgIAIAcgAzYCGAsgByAHNgIMIAcgBzYCCAwBCyADKAIIIgAgBzYCDCADIAc2AgggB0EANgIYIAcgAzYCDCAHIAA2AggLIAhBCGohAAwBCwJAIApFDQACQAJAIAcgBygCHCIIQQJ0QcAeaiIFKAIARw0AIAUgADYCACAADQFBACAJQX4gCHdxNgKUHAwCCwJAAkAgCigCECAHRw0AIAogADYCEAwBCyAKIAA2AhQLIABFDQELIAAgCjYCGAJAIAcoAhAiBUUNACAAIAU2AhAgBSAANgIYCyAHKAIUIgVFDQAgACAFNgIUIAUgADYCGAsCQAJAIARBD0sNACAHIAQgA2oiAEEDcjYCBCAHIABqIgAgACgCBEEBcjYCBAwBCyAHIANBA3I2AgQgByADaiIDIARBAXI2AgQgAyAEaiAENgIAAkAgBkUNACAGQXhxQbgcaiEFQQAoAqQcIQACQAJAQQEgBkEDdnQiCCACcQ0AQQAgCCACcjYCkBwgBSEIDAELIAUoAgghCAsgBSAANgIIIAggADYCDCAAIAU2AgwgACAINgIIC0EAIAM2AqQcQQAgBDYCmBwLIAdBCGohAAsgAUEQaiQAIAAL4wcBB38gAEF4IABrQQdxaiIDIAJBA3I2AgQgAUF4IAFrQQdxaiIEIAMgAmoiBWshAAJAAkAgBEEAKAKoHEcNAEEAIAU2AqgcQQBBACgCnBwgAGoiAjYCnBwgBSACQQFyNgIEDAELAkAgBEEAKAKkHEcNAEEAIAU2AqQcQQBBACgCmBwgAGoiAjYCmBwgBSACQQFyNgIEIAUgAmogAjYCAAwBCwJAIAQoAgQiAUEDcUEBRw0AIAFBeHEhBiAEKAIMIQICQAJAIAFB/wFLDQACQCACIAQoAggiB0cNAEEAQQAoApAcQX4gAUEDdndxNgKQHAwCCyAHIAI2AgwgAiAHNgIIDAELIAQoAhghCAJAAkAgAiAERg0AIAQoAggiASACNgIMIAIgATYCCAwBCwJAAkACQCAEKAIUIgFFDQAgBEEUaiEHDAELIAQoAhAiAUUNASAEQRBqIQcLA0AgByEJIAEiAkEUaiEHIAIoAhQiAQ0AIAJBEGohByACKAIQIgENAAsgCUEANgIADAELQQAhAgsgCEUNAAJAAkAgBCAEKAIcIgdBAnRBwB5qIgEoAgBHDQAgASACNgIAIAINAUEAQQAoApQcQX4gB3dxNgKUHAwCCwJAAkAgCCgCECAERw0AIAggAjYCEAwBCyAIIAI2AhQLIAJFDQELIAIgCDYCGAJAIAQoAhAiAUUNACACIAE2AhAgASACNgIYCyAEKAIUIgFFDQAgAiABNgIUIAEgAjYCGAsgBiAAaiEAIAQgBmoiBCgCBCEBCyAEIAFBfnE2AgQgBSAAQQFyNgIEIAUgAGogADYCAAJAIABB/wFLDQAgAEF4cUG4HGohAgJAAkBBACgCkBwiAUEBIABBA3Z0IgBxDQBBACABIAByNgKQHCACIQAMAQsgAigCCCEACyACIAU2AgggACAFNgIMIAUgAjYCDCAFIAA2AggMAQtBHyECAkAgAEH///8HSw0AIABBJiAAQQh2ZyICa3ZBAXEgAkEBdGtBPmohAgsgBSACNgIcIAVCADcCECACQQJ0QcAeaiEBAkACQAJAQQAoApQcIgdBASACdCIEcQ0AQQAgByAEcjYClBwgASAFNgIAIAUgATYCGAwBCyAAQQBBGSACQQF2ayACQR9GG3QhAiABKAIAIQcDQCAHIgEoAgRBeHEgAEYNAiACQR12IQcgAkEBdCECIAEgB0EEcWoiBCgCECIHDQALIARBEGogBTYCACAFIAE2AhgLIAUgBTYCDCAFIAU2AggMAQsgASgCCCICIAU2AgwgASAFNgIIIAVBADYCGCAFIAE2AgwgBSACNgIICyADQQhqC54MAQh/AkAgAEUNACAAQXhqIgEgAEF8aigCACICQXhxIgBqIQMCQCACQQFxDQAgAkECcUUNASABIAEoAgAiBGsiAUEAKAKgHEkNASAEIABqIQACQAJAAkACQCABQQAoAqQcRg0AIAEoAgwhAgJAIARB/wFLDQAgAiABKAIIIgVHDQJBAEEAKAKQHEF+IARBA3Z3cTYCkBwMBQsgASgCGCEGAkAgAiABRg0AIAEoAggiBCACNgIMIAIgBDYCCAwECwJAAkAgASgCFCIERQ0AIAFBFGohBQwBCyABKAIQIgRFDQMgAUEQaiEFCwNAIAUhByAEIgJBFGohBSACKAIUIgQNACACQRBqIQUgAigCECIEDQALIAdBADYCAAwDCyADKAIEIgJBA3FBA0cNA0EAIAA2ApgcIAMgAkF+cTYCBCABIABBAXI2AgQgAyAANgIADwsgBSACNgIMIAIgBTYCCAwCC0EAIQILIAZFDQACQAJAIAEgASgCHCIFQQJ0QcAeaiIEKAIARw0AIAQgAjYCACACDQFBAEEAKAKUHEF+IAV3cTYClBwMAgsCQAJAIAYoAhAgAUcNACAGIAI2AhAMAQsgBiACNgIUCyACRQ0BCyACIAY2AhgCQCABKAIQIgRFDQAgAiAENgIQIAQgAjYCGAsgASgCFCIERQ0AIAIgBDYCFCAEIAI2AhgLIAEgA08NACADKAIEIgRBAXFFDQACQAJAAkACQAJAIARBAnENAAJAIANBACgCqBxHDQBBACABNgKoHEEAQQAoApwcIABqIgA2ApwcIAEgAEEBcjYCBCABQQAoAqQcRw0GQQBBADYCmBxBAEEANgKkHA8LAkAgA0EAKAKkHCIGRw0AQQAgATYCpBxBAEEAKAKYHCAAaiIANgKYHCABIABBAXI2AgQgASAAaiAANgIADwsgBEF4cSAAaiEAIAMoAgwhAgJAIARB/wFLDQACQCACIAMoAggiBUcNAEEAQQAoApAcQX4gBEEDdndxNgKQHAwFCyAFIAI2AgwgAiAFNgIIDAQLIAMoAhghCAJAIAIgA0YNACADKAIIIgQgAjYCDCACIAQ2AggMAwsCQAJAIAMoAhQiBEUNACADQRRqIQUMAQsgAygCECIERQ0CIANBEGohBQsDQCAFIQcgBCICQRRqIQUgAigCFCIEDQAgAkEQaiEFIAIoAhAiBA0ACyAHQQA2AgAMAgsgAyAEQX5xNgIEIAEgAEEBcjYCBCABIABqIAA2AgAMAwtBACECCyAIRQ0AAkACQCADIAMoAhwiBUECdEHAHmoiBCgCAEcNACAEIAI2AgAgAg0BQQBBACgClBxBfiAFd3E2ApQcDAILAkACQCAIKAIQIANHDQAgCCACNgIQDAELIAggAjYCFAsgAkUNAQsgAiAINgIYAkAgAygCECIERQ0AIAIgBDYCECAEIAI2AhgLIAMoAhQiBEUNACACIAQ2AhQgBCACNgIYCyABIABBAXI2AgQgASAAaiAANgIAIAEgBkcNAEEAIAA2ApgcDwsCQCAAQf8BSw0AIABBeHFBuBxqIQICQAJAQQAoApAcIgRBASAAQQN2dCIAcQ0AQQAgBCAAcjYCkBwgAiEADAELIAIoAgghAAsgAiABNgIIIAAgATYCDCABIAI2AgwgASAANgIIDwtBHyECAkAgAEH///8HSw0AIABBJiAAQQh2ZyICa3ZBAXEgAkEBdGtBPmohAgsgASACNgIcIAFCADcCECACQQJ0QcAeaiEFAkACQAJAAkBBACgClBwiBEEBIAJ0IgNxDQBBACAEIANyNgKUHCAFIAE2AgBBCCEAQRghAgwBCyAAQQBBGSACQQF2ayACQR9GG3QhAiAFKAIAIQUDQCAFIgQoAgRBeHEgAEYNAiACQR12IQUgAkEBdCECIAQgBUEEcWoiAygCECIFDQALIANBEGogATYCAEEIIQBBGCECIAQhBQsgASEEIAEhAwwBCyAEKAIIIgUgATYCDCAEIAE2AghBACEDQRghAEEIIQILIAEgAmogBTYCACABIAQ2AgwgASAAaiADNgIAQQBBACgCsBxBf2oiAUF/IAEbNgKwHAsLBwA/AEEQdAtPAQJ/QQAoAvQbIgEgAEEHakF4cSICaiEAAkACQAJAIAJFDQAgACABTQ0BCyAAECRNDQEgABAMDQELECBBMDYCAEF/DwtBACAANgL0GyABCxEAAkAgABAnIgANABAoCyAACy8BAn8gAEEBIABBAUsbIQECQANAIAEQISICDQEQLiIARQ0BIAARAwAMAAsACyACCwUAECwACwYAIAAQIwsGACAAECkLBQAQDQALBQAQKwALBwAgACgCAAsHAEGAIBAtC1kBAn8gAS0AACECAkAgAC0AACIDRQ0AIAMgAkH/AXFHDQADQCABLQABIQIgAC0AASIDRQ0BIAFBAWohASAAQQFqIQAgAyACQf8BcUYNAAsLIAMgAkH/AXFrCwYAIAAQTQsCAAsCAAsKACAAEDBBCBAqCwoAIAAQMEEIECoLCgAgABAwQQwQKgsKACAAEDBBEBAqCwoAIAAgAUEAEDgLLQACQCACDQAgACgCBCABKAIERg8LAkAgACABRw0AQQEPCyAAEDkgARA5EC9FCwcAIAAoAgQLrwEBAn8jAEHAAGsiAyQAQQEhBAJAIAAgAUEAEDgNAEEAIQQgAUUNAEEAIQQgAUH8FUGsFkEAEDsiAUUNACADQQhqQQBBOBAdGiADQQE6ADsgA0F/NgIQIAMgADYCDCADIAE2AgQgA0EBNgI0IAEgA0EEaiACKAIAQQEgASgCACgCHBECAAJAIAMoAhwiBEEBRw0AIAIgAygCFDYCAAsgBEEBRiEECyADQcAAaiQAIAQLdQEEfyMAQRBrIgQkACAEQQRqIAAQPCAEKAIIIgUgAkEAEDghBiAEKAIEIQcCQAJAIAZFDQAgACAHIAEgAiAEKAIMIAMQPSEGDAELIAAgByACIAUgAxA+IgYNACAAIAcgASACIAUgAxA/IQYLIARBEGokACAGCy8BAn8gACABKAIAIgJBeGooAgAiAzYCCCAAIAEgA2o2AgAgACACQXxqKAIANgIEC8MBAQJ/IwBBwABrIgYkAEEAIQcCQAJAIAVBAEgNACABQQAgBEEAIAVrRhshBwwBCyAFQX5GDQAgBkEcaiIHQgA3AgAgBkEkakIANwIAIAZBLGpCADcCACAGQgA3AhQgBiAFNgIQIAYgAjYCDCAGIAA2AgggBiADNgIEIAZBADYCPCAGQoGAgICAgICAATcCNCADIAZBBGogASABQQFBACADKAIAKAIUEQUAIAFBACAHKAIAQQFGGyEHCyAGQcAAaiQAIAcLsQEBAn8jAEHAAGsiBSQAQQAhBgJAIARBAEgNACAAIARrIgAgAUgNACAFQRxqIgZCADcCACAFQSRqQgA3AgAgBUEsakIANwIAIAVCADcCFCAFIAQ2AhAgBSACNgIMIAUgAzYCBCAFQQA2AjwgBUKBgICAgICAgAE3AjQgBSAANgIIIAMgBUEEaiABIAFBAUEAIAMoAgAoAhQRBQAgAEEAIAYoAgAbIQYLIAVBwABqJAAgBgvWAQEBfyMAQcAAayIGJAAgBiAFNgIQIAYgAjYCDCAGIAA2AgggBiADNgIEQQAhBSAGQRRqQQBBJxAdGiAGQQA2AjwgBkEBOgA7IAQgBkEEaiABQQFBACAEKAIAKAIYEQYAAkACQAJAIAYoAigOAgABAgsgBigCGEEAIAYoAiRBAUYbQQAgBigCIEEBRhtBACAGKAIsQQFGGyEFDAELAkAgBigCHEEBRg0AIAYoAiwNASAGKAIgQQFHDQEgBigCJEEBRw0BCyAGKAIUIQULIAZBwABqJAAgBQt3AQF/AkAgASgCJCIEDQAgASADNgIYIAEgAjYCECABQQE2AiQgASABKAI4NgIUDwsCQAJAIAEoAhQgASgCOEcNACABKAIQIAJHDQAgASgCGEECRw0BIAEgAzYCGA8LIAFBAToANiABQQI2AhggASAEQQFqNgIkCwsdAAJAIAAgASgCCEEAEDhFDQAgASABIAIgAxBACws2AAJAIAAgASgCCEEAEDhFDQAgASABIAIgAxBADwsgACgCCCIAIAEgAiADIAAoAgAoAhwRAgALSwECf0EBIQMCQAJAIAAtAAhBGHENAEEAIQMgAUUNASABQfwVQdwWQQAQOyIERQ0BIAQtAAhBGHFBAEchAwsgACABIAMQOCEDCyADC5EEAQR/IwBBwABrIgMkAAJAAkAgAUGIGUEAEDhFDQAgAkEANgIAQQEhBAwBCwJAIAAgASABEENFDQBBASEEIAIoAgAiAUUNASACIAEoAgA2AgAMAQsCQCABRQ0AQQAhBCABQfwVQYwXQQAQOyIBRQ0BAkAgAigCACIFRQ0AIAIgBSgCADYCAAsgASgCCCIFIAAoAggiBkF/c3FBB3ENASAFQX9zIAZxQeAAcQ0BQQEhBCAAKAIMIAEoAgxBABA4DQECQCAAKAIMQfwYQQAQOEUNACABKAIMIgFFDQIgAUH8FUG8F0EAEDtFIQQMAgsgACgCDCIFRQ0AQQAhBAJAIAVB/BVBjBdBABA7IgZFDQAgAC0ACEEBcUUNAiAGIAEoAgwQRSEEDAILQQAhBAJAIAVB/BVB8BdBABA7IgZFDQAgAC0ACEEBcUUNAiAGIAEoAgwQRiEEDAILQQAhBCAFQfwVQawWQQAQOyIARQ0BIAEoAgwiAUUNAUEAIQQgAUH8FUGsFkEAEDsiAUUNASACKAIAIQQgA0EIakEAQTgQHRogAyAEQQBHOgA7IANBfzYCECADIAA2AgwgAyABNgIEIANBATYCNCABIANBBGogBEEBIAEoAgAoAhwRAgACQCADKAIcIgFBAUcNACACIAMoAhRBACAEGzYCAAsgAUEBRiEEDAELQQAhBAsgA0HAAGokACAEC6QBAQJ/AkADQAJAIAENAEEADwtBACECIAFB/BVBjBdBABA7IgFFDQEgASgCCCAAKAIIQX9zcQ0BAkAgACgCDCABKAIMQQAQOEUNAEEBDwsgAC0ACEEBcUUNASAAKAIMIgNFDQECQCADQfwVQYwXQQAQOyIARQ0AIAEoAgwhAQwBCwtBACECIANB/BVB8BdBABA7IgBFDQAgACABKAIMEEYhAgsgAgtYAQF/QQAhAgJAIAFFDQAgAUH8FUHwF0EAEDsiAUUNACABKAIIIAAoAghBf3NxDQBBACECIAAoAgwgASgCDEEAEDhFDQAgACgCECABKAIQQQAQOCECCyACC58BACABQQE6ADUCQCADIAEoAgRHDQAgAUEBOgA0AkACQCABKAIQIgMNACABQQE2AiQgASAENgIYIAEgAjYCECAEQQFHDQIgASgCMEEBRg0BDAILAkAgAyACRw0AAkAgASgCGCIDQQJHDQAgASAENgIYIAQhAwsgASgCMEEBRw0CIANBAUYNAQwCCyABIAEoAiRBAWo2AiQLIAFBAToANgsLIAACQCACIAEoAgRHDQAgASgCHEEBRg0AIAEgAzYCHAsLgQIAAkAgACABKAIIIAQQOEUNACABIAEgAiADEEgPCwJAAkAgACABKAIAIAQQOEUNAAJAAkAgAiABKAIQRg0AIAIgASgCFEcNAQsgA0EBRw0CIAFBATYCIA8LIAEgAzYCIAJAIAEoAixBBEYNACABQQA7ATQgACgCCCIAIAEgAiACQQEgBCAAKAIAKAIUEQUAAkAgAS0ANUEBRw0AIAFBAzYCLCABLQA0RQ0BDAMLIAFBBDYCLAsgASACNgIUIAEgASgCKEEBajYCKCABKAIkQQFHDQEgASgCGEECRw0BIAFBAToANg8LIAAoAggiACABIAIgAyAEIAAoAgAoAhgRBgALC5gBAAJAIAAgASgCCCAEEDhFDQAgASABIAIgAxBIDwsCQCAAIAEoAgAgBBA4RQ0AAkACQCACIAEoAhBGDQAgAiABKAIURw0BCyADQQFHDQEgAUEBNgIgDwsgASACNgIUIAEgAzYCICABIAEoAihBAWo2AigCQCABKAIkQQFHDQAgASgCGEECRw0AIAFBAToANgsgAUEENgIsCws8AAJAIAAgASgCCCAFEDhFDQAgASABIAIgAyAEEEcPCyAAKAIIIgAgASACIAMgBCAFIAAoAgAoAhQRBQALHwACQCAAIAEoAgggBRA4RQ0AIAEgASACIAMgBBBHCwsEACAACwYAIAAkAQsEACMBCwYAIAAkAAsSAQJ/IwAgAGtBcHEiASQAIAELBAAjAAscACAAIAEgAiADpyADQiCIpyAEpyAEQiCIpxAOCwuDFAIAQYAIC/ETdW5zaWduZWQgc2hvcnQAdW5zaWduZWQgaW50AGZsb2F0AHVpbnQ2NF90AHByb2Nlc3MAdW5zaWduZWQgY2hhcgBib29sAFNpbXBsZUtlcm5lbAB1bnNpZ25lZCBsb25nAHN0ZDo6d3N0cmluZwBzdGQ6OnN0cmluZwBzdGQ6OnUxNnN0cmluZwBzdGQ6OnUzMnN0cmluZwBkb3VibGUAdm9pZABlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxzaG9ydD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgc2hvcnQ+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgaW50PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxmbG9hdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDhfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50OF90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1aW50MTZfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50MTZfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDY0X3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludDY0X3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVpbnQzMl90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxpbnQzMl90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxjaGFyPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1bnNpZ25lZCBjaGFyPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxzaWduZWQgY2hhcj4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8bG9uZz4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgbG9uZz4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8ZG91YmxlPgAAAEQNAAAwBwAATlN0M19fMjEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRUUAAEQNAAB4BwAATlN0M19fMjEyYmFzaWNfc3RyaW5nSXdOU18xMWNoYXJfdHJhaXRzSXdFRU5TXzlhbGxvY2F0b3JJd0VFRUUAAEQNAADABwAATlN0M19fMjEyYmFzaWNfc3RyaW5nSURzTlNfMTFjaGFyX3RyYWl0c0lEc0VFTlNfOWFsbG9jYXRvcklEc0VFRUUAAABEDQAADAgAAE5TdDNfXzIxMmJhc2ljX3N0cmluZ0lEaU5TXzExY2hhcl90cmFpdHNJRGlFRU5TXzlhbGxvY2F0b3JJRGlFRUVFAAAARA0AAFgIAABOMTBlbXNjcmlwdGVuM3ZhbEUAAEQNAAB0CAAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJY0VFAABEDQAAnAgAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWFFRQAARA0AAMQIAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0loRUUAAEQNAADsCAAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJc0VFAABEDQAAFAkAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SXRFRQAARA0AADwJAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lpRUUAAEQNAABkCQAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJakVFAABEDQAAjAkAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWxFRQAARA0AALQJAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0ltRUUAAEQNAADcCQAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJeEVFAABEDQAABAoAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SXlFRQAARA0AACwKAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lmRUUAAEQNAABUCgAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJZEVFAABEDQAAfAoAADEyU2ltcGxlS2VybmVsAADIDQAAnAoAAAAAAAB0CgAAUDEyU2ltcGxlS2VybmVsAMgNAAC8CgAAAQAAAHQKAABQSzEyU2ltcGxlS2VybmVsAHBwAHYAdnAAAAAAjAoAAAAAAAB8DAAAjAoAAAANAAAADQAA6AwAAHZwcHBwaQAAbA0AAAgLAADcDQAATjEwX19jeHhhYml2MTE2X19zaGltX3R5cGVfaW5mb0UAAAAAbA0AADgLAAD8CgAATjEwX19jeHhhYml2MTE3X19jbGFzc190eXBlX2luZm9FAAAAbA0AAGgLAAD8CgAATjEwX19jeHhhYml2MTE3X19wYmFzZV90eXBlX2luZm9FAAAAbA0AAJgLAABcCwAATjEwX19jeHhhYml2MTE5X19wb2ludGVyX3R5cGVfaW5mb0UAbA0AAMgLAAD8CgAATjEwX19jeHhhYml2MTIwX19mdW5jdGlvbl90eXBlX2luZm9FAAAAAGwNAAD8CwAAXAsAAE4xMF9fY3h4YWJpdjEyOV9fcG9pbnRlcl90b19tZW1iZXJfdHlwZV9pbmZvRQAAAAAAAABIDAAACQAAAAoAAAALAAAADAAAAA0AAABsDQAAVAwAAPwKAABOMTBfX2N4eGFiaXYxMjNfX2Z1bmRhbWVudGFsX3R5cGVfaW5mb0UANAwAAIQMAAB2AAAANAwAAJAMAABEbgAANAwAAJwMAABiAAAANAwAAKgMAABjAAAANAwAALQMAABoAAAANAwAAMAMAABhAAAANAwAAMwMAABzAAAANAwAANgMAAB0AAAANAwAAOQMAABpAAAANAwAAPAMAABqAAAANAwAAPwMAABsAAAANAwAAAgNAABtAAAANAwAABQNAAB4AAAANAwAACANAAB5AAAANAwAACwNAABmAAAANAwAADgNAABkAAAAAAAAACwLAAAJAAAADgAAAAsAAAAMAAAADwAAABAAAAARAAAAEgAAAAAAAACMDQAACQAAABMAAAALAAAADAAAAA8AAAAUAAAAFQAAABYAAABsDQAAmA0AACwLAABOMTBfX2N4eGFiaXYxMjBfX3NpX2NsYXNzX3R5cGVfaW5mb0UAAAAAAAAAAIwLAAAJAAAAFwAAAAsAAAAMAAAAGAAAAEQNAADkDQAAU3Q5dHlwZV9pbmZvAABB9BsLBBAQAQAASQ90YXJnZXRfZmVhdHVyZXMEKw9tdXRhYmxlLWdsb2JhbHMrCHNpZ24tZXh0Kw9yZWZlcmVuY2UtdHlwZXMrCm11bHRpdmFsdWU='; + return f; +} + +var wasmBinaryFile; + +function getBinarySync(file) { + if (file == wasmBinaryFile && wasmBinary) { + return new Uint8Array(wasmBinary); + } + var binary = tryParseAsDataURI(file); + if (binary) { + return binary; + } + if (readBinary) { + return readBinary(file); + } + throw 'sync fetching of the wasm failed: you can preload it to Module["wasmBinary"] manually, or emcc.py will do that for you when generating HTML (but not JS)'; +} + +async function getWasmBinary(binaryFile) { + + // Otherwise, getBinarySync should be able to get it synchronously + return getBinarySync(binaryFile); +} + +function instantiateSync(file, info) { + var module; + var binary = getBinarySync(file); + module = new WebAssembly.Module(binary); + var instance = new WebAssembly.Instance(module, info); + return [instance, module]; +} + +function getWasmImports() { + // prepare imports + return { + 'env': wasmImports, + 'wasi_snapshot_preview1': wasmImports, + } +} + +// Create the wasm instance. +// Receives the wasm imports, returns the exports. + function createWasm() { + // Load the wasm module and create an instance of using native support in the JS engine. + // handle a generated wasm instance, receiving its exports and + // performing other necessary setup + /** @param {WebAssembly.Module=} module*/ + function receiveInstance(instance, module) { + wasmExports = instance.exports; + + + + wasmMemory = wasmExports['memory']; + + updateMemoryViews(); + + wasmTable = wasmExports['__indirect_function_table']; + + + addOnInit(wasmExports['__wasm_call_ctors']); + + removeRunDependency('wasm-instantiate'); + return wasmExports; + } + // wait for the pthread pool (if any) + addRunDependency('wasm-instantiate'); + + // Prefer streaming instantiation if available. + + var info = getWasmImports(); + + // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback + // to manually instantiate the Wasm module themselves. This allows pages to + // run the instantiation parallel to any other async startup actions they are + // performing. + // Also pthreads and wasm workers initialize the wasm instance through this + // path. + if (Module['instantiateWasm']) { + try { + return Module['instantiateWasm'](info, receiveInstance); + } catch(e) { + err(`Module.instantiateWasm callback failed with error: ${e}`); + // If instantiation fails, reject the module ready promise. + readyPromiseReject(e); + } + } + + wasmBinaryFile ??= findWasmBinary(); + + var result = instantiateSync(wasmBinaryFile, info); + // 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. + // When the regression is fixed, we can remove this if/else. + return receiveInstance(result[0]); +} + +// Globals used by JS i64 conversions (see makeSetValue) +var tempDouble; +var tempI64; + +// include: runtime_debug.js +// end include: runtime_debug.js +// === Body === +// end include: preamble.js + + + class ExitStatus { + name = 'ExitStatus'; + constructor(status) { + this.message = `Program terminated with exit(${status})`; + this.status = status; + } + } + + var callRuntimeCallbacks = (callbacks) => { + while (callbacks.length > 0) { + // Pass the module as the first argument. + callbacks.shift()(Module); + } + }; + + + /** + * @param {number} ptr + * @param {string} type + */ + function getValue(ptr, type = 'i8') { + if (type.endsWith('*')) type = '*'; + switch (type) { + case 'i1': return HEAP8[ptr]; + case 'i8': return HEAP8[ptr]; + case 'i16': return HEAP16[((ptr)>>1)]; + case 'i32': return HEAP32[((ptr)>>2)]; + case 'i64': abort('to do getValue(i64) use WASM_BIGINT'); + case 'float': return HEAPF32[((ptr)>>2)]; + case 'double': return HEAPF64[((ptr)>>3)]; + case '*': return HEAPU32[((ptr)>>2)]; + default: abort(`invalid type for getValue: ${type}`); + } + } + + var noExitRuntime = Module['noExitRuntime'] || true; + + + /** + * @param {number} ptr + * @param {number} value + * @param {string} type + */ + function setValue(ptr, value, type = 'i8') { + if (type.endsWith('*')) type = '*'; + switch (type) { + case 'i1': HEAP8[ptr] = value; break; + case 'i8': HEAP8[ptr] = value; break; + case 'i16': HEAP16[((ptr)>>1)] = value; break; + case 'i32': HEAP32[((ptr)>>2)] = value; break; + case 'i64': abort('to do setValue(i64) use WASM_BIGINT'); + case 'float': HEAPF32[((ptr)>>2)] = value; break; + case 'double': HEAPF64[((ptr)>>3)] = value; break; + case '*': HEAPU32[((ptr)>>2)] = value; break; + default: abort(`invalid type for setValue: ${type}`); + } + } + + var stackRestore = (val) => __emscripten_stack_restore(val); + + var stackSave = () => _emscripten_stack_get_current(); + + var __abort_js = () => + abort(''); + + var __embind_register_bigint = (primitiveType, name, size, minRange, maxRange) => {}; + + var embind_init_charCodes = () => { + var codes = new Array(256); + for (var i = 0; i < 256; ++i) { + codes[i] = String.fromCharCode(i); + } + embind_charCodes = codes; + }; + var embind_charCodes; + var readLatin1String = (ptr) => { + var ret = ""; + var c = ptr; + while (HEAPU8[c]) { + ret += embind_charCodes[HEAPU8[c++]]; + } + return ret; + }; + + var awaitingDependencies = { + }; + + var registeredTypes = { + }; + + var typeDependencies = { + }; + + var BindingError; + var throwBindingError = (message) => { throw new BindingError(message); }; + + + + + var InternalError; + var throwInternalError = (message) => { throw new InternalError(message); }; + var whenDependentTypesAreResolved = (myTypes, dependentTypes, getTypeConverters) => { + myTypes.forEach((type) => typeDependencies[type] = dependentTypes); + + function onComplete(typeConverters) { + var myTypeConverters = getTypeConverters(typeConverters); + if (myTypeConverters.length !== myTypes.length) { + throwInternalError('Mismatched type converter count'); + } + for (var i = 0; i < myTypes.length; ++i) { + registerType(myTypes[i], myTypeConverters[i]); + } + } + + var typeConverters = new Array(dependentTypes.length); + var unregisteredTypes = []; + var registered = 0; + dependentTypes.forEach((dt, i) => { + if (registeredTypes.hasOwnProperty(dt)) { + typeConverters[i] = registeredTypes[dt]; + } else { + unregisteredTypes.push(dt); + if (!awaitingDependencies.hasOwnProperty(dt)) { + awaitingDependencies[dt] = []; + } + awaitingDependencies[dt].push(() => { + typeConverters[i] = registeredTypes[dt]; + ++registered; + if (registered === unregisteredTypes.length) { + onComplete(typeConverters); + } + }); + } + }); + if (0 === unregisteredTypes.length) { + onComplete(typeConverters); + } + }; + /** @param {Object=} options */ + function sharedRegisterType(rawType, registeredInstance, options = {}) { + var name = registeredInstance.name; + if (!rawType) { + throwBindingError(`type "${name}" must have a positive integer typeid pointer`); + } + if (registeredTypes.hasOwnProperty(rawType)) { + if (options.ignoreDuplicateRegistrations) { + return; + } else { + throwBindingError(`Cannot register type '${name}' twice`); + } + } + + registeredTypes[rawType] = registeredInstance; + delete typeDependencies[rawType]; + + if (awaitingDependencies.hasOwnProperty(rawType)) { + var callbacks = awaitingDependencies[rawType]; + delete awaitingDependencies[rawType]; + callbacks.forEach((cb) => cb()); + } + } + /** @param {Object=} options */ + function registerType(rawType, registeredInstance, options = {}) { + return sharedRegisterType(rawType, registeredInstance, options); + } + + var GenericWireTypeSize = 8; + /** @suppress {globalThis} */ + var __embind_register_bool = (rawType, name, trueValue, falseValue) => { + name = readLatin1String(name); + registerType(rawType, { + name, + 'fromWireType': function(wt) { + // ambiguous emscripten ABI: sometimes return values are + // true or false, and sometimes integers (0 or 1) + return !!wt; + }, + 'toWireType': function(destructors, o) { + return o ? trueValue : falseValue; + }, + argPackAdvance: GenericWireTypeSize, + 'readValueFromPointer': function(pointer) { + return this['fromWireType'](HEAPU8[pointer]); + }, + destructorFunction: null, // This type does not need a destructor + }); + }; + + + + var shallowCopyInternalPointer = (o) => { + return { + count: o.count, + deleteScheduled: o.deleteScheduled, + preservePointerOnDelete: o.preservePointerOnDelete, + ptr: o.ptr, + ptrType: o.ptrType, + smartPtr: o.smartPtr, + smartPtrType: o.smartPtrType, + }; + }; + + var throwInstanceAlreadyDeleted = (obj) => { + function getInstanceTypeName(handle) { + return handle.$$.ptrType.registeredClass.name; + } + throwBindingError(getInstanceTypeName(obj) + ' instance already deleted'); + }; + + var finalizationRegistry = false; + + var detachFinalizer = (handle) => {}; + + var runDestructor = ($$) => { + if ($$.smartPtr) { + $$.smartPtrType.rawDestructor($$.smartPtr); + } else { + $$.ptrType.registeredClass.rawDestructor($$.ptr); + } + }; + var releaseClassHandle = ($$) => { + $$.count.value -= 1; + var toDelete = 0 === $$.count.value; + if (toDelete) { + runDestructor($$); + } + }; + + var downcastPointer = (ptr, ptrClass, desiredClass) => { + if (ptrClass === desiredClass) { + return ptr; + } + if (undefined === desiredClass.baseClass) { + return null; // no conversion + } + + var rv = downcastPointer(ptr, ptrClass, desiredClass.baseClass); + if (rv === null) { + return null; + } + return desiredClass.downcast(rv); + }; + + var registeredPointers = { + }; + + var registeredInstances = { + }; + + var getBasestPointer = (class_, ptr) => { + if (ptr === undefined) { + throwBindingError('ptr should not be undefined'); + } + while (class_.baseClass) { + ptr = class_.upcast(ptr); + class_ = class_.baseClass; + } + return ptr; + }; + var getInheritedInstance = (class_, ptr) => { + ptr = getBasestPointer(class_, ptr); + return registeredInstances[ptr]; + }; + + + var makeClassHandle = (prototype, record) => { + if (!record.ptrType || !record.ptr) { + throwInternalError('makeClassHandle requires ptr and ptrType'); + } + var hasSmartPtrType = !!record.smartPtrType; + var hasSmartPtr = !!record.smartPtr; + if (hasSmartPtrType !== hasSmartPtr) { + throwInternalError('Both smartPtrType and smartPtr must be specified'); + } + record.count = { value: 1 }; + return attachFinalizer(Object.create(prototype, { + $$: { + value: record, + writable: true, + }, + })); + }; + /** @suppress {globalThis} */ + function RegisteredPointer_fromWireType(ptr) { + // ptr is a raw pointer (or a raw smartpointer) + + // rawPointer is a maybe-null raw pointer + var rawPointer = this.getPointee(ptr); + if (!rawPointer) { + this.destructor(ptr); + return null; + } + + var registeredInstance = getInheritedInstance(this.registeredClass, rawPointer); + if (undefined !== registeredInstance) { + // JS object has been neutered, time to repopulate it + if (0 === registeredInstance.$$.count.value) { + registeredInstance.$$.ptr = rawPointer; + registeredInstance.$$.smartPtr = ptr; + return registeredInstance['clone'](); + } else { + // else, just increment reference count on existing object + // it already has a reference to the smart pointer + var rv = registeredInstance['clone'](); + this.destructor(ptr); + return rv; + } + } + + function makeDefaultHandle() { + if (this.isSmartPointer) { + return makeClassHandle(this.registeredClass.instancePrototype, { + ptrType: this.pointeeType, + ptr: rawPointer, + smartPtrType: this, + smartPtr: ptr, + }); + } else { + return makeClassHandle(this.registeredClass.instancePrototype, { + ptrType: this, + ptr, + }); + } + } + + var actualType = this.registeredClass.getActualType(rawPointer); + var registeredPointerRecord = registeredPointers[actualType]; + if (!registeredPointerRecord) { + return makeDefaultHandle.call(this); + } + + var toType; + if (this.isConst) { + toType = registeredPointerRecord.constPointerType; + } else { + toType = registeredPointerRecord.pointerType; + } + var dp = downcastPointer( + rawPointer, + this.registeredClass, + toType.registeredClass); + if (dp === null) { + return makeDefaultHandle.call(this); + } + if (this.isSmartPointer) { + return makeClassHandle(toType.registeredClass.instancePrototype, { + ptrType: toType, + ptr: dp, + smartPtrType: this, + smartPtr: ptr, + }); + } else { + return makeClassHandle(toType.registeredClass.instancePrototype, { + ptrType: toType, + ptr: dp, + }); + } + } + var attachFinalizer = (handle) => { + if ('undefined' === typeof FinalizationRegistry) { + attachFinalizer = (handle) => handle; + return handle; + } + // If the running environment has a FinalizationRegistry (see + // https://github.com/tc39/proposal-weakrefs), then attach finalizers + // for class handles. We check for the presence of FinalizationRegistry + // at run-time, not build-time. + finalizationRegistry = new FinalizationRegistry((info) => { + releaseClassHandle(info.$$); + }); + attachFinalizer = (handle) => { + var $$ = handle.$$; + var hasSmartPtr = !!$$.smartPtr; + if (hasSmartPtr) { + // We should not call the destructor on raw pointers in case other code expects the pointee to live + var info = { $$: $$ }; + finalizationRegistry.register(handle, info, handle); + } + return handle; + }; + detachFinalizer = (handle) => finalizationRegistry.unregister(handle); + return attachFinalizer(handle); + }; + + + + + var deletionQueue = []; + var flushPendingDeletes = () => { + while (deletionQueue.length) { + var obj = deletionQueue.pop(); + obj.$$.deleteScheduled = false; + obj['delete'](); + } + }; + + var delayFunction; + var init_ClassHandle = () => { + Object.assign(ClassHandle.prototype, { + "isAliasOf"(other) { + if (!(this instanceof ClassHandle)) { + return false; + } + if (!(other instanceof ClassHandle)) { + return false; + } + + var leftClass = this.$$.ptrType.registeredClass; + var left = this.$$.ptr; + other.$$ = /** @type {Object} */ (other.$$); + var rightClass = other.$$.ptrType.registeredClass; + var right = other.$$.ptr; + + while (leftClass.baseClass) { + left = leftClass.upcast(left); + leftClass = leftClass.baseClass; + } + + while (rightClass.baseClass) { + right = rightClass.upcast(right); + rightClass = rightClass.baseClass; + } + + return leftClass === rightClass && left === right; + }, + + "clone"() { + if (!this.$$.ptr) { + throwInstanceAlreadyDeleted(this); + } + + if (this.$$.preservePointerOnDelete) { + this.$$.count.value += 1; + return this; + } else { + var clone = attachFinalizer(Object.create(Object.getPrototypeOf(this), { + $$: { + value: shallowCopyInternalPointer(this.$$), + } + })); + + clone.$$.count.value += 1; + clone.$$.deleteScheduled = false; + return clone; + } + }, + + "delete"() { + if (!this.$$.ptr) { + throwInstanceAlreadyDeleted(this); + } + + if (this.$$.deleteScheduled && !this.$$.preservePointerOnDelete) { + throwBindingError('Object already scheduled for deletion'); + } + + detachFinalizer(this); + releaseClassHandle(this.$$); + + if (!this.$$.preservePointerOnDelete) { + this.$$.smartPtr = undefined; + this.$$.ptr = undefined; + } + }, + + "isDeleted"() { + return !this.$$.ptr; + }, + + "deleteLater"() { + if (!this.$$.ptr) { + throwInstanceAlreadyDeleted(this); + } + if (this.$$.deleteScheduled && !this.$$.preservePointerOnDelete) { + throwBindingError('Object already scheduled for deletion'); + } + deletionQueue.push(this); + if (deletionQueue.length === 1 && delayFunction) { + delayFunction(flushPendingDeletes); + } + this.$$.deleteScheduled = true; + return this; + }, + }); + }; + /** @constructor */ + function ClassHandle() { + } + + var createNamedFunction = (name, body) => Object.defineProperty(body, 'name', { + value: name + }); + + + var ensureOverloadTable = (proto, methodName, humanName) => { + if (undefined === proto[methodName].overloadTable) { + var prevFunc = proto[methodName]; + // Inject an overload resolver function that routes to the appropriate overload based on the number of arguments. + proto[methodName] = function(...args) { + // TODO This check can be removed in -O3 level "unsafe" optimizations. + if (!proto[methodName].overloadTable.hasOwnProperty(args.length)) { + throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${args.length}) - expects one of (${proto[methodName].overloadTable})!`); + } + return proto[methodName].overloadTable[args.length].apply(this, args); + }; + // Move the previous function into the overload table. + proto[methodName].overloadTable = []; + proto[methodName].overloadTable[prevFunc.argCount] = prevFunc; + } + }; + + /** @param {number=} numArguments */ + var exposePublicSymbol = (name, value, numArguments) => { + if (Module.hasOwnProperty(name)) { + if (undefined === numArguments || (undefined !== Module[name].overloadTable && undefined !== Module[name].overloadTable[numArguments])) { + throwBindingError(`Cannot register public name '${name}' twice`); + } + + // We are exposing a function with the same name as an existing function. Create an overload table and a function selector + // that routes between the two. + ensureOverloadTable(Module, name, name); + if (Module[name].overloadTable.hasOwnProperty(numArguments)) { + throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`); + } + // Add the new function into the overload table. + Module[name].overloadTable[numArguments] = value; + } else { + Module[name] = value; + Module[name].argCount = numArguments; + } + }; + + var char_0 = 48; + + var char_9 = 57; + var makeLegalFunctionName = (name) => { + name = name.replace(/[^a-zA-Z0-9_]/g, '$'); + var f = name.charCodeAt(0); + if (f >= char_0 && f <= char_9) { + return `_${name}`; + } + return name; + }; + + + /** @constructor */ + function RegisteredClass(name, + constructor, + instancePrototype, + rawDestructor, + baseClass, + getActualType, + upcast, + downcast) { + this.name = name; + this.constructor = constructor; + this.instancePrototype = instancePrototype; + this.rawDestructor = rawDestructor; + this.baseClass = baseClass; + this.getActualType = getActualType; + this.upcast = upcast; + this.downcast = downcast; + this.pureVirtualFunctions = []; + } + + + var upcastPointer = (ptr, ptrClass, desiredClass) => { + while (ptrClass !== desiredClass) { + if (!ptrClass.upcast) { + throwBindingError(`Expected null or instance of ${desiredClass.name}, got an instance of ${ptrClass.name}`); + } + ptr = ptrClass.upcast(ptr); + ptrClass = ptrClass.baseClass; + } + return ptr; + }; + /** @suppress {globalThis} */ + function constNoSmartPtrRawPointerToWireType(destructors, handle) { + if (handle === null) { + if (this.isReference) { + throwBindingError(`null is not a valid ${this.name}`); + } + return 0; + } + + if (!handle.$$) { + throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`); + } + if (!handle.$$.ptr) { + throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`); + } + var handleClass = handle.$$.ptrType.registeredClass; + var ptr = upcastPointer(handle.$$.ptr, handleClass, this.registeredClass); + return ptr; + } + + + /** @suppress {globalThis} */ + function genericPointerToWireType(destructors, handle) { + var ptr; + if (handle === null) { + if (this.isReference) { + throwBindingError(`null is not a valid ${this.name}`); + } + + if (this.isSmartPointer) { + ptr = this.rawConstructor(); + if (destructors !== null) { + destructors.push(this.rawDestructor, ptr); + } + return ptr; + } else { + return 0; + } + } + + if (!handle || !handle.$$) { + throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`); + } + if (!handle.$$.ptr) { + throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`); + } + if (!this.isConst && handle.$$.ptrType.isConst) { + throwBindingError(`Cannot convert argument of type ${(handle.$$.smartPtrType ? handle.$$.smartPtrType.name : handle.$$.ptrType.name)} to parameter type ${this.name}`); + } + var handleClass = handle.$$.ptrType.registeredClass; + ptr = upcastPointer(handle.$$.ptr, handleClass, this.registeredClass); + + if (this.isSmartPointer) { + // TODO: this is not strictly true + // We could support BY_EMVAL conversions from raw pointers to smart pointers + // because the smart pointer can hold a reference to the handle + if (undefined === handle.$$.smartPtr) { + throwBindingError('Passing raw pointer to smart pointer is illegal'); + } + + switch (this.sharingPolicy) { + case 0: // NONE + // no upcasting + if (handle.$$.smartPtrType === this) { + ptr = handle.$$.smartPtr; + } else { + throwBindingError(`Cannot convert argument of type ${(handle.$$.smartPtrType ? handle.$$.smartPtrType.name : handle.$$.ptrType.name)} to parameter type ${this.name}`); + } + break; + + case 1: // INTRUSIVE + ptr = handle.$$.smartPtr; + break; + + case 2: // BY_EMVAL + if (handle.$$.smartPtrType === this) { + ptr = handle.$$.smartPtr; + } else { + var clonedHandle = handle['clone'](); + ptr = this.rawShare( + ptr, + Emval.toHandle(() => clonedHandle['delete']()) + ); + if (destructors !== null) { + destructors.push(this.rawDestructor, ptr); + } + } + break; + + default: + throwBindingError('Unsupporting sharing policy'); + } + } + return ptr; + } + + + /** @suppress {globalThis} */ + function nonConstNoSmartPtrRawPointerToWireType(destructors, handle) { + if (handle === null) { + if (this.isReference) { + throwBindingError(`null is not a valid ${this.name}`); + } + return 0; + } + + if (!handle.$$) { + throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`); + } + if (!handle.$$.ptr) { + throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`); + } + if (handle.$$.ptrType.isConst) { + throwBindingError(`Cannot convert argument of type ${handle.$$.ptrType.name} to parameter type ${this.name}`); + } + var handleClass = handle.$$.ptrType.registeredClass; + var ptr = upcastPointer(handle.$$.ptr, handleClass, this.registeredClass); + return ptr; + } + + + /** @suppress {globalThis} */ + function readPointer(pointer) { + return this['fromWireType'](HEAPU32[((pointer)>>2)]); + } + + + var init_RegisteredPointer = () => { + Object.assign(RegisteredPointer.prototype, { + getPointee(ptr) { + if (this.rawGetPointee) { + ptr = this.rawGetPointee(ptr); + } + return ptr; + }, + destructor(ptr) { + this.rawDestructor?.(ptr); + }, + argPackAdvance: GenericWireTypeSize, + 'readValueFromPointer': readPointer, + 'fromWireType': RegisteredPointer_fromWireType, + }); + }; + /** @constructor + @param {*=} pointeeType, + @param {*=} sharingPolicy, + @param {*=} rawGetPointee, + @param {*=} rawConstructor, + @param {*=} rawShare, + @param {*=} rawDestructor, + */ + function RegisteredPointer( + name, + registeredClass, + isReference, + isConst, + + // smart pointer properties + isSmartPointer, + pointeeType, + sharingPolicy, + rawGetPointee, + rawConstructor, + rawShare, + rawDestructor + ) { + this.name = name; + this.registeredClass = registeredClass; + this.isReference = isReference; + this.isConst = isConst; + + // smart pointer properties + this.isSmartPointer = isSmartPointer; + this.pointeeType = pointeeType; + this.sharingPolicy = sharingPolicy; + this.rawGetPointee = rawGetPointee; + this.rawConstructor = rawConstructor; + this.rawShare = rawShare; + this.rawDestructor = rawDestructor; + + if (!isSmartPointer && registeredClass.baseClass === undefined) { + if (isConst) { + this['toWireType'] = constNoSmartPtrRawPointerToWireType; + this.destructorFunction = null; + } else { + this['toWireType'] = nonConstNoSmartPtrRawPointerToWireType; + this.destructorFunction = null; + } + } else { + this['toWireType'] = genericPointerToWireType; + // Here we must leave this.destructorFunction undefined, since whether genericPointerToWireType returns + // a pointer that needs to be freed up is runtime-dependent, and cannot be evaluated at registration time. + // TODO: Create an alternative mechanism that allows removing the use of var destructors = []; array in + // craftInvokerFunction altogether. + } + } + + /** @param {number=} numArguments */ + var replacePublicSymbol = (name, value, numArguments) => { + if (!Module.hasOwnProperty(name)) { + throwInternalError('Replacing nonexistent public symbol'); + } + // If there's an overload table for this symbol, replace the symbol in the overload table instead. + if (undefined !== Module[name].overloadTable && undefined !== numArguments) { + Module[name].overloadTable[numArguments] = value; + } else { + Module[name] = value; + Module[name].argCount = numArguments; + } + }; + + + + var dynCallLegacy = (sig, ptr, args) => { + sig = sig.replace(/p/g, 'i') + var f = Module['dynCall_' + sig]; + return f(ptr, ...args); + }; + + var wasmTableMirror = []; + + /** @type {WebAssembly.Table} */ + var wasmTable; + var getWasmTableEntry = (funcPtr) => { + var func = wasmTableMirror[funcPtr]; + if (!func) { + if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1; + /** @suppress {checkTypes} */ + wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr); + } + return func; + }; + + var dynCall = (sig, ptr, args = []) => { + // Without WASM_BIGINT support we cannot directly call function with i64 as + // part of their signature, so we rely on the dynCall functions generated by + // wasm-emscripten-finalize + if (sig.includes('j')) { + return dynCallLegacy(sig, ptr, args); + } + var rtn = getWasmTableEntry(ptr)(...args); + return rtn; + }; + var getDynCaller = (sig, ptr) => { + return (...args) => dynCall(sig, ptr, args); + }; + + + var embind__requireFunction = (signature, rawFunction) => { + signature = readLatin1String(signature); + + function makeDynCaller() { + if (signature.includes('j')) { + return getDynCaller(signature, rawFunction); + } + return getWasmTableEntry(rawFunction); + } + + var fp = makeDynCaller(); + if (typeof fp != "function") { + throwBindingError(`unknown function pointer with signature ${signature}: ${rawFunction}`); + } + return fp; + }; + + + + var extendError = (baseErrorType, errorName) => { + var errorClass = createNamedFunction(errorName, function(message) { + this.name = errorName; + this.message = message; + + var stack = (new Error(message)).stack; + if (stack !== undefined) { + this.stack = this.toString() + '\n' + + stack.replace(/^Error(:[^\n]*)?\n/, ''); + } + }); + errorClass.prototype = Object.create(baseErrorType.prototype); + errorClass.prototype.constructor = errorClass; + errorClass.prototype.toString = function() { + if (this.message === undefined) { + return this.name; + } else { + return `${this.name}: ${this.message}`; + } + }; + + return errorClass; + }; + var UnboundTypeError; + + + + var getTypeName = (type) => { + var ptr = ___getTypeName(type); + var rv = readLatin1String(ptr); + _free(ptr); + return rv; + }; + var throwUnboundTypeError = (message, types) => { + var unboundTypes = []; + var seen = {}; + function visit(type) { + if (seen[type]) { + return; + } + if (registeredTypes[type]) { + return; + } + if (typeDependencies[type]) { + typeDependencies[type].forEach(visit); + return; + } + unboundTypes.push(type); + seen[type] = true; + } + types.forEach(visit); + + throw new UnboundTypeError(`${message}: ` + unboundTypes.map(getTypeName).join([', '])); + }; + + var __embind_register_class = (rawType, + rawPointerType, + rawConstPointerType, + baseClassRawType, + getActualTypeSignature, + getActualType, + upcastSignature, + upcast, + downcastSignature, + downcast, + name, + destructorSignature, + rawDestructor) => { + name = readLatin1String(name); + getActualType = embind__requireFunction(getActualTypeSignature, getActualType); + upcast &&= embind__requireFunction(upcastSignature, upcast); + downcast &&= embind__requireFunction(downcastSignature, downcast); + rawDestructor = embind__requireFunction(destructorSignature, rawDestructor); + var legalFunctionName = makeLegalFunctionName(name); + + exposePublicSymbol(legalFunctionName, function() { + // this code cannot run if baseClassRawType is zero + throwUnboundTypeError(`Cannot construct ${name} due to unbound types`, [baseClassRawType]); + }); + + whenDependentTypesAreResolved( + [rawType, rawPointerType, rawConstPointerType], + baseClassRawType ? [baseClassRawType] : [], + (base) => { + base = base[0]; + + var baseClass; + var basePrototype; + if (baseClassRawType) { + baseClass = base.registeredClass; + basePrototype = baseClass.instancePrototype; + } else { + basePrototype = ClassHandle.prototype; + } + + var constructor = createNamedFunction(name, function(...args) { + if (Object.getPrototypeOf(this) !== instancePrototype) { + throw new BindingError("Use 'new' to construct " + name); + } + if (undefined === registeredClass.constructor_body) { + throw new BindingError(name + " has no accessible constructor"); + } + var body = registeredClass.constructor_body[args.length]; + if (undefined === body) { + throw new BindingError(`Tried to invoke ctor of ${name} with invalid number of parameters (${args.length}) - expected (${Object.keys(registeredClass.constructor_body).toString()}) parameters instead!`); + } + return body.apply(this, args); + }); + + var instancePrototype = Object.create(basePrototype, { + constructor: { value: constructor }, + }); + + constructor.prototype = instancePrototype; + + var registeredClass = new RegisteredClass(name, + constructor, + instancePrototype, + rawDestructor, + baseClass, + getActualType, + upcast, + downcast); + + if (registeredClass.baseClass) { + // Keep track of class hierarchy. Used to allow sub-classes to inherit class functions. + registeredClass.baseClass.__derivedClasses ??= []; + + registeredClass.baseClass.__derivedClasses.push(registeredClass); + } + + var referenceConverter = new RegisteredPointer(name, + registeredClass, + true, + false, + false); + + var pointerConverter = new RegisteredPointer(name + '*', + registeredClass, + false, + false, + false); + + var constPointerConverter = new RegisteredPointer(name + ' const*', + registeredClass, + false, + true, + false); + + registeredPointers[rawType] = { + pointerType: pointerConverter, + constPointerType: constPointerConverter + }; + + replacePublicSymbol(legalFunctionName, constructor); + + return [referenceConverter, pointerConverter, constPointerConverter]; + } + ); + }; + + var heap32VectorToArray = (count, firstElement) => { + var array = []; + for (var i = 0; i < count; i++) { + // TODO(https://github.com/emscripten-core/emscripten/issues/17310): + // Find a way to hoist the `>> 2` or `>> 3` out of this loop. + array.push(HEAPU32[(((firstElement)+(i * 4))>>2)]); + } + return array; + }; + + + var runDestructors = (destructors) => { + while (destructors.length) { + var ptr = destructors.pop(); + var del = destructors.pop(); + del(ptr); + } + }; + + + + + + + + function usesDestructorStack(argTypes) { + // Skip return value at index 0 - it's not deleted here. + for (var i = 1; i < argTypes.length; ++i) { + // The type does not define a destructor function - must use dynamic stack + if (argTypes[i] !== null && argTypes[i].destructorFunction === undefined) { + return true; + } + } + return false; + } + + function newFunc(constructor, argumentList) { + if (!(constructor instanceof Function)) { + throw new TypeError(`new_ called with constructor type ${typeof(constructor)} which is not a function`); + } + /* + * Previously, the following line was just: + * function dummy() {}; + * Unfortunately, Chrome was preserving 'dummy' as the object's name, even + * though at creation, the 'dummy' has the correct constructor name. Thus, + * objects created with IMVU.new would show up in the debugger as 'dummy', + * which isn't very helpful. Using IMVU.createNamedFunction addresses the + * issue. Doubly-unfortunately, there's no way to write a test for this + * behavior. -NRD 2013.02.22 + */ + var dummy = createNamedFunction(constructor.name || 'unknownFunctionName', function(){}); + dummy.prototype = constructor.prototype; + var obj = new dummy; + + var r = constructor.apply(obj, argumentList); + return (r instanceof Object) ? r : obj; + } + + function createJsInvoker(argTypes, isClassMethodFunc, returns, isAsync) { + var needsDestructorStack = usesDestructorStack(argTypes); + var argCount = argTypes.length - 2; + var argsList = []; + var argsListWired = ['fn']; + if (isClassMethodFunc) { + argsListWired.push('thisWired'); + } + for (var i = 0; i < argCount; ++i) { + argsList.push(`arg${i}`) + argsListWired.push(`arg${i}Wired`) + } + argsList = argsList.join(',') + argsListWired = argsListWired.join(',') + + var invokerFnBody = `return function (${argsList}) {\n`; + + if (needsDestructorStack) { + invokerFnBody += "var destructors = [];\n"; + } + + var dtorStack = needsDestructorStack ? "destructors" : "null"; + var args1 = ["humanName", "throwBindingError", "invoker", "fn", "runDestructors", "retType", "classParam"]; + + if (isClassMethodFunc) { + invokerFnBody += `var thisWired = classParam['toWireType'](${dtorStack}, this);\n`; + } + + for (var i = 0; i < argCount; ++i) { + invokerFnBody += `var arg${i}Wired = argType${i}['toWireType'](${dtorStack}, arg${i});\n`; + args1.push(`argType${i}`); + } + + invokerFnBody += (returns || isAsync ? "var rv = ":"") + `invoker(${argsListWired});\n`; + + var returnVal = returns ? "rv" : ""; + + if (needsDestructorStack) { + invokerFnBody += "runDestructors(destructors);\n"; + } else { + for (var i = isClassMethodFunc?1:2; i < argTypes.length; ++i) { // Skip return value at index 0 - it's not deleted here. Also skip class type if not a method. + var paramName = (i === 1 ? "thisWired" : ("arg"+(i - 2)+"Wired")); + if (argTypes[i].destructorFunction !== null) { + invokerFnBody += `${paramName}_dtor(${paramName});\n`; + args1.push(`${paramName}_dtor`); + } + } + } + + if (returns) { + invokerFnBody += "var ret = retType['fromWireType'](rv);\n" + + "return ret;\n"; + } else { + } + + invokerFnBody += "}\n"; + + return [args1, invokerFnBody]; + } + function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cppTargetFunc, /** boolean= */ isAsync) { + // humanName: a human-readable string name for the function to be generated. + // argTypes: An array that contains the embind type objects for all types in the function signature. + // argTypes[0] is the type object for the function return value. + // argTypes[1] is the type object for function this object/class type, or null if not crafting an invoker for a class method. + // argTypes[2...] are the actual function parameters. + // classType: The embind type object for the class to be bound, or null if this is not a method of a class. + // cppInvokerFunc: JS Function object to the C++-side function that interops into C++ code. + // cppTargetFunc: Function pointer (an integer to FUNCTION_TABLE) to the target C++ function the cppInvokerFunc will end up calling. + // isAsync: Optional. If true, returns an async function. Async bindings are only supported with JSPI. + var argCount = argTypes.length; + + if (argCount < 2) { + throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!"); + } + + var isClassMethodFunc = (argTypes[1] !== null && classType !== null); + + // Free functions with signature "void function()" do not need an invoker that marshalls between wire types. + // TODO: This omits argument count check - enable only at -O3 or similar. + // if (ENABLE_UNSAFE_OPTS && argCount == 2 && argTypes[0].name == "void" && !isClassMethodFunc) { + // return FUNCTION_TABLE[fn]; + // } + + // Determine if we need to use a dynamic stack to store the destructors for the function parameters. + // TODO: Remove this completely once all function invokers are being dynamically generated. + var needsDestructorStack = usesDestructorStack(argTypes); + + var returns = (argTypes[0].name !== "void"); + + var expectedArgCount = argCount - 2; + // Builld the arguments that will be passed into the closure around the invoker + // function. + var closureArgs = [humanName, throwBindingError, cppInvokerFunc, cppTargetFunc, runDestructors, argTypes[0], argTypes[1]]; + for (var i = 0; i < argCount - 2; ++i) { + closureArgs.push(argTypes[i+2]); + } + if (!needsDestructorStack) { + for (var i = isClassMethodFunc?1:2; i < argTypes.length; ++i) { // Skip return value at index 0 - it's not deleted here. Also skip class type if not a method. + if (argTypes[i].destructorFunction !== null) { + closureArgs.push(argTypes[i].destructorFunction); + } + } + } + + let [args, invokerFnBody] = createJsInvoker(argTypes, isClassMethodFunc, returns, isAsync); + args.push(invokerFnBody); + var invokerFn = newFunc(Function, args)(...closureArgs); + return createNamedFunction(humanName, invokerFn); + } + var __embind_register_class_constructor = ( + rawClassType, + argCount, + rawArgTypesAddr, + invokerSignature, + invoker, + rawConstructor + ) => { + var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); + invoker = embind__requireFunction(invokerSignature, invoker); + var args = [rawConstructor]; + var destructors = []; + + whenDependentTypesAreResolved([], [rawClassType], (classType) => { + classType = classType[0]; + var humanName = `constructor ${classType.name}`; + + if (undefined === classType.registeredClass.constructor_body) { + classType.registeredClass.constructor_body = []; + } + if (undefined !== classType.registeredClass.constructor_body[argCount - 1]) { + throw new BindingError(`Cannot register multiple constructors with identical number of parameters (${argCount-1}) for class '${classType.name}'! Overload resolution is currently only performed using the parameter count, not actual type info!`); + } + classType.registeredClass.constructor_body[argCount - 1] = () => { + throwUnboundTypeError(`Cannot construct ${classType.name} due to unbound types`, rawArgTypes); + }; + + whenDependentTypesAreResolved([], rawArgTypes, (argTypes) => { + // Insert empty slot for context type (argTypes[1]). + argTypes.splice(1, 0, null); + classType.registeredClass.constructor_body[argCount - 1] = craftInvokerFunction(humanName, argTypes, null, invoker, rawConstructor); + return []; + }); + return []; + }); + }; + + + + + + + + var getFunctionName = (signature) => { + signature = signature.trim(); + const argsIndex = signature.indexOf("("); + if (argsIndex !== -1) { + return signature.substr(0, argsIndex); + } else { + return signature; + } + }; + var __embind_register_class_function = (rawClassType, + methodName, + argCount, + rawArgTypesAddr, // [ReturnType, ThisType, Args...] + invokerSignature, + rawInvoker, + context, + isPureVirtual, + isAsync, + isNonnullReturn) => { + var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); + methodName = readLatin1String(methodName); + methodName = getFunctionName(methodName); + rawInvoker = embind__requireFunction(invokerSignature, rawInvoker); + + whenDependentTypesAreResolved([], [rawClassType], (classType) => { + classType = classType[0]; + var humanName = `${classType.name}.${methodName}`; + + if (methodName.startsWith("@@")) { + methodName = Symbol[methodName.substring(2)]; + } + + if (isPureVirtual) { + classType.registeredClass.pureVirtualFunctions.push(methodName); + } + + function unboundTypesHandler() { + throwUnboundTypeError(`Cannot call ${humanName} due to unbound types`, rawArgTypes); + } + + var proto = classType.registeredClass.instancePrototype; + var method = proto[methodName]; + if (undefined === method || (undefined === method.overloadTable && method.className !== classType.name && method.argCount === argCount - 2)) { + // This is the first overload to be registered, OR we are replacing a + // function in the base class with a function in the derived class. + unboundTypesHandler.argCount = argCount - 2; + unboundTypesHandler.className = classType.name; + proto[methodName] = unboundTypesHandler; + } else { + // There was an existing function with the same name registered. Set up + // a function overload routing table. + ensureOverloadTable(proto, methodName, humanName); + proto[methodName].overloadTable[argCount - 2] = unboundTypesHandler; + } + + whenDependentTypesAreResolved([], rawArgTypes, (argTypes) => { + var memberFunction = craftInvokerFunction(humanName, argTypes, classType, rawInvoker, context, isAsync); + + // Replace the initial unbound-handler-stub function with the + // appropriate member function, now that all types are resolved. If + // multiple overloads are registered for this function, the function + // goes into an overload table. + if (undefined === proto[methodName].overloadTable) { + // Set argCount in case an overload is registered later + memberFunction.argCount = argCount - 2; + proto[methodName] = memberFunction; + } else { + proto[methodName].overloadTable[argCount - 2] = memberFunction; + } + + return []; + }); + return []; + }); + }; + + + var emval_freelist = []; + + var emval_handles = []; + var __emval_decref = (handle) => { + if (handle > 9 && 0 === --emval_handles[handle + 1]) { + emval_handles[handle] = undefined; + emval_freelist.push(handle); + } + }; + + + + + + var count_emval_handles = () => { + return emval_handles.length / 2 - 5 - emval_freelist.length; + }; + + var init_emval = () => { + // reserve 0 and some special values. These never get de-allocated. + emval_handles.push( + 0, 1, + undefined, 1, + null, 1, + true, 1, + false, 1, + ); + Module['count_emval_handles'] = count_emval_handles; + }; + var Emval = { + toValue:(handle) => { + if (!handle) { + throwBindingError('Cannot use deleted val. handle = ' + handle); + } + return emval_handles[handle]; + }, + toHandle:(value) => { + switch (value) { + case undefined: return 2; + case null: return 4; + case true: return 6; + case false: return 8; + default:{ + const handle = emval_freelist.pop() || emval_handles.length; + emval_handles[handle] = value; + emval_handles[handle + 1] = 1; + return handle; + } + } + }, + }; + + + var EmValType = { + name: 'emscripten::val', + 'fromWireType': (handle) => { + var rv = Emval.toValue(handle); + __emval_decref(handle); + return rv; + }, + 'toWireType': (destructors, value) => Emval.toHandle(value), + argPackAdvance: GenericWireTypeSize, + 'readValueFromPointer': readPointer, + destructorFunction: null, // This type does not need a destructor + + // TODO: do we need a deleteObject here? write a test where + // emval is passed into JS via an interface + }; + var __embind_register_emval = (rawType) => registerType(rawType, EmValType); + + var embindRepr = (v) => { + if (v === null) { + return 'null'; + } + var t = typeof v; + if (t === 'object' || t === 'array' || t === 'function') { + return v.toString(); + } else { + return '' + v; + } + }; + + var floatReadValueFromPointer = (name, width) => { + switch (width) { + case 4: return function(pointer) { + return this['fromWireType'](HEAPF32[((pointer)>>2)]); + }; + case 8: return function(pointer) { + return this['fromWireType'](HEAPF64[((pointer)>>3)]); + }; + default: + throw new TypeError(`invalid float width (${width}): ${name}`); + } + }; + + + var __embind_register_float = (rawType, name, size) => { + name = readLatin1String(name); + registerType(rawType, { + name, + 'fromWireType': (value) => value, + 'toWireType': (destructors, value) => { + // The VM will perform JS to Wasm value conversion, according to the spec: + // https://www.w3.org/TR/wasm-js-api-1/#towebassemblyvalue + return value; + }, + argPackAdvance: GenericWireTypeSize, + 'readValueFromPointer': floatReadValueFromPointer(name, size), + destructorFunction: null, // This type does not need a destructor + }); + }; + + + var integerReadValueFromPointer = (name, width, signed) => { + // integers are quite common, so generate very specialized functions + switch (width) { + case 1: return signed ? + (pointer) => HEAP8[pointer] : + (pointer) => HEAPU8[pointer]; + case 2: return signed ? + (pointer) => HEAP16[((pointer)>>1)] : + (pointer) => HEAPU16[((pointer)>>1)] + case 4: return signed ? + (pointer) => HEAP32[((pointer)>>2)] : + (pointer) => HEAPU32[((pointer)>>2)] + default: + throw new TypeError(`invalid integer width (${width}): ${name}`); + } + }; + + + /** @suppress {globalThis} */ + var __embind_register_integer = (primitiveType, name, size, minRange, maxRange) => { + name = readLatin1String(name); + // LLVM doesn't have signed and unsigned 32-bit types, so u32 literals come + // out as 'i32 -1'. Always treat those as max u32. + if (maxRange === -1) { + maxRange = 4294967295; + } + + var fromWireType = (value) => value; + + if (minRange === 0) { + var bitshift = 32 - 8*size; + fromWireType = (value) => (value << bitshift) >>> bitshift; + } + + var isUnsignedType = (name.includes('unsigned')); + var checkAssertions = (value, toTypeName) => { + } + var toWireType; + if (isUnsignedType) { + toWireType = function(destructors, value) { + checkAssertions(value, this.name); + return value >>> 0; + } + } else { + toWireType = function(destructors, value) { + checkAssertions(value, this.name); + // The VM will perform JS to Wasm value conversion, according to the spec: + // https://www.w3.org/TR/wasm-js-api-1/#towebassemblyvalue + return value; + } + } + registerType(primitiveType, { + name, + 'fromWireType': fromWireType, + 'toWireType': toWireType, + argPackAdvance: GenericWireTypeSize, + 'readValueFromPointer': integerReadValueFromPointer(name, size, minRange !== 0), + destructorFunction: null, // This type does not need a destructor + }); + }; + + + var __embind_register_memory_view = (rawType, dataTypeIndex, name) => { + var typeMapping = [ + Int8Array, + Uint8Array, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + Float32Array, + Float64Array, + ]; + + var TA = typeMapping[dataTypeIndex]; + + function decodeMemoryView(handle) { + var size = HEAPU32[((handle)>>2)]; + var data = HEAPU32[(((handle)+(4))>>2)]; + return new TA(HEAP8.buffer, data, size); + } + + name = readLatin1String(name); + registerType(rawType, { + name, + 'fromWireType': decodeMemoryView, + argPackAdvance: GenericWireTypeSize, + 'readValueFromPointer': decodeMemoryView, + }, { + ignoreDuplicateRegistrations: true, + }); + }; + + + + + + var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => { + // Parameter maxBytesToWrite is not optional. Negative values, 0, null, + // undefined and false each don't write out any bytes. + if (!(maxBytesToWrite > 0)) + return 0; + + var startIdx = outIdx; + var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator. + for (var i = 0; i < str.length; ++i) { + // 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. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + // 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/rfc3629 + var u = str.charCodeAt(i); // possibly a lead surrogate + if (u >= 0xD800 && u <= 0xDFFF) { + var u1 = str.charCodeAt(++i); + u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF); + } + if (u <= 0x7F) { + if (outIdx >= endIdx) break; + heap[outIdx++] = u; + } else if (u <= 0x7FF) { + if (outIdx + 1 >= endIdx) break; + heap[outIdx++] = 0xC0 | (u >> 6); + heap[outIdx++] = 0x80 | (u & 63); + } else if (u <= 0xFFFF) { + if (outIdx + 2 >= endIdx) break; + heap[outIdx++] = 0xE0 | (u >> 12); + heap[outIdx++] = 0x80 | ((u >> 6) & 63); + heap[outIdx++] = 0x80 | (u & 63); + } else { + if (outIdx + 3 >= endIdx) break; + heap[outIdx++] = 0xF0 | (u >> 18); + heap[outIdx++] = 0x80 | ((u >> 12) & 63); + heap[outIdx++] = 0x80 | ((u >> 6) & 63); + heap[outIdx++] = 0x80 | (u & 63); + } + } + // Null-terminate the pointer to the buffer. + heap[outIdx] = 0; + return outIdx - startIdx; + }; + var stringToUTF8 = (str, outPtr, maxBytesToWrite) => { + return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite); + }; + + var lengthBytesUTF8 = (str) => { + var len = 0; + for (var i = 0; i < str.length; ++i) { + // 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. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var c = str.charCodeAt(i); // possibly a lead surrogate + if (c <= 0x7F) { + len++; + } else if (c <= 0x7FF) { + len += 2; + } else if (c >= 0xD800 && c <= 0xDFFF) { + len += 4; ++i; + } else { + len += 3; + } + } + return len; + }; + + + + var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder() : undefined; + + /** + * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given + * array that contains uint8 values, returns a copy of that string as a + * Javascript String object. + * heapOrArray is either a regular array, or a JavaScript typed array view. + * @param {number=} idx + * @param {number=} maxBytesToRead + * @return {string} + */ + var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead = NaN) => { + var endIdx = idx + maxBytesToRead; + var endPtr = idx; + // TextDecoder needs to know the byte length in advance, it doesn't stop on + // null terminator by itself. Also, use the length info to avoid running tiny + // strings through TextDecoder, since .subarray() allocates garbage. + // (As a tiny code save trick, compare endPtr against endIdx using a negation, + // so that undefined/NaN means Infinity) + while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr; + + if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) { + return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr)); + } + var str = ''; + // If building with TextDecoder, we have already computed the string length + // above, so test loop end condition against that + while (idx < endPtr) { + // For UTF8 byte structure, see: + // http://en.wikipedia.org/wiki/UTF-8#Description + // https://www.ietf.org/rfc/rfc2279.txt + // https://tools.ietf.org/html/rfc3629 + var u0 = heapOrArray[idx++]; + if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; } + var u1 = heapOrArray[idx++] & 63; + if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; } + var u2 = heapOrArray[idx++] & 63; + if ((u0 & 0xF0) == 0xE0) { + u0 = ((u0 & 15) << 12) | (u1 << 6) | u2; + } else { + u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63); + } + + if (u0 < 0x10000) { + str += String.fromCharCode(u0); + } else { + var ch = u0 - 0x10000; + str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); + } + } + return str; + }; + + /** + * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the + * emscripten HEAP, returns a copy of that string as a Javascript String object. + * + * @param {number} ptr + * @param {number=} maxBytesToRead - An optional length that specifies the + * maximum number of bytes to read. You can omit this parameter to scan the + * string until the first 0 byte. If maxBytesToRead is passed, and the string + * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the + * string will cut short at that byte index (i.e. maxBytesToRead will not + * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing + * frequent uses of UTF8ToString() with and without maxBytesToRead may throw + * JS JIT optimizations off, so it is worth to consider consistently using one + * @return {string} + */ + var UTF8ToString = (ptr, maxBytesToRead) => { + return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ''; + }; + var __embind_register_std_string = (rawType, name) => { + name = readLatin1String(name); + var stdStringIsUTF8 + = true; + + registerType(rawType, { + name, + // For some method names we use string keys here since they are part of + // the public/external API and/or used by the runtime-generated code. + 'fromWireType'(value) { + var length = HEAPU32[((value)>>2)]; + var payload = value + 4; + + var str; + if (stdStringIsUTF8) { + var decodeStartPtr = payload; + // Looping here to support possible embedded '0' bytes + for (var i = 0; i <= length; ++i) { + var currentBytePtr = payload + i; + if (i == length || HEAPU8[currentBytePtr] == 0) { + var maxRead = currentBytePtr - decodeStartPtr; + var stringSegment = UTF8ToString(decodeStartPtr, maxRead); + if (str === undefined) { + str = stringSegment; + } else { + str += String.fromCharCode(0); + str += stringSegment; + } + decodeStartPtr = currentBytePtr + 1; + } + } + } else { + var a = new Array(length); + for (var i = 0; i < length; ++i) { + a[i] = String.fromCharCode(HEAPU8[payload + i]); + } + str = a.join(''); + } + + _free(value); + + return str; + }, + 'toWireType'(destructors, value) { + if (value instanceof ArrayBuffer) { + value = new Uint8Array(value); + } + + var length; + var valueIsOfTypeString = (typeof value == 'string'); + + if (!(valueIsOfTypeString || value instanceof Uint8Array || value instanceof Uint8ClampedArray || value instanceof Int8Array)) { + throwBindingError('Cannot pass non-string to std::string'); + } + if (stdStringIsUTF8 && valueIsOfTypeString) { + length = lengthBytesUTF8(value); + } else { + length = value.length; + } + + // assumes POINTER_SIZE alignment + var base = _malloc(4 + length + 1); + var ptr = base + 4; + HEAPU32[((base)>>2)] = length; + if (stdStringIsUTF8 && valueIsOfTypeString) { + stringToUTF8(value, ptr, length + 1); + } else { + if (valueIsOfTypeString) { + for (var i = 0; i < length; ++i) { + var charCode = value.charCodeAt(i); + if (charCode > 255) { + _free(ptr); + throwBindingError('String has UTF-16 code units that do not fit in 8 bits'); + } + HEAPU8[ptr + i] = charCode; + } + } else { + for (var i = 0; i < length; ++i) { + HEAPU8[ptr + i] = value[i]; + } + } + } + + if (destructors !== null) { + destructors.push(_free, base); + } + return base; + }, + argPackAdvance: GenericWireTypeSize, + 'readValueFromPointer': readPointer, + destructorFunction(ptr) { + _free(ptr); + }, + }); + }; + + + + + var UTF16Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf-16le') : undefined;; + var UTF16ToString = (ptr, maxBytesToRead) => { + var endPtr = ptr; + // TextDecoder needs to know the byte length in advance, it doesn't stop on + // null terminator by itself. + // Also, use the length info to avoid running tiny strings through + // TextDecoder, since .subarray() allocates garbage. + var idx = endPtr >> 1; + var maxIdx = idx + maxBytesToRead / 2; + // If maxBytesToRead is not passed explicitly, it will be undefined, and this + // will always evaluate to true. This saves on code size. + while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx; + endPtr = idx << 1; + + if (endPtr - ptr > 32 && UTF16Decoder) + return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr)); + + // Fallback: decode without UTF16Decoder + var str = ''; + + // If maxBytesToRead is not passed explicitly, it will be undefined, and the + // for-loop's condition will always evaluate to true. The loop is then + // terminated on the first null char. + for (var i = 0; !(i >= maxBytesToRead / 2); ++i) { + var codeUnit = HEAP16[(((ptr)+(i*2))>>1)]; + if (codeUnit == 0) break; + // fromCharCode constructs a character from a UTF-16 code unit, so we can + // pass the UTF16 string right through. + str += String.fromCharCode(codeUnit); + } + + return str; + }; + + var stringToUTF16 = (str, outPtr, maxBytesToWrite) => { + // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. + maxBytesToWrite ??= 0x7FFFFFFF; + if (maxBytesToWrite < 2) return 0; + maxBytesToWrite -= 2; // Null terminator. + var startPtr = outPtr; + var numCharsToWrite = (maxBytesToWrite < str.length*2) ? (maxBytesToWrite / 2) : str.length; + for (var i = 0; i < numCharsToWrite; ++i) { + // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP. + var codeUnit = str.charCodeAt(i); // possibly a lead surrogate + HEAP16[((outPtr)>>1)] = codeUnit; + outPtr += 2; + } + // Null-terminate the pointer to the HEAP. + HEAP16[((outPtr)>>1)] = 0; + return outPtr - startPtr; + }; + + var lengthBytesUTF16 = (str) => str.length*2; + + var UTF32ToString = (ptr, maxBytesToRead) => { + var i = 0; + + var str = ''; + // If maxBytesToRead is not passed explicitly, it will be undefined, and this + // will always evaluate to true. This saves on code size. + while (!(i >= maxBytesToRead / 4)) { + var utf32 = HEAP32[(((ptr)+(i*4))>>2)]; + if (utf32 == 0) break; + ++i; + // 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. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + if (utf32 >= 0x10000) { + var ch = utf32 - 0x10000; + str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); + } else { + str += String.fromCharCode(utf32); + } + } + return str; + }; + + var stringToUTF32 = (str, outPtr, maxBytesToWrite) => { + // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. + maxBytesToWrite ??= 0x7FFFFFFF; + if (maxBytesToWrite < 4) return 0; + var startPtr = outPtr; + var endPtr = startPtr + maxBytesToWrite - 4; + for (var i = 0; i < str.length; ++i) { + // 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. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var codeUnit = str.charCodeAt(i); // possibly a lead surrogate + if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) { + var trailSurrogate = str.charCodeAt(++i); + codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF); + } + HEAP32[((outPtr)>>2)] = codeUnit; + outPtr += 4; + if (outPtr + 4 > endPtr) break; + } + // Null-terminate the pointer to the HEAP. + HEAP32[((outPtr)>>2)] = 0; + return outPtr - startPtr; + }; + + var lengthBytesUTF32 = (str) => { + var len = 0; + for (var i = 0; i < str.length; ++i) { + // 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. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var codeUnit = str.charCodeAt(i); + if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) ++i; // possibly a lead surrogate, so skip over the tail surrogate. + len += 4; + } + + return len; + }; + var __embind_register_std_wstring = (rawType, charSize, name) => { + name = readLatin1String(name); + var decodeString, encodeString, readCharAt, lengthBytesUTF; + if (charSize === 2) { + decodeString = UTF16ToString; + encodeString = stringToUTF16; + lengthBytesUTF = lengthBytesUTF16; + readCharAt = (pointer) => HEAPU16[((pointer)>>1)]; + } else if (charSize === 4) { + decodeString = UTF32ToString; + encodeString = stringToUTF32; + lengthBytesUTF = lengthBytesUTF32; + readCharAt = (pointer) => HEAPU32[((pointer)>>2)]; + } + registerType(rawType, { + name, + 'fromWireType': (value) => { + // Code mostly taken from _embind_register_std_string fromWireType + var length = HEAPU32[((value)>>2)]; + var str; + + var decodeStartPtr = value + 4; + // Looping here to support possible embedded '0' bytes + for (var i = 0; i <= length; ++i) { + var currentBytePtr = value + 4 + i * charSize; + if (i == length || readCharAt(currentBytePtr) == 0) { + var maxReadBytes = currentBytePtr - decodeStartPtr; + var stringSegment = decodeString(decodeStartPtr, maxReadBytes); + if (str === undefined) { + str = stringSegment; + } else { + str += String.fromCharCode(0); + str += stringSegment; + } + decodeStartPtr = currentBytePtr + charSize; + } + } + + _free(value); + + return str; + }, + 'toWireType': (destructors, value) => { + if (!(typeof value == 'string')) { + throwBindingError(`Cannot pass non-string to C++ string type ${name}`); + } + + // assumes POINTER_SIZE alignment + var length = lengthBytesUTF(value); + var ptr = _malloc(4 + length + charSize); + HEAPU32[((ptr)>>2)] = length / charSize; + + encodeString(value, ptr + 4, length + charSize); + + if (destructors !== null) { + destructors.push(_free, ptr); + } + return ptr; + }, + argPackAdvance: GenericWireTypeSize, + 'readValueFromPointer': readPointer, + destructorFunction(ptr) { + _free(ptr); + } + }); + }; + + + var __embind_register_void = (rawType, name) => { + name = readLatin1String(name); + registerType(rawType, { + isVoid: true, // void return values can be optimized out sometimes + name, + argPackAdvance: 0, + 'fromWireType': () => undefined, + // TODO: assert if anything else is given? + 'toWireType': (destructors, o) => undefined, + }); + }; + + var __emscripten_memcpy_js = (dest, src, num) => HEAPU8.copyWithin(dest, src, src + num); + + var getHeapMax = () => + HEAPU8.length; + + var alignMemory = (size, alignment) => { + return Math.ceil(size / alignment) * alignment; + }; + + var abortOnCannotGrowMemory = (requestedSize) => { + abort('OOM'); + }; + var _emscripten_resize_heap = (requestedSize) => { + var oldSize = HEAPU8.length; + // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned. + requestedSize >>>= 0; + abortOnCannotGrowMemory(requestedSize); + }; +embind_init_charCodes(); +BindingError = Module['BindingError'] = class BindingError extends Error { constructor(message) { super(message); this.name = 'BindingError'; }}; +InternalError = Module['InternalError'] = class InternalError extends Error { constructor(message) { super(message); this.name = 'InternalError'; }}; +init_ClassHandle(); +init_RegisteredPointer(); +UnboundTypeError = Module['UnboundTypeError'] = extendError(Error, 'UnboundTypeError');; +init_emval();; +var wasmImports = { + /** @export */ + _abort_js: __abort_js, + /** @export */ + _embind_register_bigint: __embind_register_bigint, + /** @export */ + _embind_register_bool: __embind_register_bool, + /** @export */ + _embind_register_class: __embind_register_class, + /** @export */ + _embind_register_class_constructor: __embind_register_class_constructor, + /** @export */ + _embind_register_class_function: __embind_register_class_function, + /** @export */ + _embind_register_emval: __embind_register_emval, + /** @export */ + _embind_register_float: __embind_register_float, + /** @export */ + _embind_register_integer: __embind_register_integer, + /** @export */ + _embind_register_memory_view: __embind_register_memory_view, + /** @export */ + _embind_register_std_string: __embind_register_std_string, + /** @export */ + _embind_register_std_wstring: __embind_register_std_wstring, + /** @export */ + _embind_register_void: __embind_register_void, + /** @export */ + _emscripten_memcpy_js: __emscripten_memcpy_js, + /** @export */ + emscripten_resize_heap: _emscripten_resize_heap +}; +var wasmExports = createWasm(); +var ___wasm_call_ctors = wasmExports['__wasm_call_ctors'] +var ___getTypeName = wasmExports['__getTypeName'] +var _malloc = Module['_malloc'] = wasmExports['malloc'] +var _free = wasmExports['free'] +var __emscripten_stack_restore = wasmExports['_emscripten_stack_restore'] +var __emscripten_stack_alloc = wasmExports['_emscripten_stack_alloc'] +var _emscripten_stack_get_current = wasmExports['emscripten_stack_get_current'] + + +// include: postamble.js +// === Auto-generated postamble setup entry stuff === + + + + +var calledRun; + +dependenciesFulfilled = function runCaller() { + // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false) + if (!calledRun) run(); + if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled +}; + +function run() { + + if (runDependencies > 0) { + return; + } + + preRun(); + + // a preRun added a dependency, run will be called later + if (runDependencies > 0) { + return; + } + + function doRun() { + // run may have just been called through dependencies being fulfilled just in this very frame, + // or while the async setStatus time below was happening + if (calledRun) return; + calledRun = true; + Module['calledRun'] = true; + + if (ABORT) return; + + initRuntime(); + + readyPromiseResolve(Module); + Module['onRuntimeInitialized']?.(); + + postRun(); + } + + if (Module['setStatus']) { + Module['setStatus']('Running...'); + setTimeout(() => { + setTimeout(() => Module['setStatus'](''), 1); + doRun(); + }, 1); + } else + { + doRun(); + } +} + +if (Module['preInit']) { + if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']]; + while (Module['preInit'].length > 0) { + Module['preInit'].pop()(); + } +} + +run(); + +// end include: postamble.js + +// include: postamble_modularize.js +// In MODULARIZE mode we wrap the generated code in a factory function +// and return either the Module itself, or a promise of the module. +// +// We assign to the `moduleRtn` global here and configure closure to see +// this as and extern so it won't get minified. + +moduleRtn = Module; + +// end include: postamble_modularize.js + + + + return moduleRtn; +} +); +})(); +export default Module; diff --git a/examples/worklets/wasm-worklet-processor.mjs b/examples/worklets/wasm-worklet-processor.mjs new file mode 100644 index 0000000..76cfe05 --- /dev/null +++ b/examples/worklets/wasm-worklet-processor.mjs @@ -0,0 +1,76 @@ +// adapted from https://github.com/GoogleChromeLabs/web-audio-samples/tree/main/src/audio-worklet/design-pattern/wasm +// +// Copyright (c) 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Module from './simple-kernel.wasmmodule.mjs'; +import { RENDER_QUANTUM_FRAMES, MAX_CHANNEL_COUNT, FreeQueue } from './free-queue.mjs'; + +/** + * A simple demonstration of WASM-powered AudioWorkletProcessor. + * + * @class WASMWorkletProcessor + * @extends AudioWorkletProcessor + */ +class WASMWorkletProcessor extends AudioWorkletProcessor { + /** + * @constructor + */ + constructor() { + super(); + + const mod = Module(); + // Allocate the buffer for the heap access. Start with stereo, but it can + // be expanded up to 32 channels. + try { + this._heapInputBuffer = new FreeQueue( + mod, RENDER_QUANTUM_FRAMES, 2, MAX_CHANNEL_COUNT); + this._heapOutputBuffer = new FreeQueue( + mod, RENDER_QUANTUM_FRAMES, 2, MAX_CHANNEL_COUNT); + this._kernel = new mod.SimpleKernel(); + } catch (err) { + console.log(err.message); + } + } + + /** + * System-invoked process callback function. + * @param {Array} inputs Incoming audio stream. + * @param {Array} outputs Outgoing audio stream. + * @param {Object} parameters AudioParam data. + * @return {Boolean} Active source flag. + */ + process(inputs, outputs, parameters) { + // Use the 1st input and output only to make the example simpler. |input| + // and |output| here have the similar structure with the AudioBuffer + // interface. (i.e. An array of Float32Array) + const input = inputs[0]; + const output = outputs[0]; + + // For this given render quantum, the channel count of the node is fixed + // and identical for the input and the output. + const channelCount = input.length; + + // Prepare HeapAudioBuffer for the channel count change in the current + // render quantum. + this._heapInputBuffer.adaptChannel(channelCount); + this._heapOutputBuffer.adaptChannel(channelCount); + + // Copy-in, process and copy-out. + for (let channel = 0; channel < channelCount; ++channel) { + this._heapInputBuffer.getChannelData(channel).set(input[channel]); + } + this._kernel.process( + this._heapInputBuffer.getHeapAddress(), + this._heapOutputBuffer.getHeapAddress(), + channelCount); + for (let channel = 0; channel < channelCount; ++channel) { + output[channel].set(this._heapOutputBuffer.getChannelData(channel)); + } + + return true; + } +} + +registerProcessor('wasm-worklet-processor', WASMWorkletProcessor);