From 4710ea42dcbd6d44e4f00fdc17f4c9dbc4609b57 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Mon, 8 Jun 2020 11:33:37 +0200 Subject: [PATCH 01/48] initial stab at reworking the general flow of the README --- README.outline.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 README.outline.md diff --git a/README.outline.md b/README.outline.md new file mode 100644 index 0000000..cc99b9a --- /dev/null +++ b/README.outline.md @@ -0,0 +1,51 @@ +add Announcement, something like _Five ways to host your C++ program online_ + +1. Web service using Common Gateway Interface +1. Python web service using Swagger/OpenAPI +1. Python web application using Flask +1. JavaScript web service using Emscriptem and WebAssembly +1. JavaScript web application with React + +Consider adding a line that helps people decide which section to focus on. + +Introduce the example algorithm, as a CLI. +- delay introducing the interface if possible +- one file: algorithm and main +- Adapt to reading initial guess and tolerance from stdin, e.g. with argc and argv + +# Web service using Common Gateway Interface + +| Pros | Cons | +| --- | --- | +| :heart: pro1 | :no_entry: con1 | +| :heart: pro2 | :no_entry: con2 | + +- Explain that there is no longer a stdin, we need to change to JSON +- move JSON schema to swagger section +- JSON flavor of JSON schema can be removed (we still have the OpenAPI YAML) + +# Python web service + +- OpenApi, Swagger, JSON schema + +# Python web application + +- web app v web service difference +- explanation of what is a web framework + + +# JavaScript web service + +- OK to test with curl not browser? + +# JavaScript web application + + +--- + +- random tidbits: + - web framework + - long running tasks (concept, Python toolset, JavaScript toolset): consider splitting off into 1 or 2 separate documents; in the main document describe a what is basically a Promise and point to the relevant other document +- single page application +- Optional add pros and cons per section +- embedded github.io doesnt yield the same values as the CLI From aab0c4e6088cff291ebf9dd6ba5f8ffc5e465c90 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Mon, 8 Jun 2020 15:43:15 +0200 Subject: [PATCH 02/48] added outline for README --- README.outline.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.outline.md b/README.outline.md index cc99b9a..dba1b22 100644 --- a/README.outline.md +++ b/README.outline.md @@ -8,6 +8,8 @@ add Announcement, something like _Five ways to host your C++ program online_ Consider adding a line that helps people decide which section to focus on. +# Example algorithm + Introduce the example algorithm, as a CLI. - delay introducing the interface if possible - one file: algorithm and main @@ -20,8 +22,9 @@ Introduce the example algorithm, as a CLI. | :heart: pro1 | :no_entry: con1 | | :heart: pro2 | :no_entry: con2 | -- Explain that there is no longer a stdin, we need to change to JSON -- move JSON schema to swagger section +- Explain that there is no longer command line args, we need to change to JSON +- Explain what is JSON +- move JSON schema to swagger section or even to JavaScript form generation - JSON flavor of JSON schema can be removed (we still have the OpenAPI YAML) # Python web service From 67136cf5dcae8a9ba1614b0febdf4eaf22474405 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 12:58:24 +0200 Subject: [PATCH 03/48] moved files to new cli/ directory; updated references to it --- Makefile | 4 ++-- README.md | 10 +++++----- {src => cli}/algebra.hpp | 0 {src => cli}/cli-newtonraphson.cpp | 0 {src => cli}/newtonraphson.hpp | 0 5 files changed, 7 insertions(+), 7 deletions(-) rename {src => cli}/algebra.hpp (100%) rename {src => cli}/cli-newtonraphson.cpp (100%) rename {src => cli}/newtonraphson.hpp (100%) diff --git a/Makefile b/Makefile index ca6641e..2f5ac95 100644 --- a/Makefile +++ b/Makefile @@ -29,10 +29,10 @@ pip-connexion: pip install connexion[swagger-ui] bin/newtonraphson.exe: src/cli-newtonraphson.cpp - g++ src/cli-newtonraphson.cpp -o bin/newtonraphson.exe + g++ cli/cli-newtonraphson.cpp -o cli/newtonraphson.exe test-cli: bin/newtonraphson.exe - ./bin/newtonraphson.exe + ./cli/newtonraphson.exe apache2/cgi-bin/newtonraphson: src/cgi-newtonraphson.cpp g++ -Ideps src/cgi-newtonraphson.cpp -o apache2/cgi-bin/newtonraphson diff --git a/README.md b/README.md index 4305889..163b4d7 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Let's first define the mathematical equation, which we will be searching for its The equation and its derivative which we will use in this guide are $x^3 - x^2 + 2$ and $3x^2 - 2x$ respectively. -```{.hpp file=src/algebra.hpp} +```{.hpp file=cli/algebra.hpp} // this C++ code snippet is store as src/algebra.hpp namespace algebra @@ -62,7 +62,7 @@ double derivative(double x) Next, we define the interface (C++ class). -```{.cpp file=src/newtonraphson.hpp} +```{.cpp file=cli/newtonraphson.hpp} // this C++ snippet is stored as src/newtonraphson.hpp #ifndef H_NEWTONRAPHSON_H #define H_NEWTONRAPHSON_H @@ -119,7 +119,7 @@ double NewtonRaphson::solve(double xin) We are now ready to call the algorithm in a simple CLI program. It would look like -```{.cpp file=src/cli-newtonraphson.cpp} +```{.cpp file=cli/cli-newtonraphson.cpp} // this C++ snippet is stored as src/newtonraphson.cpp #include @@ -141,13 +141,13 @@ int main() Compile with ```{.awk #build-cli} -g++ src/cli-newtonraphson.cpp -o bin/newtonraphson.exe +g++ cli/cli-newtonraphson.cpp -o cli/newtonraphson.exe ``` Run with ```{.awk #test-cli} -./bin/newtonraphson.exe +./cli/newtonraphson.exe ``` Should output diff --git a/src/algebra.hpp b/cli/algebra.hpp similarity index 100% rename from src/algebra.hpp rename to cli/algebra.hpp diff --git a/src/cli-newtonraphson.cpp b/cli/cli-newtonraphson.cpp similarity index 100% rename from src/cli-newtonraphson.cpp rename to cli/cli-newtonraphson.cpp diff --git a/src/newtonraphson.hpp b/cli/newtonraphson.hpp similarity index 100% rename from src/newtonraphson.hpp rename to cli/newtonraphson.hpp From 0d2c606fea5ccaff44fe40d49d51dea46fff3ab9 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 13:08:17 +0200 Subject: [PATCH 04/48] updated Makefile/INSTALL --- INSTALL.md | 6 +++--- Makefile | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 8daf4a4..71ba7bc 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -22,7 +22,7 @@ All the commands in the [README.md](README.md) and [CONTRIBUTING.md](CONTRIBUTIN UID := $(shell id -u) # Prevent suicide by excluding Makefile ENTANGLED := $(shell perl -ne 'print $$1,"\n" if /^```\{.*file=(.*)\}/' *.md | grep -v Makefile | sort -u) -COMPILED := bin/newtonraphson.exe src/py/newtonraphsonpy.*.so apache2/cgi-bin/newtonraphson src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm +COMPILED := cli/newtonraphson.exe src/py/newtonraphsonpy.*.so apache2/cgi-bin/newtonraphson src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm entangle: *.md <> @@ -46,10 +46,10 @@ pip-celery: pip-connexion: <> -bin/newtonraphson.exe: src/cli-newtonraphson.cpp +cli/newtonraphson.exe: cli/cli-newtonraphson.cpp <> -test-cli: bin/newtonraphson.exe +test-cli: cli/newtonraphson.exe <> apache2/cgi-bin/newtonraphson: src/cgi-newtonraphson.cpp diff --git a/Makefile b/Makefile index 2f5ac95..cf970b5 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ UID := $(shell id -u) # Prevent suicide by excluding Makefile ENTANGLED := $(shell perl -ne 'print $$1,"\n" if /^```\{.*file=(.*)\}/' *.md | grep -v Makefile | sort -u) -COMPILED := bin/newtonraphson.exe src/py/newtonraphsonpy.*.so apache2/cgi-bin/newtonraphson src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm +COMPILED := cli/newtonraphson.exe src/py/newtonraphsonpy.*.so apache2/cgi-bin/newtonraphson src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm entangle: *.md docker run --rm --user ${UID} -v ${PWD}:/data nlesc/pandoc-tangle:0.5.0 --preserve-tabs *.md @@ -28,10 +28,10 @@ pip-celery: pip-connexion: pip install connexion[swagger-ui] -bin/newtonraphson.exe: src/cli-newtonraphson.cpp +cli/newtonraphson.exe: cli/cli-newtonraphson.cpp g++ cli/cli-newtonraphson.cpp -o cli/newtonraphson.exe -test-cli: bin/newtonraphson.exe +test-cli: cli/newtonraphson.exe ./cli/newtonraphson.exe apache2/cgi-bin/newtonraphson: src/cgi-newtonraphson.cpp From e176c10ac7d1ce310d92662fcde6a95b80e3fe3e Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 13:25:24 +0200 Subject: [PATCH 05/48] updated gitignore --- .gitignore | 3 ++- INSTALL.md | 6 +++--- Makefile | 10 +++++----- README.md | 14 +++++++------- {apache2 => cgi/apache2}/apache2.conf | 2 +- {apache2 => cgi/apache2}/cgi-bin/.gitignore | 0 {src => cgi}/cgi-newtonraphson.cpp | 2 +- {deps => cgi/deps}/nlohmann/json.hpp | 0 8 files changed, 19 insertions(+), 18 deletions(-) rename {apache2 => cgi/apache2}/apache2.conf (83%) rename {apache2 => cgi/apache2}/cgi-bin/.gitignore (100%) rename {src => cgi}/cgi-newtonraphson.cpp (95%) rename {deps => cgi/deps}/nlohmann/json.hpp (100%) diff --git a/.gitignore b/.gitignore index ebebfeb..d482dc0 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ cypress/support cypress/videos # Ignore compiled files -bin/newtonraphson.exe +cli/newtonraphson.exe src/py/newtonraphsonpy.*.so apache2/cgi-bin/newtonraphson @@ -15,3 +15,4 @@ apache2/cgi-bin/newtonraphson # other ignores node_modules + diff --git a/INSTALL.md b/INSTALL.md index 71ba7bc..fa0bd64 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -22,7 +22,7 @@ All the commands in the [README.md](README.md) and [CONTRIBUTING.md](CONTRIBUTIN UID := $(shell id -u) # Prevent suicide by excluding Makefile ENTANGLED := $(shell perl -ne 'print $$1,"\n" if /^```\{.*file=(.*)\}/' *.md | grep -v Makefile | sort -u) -COMPILED := cli/newtonraphson.exe src/py/newtonraphsonpy.*.so apache2/cgi-bin/newtonraphson src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm +COMPILED := cli/newtonraphson.exe src/py/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm entangle: *.md <> @@ -52,10 +52,10 @@ cli/newtonraphson.exe: cli/cli-newtonraphson.cpp test-cli: cli/newtonraphson.exe <> -apache2/cgi-bin/newtonraphson: src/cgi-newtonraphson.cpp +cgi/apache2/cgi-bin/newtonraphson: cgi/cgi-newtonraphson.cpp <> -test-cgi: apache2/cgi-bin/newtonraphson +test-cgi: cgi/apache2/cgi-bin/newtonraphson <> src/py/newtonraphsonpy.*.so: src/py-newtonraphson.cpp diff --git a/Makefile b/Makefile index cf970b5..094620b 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ UID := $(shell id -u) # Prevent suicide by excluding Makefile ENTANGLED := $(shell perl -ne 'print $$1,"\n" if /^```\{.*file=(.*)\}/' *.md | grep -v Makefile | sort -u) -COMPILED := cli/newtonraphson.exe src/py/newtonraphsonpy.*.so apache2/cgi-bin/newtonraphson src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm +COMPILED := cli/newtonraphson.exe src/py/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm entangle: *.md docker run --rm --user ${UID} -v ${PWD}:/data nlesc/pandoc-tangle:0.5.0 --preserve-tabs *.md @@ -34,11 +34,11 @@ cli/newtonraphson.exe: cli/cli-newtonraphson.cpp test-cli: cli/newtonraphson.exe ./cli/newtonraphson.exe -apache2/cgi-bin/newtonraphson: src/cgi-newtonraphson.cpp - g++ -Ideps src/cgi-newtonraphson.cpp -o apache2/cgi-bin/newtonraphson +cgi/apache2/cgi-bin/newtonraphson: cgi/cgi-newtonraphson.cpp + g++ -Icgi/deps/ -Icli/ cgi/cgi-newtonraphson.cpp -o cgi/apache2/cgi-bin/newtonraphson -test-cgi: apache2/cgi-bin/newtonraphson - echo '{"guess":-20, "epsilon":0.001}' | apache2/cgi-bin/newtonraphson +test-cgi: cgi/apache2/cgi-bin/newtonraphson + echo '{"guess":-20, "epsilon":0.001}' | cgi/apache2/cgi-bin/newtonraphson src/py/newtonraphsonpy.*.so: src/py-newtonraphson.cpp g++ -O3 -Wall -shared -std=c++14 -fPIC `python3 -m pybind11 --includes` \ diff --git a/README.md b/README.md index 163b4d7..4fe8847 100644 --- a/README.md +++ b/README.md @@ -216,8 +216,8 @@ In the [Apache httpd web server](https://httpd.apache.org/docs/2.4/howto/cgi.htm The executable can read the request body from the stdin for and the response must be printed to the stdout. A response should consist of the content type such as ``application/json`` or ``text/html``, followed by the content itself. A web service which accepts and returns JSON documents can for example look like: -```{.cpp file=src/cgi-newtonraphson.cpp} -// this C++ snippet is stored as src/cgi-newtonraphson.hpp +```{.cpp file=cgi/cgi-newtonraphson.cpp} +// this C++ snippet is stored as cgi/cgi-newtonraphson.hpp #include #include #include @@ -251,13 +251,13 @@ Where `nlohmann/json.hpp` is a JSON serialization/unserialization C++ header onl This can be compiled with ```{.awk #build-cgi} -g++ -Ideps src/cgi-newtonraphson.cpp -o apache2/cgi-bin/newtonraphson +g++ -Icgi/deps/ -Icli/ cgi/cgi-newtonraphson.cpp -o cgi/apache2/cgi-bin/newtonraphson ``` The CGI script can be tested directly with ```{.awk #test-cgi} -echo '{"guess":-20, "epsilon":0.001}' | apache2/cgi-bin/newtonraphson +echo '{"guess":-20, "epsilon":0.001}' | cgi/apache2/cgi-bin/newtonraphson ``` It should output @@ -271,10 +271,10 @@ Content-type: application/json } ``` -Example Apache config file to host executables in `./apache2/cgi-bin/` directory as `http://localhost:8080/cgi-bin/`. +Example Apache config file to host executables in `cgi/apache2/cgi-bin/` directory as `http://localhost:8080/cgi-bin/`. -```{.python file=apache2/apache2.conf} -# this Apache2 configuration snippet is stored as apache2/apache2.conf +```{.python file=cgi/apache2/apache2.conf} +# this Apache2 configuration snippet is stored as cgi/apache2/apache2.conf ServerName 127.0.0.1 Listen 8080 LoadModule mpm_event_module /usr/lib/apache2/modules/mod_mpm_event.so diff --git a/apache2/apache2.conf b/cgi/apache2/apache2.conf similarity index 83% rename from apache2/apache2.conf rename to cgi/apache2/apache2.conf index 6961d67..656b9fe 100644 --- a/apache2/apache2.conf +++ b/cgi/apache2/apache2.conf @@ -1,4 +1,4 @@ -# this Apache2 configuration snippet is stored as apache2/apache2.conf +# this Apache2 configuration snippet is stored as cgi/apache2/apache2.conf ServerName 127.0.0.1 Listen 8080 LoadModule mpm_event_module /usr/lib/apache2/modules/mod_mpm_event.so diff --git a/apache2/cgi-bin/.gitignore b/cgi/apache2/cgi-bin/.gitignore similarity index 100% rename from apache2/cgi-bin/.gitignore rename to cgi/apache2/cgi-bin/.gitignore diff --git a/src/cgi-newtonraphson.cpp b/cgi/cgi-newtonraphson.cpp similarity index 95% rename from src/cgi-newtonraphson.cpp rename to cgi/cgi-newtonraphson.cpp index 04a5feb..8dd58e0 100644 --- a/src/cgi-newtonraphson.cpp +++ b/cgi/cgi-newtonraphson.cpp @@ -1,4 +1,4 @@ -// this C++ snippet is stored as src/cgi-newtonraphson.hpp +// this C++ snippet is stored as cgi/cgi-newtonraphson.hpp #include #include #include diff --git a/deps/nlohmann/json.hpp b/cgi/deps/nlohmann/json.hpp similarity index 100% rename from deps/nlohmann/json.hpp rename to cgi/deps/nlohmann/json.hpp From 905cada2cb08f158e6abdb827e5442b8ebc305ef Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 13:28:49 +0200 Subject: [PATCH 06/48] split workflow job cpp into cli and cgi --- .github/workflows/main.yml | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 370927a..72dcea8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v2 - name: Check all entangled files are in sync with Markdown run: make check - cpp: + cli: # The type of runner that the job will run on runs-on: ubuntu-latest @@ -23,8 +23,19 @@ jobs: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v2 - - name: Run C++ examples - run: make test-cli test-cgi + - name: Run C++ test for CLI + run: make test-cli + cgi: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + - name: Run C++ test for CGI + run: make test-cgi python: # The type of runner that the job will run on name: Python ${{ matrix.python-version }} From f7e61099092688b2e8a3ec5a5f0c5d8c5117569e Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 14:41:41 +0200 Subject: [PATCH 07/48] moved src/py things to openapi/ and flask/ --- .gitignore | 6 ++-- INSTALL.md | 14 +++++----- Makefile | 26 ++++++++--------- README.md | 46 +++++++++++++++---------------- flask/tasks.py | 19 +++++++++++++ flask/webapp-celery.py | 45 ++++++++++++++++++++++++++++++ {src/py => flask}/webapp.py | 2 +- {src/py => openapi}/api.py | 2 +- {src/py => openapi}/example.py | 2 +- {src/py => openapi}/openapi.yaml | 2 +- openapi/py-newtonraphson.cpp | 45 ++++++++++++++++++++++++++++++ {src/py => openapi}/webservice.py | 2 +- 12 files changed, 160 insertions(+), 51 deletions(-) create mode 100644 flask/tasks.py create mode 100644 flask/webapp-celery.py rename {src/py => flask}/webapp.py (94%) rename {src/py => openapi}/api.py (80%) rename {src/py => openapi}/example.py (69%) rename {src/py => openapi}/openapi.yaml (95%) create mode 100644 openapi/py-newtonraphson.cpp rename {src/py => openapi}/webservice.py (67%) diff --git a/.gitignore b/.gitignore index d482dc0..8a0e5aa 100644 --- a/.gitignore +++ b/.gitignore @@ -6,9 +6,9 @@ cypress/support cypress/videos # Ignore compiled files -cli/newtonraphson.exe -src/py/newtonraphsonpy.*.so -apache2/cgi-bin/newtonraphson +/cli/newtonraphson.exe +/cgi/apache2/cgi-bin/newtonraphson +/openapi/newtonraphsonpy.*.so # Ignore entangled db .entangled/db.sqlite diff --git a/INSTALL.md b/INSTALL.md index fa0bd64..b92e91c 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -22,7 +22,7 @@ All the commands in the [README.md](README.md) and [CONTRIBUTING.md](CONTRIBUTIN UID := $(shell id -u) # Prevent suicide by excluding Makefile ENTANGLED := $(shell perl -ne 'print $$1,"\n" if /^```\{.*file=(.*)\}/' *.md | grep -v Makefile | sort -u) -COMPILED := cli/newtonraphson.exe src/py/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm +COMPILED := cli/newtonraphson.exe openapi/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm entangle: *.md <> @@ -58,10 +58,10 @@ cgi/apache2/cgi-bin/newtonraphson: cgi/cgi-newtonraphson.cpp test-cgi: cgi/apache2/cgi-bin/newtonraphson <> -src/py/newtonraphsonpy.*.so: src/py-newtonraphson.cpp +openapi/newtonraphsonpy.*.so: openapi/py-newtonraphson.cpp <> -test-py: src/py/example.py src/py/newtonraphsonpy.*.so +test-py: openapi/example.py openapi/newtonraphsonpy.*.so <> test: test-cli test-cgi test-py test-webservice @@ -84,19 +84,19 @@ start-redis: stop-redis: <> -run-webapp: src/py/newtonraphsonpy.*.so +run-webapp: openapi/newtonraphsonpy.*.so <> -run-webservice: src/py/newtonraphsonpy.*.so +run-webservice: openapi/newtonraphsonpy.*.so <> test-webservice: <> -run-celery-worker: src/py/newtonraphsonpy.*.so +run-celery-worker: openapi/newtonraphsonpy.*.so <> -run-celery-webapp: src/py/newtonraphsonpy.*.so +run-celery-webapp: openapi/newtonraphsonpy.*.so <> build-wasm: src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm diff --git a/Makefile b/Makefile index 094620b..f040346 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ UID := $(shell id -u) # Prevent suicide by excluding Makefile ENTANGLED := $(shell perl -ne 'print $$1,"\n" if /^```\{.*file=(.*)\}/' *.md | grep -v Makefile | sort -u) -COMPILED := cli/newtonraphson.exe src/py/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm +COMPILED := cli/newtonraphson.exe openapi/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm entangle: *.md docker run --rm --user ${UID} -v ${PWD}:/data nlesc/pandoc-tangle:0.5.0 --preserve-tabs *.md @@ -40,12 +40,12 @@ cgi/apache2/cgi-bin/newtonraphson: cgi/cgi-newtonraphson.cpp test-cgi: cgi/apache2/cgi-bin/newtonraphson echo '{"guess":-20, "epsilon":0.001}' | cgi/apache2/cgi-bin/newtonraphson -src/py/newtonraphsonpy.*.so: src/py-newtonraphson.cpp - g++ -O3 -Wall -shared -std=c++14 -fPIC `python3 -m pybind11 --includes` \ - src/py-newtonraphson.cpp -o src/py/newtonraphsonpy`python3-config --extension-suffix` +openapi/newtonraphsonpy.*.so: openapi/py-newtonraphson.cpp + g++ -O3 -Wall -shared -std=c++14 -fPIC -Icli/ `python3 -m pybind11 --includes` \ + openapi/py-newtonraphson.cpp -o openapi/newtonraphsonpy`python3-config --extension-suffix` -test-py: src/py/example.py src/py/newtonraphsonpy.*.so - python src/py/example.py +test-py: openapi/example.py openapi/newtonraphsonpy.*.so + python openapi/example.py test: test-cli test-cgi test-py test-webservice @@ -67,20 +67,20 @@ start-redis: stop-redis: docker stop some-redis -run-webapp: src/py/newtonraphsonpy.*.so - python src/py/webapp.py +run-webapp: openapi/newtonraphsonpy.*.so + python flask/webapp.py -run-webservice: src/py/newtonraphsonpy.*.so - python src/py/webservice.py +run-webservice: openapi/newtonraphsonpy.*.so + python openapi/webservice.py test-webservice: curl -X POST "http://localhost:8080/api/newtonraphson" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"epsilon\":0.001,\"guess\":-20}" -run-celery-worker: src/py/newtonraphsonpy.*.so +run-celery-worker: openapi/newtonraphsonpy.*.so PYTHONPATH=src/py celery worker -A tasks -run-celery-webapp: src/py/newtonraphsonpy.*.so - python src/py/webapp-celery.py +run-celery-webapp: openapi/newtonraphsonpy.*.so + python flask/webapp-celery.py build-wasm: src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm diff --git a/README.md b/README.md index 4fe8847..412ae71 100644 --- a/README.md +++ b/README.md @@ -341,8 +341,8 @@ Pybind11 requires a bindings to expose C++ constants/functions/enumerations/clas For example the bindings of `newtonraphson.hpp:NewtonRaphson` class would look like: -```{.cpp file=src/py-newtonraphson.cpp} -// this C++ snippet is stored as src/py-newtonraphson.cpp +```{.cpp file=openapi/py-newtonraphson.cpp} +// this C++ snippet is stored as openapi/py-newtonraphson.cpp #include #include @@ -365,14 +365,14 @@ PYBIND11_MODULE(newtonraphsonpy, m) { Compile with ```{.awk #build-py} -g++ -O3 -Wall -shared -std=c++14 -fPIC `python3 -m pybind11 --includes` \ -src/py-newtonraphson.cpp -o src/py/newtonraphsonpy`python3-config --extension-suffix` +g++ -O3 -Wall -shared -std=c++14 -fPIC -Icli/ `python3 -m pybind11 --includes` \ +openapi/py-newtonraphson.cpp -o openapi/newtonraphsonpy`python3-config --extension-suffix` ``` In Python it can be used: -```{.python file=src/py/example.py} -# this Python snippet is stored as src/py/example.py +```{.python file=openapi/example.py} +# this Python snippet is stored as openapi/example.py from newtonraphsonpy import NewtonRaphson finder = NewtonRaphson(epsilon=0.001) @@ -383,7 +383,7 @@ print(root) The Python example can be run with ```{.awk #test-py} -python src/py/example.py +python openapi/example.py ``` It will output something like @@ -450,8 +450,8 @@ def calculate(): Putting it all together in -```{.python file=src/py/webapp.py} -# this Python snippet is stored as src/py/webapp.py +```{.python file=flask/webapp.py} +# this Python snippet is stored as flask/webapp.py from flask import Flask, request app = Flask(__name__) @@ -465,7 +465,7 @@ app.run(port=5001) And running it with ```{.awk #run-webapp} -python src/py/webapp.py +python flask/webapp.py ``` To test we can visit [http://localhost:5001](http://localhost:5001) fill the form and press submit to get the result. @@ -499,8 +499,8 @@ capp = Celery('tasks', broker='redis://localhost:6379', backend='redis://localho When a method is decorated with the Celery task decorator then it can be submitted to the Celery task queue. We'll add some ``sleep``s to demonstrate what would happen with a long running calculation. We'll also tell Celery about in which step the calculation is; later, we can display this step to the user. -```{.python file=src/py/tasks.py} -# this Python snippet is stored as src/py/tasks.py +```{.python file=flask/tasks.py} +# this Python snippet is stored as flask/tasks.py import time <> @@ -556,8 +556,8 @@ def result(jobid): Putting it all together -```{.python file=src/py/webapp-celery.py} -# this Python snippet is stored as src/py/webapp-celery.py +```{.python file=flask/webapp-celery.py} +# this Python snippet is stored as flask/webapp-celery.py from flask import Flask, render_template, request, redirect, url_for app = Flask(__name__) @@ -575,7 +575,7 @@ if __name__ == '__main__': Start the web application like before with ```{.awk #run-celery-webapp} -python src/py/webapp-celery.py +python flask/webapp-celery.py ``` Tasks will be run by the Celery worker. The worker can be started with @@ -584,7 +584,7 @@ Tasks will be run by the Celery worker. The worker can be started with PYTHONPATH=src/py celery worker -A tasks ``` -(The PYTHONPATH environment variable is set so the Celery worker can find the `tasks.py` and `newtonraphsonpy.*.so` files in the `src/py/` directory) +(The PYTHONPATH environment variable is set so the Celery worker can find the `tasks.py` and `newtonraphsonpy.*.so` files in the `flask/` directory) To test the web service @@ -615,8 +615,8 @@ For the Python based root finding web service, Connexion was used as the web fra The OpenAPI specification for performing root finding would look like -```{.yaml file=src/py/openapi.yaml} -# this yaml snippet is stored as src/py/openapi.yaml +```{.yaml file=openapi/openapi.yaml} +# this yaml snippet is stored as openapi/openapi.yaml openapi: 3.0.0 info: title: Root finder @@ -673,8 +673,8 @@ The request and response are in JSON format and adhere to their respective JSON The operation identifier (`operationId`) in the specification gets translated by Connexion to a Python method that will be called when the path is requested. Connexion calls the function with the JSON parsed request body. -```{.python file=src/py/api.py} -# this Python snippet is stored as src/py/api.py +```{.python file=openapi/api.py} +# this Python snippet is stored as openapi/.py def calculate(body): epsilon = body['epsilon'] guess = body['guess'] @@ -692,8 +692,8 @@ pip install connexion[swagger-ui] To run the web service we have to to tell Connexion which specification it should expose. -```{.python file=src/py/webservice.py} -# this Python snippet is stored as src/py/webservice.py +```{.python file=openapi/webservice.py} +# this Python snippet is stored as openapi/webservice.py import connexion app = connexion.App(__name__) @@ -704,7 +704,7 @@ app.run(port=8080) The web service can be started with ```{.awk #run-webservice} -python src/py/webservice.py +python openapi/webservice.py ``` We can try out the web service using the Swagger UI at [http://localhost:8080/ui/](http://localhost:8080/ui/). diff --git a/flask/tasks.py b/flask/tasks.py new file mode 100644 index 0000000..6ce779a --- /dev/null +++ b/flask/tasks.py @@ -0,0 +1,19 @@ +# this Python snippet is stored as flask/tasks.py +import time + +# this Python code snippet is later referred to as <> +from celery import Celery +capp = Celery('tasks', broker='redis://localhost:6379', backend='redis://localhost:6379') + +@capp.task(bind=True) +def calculate(self, epsilon, guess): + if not self.request.called_directly: + self.update_state(state='INITIALIZING') + time.sleep(5) + from newtonraphsonpy import NewtonRaphson + finder = NewtonRaphson(epsilon) + if not self.request.called_directly: + self.update_state(state='FINDING') + time.sleep(5) + root = finder.solve(guess) + return {'root': root, 'guess': guess, 'epsilon':epsilon} \ No newline at end of file diff --git a/flask/webapp-celery.py b/flask/webapp-celery.py new file mode 100644 index 0000000..e9caae6 --- /dev/null +++ b/flask/webapp-celery.py @@ -0,0 +1,45 @@ +# this Python snippet is stored as flask/webapp-celery.py +from flask import Flask, render_template, request, redirect, url_for + +app = Flask(__name__) + +# this Python code snippet is later referred to as <> +@app.route('/', methods=['GET']) +def form(): + return ''' +
+ + + + + +
''' + +# this Python code snippet is later referred to as <> +@app.route('/', methods=['POST']) +def submit(): + epsilon = float(request.form['epsilon']) + guess = float(request.form['guess']) + from tasks import calculate + job = calculate.delay(epsilon, guess) + return redirect(url_for('result', jobid=job.id)) + +# this Python code snippet is later referred to as <> +@app.route('/result/') +def result(jobid): + from tasks import capp + job = capp.AsyncResult(jobid) + job.maybe_throw() + if job.successful(): + result = job.get() + epsilon = result['epsilon'] + guess = result['guess'] + root = result['root'] + return f''' +

With epsilon of {epsilon} and a guess of {guess} the found root is {root}.

''' + else: + return f''' +

{job.status}

''' + +if __name__ == '__main__': + app.run(port=5000) \ No newline at end of file diff --git a/src/py/webapp.py b/flask/webapp.py similarity index 94% rename from src/py/webapp.py rename to flask/webapp.py index 397193a..3d67b7d 100644 --- a/src/py/webapp.py +++ b/flask/webapp.py @@ -1,4 +1,4 @@ -# this Python snippet is stored as src/py/webapp.py +# this Python snippet is stored as flask/webapp.py from flask import Flask, request app = Flask(__name__) diff --git a/src/py/api.py b/openapi/api.py similarity index 80% rename from src/py/api.py rename to openapi/api.py index f0b3c3f..d35f511 100644 --- a/src/py/api.py +++ b/openapi/api.py @@ -1,4 +1,4 @@ -# this Python snippet is stored as src/py/api.py +# this Python snippet is stored as openapi/.py def calculate(body): epsilon = body['epsilon'] guess = body['guess'] diff --git a/src/py/example.py b/openapi/example.py similarity index 69% rename from src/py/example.py rename to openapi/example.py index 12df20d..b0b9eda 100644 --- a/src/py/example.py +++ b/openapi/example.py @@ -1,4 +1,4 @@ -# this Python snippet is stored as src/py/example.py +# this Python snippet is stored as openapi/example.py from newtonraphsonpy import NewtonRaphson finder = NewtonRaphson(epsilon=0.001) diff --git a/src/py/openapi.yaml b/openapi/openapi.yaml similarity index 95% rename from src/py/openapi.yaml rename to openapi/openapi.yaml index 3ff1f97..6d74ccf 100644 --- a/src/py/openapi.yaml +++ b/openapi/openapi.yaml @@ -1,4 +1,4 @@ -# this yaml snippet is stored as src/py/openapi.yaml +# this yaml snippet is stored as openapi/openapi.yaml openapi: 3.0.0 info: title: Root finder diff --git a/openapi/py-newtonraphson.cpp b/openapi/py-newtonraphson.cpp new file mode 100644 index 0000000..4545254 --- /dev/null +++ b/openapi/py-newtonraphson.cpp @@ -0,0 +1,45 @@ +// this C++ snippet is stored as openapi/py-newtonraphson.cpp +#include +#include + +// this C++ code snippet is later referred to as <> +#include "newtonraphson.hpp" +#include "algebra.hpp" + +using namespace algebra; + +namespace rootfinding +{ + +NewtonRaphson::NewtonRaphson(double tolerancein) : tolerance(tolerancein) {} + +// Function to find the root +double NewtonRaphson::solve(double xin) +{ + double x = xin; + double delta_x = equation(x) / derivative(x); + while (abs(delta_x) >= tolerance) + { + delta_x = equation(x) / derivative(x); + + // x_new = x_old - f(x) / f'(x) + x = x - delta_x; + } + return x; +}; + + +} // namespace rootfinding + +namespace py = pybind11; + +PYBIND11_MODULE(newtonraphsonpy, m) { + py::class_(m, "NewtonRaphson") + .def(py::init(), py::arg("epsilon")) + .def("solve", + &rootfinding::NewtonRaphson::solve, + py::arg("guess"), + "Find root starting from initial guess" + ) + ; +} \ No newline at end of file diff --git a/src/py/webservice.py b/openapi/webservice.py similarity index 67% rename from src/py/webservice.py rename to openapi/webservice.py index bfaabcf..de48aa9 100644 --- a/src/py/webservice.py +++ b/openapi/webservice.py @@ -1,4 +1,4 @@ -# this Python snippet is stored as src/py/webservice.py +# this Python snippet is stored as openapi/webservice.py import connexion app = connexion.App(__name__) From 8cad0e10aff56cd78f1dbc01c14d12d6a91ef5d9 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 14:48:10 +0200 Subject: [PATCH 08/48] split the python gh action into openapi and flask --- .github/workflows/main.yml | 41 +++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 72dcea8..aa9abc3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,7 +36,46 @@ jobs: - name: Run C++ test for CGI run: make test-cgi - python: + openapi: + # The type of runner that the job will run on + name: Python ${{ matrix.python-version }} + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.6, 3.7, 3.8] + fail-fast: true + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + architecture: "x64" + + - name: Which Python + run: which python + + - name: Install Python dependencies + run: make pip-pybind11 && make pip-connexion + + - name: Run Python example + run: make test-py + + - name: Start web service in background + run: make run-webservice 2>&1 | tee ./run-webservice.log & + + - name: Test web service + run: make test-webservice + + - name: Upload log of services + if: ${{ always() }} + uses: actions/upload-artifact@v2 + with: + name: service-logs + path: ./run-*.log + flask: # The type of runner that the job will run on name: Python ${{ matrix.python-version }} runs-on: ubuntu-latest From 765daf14c6fa0677f7c89c952b93af16ddb8fc09 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 14:49:55 +0200 Subject: [PATCH 09/48] clearer gh action job names --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index aa9abc3..04b1281 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -38,7 +38,7 @@ jobs: run: make test-cgi openapi: # The type of runner that the job will run on - name: Python ${{ matrix.python-version }} + name: openapi / python-${{ matrix.python-version }} runs-on: ubuntu-latest strategy: matrix: @@ -77,7 +77,7 @@ jobs: path: ./run-*.log flask: # The type of runner that the job will run on - name: Python ${{ matrix.python-version }} + name: flask / python-${{ matrix.python-version }} runs-on: ubuntu-latest strategy: matrix: From add333d9a076ffe44f119c799d631135385ad910 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 14:57:21 +0200 Subject: [PATCH 10/48] removed openapi stuff from flask job in gh action --- .github/workflows/main.yml | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 04b1281..fd7a3d1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -103,10 +103,7 @@ jobs: run: which python - name: Install Python dependencies - run: make py-deps && pip install httpie - - - name: Run Python example - run: make test-py + run: make pip-pybind11 && make pip-flask && make pip-celery && pip install httpie - name: Start web application in background run: make run-webapp 2>&1 | tee ./run-webapp.log & @@ -114,18 +111,12 @@ jobs: - name: Test web application run: http --ignore-stdin -f localhost:5001 epsilon=0.001 guess=-20 - - name: Start web service in background - run: make run-webservice 2>&1 | tee ./run-webservice.log & - - - name: Test web service - run: make test-webservice - - name: Start Celery web app in background run: make run-celery-webapp 2>&1 | tee ./run-celery-webapp.log & - name: Start Celery worker in background run: | - cd src/py + cd flask PYTHONPATH=$PWD/../.. celery -A tasks worker 2>&1 | tee ./run-celery-worker.log & cd ../.. From 8509ba73df4808a709dc5a6bb6b998419ac68d93 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 15:35:45 +0200 Subject: [PATCH 11/48] new directory structure --- INSTALL.md | 6 +- Makefile | 4 +- README.md | 98 +++++++-------- bin/.gitignore | 1 - cgi-bin/.gitkeep | 0 cli/algebra.hpp | 2 +- cli/cli-newtonraphson.cpp | 2 +- cli/newtonraphson.hpp | 2 +- react/app.js | 76 ++++++++++++ react/example-app.html | 22 ++++ react/example-jsonschema-form.html | 22 ++++ react/example-plot.html | 24 ++++ react/jsonschema-app.js | 87 ++++++++++++++ react/plot-app.js | 126 ++++++++++++++++++++ react/worker-sweep.js | 36 ++++++ src/py-newtonraphson.cpp | 45 ------- src/py/.gitignore | 1 - src/py/hello-templated.py | 10 -- src/py/hello.py | 9 -- src/py/tasks.py | 19 --- src/py/webapp-celery.py | 45 ------- webassembly/example-web-worker.html | 26 ++++ webassembly/example.html | 22 ++++ {src => webassembly}/wasm-newtonraphson.cpp | 2 +- webassembly/worker.js | 23 ++++ 25 files changed, 522 insertions(+), 188 deletions(-) delete mode 100644 bin/.gitignore delete mode 100644 cgi-bin/.gitkeep create mode 100644 react/app.js create mode 100644 react/example-app.html create mode 100644 react/example-jsonschema-form.html create mode 100644 react/example-plot.html create mode 100644 react/jsonschema-app.js create mode 100644 react/plot-app.js create mode 100644 react/worker-sweep.js delete mode 100644 src/py-newtonraphson.cpp delete mode 100644 src/py/.gitignore delete mode 100644 src/py/hello-templated.py delete mode 100644 src/py/hello.py delete mode 100644 src/py/tasks.py delete mode 100644 src/py/webapp-celery.py create mode 100644 webassembly/example-web-worker.html create mode 100644 webassembly/example.html rename {src => webassembly}/wasm-newtonraphson.cpp (92%) create mode 100644 webassembly/worker.js diff --git a/INSTALL.md b/INSTALL.md index b92e91c..234ce4c 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -22,7 +22,7 @@ All the commands in the [README.md](README.md) and [CONTRIBUTING.md](CONTRIBUTIN UID := $(shell id -u) # Prevent suicide by excluding Makefile ENTANGLED := $(shell perl -ne 'print $$1,"\n" if /^```\{.*file=(.*)\}/' *.md | grep -v Makefile | sort -u) -COMPILED := cli/newtonraphson.exe openapi/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm +COMPILED := cli/newtonraphson.exe openapi/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm entangle: *.md <> @@ -99,9 +99,9 @@ run-celery-worker: openapi/newtonraphsonpy.*.so run-celery-webapp: openapi/newtonraphsonpy.*.so <> -build-wasm: src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm +build-wasm: webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm -src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm: src/wasm-newtonraphson.cpp +webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm: webassembly/wasm-newtonraphson.cpp <> host-files: build-wasm diff --git a/Makefile b/Makefile index f040346..71e765d 100644 --- a/Makefile +++ b/Makefile @@ -77,7 +77,7 @@ test-webservice: curl -X POST "http://localhost:8080/api/newtonraphson" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"epsilon\":0.001,\"guess\":-20}" run-celery-worker: openapi/newtonraphsonpy.*.so - PYTHONPATH=src/py celery worker -A tasks + PYTHONPATH=openapi celery worker -A tasks run-celery-webapp: openapi/newtonraphsonpy.*.so python flask/webapp-celery.py @@ -85,7 +85,7 @@ run-celery-webapp: openapi/newtonraphsonpy.*.so build-wasm: src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm: src/wasm-newtonraphson.cpp - emcc --bind -o src/js/newtonraphsonwasm.js -s MODULARIZE=1 -s EXPORT_NAME=createModule src/wasm-newtonraphson.cpp + emcc --bind -o webassembly/newtonraphsonwasm.js -s MODULARIZE=1 -s EXPORT_NAME=createModule webassembly/wasm-newtonraphson.cpp host-files: build-wasm python3 -m http.server 8000 diff --git a/README.md b/README.md index 412ae71..1316d19 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Let's first define the mathematical equation, which we will be searching for its The equation and its derivative which we will use in this guide are $x^3 - x^2 + 2$ and $3x^2 - 2x$ respectively. ```{.hpp file=cli/algebra.hpp} -// this C++ code snippet is store as src/algebra.hpp +// this C++ code snippet is store as cli/algebra.hpp namespace algebra { @@ -63,7 +63,7 @@ double derivative(double x) Next, we define the interface (C++ class). ```{.cpp file=cli/newtonraphson.hpp} -// this C++ snippet is stored as src/newtonraphson.hpp +// this C++ snippet is stored as cli/newtonraphson.hpp #ifndef H_NEWTONRAPHSON_H #define H_NEWTONRAPHSON_H @@ -120,7 +120,7 @@ double NewtonRaphson::solve(double xin) We are now ready to call the algorithm in a simple CLI program. It would look like ```{.cpp file=cli/cli-newtonraphson.cpp} -// this C++ snippet is stored as src/newtonraphson.cpp +// this C++ snippet is stored as cli/newtonraphson.cpp #include <> @@ -581,7 +581,7 @@ python flask/webapp-celery.py Tasks will be run by the Celery worker. The worker can be started with ```{.awk #run-celery-worker} -PYTHONPATH=src/py celery worker -A tasks +PYTHONPATH=openapi celery worker -A tasks ``` (The PYTHONPATH environment variable is set so the Celery worker can find the `tasks.py` and `newtonraphsonpy.*.so` files in the `flask/` directory) @@ -731,8 +731,8 @@ Instead of writing code in the WebAssembly language, there are compilers that ca The binding of the C++ code will be -```{.cpp file=src/wasm-newtonraphson.cpp} -// this C++ snippet is stored as src/wasm-newtonraphson.cpp +```{.cpp file=webassembly/wasm-newtonraphson.cpp} +// this C++ snippet is stored as webassembly/wasm-newtonraphson.cpp #include <> @@ -748,13 +748,13 @@ EMSCRIPTEN_BINDINGS(newtonraphsonwasm) { ``` The algorithm and binding can be compiled into a WebAssembly module with the Emscripten compiler called `emcc`. -To make live easier we configure the compile command to generate a `src/js/newtonraphsonwasm.js` file which exports the `createModule` function. +To make live easier we configure the compile command to generate a `webassembly/newtonraphsonwasm.js` file which exports the `createModule` function. ```{.awk #build-wasm} -emcc --bind -o src/js/newtonraphsonwasm.js -s MODULARIZE=1 -s EXPORT_NAME=createModule src/wasm-newtonraphson.cpp +emcc --bind -o webassembly/newtonraphsonwasm.js -s MODULARIZE=1 -s EXPORT_NAME=createModule webassembly/wasm-newtonraphson.cpp ``` -The compilation also generates a `src/js/newtonraphsonwasm.wasm` file which will be loaded with the `createModule` function. +The compilation also generates a `webassembly/newtonraphsonwasm.wasm` file which will be loaded with the `createModule` function. The WebAssembly module must be loaded and initialized by calling the `createModule` function and waiting for the JavaScript promise to resolve. @@ -787,9 +787,9 @@ document.getElementById('answer').innerHTML = root.toFixed(2); To run the JavaScript in a web browser a HTML page is needed. To be able to use the `createModule` function, we will import the `newtonraphsonwasm.js` with a script tag. -```{.html file=src/js/example.html} +```{.html file=webassembly/example.html} - + Example @@ -811,10 +811,10 @@ Python ships with a built-in web server, we will use it to host the all files of python3 -m http.server 8000 ``` -Visit [http://localhost:8000/src/js/example.html](http://localhost:8000/src/js/example.html) to see the result of the calculation. -Embedded below is the example hosted on [GitHub pages](https://nlesc-jcer.github.io/cpp2wasm/src/js/example.html) +Visit [http://localhost:8000/webassembly/example.html](http://localhost:8000/webassembly/example.html) to see the result of the calculation. +Embedded below is the example hosted on [GitHub pages](https://nlesc-jcer.github.io/cpp2wasm/webassembly/example.html) -[https://nlesc-jcer.github.io/cpp2wasm/src/js/example.html](https://nlesc-jcer.github.io/cpp2wasm/src/js/example.html ':include :type=iframe width=100% height=60px'). +[https://nlesc-jcer.github.io/cpp2wasm/webassembly/example.html](https://nlesc-jcer.github.io/cpp2wasm/webassembly/example.html ':include :type=iframe width=100% height=60px'). The result of root finding was calculated using the C++ algorithm compiled to a WebAssembly module, executed by some JavaScript and rendered on a HTML page. @@ -822,7 +822,7 @@ The result of root finding was calculated using the C++ algorithm compiled to a Executing a long running C++ method will block the browser from running any other code like updating the user interface. In order to avoid this, the method can be run in the background using [web workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers). A web worker runs in its own thread and can be interacted with from JavaScript using messages. -We need to instantiate a web worker which we will implement later in `src/js/worker.js`. +We need to instantiate a web worker which we will implement later in `webassembly/worker.js`. ```{.js #worker-consumer} // this JavaScript snippet is later referred to as <> @@ -850,8 +850,8 @@ onmessage = function(message) { Before we can handle the message we need to import the WebAssembly module. -```{.js file=src/js/worker.js} -// this JavaScript snippet is stored as src/js/worker.js +```{.js file=webassembly/worker.js} +// this JavaScript snippet is stored as webassembly/worker.js importScripts('newtonraphsonwasm.js'); <> @@ -905,9 +905,9 @@ worker.onmessage = function(message) { Like before we need a HTML page to run the JavaScript, but now we don't need to import the `newtonraphsonwasm.js` file here as it is imported in the `worker.js` file. -```{.html file=src/js/example-web-worker.html} +```{.html file=webassembly/example-web-worker.html} - + Example web worker @@ -927,10 +927,10 @@ Like before we also need to host the files in a web server with python3 -m http.server 8000 ``` -Visit [http://localhost:8000/src/js/example-web-worker.html](http://localhost:8000/src/js/example-web-worker.html) to see the result of the calculation. -Embedded below is the example hosted on [GitHub pages](https://nlesc-jcer.github.io/cpp2wasm/src/js/example-web-worker.html) +Visit [http://localhost:8000/webassembly/example-web-worker.html](http://localhost:8000/webassembly/example-web-worker.html) to see the result of the calculation. +Embedded below is the example hosted on [GitHub pages](https://nlesc-jcer.github.io/cpp2wasm/webassembly/example-web-worker.html) - + The result of root finding was calculated using the C++ algorithm compiled to a WebAssembly module, imported in a web worker (separate thread), executed by JavaScript with messages to/from the web worker and rendered on a HTML page. @@ -955,9 +955,9 @@ The C++ algorithm is compiled into a wasm file using bindings. When a calculatio To render the React application we need a HTML tag as a container. We will give it the identifier `container` which will use later when we implement the React application in the `app.js` file. -```{.html file=src/js/example-app.html} +```{.html file=react/example-app.html} - + Example React application @@ -1139,11 +1139,11 @@ function Result(props) { We can combine the heading, form and result components and all the states and handleSubmit function into the `App` React component. -```{.jsx file=src/js/app.js} +```{.jsx file=react/app.js} <> <> -// this JavaScript snippet appenended to src/js/app.js +// this JavaScript snippet appenended to react/app.js function App() { <> @@ -1163,8 +1163,8 @@ function App() { Finally we can render the `App` component to the HTML container with `container` as identifier. -```{.jsx file=src/js/app.js} -// this JavaScript snippet appenended to src/js/app.js +```{.jsx file=react/app.js} +// this JavaScript snippet appenended to react/app.js ReactDOM.render( , document.getElementById('container') @@ -1177,10 +1177,10 @@ Like before we also need to host the files in a web server with python3 -m http.server 8000 ``` -Visit [http://localhost:8000/src/js/example-app.html](http://localhost:8000/src/js/example-app.html) to see the root answer. -Embedded below is the example app hosted on [GitHub pages](https://nlesc-jcer.github.io/cpp2wasm/src/js/example-app.html) +Visit [http://localhost:8000/react/example-app.html](http://localhost:8000/react/example-app.html) to see the root answer. +Embedded below is the example app hosted on [GitHub pages](https://nlesc-jcer.github.io/cpp2wasm/react/example-app.html) - + ### JSON schema powered form @@ -1215,9 +1215,9 @@ const schema = { To render the application we need a HTML page. We will reuse the imports we did in the previous chapter. -```{.html file=src/js/example-jsonschema-form.html} +```{.html file=react/example-jsonschema-form.html} - + Example JSON schema powered form @@ -1301,8 +1301,8 @@ function handleSubmit(submission, event) { The App component can be defined and rendered with. -```{.jsx file=src/js/jsonschema-app.js} -// this JavaScript snippet stored as src/js/jsonschema-app.js +```{.jsx file=react/jsonschema-app.js} +// this JavaScript snippet stored as react/jsonschema-app.js function App() { <> @@ -1323,8 +1323,8 @@ ReactDOM.render( The `Heading` and `Result` React component can be reused. -```{.jsx file=src/js/jsonschema-app.js} -// this JavaScript snippet appended to src/js/jsonschema-app.js +```{.jsx file=react/jsonschema-app.js} +// this JavaScript snippet appended to react/jsonschema-app.js <> <> ``` @@ -1335,10 +1335,10 @@ Like before we also need to host the files in a web server with python3 -m http.server 8000 ``` -Visit [http://localhost:8000/src/js/example-jsonschema-form.html](http://localhost:8000/src/js/example-jsonschema-form.html) to see the root answer. -Embedded below is the example app hosted on [GitHub pages](https://nlesc-jcer.github.io/cpp2wasm/src/js/example-app.html) +Visit [http://localhost:8000/react/example-jsonschema-form.html](http://localhost:8000/react/example-jsonschema-form.html) to see the root answer. +Embedded below is the example app hosted on [GitHub pages](https://nlesc-jcer.github.io/cpp2wasm/react/example-app.html) - + If you enter a negative number in the `epsilon` field the form will become invalid with a error message. @@ -1476,8 +1476,8 @@ postMessage({ The sweep calculation snippet (`<>`) must be run in a new web worker called `worker-sweep.js`. Like before we need to wait for the WebAssembly module to be initialized before we can start the calculation. -```{.js file=src/js/worker-sweep.js} -// this JavaScript snippet stored as src/js/worker-sweep.js +```{.js file=react/worker-sweep.js} +// this JavaScript snippet stored as react/worker-sweep.js importScripts('newtonraphsonwasm.js'); onmessage = function(message) { @@ -1563,8 +1563,8 @@ function Plot({roots}) { The App component can be defined and rendered with. -```{.jsx file=src/js/plot-app.js} -// this JavaScript snippet stored as src/js/plot-app.js +```{.jsx file=react/plot-app.js} +// this JavaScript snippet stored as react/plot-app.js <> <> @@ -1603,9 +1603,9 @@ ReactDOM.render( The HTML page should look like -```{.html file=src/js/example-plot.html} +```{.html file=react/example-plot.html} - + Example plot @@ -1625,10 +1625,10 @@ Like before we also need to host the files in a web server with python3 -m http.server 8000 ``` -Visit [http://localhost:8000/src/js/example-plot.html](http://localhost:8000/src/js/example-plot.html) to see the epsilon/duration plot. +Visit [http://localhost:8000/react/example-plot.html](http://localhost:8000/react/example-plot.html) to see the epsilon/duration plot. -Embedded below is the example app hosted on [GitHub pages](https://nlesc-jcer.github.io/cpp2wasm/src/js/example-plot.html) +Embedded below is the example app hosted on [GitHub pages](https://nlesc-jcer.github.io/cpp2wasm/react/example-plot.html) - + After the submit button is pressed the plot should show that the first calculation took a bit longer then the rest. diff --git a/bin/.gitignore b/bin/.gitignore deleted file mode 100644 index 1d74160..0000000 --- a/bin/.gitignore +++ /dev/null @@ -1 +0,0 @@ -newtonraphson.exe \ No newline at end of file diff --git a/cgi-bin/.gitkeep b/cgi-bin/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/cli/algebra.hpp b/cli/algebra.hpp index 4195052..ae21ba6 100644 --- a/cli/algebra.hpp +++ b/cli/algebra.hpp @@ -1,4 +1,4 @@ -// this C++ code snippet is store as src/algebra.hpp +// this C++ code snippet is store as cli/algebra.hpp namespace algebra { diff --git a/cli/cli-newtonraphson.cpp b/cli/cli-newtonraphson.cpp index eba45c5..9647017 100644 --- a/cli/cli-newtonraphson.cpp +++ b/cli/cli-newtonraphson.cpp @@ -1,4 +1,4 @@ -// this C++ snippet is stored as src/newtonraphson.cpp +// this C++ snippet is stored as cli/newtonraphson.cpp #include // this C++ code snippet is later referred to as <> diff --git a/cli/newtonraphson.hpp b/cli/newtonraphson.hpp index b4524ce..5e6899e 100644 --- a/cli/newtonraphson.hpp +++ b/cli/newtonraphson.hpp @@ -1,4 +1,4 @@ -// this C++ snippet is stored as src/newtonraphson.hpp +// this C++ snippet is stored as cli/newtonraphson.hpp #ifndef H_NEWTONRAPHSON_H #define H_NEWTONRAPHSON_H diff --git a/react/app.js b/react/app.js new file mode 100644 index 0000000..ac31b0e --- /dev/null +++ b/react/app.js @@ -0,0 +1,76 @@ +// this JavaScript snippet is later referred to as <> +function Heading() { + const title = 'Root finding web application'; + return

{title}

+} +// this JavaScript snippet is later referred to as <> +function Result(props) { + const root = props.root; + let message = 'Not submitted'; + if (root !== undefined) { + message = 'Root = ' + root; + } + return
{message}
; +} + +// this JavaScript snippet appenended to react/app.js +function App() { + // this JavaScript snippet is later referred to as <> + const [epsilon, setEpsilon] = React.useState(0.001); + // this JavaScript snippet is appended to <> + function onEpsilonChange(event) { + setEpsilon(Number(event.target.value)); + } + // this JavaScript snippet is appended to <> + const [guess, setGuess] = React.useState(-20); + + function onGuessChange(event) { + setGuess(Number(event.target.value)); + } + // this JavaScript snippet is appended to <> + const [root, setRoot] = React.useState(undefined); + + function handleSubmit(event) { + // this JavaScript snippet is later referred to as <> + event.preventDefault(); + // this JavaScript snippet is appended to <> + const worker = new Worker('worker.js'); + // this JavaScript snippet is appended to <> + worker.postMessage({ + type: 'CALCULATE', + payload: { epsilon: epsilon, guess: guess } + }); + // this JavaScript snippet is appended to <> + worker.onmessage = function(message) { + if (message.data.type === 'RESULT') { + const result = message.data.payload.root; + setRoot(result); + worker.terminate(); + } + }; + } + + return ( +
+ + { /* this JavaScript snippet is later referred to as <> */ } +
+ + + +
+ +
+ ); +} +// this JavaScript snippet appenended to react/app.js +ReactDOM.render( + , + document.getElementById('container') +); \ No newline at end of file diff --git a/react/example-app.html b/react/example-app.html new file mode 100644 index 0000000..4611297 --- /dev/null +++ b/react/example-app.html @@ -0,0 +1,22 @@ + + + + + Example React application + + + + + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/react/example-jsonschema-form.html b/react/example-jsonschema-form.html new file mode 100644 index 0000000..f841c9f --- /dev/null +++ b/react/example-jsonschema-form.html @@ -0,0 +1,22 @@ + + + + + Example JSON schema powered form + + + + + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/react/example-plot.html b/react/example-plot.html new file mode 100644 index 0000000..fa49565 --- /dev/null +++ b/react/example-plot.html @@ -0,0 +1,24 @@ + + + + + Example plot + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/react/jsonschema-app.js b/react/jsonschema-app.js new file mode 100644 index 0000000..afa820f --- /dev/null +++ b/react/jsonschema-app.js @@ -0,0 +1,87 @@ +// this JavaScript snippet stored as react/jsonschema-app.js +function App() { + // this JavaScript snippet is later referred to as <> + const schema = { + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://nlesc-jcer.github.io/cpp2wasm/NNRequest.json", + "type": "object", + "properties": { + "epsilon": { + "title": "Epsilon", + "type": "number", + "minimum": 0 + }, + "guess": { + "title": "Initial guess", + "type": "integer", + "minimum": -100, + "maximum": 100 + } + }, + "required": ["epsilon", "guess"], + "additionalProperties": false + } + // this JavaScript snippet is appended to <> + const Form = JSONSchemaForm.default; + // this JavaScript snippet is appended to <> + const [formData, setFormData] = React.useState({ + epsilon: 0.001, + guess: -20 + }); + + function handleChange(event) { + setFormData(event.formData); + } + // this JavaScript snippet is appended to <> + const [root, setRoot] = React.useState(undefined); + + function handleSubmit(submission, event) { + event.preventDefault(); + const worker = new Worker('worker.js'); + worker.postMessage({ + type: 'CALCULATE', + payload: submission.formData + }); + worker.onmessage = function(message) { + if (message.data.type === 'RESULT') { + const result = message.data.payload.root; + setRoot(result); + worker.terminate(); + } + }; + } + + return ( +
+ + { /* this JavaScript snippet is later referred to as <> */} +
+ +
+ ); +} + +ReactDOM.render( + , + document.getElementById('container') +); +// this JavaScript snippet appended to react/jsonschema-app.js +// this JavaScript snippet is later referred to as <> +function Heading() { + const title = 'Root finding web application'; + return

{title}

+} +// this JavaScript snippet is later referred to as <> +function Result(props) { + const root = props.root; + let message = 'Not submitted'; + if (root !== undefined) { + message = 'Root = ' + root; + } + return
{message}
; +} \ No newline at end of file diff --git a/react/plot-app.js b/react/plot-app.js new file mode 100644 index 0000000..db23c8f --- /dev/null +++ b/react/plot-app.js @@ -0,0 +1,126 @@ +// this JavaScript snippet stored as react/plot-app.js +// this JavaScript snippet is later referred to as <> +function Heading() { + const title = 'Root finding web application'; + return

{title}

+} + +// this JavaScript snippet is later referred to as <> +function Plot({roots}) { + const container = React.useRef(null); + + function didUpdate() { + if (container.current === null) { + return; + } + // this JavaScript snippet is later referred to as <> + const spec = { + "$schema": "https://vega.github.io/schema/vega-lite/v4.json", + "data": { "values": roots }, + "mark": "point", + "encoding": { + "x": { "field": "epsilon", "type": "quantitative" }, + "y": { "field": "duration", "type": "quantitative", "title": "Duration (ms)" } + }, + "width": 800, + "height": 600 + }; + vegaEmbed(container.current, spec); + } + const dependencies = [container, roots]; + React.useEffect(didUpdate, dependencies); + + return
; +} + +function App() { + const Form = JSONSchemaForm.default; + const uiSchema = { + "guess": { + "ui:widget": "range" + } + } + const [formData, setFormData] = React.useState({ + + }); + + function handleChange(event) { + setFormData(event.formData); + } + + // this JavaScript snippet is later referred to as <> + const schema = { + "type": "object", + "properties": { + "epsilon": { + "title": "Epsilon", + "type": "object", + "properties": { + "min": { + "type": "number", + "minimum": 0, + "default": 0.0001 + }, + "max": { + "type": "number", + "minimum": 0, + "default": 0.001 + }, + "step": { + "type": "number", + "minimum": 0, + "default": 0.0001 + } + }, + "required": ["min", "max", "step"], + "additionalProperties": false + }, + "guess": { + "title": "Initial guess", + "type": "number", + "minimum": -100, + "maximum": 100, + "default": -20 + } + }, + "required": ["epsilon", "guess"], + "additionalProperties": false + } + // this JavaScript snippet is appended to <> + const [roots, setRoots] = React.useState([]); + + function handleSubmit(submission, event) { + event.preventDefault(); + const worker = new Worker('worker-sweep.js'); + worker.postMessage({ + type: 'CALCULATE', + payload: submission.formData + }); + worker.onmessage = function(message) { + if (message.data.type === 'RESULT') { + const result = message.data.payload.roots; + setRoots(result); + worker.terminate(); + } + }; + } + + return ( +
+ + { /* this JavaScript snippet is later referred to as <> */} + + +
+ ); +} + +ReactDOM.render( + , + document.getElementById('container') +); \ No newline at end of file diff --git a/react/worker-sweep.js b/react/worker-sweep.js new file mode 100644 index 0000000..1251b4a --- /dev/null +++ b/react/worker-sweep.js @@ -0,0 +1,36 @@ +// this JavaScript snippet stored as react/worker-sweep.js +importScripts('newtonraphsonwasm.js'); + +onmessage = function(message) { + if (message.data.type === 'CALCULATE') { + createModule().then((module) => { + // this JavaScript snippet is later referred to as <> + const {min, max, step} = message.data.payload.epsilon; + const guess = message.data.payload.guess; + // this JavaScript snippet appended to <> + const roots = []; + // this JavaScript snippet appended to <> + for (let epsilon = min; epsilon <= max; epsilon += step) { + // this JavaScript snippet appended to <> + const t0 = performance.now(); + const finder = new module.NewtonRaphson(epsilon); + const root = finder.solve(guess); + const duration = performance.now() - t0; + // this JavaScript snippet appended to <> + roots.push({ + epsilon, + guess, + root, + duration + }); + // this JavaScript snippet appended to <> + } + postMessage({ + type: 'RESULT', + payload: { + roots + } + }); + }); + } +}; \ No newline at end of file diff --git a/src/py-newtonraphson.cpp b/src/py-newtonraphson.cpp deleted file mode 100644 index 4ab1b40..0000000 --- a/src/py-newtonraphson.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// this C++ snippet is stored as src/py-newtonraphson.cpp -#include -#include - -// this C++ code snippet is later referred to as <> -#include "newtonraphson.hpp" -#include "algebra.hpp" - -using namespace algebra; - -namespace rootfinding -{ - -NewtonRaphson::NewtonRaphson(double tolerancein) : tolerance(tolerancein) {} - -// Function to find the root -double NewtonRaphson::solve(double xin) -{ - double x = xin; - double delta_x = equation(x) / derivative(x); - while (abs(delta_x) >= tolerance) - { - delta_x = equation(x) / derivative(x); - - // x_new = x_old - f(x) / f'(x) - x = x - delta_x; - } - return x; -}; - - -} // namespace rootfinding - -namespace py = pybind11; - -PYBIND11_MODULE(newtonraphsonpy, m) { - py::class_(m, "NewtonRaphson") - .def(py::init(), py::arg("epsilon")) - .def("solve", - &rootfinding::NewtonRaphson::solve, - py::arg("guess"), - "Find root starting from initial guess" - ) - ; -} \ No newline at end of file diff --git a/src/py/.gitignore b/src/py/.gitignore deleted file mode 100644 index 303815a..0000000 --- a/src/py/.gitignore +++ /dev/null @@ -1 +0,0 @@ -newtonraphsonpy.cpython-36m-x86_64-linux-gnu.so diff --git a/src/py/hello-templated.py b/src/py/hello-templated.py deleted file mode 100644 index 2c3144d..0000000 --- a/src/py/hello-templated.py +++ /dev/null @@ -1,10 +0,0 @@ -# this Python snippet is stored as src/py/hello-templated.py -from flask import Flask, render_template - -app = Flask(__name__) - -@app.route('/hello/') -def hello_name(name=None): - return render_template('hello.html', name=name) - -app.run() \ No newline at end of file diff --git a/src/py/hello.py b/src/py/hello.py deleted file mode 100644 index ebb2637..0000000 --- a/src/py/hello.py +++ /dev/null @@ -1,9 +0,0 @@ -# this Python snippet is stored as src/py/hello.py -from flask import Flask -app = Flask(__name__) - -@app.route("/") -def hello(): - return "Hello World!" - -app.run() \ No newline at end of file diff --git a/src/py/tasks.py b/src/py/tasks.py deleted file mode 100644 index 7af126b..0000000 --- a/src/py/tasks.py +++ /dev/null @@ -1,19 +0,0 @@ -# this Python snippet is stored as src/py/tasks.py -import time - -# this Python code snippet is later referred to as <> -from celery import Celery -capp = Celery('tasks', broker='redis://localhost:6379', backend='redis://localhost:6379') - -@capp.task(bind=True) -def calculate(self, epsilon, guess): - if not self.request.called_directly: - self.update_state(state='INITIALIZING') - time.sleep(5) - from newtonraphsonpy import NewtonRaphson - finder = NewtonRaphson(epsilon) - if not self.request.called_directly: - self.update_state(state='FINDING') - time.sleep(5) - root = finder.solve(guess) - return {'root': root, 'guess': guess, 'epsilon':epsilon} \ No newline at end of file diff --git a/src/py/webapp-celery.py b/src/py/webapp-celery.py deleted file mode 100644 index 874002d..0000000 --- a/src/py/webapp-celery.py +++ /dev/null @@ -1,45 +0,0 @@ -# this Python snippet is stored as src/py/webapp-celery.py -from flask import Flask, render_template, request, redirect, url_for - -app = Flask(__name__) - -# this Python code snippet is later referred to as <> -@app.route('/', methods=['GET']) -def form(): - return ''' - - - - - - - ''' - -# this Python code snippet is later referred to as <> -@app.route('/', methods=['POST']) -def submit(): - epsilon = float(request.form['epsilon']) - guess = float(request.form['guess']) - from tasks import calculate - job = calculate.delay(epsilon, guess) - return redirect(url_for('result', jobid=job.id)) - -# this Python code snippet is later referred to as <> -@app.route('/result/') -def result(jobid): - from tasks import capp - job = capp.AsyncResult(jobid) - job.maybe_throw() - if job.successful(): - result = job.get() - epsilon = result['epsilon'] - guess = result['guess'] - root = result['root'] - return f''' -

With epsilon of {epsilon} and a guess of {guess} the found root is {root}.

''' - else: - return f''' -

{job.status}

''' - -if __name__ == '__main__': - app.run(port=5000) \ No newline at end of file diff --git a/webassembly/example-web-worker.html b/webassembly/example-web-worker.html new file mode 100644 index 0000000..296931f --- /dev/null +++ b/webassembly/example-web-worker.html @@ -0,0 +1,26 @@ + + + + + Example web worker + + + + + + \ No newline at end of file diff --git a/webassembly/example.html b/webassembly/example.html new file mode 100644 index 0000000..cf0f557 --- /dev/null +++ b/webassembly/example.html @@ -0,0 +1,22 @@ + + + + + Example + + + + + + + \ No newline at end of file diff --git a/src/wasm-newtonraphson.cpp b/webassembly/wasm-newtonraphson.cpp similarity index 92% rename from src/wasm-newtonraphson.cpp rename to webassembly/wasm-newtonraphson.cpp index 32a697d..845c7be 100644 --- a/src/wasm-newtonraphson.cpp +++ b/webassembly/wasm-newtonraphson.cpp @@ -1,4 +1,4 @@ -// this C++ snippet is stored as src/wasm-newtonraphson.cpp +// this C++ snippet is stored as webassembly/wasm-newtonraphson.cpp #include // this C++ code snippet is later referred to as <> diff --git a/webassembly/worker.js b/webassembly/worker.js new file mode 100644 index 0000000..641ae7a --- /dev/null +++ b/webassembly/worker.js @@ -0,0 +1,23 @@ +// this JavaScript snippet is stored as webassembly/worker.js +importScripts('newtonraphsonwasm.js'); + +// this JavaScript snippet is later referred to as <> +onmessage = function(message) { + // this JavaScript snippet is before referred to as <> + if (message.data.type === 'CALCULATE') { + createModule().then((module) => { + // this JavaScript snippet is before referred to as <> + const epsilon = message.data.payload.epsilon; + const finder = new module.NewtonRaphson(epsilon); + const guess = message.data.payload.guess; + const root = finder.solve(guess); + // this JavaScript snippet is before referred to as <> + postMessage({ + type: 'RESULT', + payload: { + root: root + } + }); + }); + } +}; \ No newline at end of file From aa463500f7f6b0f674231b4d1a186aed8b1aee83 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 15:37:25 +0200 Subject: [PATCH 12/48] updated Makefile --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 71e765d..1ca8004 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ UID := $(shell id -u) # Prevent suicide by excluding Makefile ENTANGLED := $(shell perl -ne 'print $$1,"\n" if /^```\{.*file=(.*)\}/' *.md | grep -v Makefile | sort -u) -COMPILED := cli/newtonraphson.exe openapi/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm +COMPILED := cli/newtonraphson.exe openapi/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm entangle: *.md docker run --rm --user ${UID} -v ${PWD}:/data nlesc/pandoc-tangle:0.5.0 --preserve-tabs *.md @@ -82,9 +82,9 @@ run-celery-worker: openapi/newtonraphsonpy.*.so run-celery-webapp: openapi/newtonraphsonpy.*.so python flask/webapp-celery.py -build-wasm: src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm +build-wasm: webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm -src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm: src/wasm-newtonraphson.cpp +webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm: webassembly/wasm-newtonraphson.cpp emcc --bind -o webassembly/newtonraphsonwasm.js -s MODULARIZE=1 -s EXPORT_NAME=createModule webassembly/wasm-newtonraphson.cpp host-files: build-wasm From 7f2d8913c03aff671fe41811896914555fd087d3 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 15:46:06 +0200 Subject: [PATCH 13/48] added sleeps to gh actions to allow services to be up in time --- .github/workflows/main.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fd7a3d1..6c8bed6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -64,8 +64,9 @@ jobs: run: make test-py - name: Start web service in background - run: make run-webservice 2>&1 | tee ./run-webservice.log & - + run: | + make run-webservice 2>&1 | tee ./run-webservice.log & + sleep 2 - name: Test web service run: make test-webservice @@ -106,13 +107,16 @@ jobs: run: make pip-pybind11 && make pip-flask && make pip-celery && pip install httpie - name: Start web application in background - run: make run-webapp 2>&1 | tee ./run-webapp.log & + run: | + make run-webapp 2>&1 | tee ./run-webapp.log & + sleep 2 - name: Test web application run: http --ignore-stdin -f localhost:5001 epsilon=0.001 guess=-20 - name: Start Celery web app in background - run: make run-celery-webapp 2>&1 | tee ./run-celery-webapp.log & + run: | + make run-celery-webapp 2>&1 | tee ./run-celery-webapp.log & - name: Start Celery worker in background run: | From a8232773bb4dfbc4f99aa93328be0a818eed674e Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 16:07:42 +0200 Subject: [PATCH 14/48] test workflow --- .github/workflows/main.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6c8bed6..e031d08 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -106,6 +106,12 @@ jobs: - name: Install Python dependencies run: make pip-pybind11 && make pip-flask && make pip-celery && pip install httpie + - name: TEMP build so + shell: bash -l {0} + run: | + make openapi/newtonraphsonpy.*.so + cd flask && ln -s openapi/newtonraphsonpy.cpython-36m-x86_64-linux-gnu.so && cd - + - name: Start web application in background run: | make run-webapp 2>&1 | tee ./run-webapp.log & From 8aeecfc818c015f080a5939fe4baab939b54b965 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 16:17:27 +0200 Subject: [PATCH 15/48] linking to shared library is now a makefile task --- .github/workflows/main.yml | 6 ++---- .gitignore | 1 + INSTALL.md | 3 +++ Makefile | 3 +++ README.md | 6 ++++++ 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e031d08..ffb4dd7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -106,11 +106,9 @@ jobs: - name: Install Python dependencies run: make pip-pybind11 && make pip-flask && make pip-celery && pip install httpie - - name: TEMP build so - shell: bash -l {0} + - name: Build shared library and link to it run: | - make openapi/newtonraphsonpy.*.so - cd flask && ln -s openapi/newtonraphsonpy.cpython-36m-x86_64-linux-gnu.so && cd - + make flask-link-newtonraphsonpy - name: Start web application in background run: | diff --git a/.gitignore b/.gitignore index 8a0e5aa..91d35ce 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ cypress/videos /cli/newtonraphson.exe /cgi/apache2/cgi-bin/newtonraphson /openapi/newtonraphsonpy.*.so +/flask/newtonraphsonpy.*.so # Ignore entangled db .entangled/db.sqlite diff --git a/INSTALL.md b/INSTALL.md index 234ce4c..ba5d7d1 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -61,6 +61,9 @@ test-cgi: cgi/apache2/cgi-bin/newtonraphson openapi/newtonraphsonpy.*.so: openapi/py-newtonraphson.cpp <> +flask-link-newtonraphsonpy: openapi/newtonraphsonpy.*.so + <> + test-py: openapi/example.py openapi/newtonraphsonpy.*.so <> diff --git a/Makefile b/Makefile index 1ca8004..43a2c87 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,9 @@ openapi/newtonraphsonpy.*.so: openapi/py-newtonraphson.cpp g++ -O3 -Wall -shared -std=c++14 -fPIC -Icli/ `python3 -m pybind11 --includes` \ openapi/py-newtonraphson.cpp -o openapi/newtonraphsonpy`python3-config --extension-suffix` +flask-link-newtonraphsonpy: openapi/newtonraphsonpy.*.so + cd flask && ln -s openapi/newtonraphsonpy.*.so && cd - + test-py: openapi/example.py openapi/newtonraphsonpy.*.so python openapi/example.py diff --git a/README.md b/README.md index 1316d19..13119e9 100644 --- a/README.md +++ b/README.md @@ -403,6 +403,12 @@ The Flask Python library can be installed with pip install flask ``` +We'll use the shared library that the openapi example also uses: + +```{.awk #flask-link-newtonraphsonpy} + cd flask && ln -s openapi/newtonraphsonpy.*.so && cd - +``` + The web application has 3 kinds of pages: 1. a page with form and submit button, From 79b07823dd5bad5263e4c65242d16ee7ba39696d Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 16:38:22 +0200 Subject: [PATCH 16/48] added serving from flask directory for testing --- .github/workflows/main.yml | 25 ++++++++++++++++++++++++- .gitignore | 3 +++ Makefile | 4 ++-- README.md | 4 ++-- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ffb4dd7..250a5be 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -142,7 +142,30 @@ jobs: with: name: service-logs path: ./run-*.log - wasm: + webassembly: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Install emscripten + uses: mymindstorm/setup-emsdk@v4 + + - name: Build WebAssembly module + run: make build-wasm + + - name: Start web server for hosting files in background + run: make host-files 2>&1 | tee ./web-server.log & + + - name: Run tests + run: make test-wasm + + - name: Upload log of web server + if: ${{ always() }} + uses: actions/upload-artifact@v2 + with: + name: web-server-log + path: ./web-server.log + react: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 diff --git a/.gitignore b/.gitignore index 91d35ce..945a084 100644 --- a/.gitignore +++ b/.gitignore @@ -4,12 +4,15 @@ __pycache__/ cypress/plugins cypress/support cypress/videos +/cypress/screenshots # Ignore compiled files /cli/newtonraphson.exe /cgi/apache2/cgi-bin/newtonraphson /openapi/newtonraphsonpy.*.so /flask/newtonraphsonpy.*.so +/webassembly/newtonraphsonwasm.js +/webassembly/newtonraphsonwasm.wasm # Ignore entangled db .entangled/db.sqlite diff --git a/Makefile b/Makefile index 43a2c87..f9471f0 100644 --- a/Makefile +++ b/Makefile @@ -88,10 +88,10 @@ run-celery-webapp: openapi/newtonraphsonpy.*.so build-wasm: webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm: webassembly/wasm-newtonraphson.cpp - emcc --bind -o webassembly/newtonraphsonwasm.js -s MODULARIZE=1 -s EXPORT_NAME=createModule webassembly/wasm-newtonraphson.cpp + emcc -Icli/ --bind -o webassembly/newtonraphsonwasm.js -s MODULARIZE=1 -s EXPORT_NAME=createModule webassembly/wasm-newtonraphson.cpp host-files: build-wasm - python3 -m http.server 8000 + cd flask && python3 -m http.server 8000 && cd - test-wasm: npx cypress run --config-file false diff --git a/README.md b/README.md index 13119e9..8ad37c9 100644 --- a/README.md +++ b/README.md @@ -757,7 +757,7 @@ The algorithm and binding can be compiled into a WebAssembly module with the Ems To make live easier we configure the compile command to generate a `webassembly/newtonraphsonwasm.js` file which exports the `createModule` function. ```{.awk #build-wasm} -emcc --bind -o webassembly/newtonraphsonwasm.js -s MODULARIZE=1 -s EXPORT_NAME=createModule webassembly/wasm-newtonraphson.cpp +emcc -Icli/ --bind -o webassembly/newtonraphsonwasm.js -s MODULARIZE=1 -s EXPORT_NAME=createModule webassembly/wasm-newtonraphson.cpp ``` The compilation also generates a `webassembly/newtonraphsonwasm.wasm` file which will be loaded with the `createModule` function. @@ -814,7 +814,7 @@ The web browser can only load the `newtonraphsonwasm.js` file when hosted by a w Python ships with a built-in web server, we will use it to host the all files of the repository on port 8000. ```{.awk #host-files} -python3 -m http.server 8000 +cd flask && python3 -m http.server 8000 && cd - ``` Visit [http://localhost:8000/webassembly/example.html](http://localhost:8000/webassembly/example.html) to see the result of the calculation. From 7a8968e0a82af4027f0c1bf973ee2f8208af3d0e Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 17:36:40 +0200 Subject: [PATCH 17/48] change makefile task name --- INSTALL.md | 2 +- Makefile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index ba5d7d1..3233a03 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -61,7 +61,7 @@ test-cgi: cgi/apache2/cgi-bin/newtonraphson openapi/newtonraphsonpy.*.so: openapi/py-newtonraphson.cpp <> -flask-link-newtonraphsonpy: openapi/newtonraphsonpy.*.so +flask/newtonraphsonpy.*.so: openapi/newtonraphsonpy.*.so <> test-py: openapi/example.py openapi/newtonraphsonpy.*.so diff --git a/Makefile b/Makefile index f9471f0..d54032d 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ openapi/newtonraphsonpy.*.so: openapi/py-newtonraphson.cpp g++ -O3 -Wall -shared -std=c++14 -fPIC -Icli/ `python3 -m pybind11 --includes` \ openapi/py-newtonraphson.cpp -o openapi/newtonraphsonpy`python3-config --extension-suffix` -flask-link-newtonraphsonpy: openapi/newtonraphsonpy.*.so +flask/newtonraphsonpy.*.so: openapi/newtonraphsonpy.*.so cd flask && ln -s openapi/newtonraphsonpy.*.so && cd - test-py: openapi/example.py openapi/newtonraphsonpy.*.so @@ -101,4 +101,4 @@ init-git-hook: git config --local core.hooksPath .githooks check: entangle - git diff-index --quiet HEAD -- \ No newline at end of file + git diff-index --quiet HEAD -- From b5259aa8b9556a70bfbe7446fdf0247aa313b8d2 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 17:39:45 +0200 Subject: [PATCH 18/48] python webapp tasks now depend on linked .so file, while web service tasks depend on openapi/*.so directly --- INSTALL.md | 6 +++--- Makefile | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 3233a03..1ff5492 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -87,7 +87,7 @@ start-redis: stop-redis: <> -run-webapp: openapi/newtonraphsonpy.*.so +run-webapp: flask/newtonraphsonpy.*.so <> run-webservice: openapi/newtonraphsonpy.*.so @@ -96,10 +96,10 @@ run-webservice: openapi/newtonraphsonpy.*.so test-webservice: <> -run-celery-worker: openapi/newtonraphsonpy.*.so +run-celery-worker: flask/newtonraphsonpy.*.so <> -run-celery-webapp: openapi/newtonraphsonpy.*.so +run-celery-webapp: flask/newtonraphsonpy.*.so <> build-wasm: webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm diff --git a/Makefile b/Makefile index d54032d..4aac3f2 100644 --- a/Makefile +++ b/Makefile @@ -70,7 +70,7 @@ start-redis: stop-redis: docker stop some-redis -run-webapp: openapi/newtonraphsonpy.*.so +run-webapp: flask/newtonraphsonpy.*.so python flask/webapp.py run-webservice: openapi/newtonraphsonpy.*.so @@ -79,10 +79,10 @@ run-webservice: openapi/newtonraphsonpy.*.so test-webservice: curl -X POST "http://localhost:8080/api/newtonraphson" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"epsilon\":0.001,\"guess\":-20}" -run-celery-worker: openapi/newtonraphsonpy.*.so +run-celery-worker: flask/newtonraphsonpy.*.so PYTHONPATH=openapi celery worker -A tasks -run-celery-webapp: openapi/newtonraphsonpy.*.so +run-celery-webapp: flask/newtonraphsonpy.*.so python flask/webapp-celery.py build-wasm: webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm @@ -101,4 +101,4 @@ init-git-hook: git config --local core.hooksPath .githooks check: entangle - git diff-index --quiet HEAD -- + git diff-index --quiet HEAD -- \ No newline at end of file From 6af82f1f8de01653f1c5e82f715e3c7a66285c6b Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 17:42:49 +0200 Subject: [PATCH 19/48] Update README.outline.md Co-authored-by: Stefan Verhoeven --- README.outline.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.outline.md b/README.outline.md index dba1b22..f0449c3 100644 --- a/README.outline.md +++ b/README.outline.md @@ -29,6 +29,7 @@ Introduce the example algorithm, as a CLI. # Python web service +- pybind11 - OpenApi, Swagger, JSON schema # Python web application From 4bab7ab1cb8270ba0a265e1ad65be8392b352279 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 17:43:00 +0200 Subject: [PATCH 20/48] Update README.outline.md Co-authored-by: Stefan Verhoeven --- README.outline.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.outline.md b/README.outline.md index f0449c3..6cc7930 100644 --- a/README.outline.md +++ b/README.outline.md @@ -36,7 +36,7 @@ Introduce the example algorithm, as a CLI. - web app v web service difference - explanation of what is a web framework - +- long running tasks, celery # JavaScript web service From 771f4df6d6c622f3f2b2c07b440da711e2d52ee8 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 17:43:18 +0200 Subject: [PATCH 21/48] Update README.outline.md Co-authored-by: Stefan Verhoeven --- README.outline.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.outline.md b/README.outline.md index 6cc7930..06e1342 100644 --- a/README.outline.md +++ b/README.outline.md @@ -44,6 +44,15 @@ Introduce the example algorithm, as a CLI. # JavaScript web application +- how to use wasm in webbrowser +- long running with web worker +- react, explain react/vue/angular here +- json schema form +- vega plot + + + + --- From 919e4253e6b9d237c1780b4d3370ef5132197d56 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 17:43:26 +0200 Subject: [PATCH 22/48] Update README.outline.md Co-authored-by: Stefan Verhoeven --- README.outline.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.outline.md b/README.outline.md index 06e1342..a3c91a7 100644 --- a/README.outline.md +++ b/README.outline.md @@ -61,4 +61,3 @@ Introduce the example algorithm, as a CLI. - long running tasks (concept, Python toolset, JavaScript toolset): consider splitting off into 1 or 2 separate documents; in the main document describe a what is basically a Promise and point to the relevant other document - single page application - Optional add pros and cons per section -- embedded github.io doesnt yield the same values as the CLI From 3c24dbe2ce715c0cf7fc856e009e0bdbda8f0095 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 17:46:10 +0200 Subject: [PATCH 23/48] forgot to update the workflow --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 250a5be..38f3fec 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -108,7 +108,7 @@ jobs: - name: Build shared library and link to it run: | - make flask-link-newtonraphsonpy + make flask/newtonraphsonpy.*.so - name: Start web application in background run: | From b7a83474428ad51fa883d0117de481a810e400ef Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 17:56:41 +0200 Subject: [PATCH 24/48] now using python extension suffix in the softlink --- Makefile | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 4aac3f2..77d35a3 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ openapi/newtonraphsonpy.*.so: openapi/py-newtonraphson.cpp openapi/py-newtonraphson.cpp -o openapi/newtonraphsonpy`python3-config --extension-suffix` flask/newtonraphsonpy.*.so: openapi/newtonraphsonpy.*.so - cd flask && ln -s openapi/newtonraphsonpy.*.so && cd - + cd flask && ln -s ../openapi/newtonraphsonpy`python3-config --extension-suffix` . && cd - test-py: openapi/example.py openapi/newtonraphsonpy.*.so python openapi/example.py diff --git a/README.md b/README.md index 8ad37c9..838ad34 100644 --- a/README.md +++ b/README.md @@ -406,7 +406,7 @@ pip install flask We'll use the shared library that the openapi example also uses: ```{.awk #flask-link-newtonraphsonpy} - cd flask && ln -s openapi/newtonraphsonpy.*.so && cd - + cd flask && ln -s ../openapi/newtonraphsonpy`python3-config --extension-suffix` . && cd - ``` The web application has 3 kinds of pages: From b53c9b0903a546e6f7e564e7d7c5da9279a756b7 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 18:09:10 +0200 Subject: [PATCH 25/48] updated paths in a few spec files --- TESTING.md | 12 ++++----- .../integration/example-web-worker_spec.js | 4 +-- cypress/integration/example_spec.js | 4 +-- src/js/example-web-worker.html | 26 ------------------- src/js/example.html | 22 ---------------- 5 files changed, 10 insertions(+), 58 deletions(-) delete mode 100644 src/js/example-web-worker.html delete mode 100644 src/js/example.html diff --git a/TESTING.md b/TESTING.md index 3177a48..973ccf3 100644 --- a/TESTING.md +++ b/TESTING.md @@ -13,25 +13,25 @@ To visit a web page we need to start a simple web server with using Python python3 -m http.server 8000 ``` -Let's, first write a test for the [direct WebAssembly example](http://localhost:8000/src/js/example.html). +Let's, first write a test for the [direct WebAssembly example](http://localhost:8000/webassembly/example.html). ```{.js file=cypress/integration/example_spec.js} // this JavaScript snippet is run by cypress and is stored as cypress/integration/example_spec.js -describe('src/js/example.html', () => { +describe('webassembly/example.html', () => { it('should render -1.00', () => { - cy.visit('http://localhost:8000/src/js/example.html'); + cy.visit('http://localhost:8000/webassembly/example.html'); cy.get('#answer').contains('-1.00'); }); }); ``` -Second, a test for the WebAssembly called through a [web worker](http://localhost:8000/src/js/example-web-worker.html). +Second, a test for the WebAssembly called through a [web worker](http://localhost:8000/webassembly/example-web-worker.html). ```{.js file=cypress/integration/example-web-worker_spec.js} // this JavaScript snippet is run by cypress and is stored as cypress/integration/example-web-worker_spec.js -describe('src/js/example-web-worker.html', () => { +describe('webassembly/example-web-worker.html', () => { it('should render -1.00', () => { - cy.visit('http://localhost:8000/src/js/example-web-worker.html'); + cy.visit('http://localhost:8000/webassembly/example-web-worker.html'); cy.get('#answer').contains('-1.00'); }); }); diff --git a/cypress/integration/example-web-worker_spec.js b/cypress/integration/example-web-worker_spec.js index fcc8b24..e146e6c 100644 --- a/cypress/integration/example-web-worker_spec.js +++ b/cypress/integration/example-web-worker_spec.js @@ -1,7 +1,7 @@ // this JavaScript snippet is run by cypress and is stored as cypress/integration/example-web-worker_spec.js -describe('src/js/example-web-worker.html', () => { +describe('webassembly/example-web-worker.html', () => { it('should render -1.00', () => { - cy.visit('http://localhost:8000/src/js/example-web-worker.html'); + cy.visit('http://localhost:8000/webassembly/example-web-worker.html'); cy.get('#answer').contains('-1.00'); }); }); \ No newline at end of file diff --git a/cypress/integration/example_spec.js b/cypress/integration/example_spec.js index 023a8fd..419f58e 100644 --- a/cypress/integration/example_spec.js +++ b/cypress/integration/example_spec.js @@ -1,7 +1,7 @@ // this JavaScript snippet is run by cypress and is stored as cypress/integration/example_spec.js -describe('src/js/example.html', () => { +describe('webassembly/example.html', () => { it('should render -1.00', () => { - cy.visit('http://localhost:8000/src/js/example.html'); + cy.visit('http://localhost:8000/webassembly/example.html'); cy.get('#answer').contains('-1.00'); }); }); \ No newline at end of file diff --git a/src/js/example-web-worker.html b/src/js/example-web-worker.html deleted file mode 100644 index 7fa1213..0000000 --- a/src/js/example-web-worker.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - Example web worker - - - - - - \ No newline at end of file diff --git a/src/js/example.html b/src/js/example.html deleted file mode 100644 index 31ae418..0000000 --- a/src/js/example.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - Example - - - - - - - \ No newline at end of file From cddd5504e22e46e7fa5c2c65586bd3960826271d Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 18:15:02 +0200 Subject: [PATCH 26/48] updated tests to point to the react/ directory --- TESTING.md | 18 +++++++++--------- src/js/example-app.html | 22 ---------------------- src/js/example-jsonschema-form.html | 22 ---------------------- src/js/example-plot.html | 24 ------------------------ 4 files changed, 9 insertions(+), 77 deletions(-) delete mode 100644 src/js/example-app.html delete mode 100644 src/js/example-jsonschema-form.html delete mode 100644 src/js/example-plot.html diff --git a/TESTING.md b/TESTING.md index 973ccf3..d601b85 100644 --- a/TESTING.md +++ b/TESTING.md @@ -37,13 +37,13 @@ describe('webassembly/example-web-worker.html', () => { }); ``` -Third, a test for the [React/form/Web worker/WebAssembly combination](http://localhost:8000/src/js/example-app.html). +Third, a test for the [React/form/Web worker/WebAssembly combination](http://localhost:8000/react/example-app.html). Let us also change the initial guess value. ```{.js file=cypress/integration/example-app_spec.js} -describe('src/js/example-app.html', () => { +describe('react/example-app.html', () => { it('should render -1.00', () => { - cy.visit('http://localhost:8000/src/js/example-app.html'); + cy.visit('http://localhost:8000/react/example-app.html'); // The initial value of the guess input field is -20 so we append a 0 and it becomes -200 cy.get('input[name=guess]').type('0'); cy.contains('Submit').click(); @@ -52,12 +52,12 @@ describe('src/js/example-app.html', () => { }); ``` -And similar test to the previous one, but now with [JSON schema powered form](http://localhost:8000/src/js/example-jsonschema-form.html). +And similar test to the previous one, but now with [JSON schema powered form](http://localhost:8000/react/example-jsonschema-form.html). ```{.js file=cypress/integration/example-jsonschema-form_spec.js} -describe('src/js/example-jsonschema-form.html', () => { +describe('react/example-jsonschema-form.html', () => { it('should render -1.00', () => { - cy.visit('http://localhost:8000/src/js/example-jsonschema-form.html'); + cy.visit('http://localhost:8000/react/example-jsonschema-form.html'); // The JSON schema powered form uses a hierarchy of identifiers for each input field starting with `root` // As the `epsilon` input field is a direct child of root, it has `root_epsilon` as an identifier const input_selector = 'input[id=root_epsilon]'; @@ -69,12 +69,12 @@ describe('src/js/example-jsonschema-form.html', () => { }); ``` -And lastly a test for the [web application with a plot](http://localhost:8000/src/js/example-plot.html). +And lastly a test for the [web application with a plot](http://localhost:8000/react/example-plot.html). ```{.js file=cypress/integration/example-plot_spec.js} -describe('src/js/example-plot.html', () => { +describe('react/example-plot.html', () => { it('should render -1.00', () => { - cy.visit('http://localhost:8000/src/js/example-plot.html'); + cy.visit('http://localhost:8000/react/example-plot.html'); cy.contains('Submit').click(); // TODO assert plot has been plotted, see https://github.com/NLESC-JCER/cpp2wasm/issues/55 }); diff --git a/src/js/example-app.html b/src/js/example-app.html deleted file mode 100644 index f9d45f7..0000000 --- a/src/js/example-app.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - Example React application - - - - - - - - - - - - - -

- - - \ No newline at end of file diff --git a/src/js/example-jsonschema-form.html b/src/js/example-jsonschema-form.html deleted file mode 100644 index f9780ac..0000000 --- a/src/js/example-jsonschema-form.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - Example JSON schema powered form - - - - - - - - - - - - - -
- - - \ No newline at end of file diff --git a/src/js/example-plot.html b/src/js/example-plot.html deleted file mode 100644 index a31f9c0..0000000 --- a/src/js/example-plot.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - Example plot - - - - - - - - - - - - - - -
- - - - \ No newline at end of file From 68b5bb18a2587f7e71b6274b885f7121d3460318 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 18:15:25 +0200 Subject: [PATCH 27/48] updated tests to point to the react/ directory --- cypress/integration/example-app_spec.js | 4 ++-- cypress/integration/example-jsonschema-form_spec.js | 4 ++-- cypress/integration/example-plot_spec.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cypress/integration/example-app_spec.js b/cypress/integration/example-app_spec.js index d52c07c..2d570e2 100644 --- a/cypress/integration/example-app_spec.js +++ b/cypress/integration/example-app_spec.js @@ -1,6 +1,6 @@ -describe('src/js/example-app.html', () => { +describe('react/example-app.html', () => { it('should render -1.00', () => { - cy.visit('http://localhost:8000/src/js/example-app.html'); + cy.visit('http://localhost:8000/react/example-app.html'); // The initial value of the guess input field is -20 so we append a 0 and it becomes -200 cy.get('input[name=guess]').type('0'); cy.contains('Submit').click(); diff --git a/cypress/integration/example-jsonschema-form_spec.js b/cypress/integration/example-jsonschema-form_spec.js index 80c7209..fdebd67 100644 --- a/cypress/integration/example-jsonschema-form_spec.js +++ b/cypress/integration/example-jsonschema-form_spec.js @@ -1,6 +1,6 @@ -describe('src/js/example-jsonschema-form.html', () => { +describe('react/example-jsonschema-form.html', () => { it('should render -1.00', () => { - cy.visit('http://localhost:8000/src/js/example-jsonschema-form.html'); + cy.visit('http://localhost:8000/react/example-jsonschema-form.html'); // The JSON schema powered form uses a hierarchy of identifiers for each input field starting with `root` // As the `epsilon` input field is a direct child of root, it has `root_epsilon` as an identifier const input_selector = 'input[id=root_epsilon]'; diff --git a/cypress/integration/example-plot_spec.js b/cypress/integration/example-plot_spec.js index 384d166..b07f5f4 100644 --- a/cypress/integration/example-plot_spec.js +++ b/cypress/integration/example-plot_spec.js @@ -1,6 +1,6 @@ -describe('src/js/example-plot.html', () => { +describe('react/example-plot.html', () => { it('should render -1.00', () => { - cy.visit('http://localhost:8000/src/js/example-plot.html'); + cy.visit('http://localhost:8000/react/example-plot.html'); cy.contains('Submit').click(); // TODO assert plot has been plotted, see https://github.com/NLESC-JCER/cpp2wasm/issues/55 }); From cb1ec4cf42c8299bedf5e92b08c3088b9c84b6b5 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 18:28:35 +0200 Subject: [PATCH 28/48] removed duplicate files from src --- src/js/.gitkeep | 0 src/js/app.js | 76 - src/js/jsonschema-app.js | 87 - src/js/newtonraphsonwasm.js | 4146 --------------------------------- src/js/newtonraphsonwasm.wasm | Bin 26547 -> 0 bytes src/js/plot-app.js | 126 - src/js/worker-sweep.js | 36 - src/js/worker.js | 23 - 8 files changed, 4494 deletions(-) delete mode 100644 src/js/.gitkeep delete mode 100644 src/js/app.js delete mode 100644 src/js/jsonschema-app.js delete mode 100644 src/js/newtonraphsonwasm.js delete mode 100644 src/js/newtonraphsonwasm.wasm delete mode 100644 src/js/plot-app.js delete mode 100644 src/js/worker-sweep.js delete mode 100644 src/js/worker.js diff --git a/src/js/.gitkeep b/src/js/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/js/app.js b/src/js/app.js deleted file mode 100644 index 239d078..0000000 --- a/src/js/app.js +++ /dev/null @@ -1,76 +0,0 @@ -// this JavaScript snippet is later referred to as <> -function Heading() { - const title = 'Root finding web application'; - return

{title}

-} -// this JavaScript snippet is later referred to as <> -function Result(props) { - const root = props.root; - let message = 'Not submitted'; - if (root !== undefined) { - message = 'Root = ' + root; - } - return
{message}
; -} - -// this JavaScript snippet appenended to src/js/app.js -function App() { - // this JavaScript snippet is later referred to as <> - const [epsilon, setEpsilon] = React.useState(0.001); - // this JavaScript snippet is appended to <> - function onEpsilonChange(event) { - setEpsilon(Number(event.target.value)); - } - // this JavaScript snippet is appended to <> - const [guess, setGuess] = React.useState(-20); - - function onGuessChange(event) { - setGuess(Number(event.target.value)); - } - // this JavaScript snippet is appended to <> - const [root, setRoot] = React.useState(undefined); - - function handleSubmit(event) { - // this JavaScript snippet is later referred to as <> - event.preventDefault(); - // this JavaScript snippet is appended to <> - const worker = new Worker('worker.js'); - // this JavaScript snippet is appended to <> - worker.postMessage({ - type: 'CALCULATE', - payload: { epsilon: epsilon, guess: guess } - }); - // this JavaScript snippet is appended to <> - worker.onmessage = function(message) { - if (message.data.type === 'RESULT') { - const result = message.data.payload.root; - setRoot(result); - worker.terminate(); - } - }; - } - - return ( -
- - { /* this JavaScript snippet is later referred to as <> */ } -
- - - -
- -
- ); -} -// this JavaScript snippet appenended to src/js/app.js -ReactDOM.render( - , - document.getElementById('container') -); \ No newline at end of file diff --git a/src/js/jsonschema-app.js b/src/js/jsonschema-app.js deleted file mode 100644 index 37935eb..0000000 --- a/src/js/jsonschema-app.js +++ /dev/null @@ -1,87 +0,0 @@ -// this JavaScript snippet stored as src/js/jsonschema-app.js -function App() { - // this JavaScript snippet is later referred to as <> - const schema = { - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://nlesc-jcer.github.io/cpp2wasm/NNRequest.json", - "type": "object", - "properties": { - "epsilon": { - "title": "Epsilon", - "type": "number", - "minimum": 0 - }, - "guess": { - "title": "Initial guess", - "type": "integer", - "minimum": -100, - "maximum": 100 - } - }, - "required": ["epsilon", "guess"], - "additionalProperties": false - } - // this JavaScript snippet is appended to <> - const Form = JSONSchemaForm.default; - // this JavaScript snippet is appended to <> - const [formData, setFormData] = React.useState({ - epsilon: 0.001, - guess: -20 - }); - - function handleChange(event) { - setFormData(event.formData); - } - // this JavaScript snippet is appended to <> - const [root, setRoot] = React.useState(undefined); - - function handleSubmit(submission, event) { - event.preventDefault(); - const worker = new Worker('worker.js'); - worker.postMessage({ - type: 'CALCULATE', - payload: submission.formData - }); - worker.onmessage = function(message) { - if (message.data.type === 'RESULT') { - const result = message.data.payload.root; - setRoot(result); - worker.terminate(); - } - }; - } - - return ( -
- - { /* this JavaScript snippet is later referred to as <> */} -
- -
- ); -} - -ReactDOM.render( - , - document.getElementById('container') -); -// this JavaScript snippet appended to src/js/jsonschema-app.js -// this JavaScript snippet is later referred to as <> -function Heading() { - const title = 'Root finding web application'; - return

{title}

-} -// this JavaScript snippet is later referred to as <> -function Result(props) { - const root = props.root; - let message = 'Not submitted'; - if (root !== undefined) { - message = 'Root = ' + root; - } - return
{message}
; -} \ No newline at end of file diff --git a/src/js/newtonraphsonwasm.js b/src/js/newtonraphsonwasm.js deleted file mode 100644 index 31054d0..0000000 --- a/src/js/newtonraphsonwasm.js +++ /dev/null @@ -1,4146 +0,0 @@ - -var createModule = (function() { - var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; - if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename; - return ( -function(createModule) { - createModule = createModule || {}; - - - -// 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(Module) { ..generated code.. } -// 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 = typeof createModule !== 'undefined' ? createModule : {}; - - -// Set up the promise that indicates the Module is initialized -var readyPromiseResolve, readyPromiseReject; -Module['ready'] = new Promise(function(resolve, reject) { - readyPromiseResolve = resolve; - readyPromiseReject = reject; -}); - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_main')) { - Object.defineProperty(Module['ready'], '_main', { configurable: true, get: function() { abort('You are getting _main on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_main', { configurable: true, set: function() { abort('You are setting _main on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_malloc')) { - Object.defineProperty(Module['ready'], '_malloc', { configurable: true, get: function() { abort('You are getting _malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_malloc', { configurable: true, set: function() { abort('You are setting _malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_free')) { - Object.defineProperty(Module['ready'], '_free', { configurable: true, get: function() { abort('You are getting _free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_free', { configurable: true, set: function() { abort('You are setting _free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_stackSave')) { - Object.defineProperty(Module['ready'], '_stackSave', { configurable: true, get: function() { abort('You are getting _stackSave on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_stackSave', { configurable: true, set: function() { abort('You are setting _stackSave on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_stackRestore')) { - Object.defineProperty(Module['ready'], '_stackRestore', { configurable: true, get: function() { abort('You are getting _stackRestore on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_stackRestore', { configurable: true, set: function() { abort('You are setting _stackRestore on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_stackAlloc')) { - Object.defineProperty(Module['ready'], '_stackAlloc', { configurable: true, get: function() { abort('You are getting _stackAlloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_stackAlloc', { configurable: true, set: function() { abort('You are setting _stackAlloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '___data_end')) { - Object.defineProperty(Module['ready'], '___data_end', { configurable: true, get: function() { abort('You are getting ___data_end on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '___data_end', { configurable: true, set: function() { abort('You are setting ___data_end on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '___wasm_call_ctors')) { - Object.defineProperty(Module['ready'], '___wasm_call_ctors', { configurable: true, get: function() { abort('You are getting ___wasm_call_ctors on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '___wasm_call_ctors', { configurable: true, set: function() { abort('You are setting ___wasm_call_ctors on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_fflush')) { - Object.defineProperty(Module['ready'], '_fflush', { configurable: true, get: function() { abort('You are getting _fflush on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_fflush', { configurable: true, set: function() { abort('You are setting _fflush on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '___errno_location')) { - Object.defineProperty(Module['ready'], '___errno_location', { configurable: true, get: function() { abort('You are getting ___errno_location on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '___errno_location', { configurable: true, set: function() { abort('You are setting ___errno_location on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], 'onRuntimeInitialized')) { - Object.defineProperty(Module['ready'], 'onRuntimeInitialized', { configurable: true, get: function() { abort('You are getting onRuntimeInitialized on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], 'onRuntimeInitialized', { configurable: true, set: function() { abort('You are setting onRuntimeInitialized on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - -// --pre-jses are emitted after the Module integration code, so that they can -// refer to Module (if they choose; they can also define Module) -// {{PRE_JSES}} - -// 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 = {}; -var key; -for (key in Module) { - if (Module.hasOwnProperty(key)) { - moduleOverrides[key] = Module[key]; - } -} - -var arguments_ = []; -var thisProgram = './this.program'; -var quit_ = function(status, toThrow) { - throw toThrow; -}; - -// 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 = false; -var ENVIRONMENT_IS_SHELL = false; -ENVIRONMENT_IS_WEB = typeof window === 'object'; -ENVIRONMENT_IS_WORKER = typeof importScripts === 'function'; -// N.b. Electron.js environment is simultaneously a NODE-environment, but -// also a web environment. -ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string'; -ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; - -if (Module['ENVIRONMENT']) { - throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -s ENVIRONMENT=web or -s ENVIRONMENT=node)'); -} - - - -// `/` 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 read_, - readAsync, - readBinary, - setWindowTitle; - -var nodeFS; -var nodePath; - -if (ENVIRONMENT_IS_NODE) { - if (ENVIRONMENT_IS_WORKER) { - scriptDirectory = require('path').dirname(scriptDirectory) + '/'; - } else { - scriptDirectory = __dirname + '/'; - } - - - - - read_ = function shell_read(filename, binary) { - if (!nodeFS) nodeFS = require('fs'); - if (!nodePath) nodePath = require('path'); - filename = nodePath['normalize'](filename); - return nodeFS['readFileSync'](filename, binary ? null : 'utf8'); - }; - - readBinary = function readBinary(filename) { - var ret = read_(filename, true); - if (!ret.buffer) { - ret = new Uint8Array(ret); - } - assert(ret.buffer); - return ret; - }; - - - - - if (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 - - process['on']('uncaughtException', function(ex) { - // suppress ExitStatus exceptions from showing an error - if (!(ex instanceof ExitStatus)) { - throw ex; - } - }); - - process['on']('unhandledRejection', abort); - - quit_ = function(status) { - process['exit'](status); - }; - - Module['inspect'] = function () { return '[Emscripten Module object]'; }; - - - -} else -if (ENVIRONMENT_IS_SHELL) { - - - if (typeof read != 'undefined') { - read_ = function shell_read(f) { - return read(f); - }; - } - - readBinary = function readBinary(f) { - var data; - if (typeof readbuffer === 'function') { - return new Uint8Array(readbuffer(f)); - } - data = read(f, 'binary'); - assert(typeof data === 'object'); - return data; - }; - - if (typeof scriptArgs != 'undefined') { - arguments_ = scriptArgs; - } else if (typeof arguments != 'undefined') { - arguments_ = arguments; - } - - if (typeof quit === 'function') { - quit_ = function(status) { - quit(status); - }; - } - - if (typeof print !== 'undefined') { - // Prefer to use print/printErr where they exist, as they usually work better. - if (typeof console === 'undefined') console = /** @type{!Console} */({}); - console.log = /** @type{!function(this:Console, ...*): undefined} */ (print); - console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr !== 'undefined' ? printErr : print); - } - - -} 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. -if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { - if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled - scriptDirectory = self.location.href; - } else if (document.currentScript) { // web - scriptDirectory = document.currentScript.src; - } - // When MODULARIZE, this JS may be executed later, after document.currentScript - // is gone, so we saved it, and we use it here instead of any other info. - if (_scriptDir) { - scriptDirectory = _scriptDir; - } - // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them. - // otherwise, slice off the final part of the url to find the script directory. - // if scriptDirectory does not contain a slash, lastIndexOf will return -1, - // and scriptDirectory will correctly be replaced with an empty string. - if (scriptDirectory.indexOf('blob:') !== 0) { - scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf('/')+1); - } else { - scriptDirectory = ''; - } - - - // Differentiate the Web Worker from the Node Worker case, as reading must - // be done differently. - { - - - - - read_ = function shell_read(url) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, false); - xhr.send(null); - return xhr.responseText; - }; - - if (ENVIRONMENT_IS_WORKER) { - readBinary = function readBinary(url) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, false); - xhr.responseType = 'arraybuffer'; - xhr.send(null); - return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response)); - }; - } - - readAsync = function readAsync(url, onload, onerror) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, true); - xhr.responseType = 'arraybuffer'; - xhr.onload = function xhr_onload() { - if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0 - onload(xhr.response); - return; - } - onerror(); - }; - xhr.onerror = onerror; - xhr.send(null); - }; - - - - - } - - setWindowTitle = function(title) { document.title = title }; -} else -{ - throw new Error('environment detection error'); -} - - -// Set up the out() and err() hooks, which are how we can print to stdout or -// stderr, respectively. -var out = Module['print'] || console.log.bind(console); -var err = Module['printErr'] || console.warn.bind(console); - -// Merge back in the overrides -for (key in moduleOverrides) { - if (moduleOverrides.hasOwnProperty(key)) { - Module[key] = moduleOverrides[key]; - } -} -// Free the object hierarchy contained in the overrides, this lets the GC -// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array. -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 (!Object.getOwnPropertyDescriptor(Module, 'arguments')) Object.defineProperty(Module, 'arguments', { configurable: true, get: function() { abort('Module.arguments has been replaced with plain arguments_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); -if (Module['thisProgram']) thisProgram = Module['thisProgram'];if (!Object.getOwnPropertyDescriptor(Module, 'thisProgram')) Object.defineProperty(Module, 'thisProgram', { configurable: true, get: function() { abort('Module.thisProgram has been replaced with plain thisProgram (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); -if (Module['quit']) quit_ = Module['quit'];if (!Object.getOwnPropertyDescriptor(Module, 'quit')) Object.defineProperty(Module, 'quit', { configurable: true, get: function() { abort('Module.quit has been replaced with plain quit_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); - -// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message -// Assertions on removed incoming Module JS APIs. -assert(typeof Module['memoryInitializerPrefixURL'] === 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead'); -assert(typeof Module['pthreadMainPrefixURL'] === 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead'); -assert(typeof Module['cdInitializerPrefixURL'] === 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead'); -assert(typeof Module['filePackagePrefixURL'] === 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead'); -assert(typeof Module['read'] === 'undefined', 'Module.read option was removed (modify read_ in JS)'); -assert(typeof Module['readAsync'] === 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)'); -assert(typeof Module['readBinary'] === 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)'); -assert(typeof Module['setWindowTitle'] === 'undefined', 'Module.setWindowTitle option was removed (modify setWindowTitle in JS)'); -assert(typeof Module['TOTAL_MEMORY'] === 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY'); -if (!Object.getOwnPropertyDescriptor(Module, 'read')) Object.defineProperty(Module, 'read', { configurable: true, get: function() { abort('Module.read has been replaced with plain read_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); -if (!Object.getOwnPropertyDescriptor(Module, 'readAsync')) Object.defineProperty(Module, 'readAsync', { configurable: true, get: function() { abort('Module.readAsync has been replaced with plain readAsync (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); -if (!Object.getOwnPropertyDescriptor(Module, 'readBinary')) Object.defineProperty(Module, 'readBinary', { configurable: true, get: function() { abort('Module.readBinary has been replaced with plain readBinary (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); -if (!Object.getOwnPropertyDescriptor(Module, 'setWindowTitle')) Object.defineProperty(Module, 'setWindowTitle', { configurable: true, get: function() { abort('Module.setWindowTitle has been replaced with plain setWindowTitle (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); -var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js'; -var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js'; -var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js'; -var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js'; - - - - - - -// {{PREAMBLE_ADDITIONS}} - -var STACK_ALIGN = 16; - -function dynamicAlloc(size) { - assert(DYNAMICTOP_PTR); - var ret = HEAP32[DYNAMICTOP_PTR>>2]; - var end = (ret + size + 15) & -16; - assert(end <= HEAP8.length, 'failure to dynamicAlloc - memory growth etc. is not supported there, call malloc/sbrk directly'); - HEAP32[DYNAMICTOP_PTR>>2] = end; - return ret; -} - -function alignMemory(size, factor) { - if (!factor) factor = STACK_ALIGN; // stack alignment (16-byte) by default - return Math.ceil(size / factor) * factor; -} - -function getNativeTypeSize(type) { - switch (type) { - case 'i1': case 'i8': return 1; - case 'i16': return 2; - case 'i32': return 4; - case 'i64': return 8; - case 'float': return 4; - case 'double': return 8; - default: { - if (type[type.length-1] === '*') { - return 4; // A pointer - } else if (type[0] === 'i') { - var bits = Number(type.substr(1)); - assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type); - return bits / 8; - } else { - return 0; - } - } - } -} - -function warnOnce(text) { - if (!warnOnce.shown) warnOnce.shown = {}; - if (!warnOnce.shown[text]) { - warnOnce.shown[text] = 1; - err(text); - } -} - - - - - - - - -// Wraps a JS function as a wasm function with a given signature. -function convertJsFunctionToWasm(func, sig) { - - // If the type reflection proposal is available, use the new - // "WebAssembly.Function" constructor. - // Otherwise, construct a minimal wasm module importing the JS function and - // re-exporting it. - if (typeof WebAssembly.Function === "function") { - var typeNames = { - 'i': 'i32', - 'j': 'i64', - 'f': 'f32', - 'd': 'f64' - }; - var type = { - parameters: [], - results: sig[0] == 'v' ? [] : [typeNames[sig[0]]] - }; - for (var i = 1; i < sig.length; ++i) { - type.parameters.push(typeNames[sig[i]]); - } - return new WebAssembly.Function(type, func); - } - - // The module is static, with the exception of the type section, which is - // generated based on the signature passed in. - var typeSection = [ - 0x01, // id: section, - 0x00, // length: 0 (placeholder) - 0x01, // count: 1 - 0x60, // form: func - ]; - var sigRet = sig.slice(0, 1); - var sigParam = sig.slice(1); - var typeCodes = { - 'i': 0x7f, // i32 - 'j': 0x7e, // i64 - 'f': 0x7d, // f32 - 'd': 0x7c, // f64 - }; - - // Parameters, length + signatures - typeSection.push(sigParam.length); - for (var i = 0; i < sigParam.length; ++i) { - typeSection.push(typeCodes[sigParam[i]]); - } - - // Return values, length + signatures - // With no multi-return in MVP, either 0 (void) or 1 (anything else) - if (sigRet == 'v') { - typeSection.push(0x00); - } else { - typeSection = typeSection.concat([0x01, typeCodes[sigRet]]); - } - - // Write the overall length of the type section back into the section header - // (excepting the 2 bytes for the section id and length) - typeSection[1] = typeSection.length - 2; - - // Rest of the module is static - var bytes = new Uint8Array([ - 0x00, 0x61, 0x73, 0x6d, // magic ("\0asm") - 0x01, 0x00, 0x00, 0x00, // version: 1 - ].concat(typeSection, [ - 0x02, 0x07, // import section - // (import "e" "f" (func 0 (type 0))) - 0x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00, - 0x07, 0x05, // export section - // (export "f" (func 0 (type 0))) - 0x01, 0x01, 0x66, 0x00, 0x00, - ])); - - // We can compile this wasm module synchronously because it is very small. - // This accepts an import (at "e.f"), that it reroutes to an export (at "f") - var module = new WebAssembly.Module(bytes); - var instance = new WebAssembly.Instance(module, { - 'e': { - 'f': func - } - }); - var wrappedFunc = instance.exports['f']; - return wrappedFunc; -} - -var freeTableIndexes = []; - -// Weak map of functions in the table to their indexes, created on first use. -var functionsInTableMap; - -// Add a wasm function to the table. -function addFunctionWasm(func, sig) { - var table = wasmTable; - - // Check if the function is already in the table, to ensure each function - // gets a unique index. First, create the map if this is the first use. - if (!functionsInTableMap) { - functionsInTableMap = new WeakMap(); - for (var i = 0; i < table.length; i++) { - var item = table.get(i); - // Ignore null values. - if (item) { - functionsInTableMap.set(item, i); - } - } - } - if (functionsInTableMap.has(func)) { - return functionsInTableMap.get(func); - } - - // It's not in the table, add it now. - - - var ret; - // Reuse a free index if there is one, otherwise grow. - if (freeTableIndexes.length) { - ret = freeTableIndexes.pop(); - } else { - ret = table.length; - // Grow the table - try { - table.grow(1); - } catch (err) { - if (!(err instanceof RangeError)) { - throw err; - } - throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.'; - } - } - - // Set the new value. - try { - // Attempting to call this with JS function will cause of table.set() to fail - table.set(ret, func); - } catch (err) { - if (!(err instanceof TypeError)) { - throw err; - } - assert(typeof sig !== 'undefined', 'Missing signature argument to addFunction'); - var wrapped = convertJsFunctionToWasm(func, sig); - table.set(ret, wrapped); - } - - functionsInTableMap.set(func, ret); - - return ret; -} - -function removeFunctionWasm(index) { - functionsInTableMap.delete(wasmTable.get(index)); - freeTableIndexes.push(index); -} - -// 'sig' parameter is required for the llvm backend but only when func is not -// already a WebAssembly function. -function addFunction(func, sig) { - assert(typeof func !== 'undefined'); - - return addFunctionWasm(func, sig); -} - -function removeFunction(index) { - removeFunctionWasm(index); -} - - - -var funcWrappers = {}; - -function getFuncWrapper(func, sig) { - if (!func) return; // on null pointer, return undefined - assert(sig); - if (!funcWrappers[sig]) { - funcWrappers[sig] = {}; - } - var sigCache = funcWrappers[sig]; - if (!sigCache[func]) { - // optimize away arguments usage in common cases - if (sig.length === 1) { - sigCache[func] = function dynCall_wrapper() { - return dynCall(sig, func); - }; - } else if (sig.length === 2) { - sigCache[func] = function dynCall_wrapper(arg) { - return dynCall(sig, func, [arg]); - }; - } else { - // general case - sigCache[func] = function dynCall_wrapper() { - return dynCall(sig, func, Array.prototype.slice.call(arguments)); - }; - } - } - return sigCache[func]; -} - - - - - - - -function makeBigInt(low, high, unsigned) { - return unsigned ? ((+((low>>>0)))+((+((high>>>0)))*4294967296.0)) : ((+((low>>>0)))+((+((high|0)))*4294967296.0)); -} - -/** @param {Array=} args */ -function dynCall(sig, ptr, args) { - if (args && args.length) { - // j (64-bit integer) must be passed in as two numbers [low 32, high 32]. - assert(args.length === sig.substring(1).replace(/j/g, '--').length); - assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\''); - return Module['dynCall_' + sig].apply(null, [ptr].concat(args)); - } else { - assert(sig.length == 1); - assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\''); - return Module['dynCall_' + sig].call(null, ptr); - } -} - -var tempRet0 = 0; - -var setTempRet0 = function(value) { - tempRet0 = value; -}; - -var getTempRet0 = function() { - return tempRet0; -}; - -function getCompilerSetting(name) { - throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for getCompilerSetting or emscripten_get_compiler_setting to work'; -} - -// The address globals begin at. Very low in memory, for code size and optimization opportunities. -// Above 0 is static memory, starting with globals. -// Then the stack. -// Then 'dynamic' memory for sbrk. -var GLOBAL_BASE = 1024; - - - - - -// === 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;if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];if (!Object.getOwnPropertyDescriptor(Module, 'wasmBinary')) Object.defineProperty(Module, 'wasmBinary', { configurable: true, get: function() { abort('Module.wasmBinary has been replaced with plain wasmBinary (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); -var noExitRuntime;if (Module['noExitRuntime']) noExitRuntime = Module['noExitRuntime'];if (!Object.getOwnPropertyDescriptor(Module, 'noExitRuntime')) Object.defineProperty(Module, 'noExitRuntime', { configurable: true, get: function() { abort('Module.noExitRuntime has been replaced with plain noExitRuntime (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); - - -if (typeof WebAssembly !== 'object') { - abort('No WebAssembly support found. Build with -s WASM=0 to target JavaScript instead.'); -} - - - - -// In MINIMAL_RUNTIME, setValue() and getValue() are only available when building with safe heap enabled, for heap safety checking. -// In traditional runtime, setValue() and getValue() are always available (although their use is highly discouraged due to perf penalties) - -/** @param {number} ptr - @param {number} value - @param {string} type - @param {number|boolean=} noSafe */ -function setValue(ptr, value, type, noSafe) { - type = type || 'i8'; - if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit - switch(type) { - case 'i1': HEAP8[((ptr)>>0)]=value; break; - case 'i8': HEAP8[((ptr)>>0)]=value; break; - case 'i16': HEAP16[((ptr)>>1)]=value; break; - case 'i32': HEAP32[((ptr)>>2)]=value; break; - case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break; - case 'float': HEAPF32[((ptr)>>2)]=value; break; - case 'double': HEAPF64[((ptr)>>3)]=value; break; - default: abort('invalid type for setValue: ' + type); - } -} - -/** @param {number} ptr - @param {string} type - @param {number|boolean=} noSafe */ -function getValue(ptr, type, noSafe) { - type = type || 'i8'; - if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit - switch(type) { - case 'i1': return HEAP8[((ptr)>>0)]; - case 'i8': return HEAP8[((ptr)>>0)]; - case 'i16': return HEAP16[((ptr)>>1)]; - case 'i32': return HEAP32[((ptr)>>2)]; - case 'i64': return HEAP32[((ptr)>>2)]; - case 'float': return HEAPF32[((ptr)>>2)]; - case 'double': return HEAPF64[((ptr)>>3)]; - default: abort('invalid type for getValue: ' + type); - } - return null; -} - - - - - - -// Wasm globals - -var wasmMemory; - -// In fastcomp asm.js, we don't need a wasm Table at all. -// In the wasm backend, we polyfill the WebAssembly object, -// so this creates a (non-native-wasm) table for us. -var wasmTable = new WebAssembly.Table({ - 'initial': 30, - 'maximum': 30 + 0, - 'element': 'anyfunc' -}); - - -//======================================== -// 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 = 0; - -/** @type {function(*, string=)} */ -function assert(condition, text) { - if (!condition) { - abort('Assertion failed: ' + text); - } -} - -// Returns the C function with a specified identifier (for C++, you need to do manual name mangling) -function getCFunc(ident) { - var func = Module['_' + ident]; // closure exported function - assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported'); - return func; -} - -// C calling interface. -/** @param {string|null=} returnType - @param {Array=} argTypes - @param {Arguments|Array=} args - @param {Object=} opts */ -function ccall(ident, returnType, argTypes, args, opts) { - // For fast lookup of conversion functions - var toC = { - 'string': function(str) { - var ret = 0; - if (str !== null && str !== undefined && str !== 0) { // null string - // at most 4 bytes per UTF-8 code point, +1 for the trailing '\0' - var len = (str.length << 2) + 1; - ret = stackAlloc(len); - stringToUTF8(str, ret, len); - } - return ret; - }, - 'array': function(arr) { - var ret = stackAlloc(arr.length); - writeArrayToMemory(arr, ret); - return ret; - } - }; - - function convertReturnValue(ret) { - if (returnType === 'string') return UTF8ToString(ret); - if (returnType === 'boolean') return Boolean(ret); - return ret; - } - - var func = getCFunc(ident); - var cArgs = []; - var stack = 0; - assert(returnType !== 'array', 'Return type should not be "array".'); - if (args) { - for (var i = 0; i < args.length; i++) { - var converter = toC[argTypes[i]]; - if (converter) { - if (stack === 0) stack = stackSave(); - cArgs[i] = converter(args[i]); - } else { - cArgs[i] = args[i]; - } - } - } - var ret = func.apply(null, cArgs); - - ret = convertReturnValue(ret); - if (stack !== 0) stackRestore(stack); - return ret; -} - -/** @param {string=} returnType - @param {Array=} argTypes - @param {Object=} opts */ -function cwrap(ident, returnType, argTypes, opts) { - return function() { - return ccall(ident, returnType, argTypes, arguments, opts); - } -} - -var ALLOC_NORMAL = 0; // Tries to use _malloc() -var ALLOC_STACK = 1; // Lives for the duration of the current function call -var ALLOC_DYNAMIC = 2; // Cannot be freed except through sbrk -var ALLOC_NONE = 3; // Do not allocate - -// allocate(): This is for internal use. You can use it yourself as well, but the interface -// is a little tricky (see docs right below). The reason is that it is optimized -// for multiple syntaxes to save space in generated code. So you should -// normally not use allocate(), and instead allocate memory using _malloc(), -// initialize it with setValue(), and so forth. -// @slab: An array of data, or a number. If a number, then the size of the block to allocate, -// in *bytes* (note that this is sometimes confusing: the next parameter does not -// affect this!) -// @types: Either an array of types, one for each byte (or 0 if no type at that position), -// or a single type which is used for the entire block. This only matters if there -// is initial data - if @slab is a number, then this does not matter at all and is -// ignored. -// @allocator: How to allocate memory, see ALLOC_* -/** @type {function((TypedArray|Array|number), string, number, number=)} */ -function allocate(slab, types, allocator, ptr) { - var zeroinit, size; - if (typeof slab === 'number') { - zeroinit = true; - size = slab; - } else { - zeroinit = false; - size = slab.length; - } - - var singleType = typeof types === 'string' ? types : null; - - var ret; - if (allocator == ALLOC_NONE) { - ret = ptr; - } else { - ret = [_malloc, - stackAlloc, - dynamicAlloc][allocator](Math.max(size, singleType ? 1 : types.length)); - } - - if (zeroinit) { - var stop; - ptr = ret; - assert((ret & 3) == 0); - stop = ret + (size & ~3); - for (; ptr < stop; ptr += 4) { - HEAP32[((ptr)>>2)]=0; - } - stop = ret + size; - while (ptr < stop) { - HEAP8[((ptr++)>>0)]=0; - } - return ret; - } - - if (singleType === 'i8') { - if (slab.subarray || slab.slice) { - HEAPU8.set(/** @type {!Uint8Array} */ (slab), ret); - } else { - HEAPU8.set(new Uint8Array(slab), ret); - } - return ret; - } - - var i = 0, type, typeSize, previousType; - while (i < size) { - var curr = slab[i]; - - type = singleType || types[i]; - if (type === 0) { - i++; - continue; - } - assert(type, 'Must know what type to store in allocate!'); - - if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later - - setValue(ret+i, curr, type); - - // no need to look up size unless type changes, so cache it - if (previousType !== type) { - typeSize = getNativeTypeSize(type); - previousType = type; - } - i += typeSize; - } - - return ret; -} - -// Allocate memory during any stage of startup - static memory early on, dynamic memory later, malloc when ready -function getMemory(size) { - if (!runtimeInitialized) return dynamicAlloc(size); - return _malloc(size); -} - - - - -// runtime_strings.js: Strings related runtime functions that are part of both MINIMAL_RUNTIME and regular runtime. - -// Given a pointer 'ptr' 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. - -var UTF8Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined; - -/** - * @param {number} idx - * @param {number=} maxBytesToRead - * @return {string} - */ -function UTF8ArrayToString(heap, idx, maxBytesToRead) { - 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 means Infinity) - while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr; - - if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) { - return UTF8Decoder.decode(heap.subarray(idx, endPtr)); - } else { - 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 = heap[idx++]; - if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; } - var u1 = heap[idx++] & 63; - if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; } - var u2 = heap[idx++] & 63; - if ((u0 & 0xF0) == 0xE0) { - u0 = ((u0 & 15) << 12) | (u1 << 6) | u2; - } else { - if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte 0x' + u0.toString(16) + ' encountered when deserializing a UTF-8 string on the asm.js/wasm heap to a JS string!'); - u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heap[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. -// 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 -// style or the other. -/** - * @param {number} ptr - * @param {number=} maxBytesToRead - * @return {string} - */ -function UTF8ToString(ptr, maxBytesToRead) { - return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ''; -} - -// Copies the given Javascript String object 'str' to the given byte array at address 'outIdx', -// encoded in UTF8 form and null-terminated. The copy will require at most str.length*4+1 bytes of space in the HEAP. -// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write. -// Parameters: -// str: the Javascript string to copy. -// heap: the array to copy to. Each index in this array is assumed to be one 8-byte element. -// outIdx: The starting offset in the array to begin the copying. -// maxBytesToWrite: The maximum number of bytes this function can write to the array. -// This count should include the null terminator, -// i.e. if maxBytesToWrite=1, only the null terminator will be written and nothing else. -// maxBytesToWrite=0 does not write any bytes to the output, not even the null terminator. -// Returns the number of bytes written, EXCLUDING the null terminator. - -function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) { - if (!(maxBytesToWrite > 0)) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes. - 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; - if (u >= 0x200000) warnOnce('Invalid Unicode code point 0x' + u.toString(16) + ' encountered when serializing a JS string to an UTF-8 string on the asm.js/wasm heap! (Valid unicode code points should be in range 0-0x1FFFFF).'); - 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; -} - -// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', -// null-terminated and encoded in UTF8 form. The copy will require at most str.length*4+1 bytes of space in the HEAP. -// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write. -// Returns the number of bytes written, EXCLUDING the null terminator. - -function stringToUTF8(str, outPtr, maxBytesToWrite) { - assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); - return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite); -} - -// Returns the number of bytes the given Javascript string takes if encoded as a UTF8 byte array, EXCLUDING the null terminator byte. -function 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 u = str.charCodeAt(i); // possibly a lead surrogate - if (u >= 0xD800 && u <= 0xDFFF) u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); - if (u <= 0x7F) ++len; - else if (u <= 0x7FF) len += 2; - else if (u <= 0xFFFF) len += 3; - else len += 4; - } - return len; -} - - - - - -// runtime_strings_extra.js: Strings related runtime functions that are available only in regular runtime. - -// Given a pointer 'ptr' to a null-terminated ASCII-encoded string in the emscripten HEAP, returns -// a copy of that string as a Javascript String object. - -function AsciiToString(ptr) { - var str = ''; - while (1) { - var ch = HEAPU8[((ptr++)>>0)]; - if (!ch) return str; - str += String.fromCharCode(ch); - } -} - -// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', -// null-terminated and encoded in ASCII form. The copy will require at most str.length+1 bytes of space in the HEAP. - -function stringToAscii(str, outPtr) { - return writeAsciiToMemory(str, outPtr, false); -} - -// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns -// a copy of that string as a Javascript String object. - -var UTF16Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-16le') : undefined; - -function UTF16ToString(ptr, maxBytesToRead) { - assert(ptr % 2 == 0, 'Pointer passed to UTF16ToString must be aligned to two bytes!'); - 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)); - } else { - var i = 0; - - var str = ''; - while (1) { - var codeUnit = HEAP16[(((ptr)+(i*2))>>1)]; - if (codeUnit == 0 || i == maxBytesToRead / 2) return str; - ++i; - // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through. - str += String.fromCharCode(codeUnit); - } - } -} - -// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', -// null-terminated and encoded in UTF16 form. The copy will require at most str.length*4+2 bytes of space in the HEAP. -// Use the function lengthBytesUTF16() to compute the exact number of bytes (excluding null terminator) that this function will write. -// Parameters: -// str: the Javascript string to copy. -// outPtr: Byte address in Emscripten HEAP where to write the string to. -// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null -// terminator, i.e. if maxBytesToWrite=2, only the null terminator will be written and nothing else. -// maxBytesToWrite<2 does not write any bytes to the output, not even the null terminator. -// Returns the number of bytes written, EXCLUDING the null terminator. - -function stringToUTF16(str, outPtr, maxBytesToWrite) { - assert(outPtr % 2 == 0, 'Pointer passed to stringToUTF16 must be aligned to two bytes!'); - assert(typeof maxBytesToWrite == 'number', 'stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); - // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. - if (maxBytesToWrite === undefined) { - 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; -} - -// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte. - -function lengthBytesUTF16(str) { - return str.length*2; -} - -function UTF32ToString(ptr, maxBytesToRead) { - assert(ptr % 4 == 0, 'Pointer passed to UTF32ToString must be aligned to four bytes!'); - 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; -} - -// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', -// null-terminated and encoded in UTF32 form. The copy will require at most str.length*4+4 bytes of space in the HEAP. -// Use the function lengthBytesUTF32() to compute the exact number of bytes (excluding null terminator) that this function will write. -// Parameters: -// str: the Javascript string to copy. -// outPtr: Byte address in Emscripten HEAP where to write the string to. -// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null -// terminator, i.e. if maxBytesToWrite=4, only the null terminator will be written and nothing else. -// maxBytesToWrite<4 does not write any bytes to the output, not even the null terminator. -// Returns the number of bytes written, EXCLUDING the null terminator. - -function stringToUTF32(str, outPtr, maxBytesToWrite) { - assert(outPtr % 4 == 0, 'Pointer passed to stringToUTF32 must be aligned to four bytes!'); - assert(typeof maxBytesToWrite == 'number', 'stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); - // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. - if (maxBytesToWrite === undefined) { - 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; -} - -// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte. - -function 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; -} - -// Allocate heap space for a JS string, and write it there. -// It is the responsibility of the caller to free() that memory. -function allocateUTF8(str) { - var size = lengthBytesUTF8(str) + 1; - var ret = _malloc(size); - if (ret) stringToUTF8Array(str, HEAP8, ret, size); - return ret; -} - -// Allocate stack space for a JS string, and write it there. -function allocateUTF8OnStack(str) { - var size = lengthBytesUTF8(str) + 1; - var ret = stackAlloc(size); - stringToUTF8Array(str, HEAP8, ret, size); - return ret; -} - -// Deprecated: This function should not be called because it is unsafe and does not provide -// a maximum length limit of how many bytes it is allowed to write. Prefer calling the -// function stringToUTF8Array() instead, which takes in a maximum length that can be used -// to be secure from out of bounds writes. -/** @deprecated - @param {boolean=} dontAddNull */ -function writeStringToMemory(string, buffer, dontAddNull) { - warnOnce('writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!'); - - var /** @type {number} */ lastChar, /** @type {number} */ end; - if (dontAddNull) { - // stringToUTF8Array always appends null. If we don't want to do that, remember the - // character that existed at the location where the null will be placed, and restore - // that after the write (below). - end = buffer + lengthBytesUTF8(string); - lastChar = HEAP8[end]; - } - stringToUTF8(string, buffer, Infinity); - if (dontAddNull) HEAP8[end] = lastChar; // Restore the value under the null character. -} - -function writeArrayToMemory(array, buffer) { - assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)') - HEAP8.set(array, buffer); -} - -/** @param {boolean=} dontAddNull */ -function writeAsciiToMemory(str, buffer, dontAddNull) { - for (var i = 0; i < str.length; ++i) { - assert(str.charCodeAt(i) === str.charCodeAt(i)&0xff); - HEAP8[((buffer++)>>0)]=str.charCodeAt(i); - } - // Null-terminate the pointer to the HEAP. - if (!dontAddNull) HEAP8[((buffer)>>0)]=0; -} - - - -// Memory management - -var PAGE_SIZE = 16384; -var WASM_PAGE_SIZE = 65536; -var ASMJS_PAGE_SIZE = 16777216; - -function alignUp(x, multiple) { - if (x % multiple > 0) { - x += multiple - (x % multiple); - } - return x; -} - -var HEAP, -/** @type {ArrayBuffer} */ - buffer, -/** @type {Int8Array} */ - HEAP8, -/** @type {Uint8Array} */ - HEAPU8, -/** @type {Int16Array} */ - HEAP16, -/** @type {Uint16Array} */ - HEAPU16, -/** @type {Int32Array} */ - HEAP32, -/** @type {Uint32Array} */ - HEAPU32, -/** @type {Float32Array} */ - HEAPF32, -/** @type {Float64Array} */ - HEAPF64; - -function updateGlobalBufferAndViews(buf) { - buffer = buf; - Module['HEAP8'] = HEAP8 = new Int8Array(buf); - Module['HEAP16'] = HEAP16 = new Int16Array(buf); - Module['HEAP32'] = HEAP32 = new Int32Array(buf); - Module['HEAPU8'] = HEAPU8 = new Uint8Array(buf); - Module['HEAPU16'] = HEAPU16 = new Uint16Array(buf); - Module['HEAPU32'] = HEAPU32 = new Uint32Array(buf); - Module['HEAPF32'] = HEAPF32 = new Float32Array(buf); - Module['HEAPF64'] = HEAPF64 = new Float64Array(buf); -} - -var STATIC_BASE = 1024, - STACK_BASE = 5247376, - STACKTOP = STACK_BASE, - STACK_MAX = 4496, - DYNAMIC_BASE = 5247376, - DYNAMICTOP_PTR = 4336; - -assert(STACK_BASE % 16 === 0, 'stack must start aligned'); -assert(DYNAMIC_BASE % 16 === 0, 'heap must start aligned'); - - -var TOTAL_STACK = 5242880; -if (Module['TOTAL_STACK']) assert(TOTAL_STACK === Module['TOTAL_STACK'], 'the stack size can no longer be determined at runtime') - -var INITIAL_INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 16777216;if (!Object.getOwnPropertyDescriptor(Module, 'INITIAL_MEMORY')) Object.defineProperty(Module, 'INITIAL_MEMORY', { configurable: true, get: function() { abort('Module.INITIAL_MEMORY has been replaced with plain INITIAL_INITIAL_MEMORY (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); - -assert(INITIAL_INITIAL_MEMORY >= TOTAL_STACK, 'INITIAL_MEMORY should be larger than TOTAL_STACK, was ' + INITIAL_INITIAL_MEMORY + '! (TOTAL_STACK=' + TOTAL_STACK + ')'); - -// check for full engine support (use string 'subarray' to avoid closure compiler confusion) -assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray !== undefined && Int32Array.prototype.set !== undefined, - 'JS engine does not provide full typed array support'); - - - - - - - - -// In non-standalone/normal mode, we create the memory here. - - - -// Create the main memory. (Note: this isn't used in STANDALONE_WASM mode since the wasm -// memory is created in the wasm, not in JS.) - - if (Module['wasmMemory']) { - wasmMemory = Module['wasmMemory']; - } else - { - wasmMemory = new WebAssembly.Memory({ - 'initial': INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE - , - 'maximum': INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE - }); - } - - -if (wasmMemory) { - buffer = wasmMemory.buffer; -} - -// If the user provides an incorrect length, just use that length instead rather than providing the user to -// specifically provide the memory length with Module['INITIAL_MEMORY']. -INITIAL_INITIAL_MEMORY = buffer.byteLength; -assert(INITIAL_INITIAL_MEMORY % WASM_PAGE_SIZE === 0); -updateGlobalBufferAndViews(buffer); - -HEAP32[DYNAMICTOP_PTR>>2] = DYNAMIC_BASE; - - - - - - -// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode. -function writeStackCookie() { - assert((STACK_MAX & 3) == 0); - // The stack grows downwards - HEAPU32[(STACK_MAX >> 2)+1] = 0x2135467; - HEAPU32[(STACK_MAX >> 2)+2] = 0x89BACDFE; - // Also test the global address 0 for integrity. - // We don't do this with ASan because ASan does its own checks for this. - HEAP32[0] = 0x63736d65; /* 'emsc' */ -} - -function checkStackCookie() { - var cookie1 = HEAPU32[(STACK_MAX >> 2)+1]; - var cookie2 = HEAPU32[(STACK_MAX >> 2)+2]; - if (cookie1 != 0x2135467 || cookie2 != 0x89BACDFE) { - abort('Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x2135467, but received 0x' + cookie2.toString(16) + ' ' + cookie1.toString(16)); - } - // Also test the global address 0 for integrity. - // We don't do this with ASan because ASan does its own checks for this. - if (HEAP32[0] !== 0x63736d65 /* 'emsc' */) abort('Runtime error: The application has corrupted its heap memory area (address zero)!'); -} - - - - - -// Endianness check (note: assumes compiler arch was little-endian) -(function() { - var h16 = new Int16Array(1); - var h8 = new Int8Array(h16.buffer); - h16[0] = 0x6373; - if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian!'; -})(); - -function abortFnPtrError(ptr, sig) { - abort("Invalid function pointer " + ptr + " called with signature '" + sig + "'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this). Build with ASSERTIONS=2 for more info."); -} - - - -function callRuntimeCallbacks(callbacks) { - while(callbacks.length > 0) { - var callback = callbacks.shift(); - if (typeof callback == 'function') { - callback(Module); // Pass the module as the first argument. - continue; - } - var func = callback.func; - if (typeof func === 'number') { - if (callback.arg === undefined) { - Module['dynCall_v'](func); - } else { - Module['dynCall_vi'](func, callback.arg); - } - } else { - func(callback.arg === undefined ? null : callback.arg); - } - } -} - -var __ATPRERUN__ = []; // functions called before the runtime is initialized -var __ATINIT__ = []; // functions called during startup -var __ATMAIN__ = []; // functions called when main() is to be run -var __ATEXIT__ = []; // functions called during shutdown -var __ATPOSTRUN__ = []; // functions called after the main() is called - -var runtimeInitialized = false; -var runtimeExited = 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() { - checkStackCookie(); - assert(!runtimeInitialized); - runtimeInitialized = true; - - callRuntimeCallbacks(__ATINIT__); -} - -function preMain() { - checkStackCookie(); - - callRuntimeCallbacks(__ATMAIN__); -} - -function exitRuntime() { - checkStackCookie(); - runtimeExited = true; -} - -function postRun() { - checkStackCookie(); - - 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 addOnPreMain(cb) { - __ATMAIN__.unshift(cb); -} - -function addOnExit(cb) { -} - -function addOnPostRun(cb) { - __ATPOSTRUN__.unshift(cb); -} - -/** @param {number|boolean=} ignore */ -function unSign(value, bits, ignore) { - if (value >= 0) { - return value; - } - return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts - : Math.pow(2, bits) + value; -} -/** @param {number|boolean=} ignore */ -function reSign(value, bits, ignore) { - if (value <= 0) { - return value; - } - var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32 - : Math.pow(2, bits-1); - if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that - // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors - // TODO: In i64 mode 1, resign the two parts separately and safely - value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts - } - return value; -} - - - - -// 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 - -assert(Math.imul, 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); -assert(Math.fround, 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); -assert(Math.clz32, 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); -assert(Math.trunc, 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); - -var Math_abs = Math.abs; -var Math_cos = Math.cos; -var Math_sin = Math.sin; -var Math_tan = Math.tan; -var Math_acos = Math.acos; -var Math_asin = Math.asin; -var Math_atan = Math.atan; -var Math_atan2 = Math.atan2; -var Math_exp = Math.exp; -var Math_log = Math.log; -var Math_sqrt = Math.sqrt; -var Math_ceil = Math.ceil; -var Math_floor = Math.floor; -var Math_pow = Math.pow; -var Math_imul = Math.imul; -var Math_fround = Math.fround; -var Math_round = Math.round; -var Math_min = Math.min; -var Math_max = Math.max; -var Math_clz32 = Math.clz32; -var Math_trunc = Math.trunc; - - - -// 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 runDependencyWatcher = null; -var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled -var runDependencyTracking = {}; - -function getUniqueRunDependency(id) { - var orig = id; - while (1) { - if (!runDependencyTracking[id]) return id; - id = orig + Math.random(); - } -} - -function addRunDependency(id) { - runDependencies++; - - if (Module['monitorRunDependencies']) { - Module['monitorRunDependencies'](runDependencies); - } - - if (id) { - assert(!runDependencyTracking[id]); - runDependencyTracking[id] = 1; - if (runDependencyWatcher === null && typeof setInterval !== 'undefined') { - // Check for missing dependencies every few seconds - runDependencyWatcher = setInterval(function() { - if (ABORT) { - clearInterval(runDependencyWatcher); - runDependencyWatcher = null; - return; - } - var shown = false; - for (var dep in runDependencyTracking) { - if (!shown) { - shown = true; - err('still waiting on run dependencies:'); - } - err('dependency: ' + dep); - } - if (shown) { - err('(end of list)'); - } - }, 10000); - } - } else { - err('warning: run dependency added without ID'); - } -} - -function removeRunDependency(id) { - runDependencies--; - - if (Module['monitorRunDependencies']) { - Module['monitorRunDependencies'](runDependencies); - } - - if (id) { - assert(runDependencyTracking[id]); - delete runDependencyTracking[id]; - } else { - err('warning: run dependency removed without ID'); - } - if (runDependencies == 0) { - if (runDependencyWatcher !== null) { - clearInterval(runDependencyWatcher); - runDependencyWatcher = null; - } - if (dependenciesFulfilled) { - var callback = dependenciesFulfilled; - dependenciesFulfilled = null; - callback(); // can add another dependenciesFulfilled - } - } -} - -Module["preloadedImages"] = {}; // maps url to image data -Module["preloadedAudios"] = {}; // maps url to audio data - -/** @param {string|number=} what */ -function abort(what) { - if (Module['onAbort']) { - Module['onAbort'](what); - } - - what += ''; - out(what); - err(what); - - ABORT = true; - EXITSTATUS = 1; - - var output = 'abort(' + what + ') at ' + stackTrace(); - what = output; - - // Throw 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. - throw new WebAssembly.RuntimeError(what); -} - - -var memoryInitializer = null; - - - - - - - -// show errors on likely calls to FS when it was not included -var FS = { - error: function() { - abort('Filesystem support (FS) was not included. The problem is that you are using files from JS, but files were not used from C/C++, so filesystem support was not auto-included. You can force-include filesystem support with -s FORCE_FILESYSTEM=1'); - }, - init: function() { FS.error() }, - createDataFile: function() { FS.error() }, - createPreloadedFile: function() { FS.error() }, - createLazyFile: function() { FS.error() }, - open: function() { FS.error() }, - mkdev: function() { FS.error() }, - registerDevice: function() { FS.error() }, - analyzePath: function() { FS.error() }, - loadFilesFromDB: function() { FS.error() }, - - ErrnoError: function ErrnoError() { FS.error() }, -}; -Module['FS_createDataFile'] = FS.createDataFile; -Module['FS_createPreloadedFile'] = FS.createPreloadedFile; - - - - - -function hasPrefix(str, prefix) { - return String.prototype.startsWith ? - str.startsWith(prefix) : - str.indexOf(prefix) === 0; -} - -// 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. -function isDataURI(filename) { - return hasPrefix(filename, dataURIPrefix); -} - -var fileURIPrefix = "file://"; - -// Indicates whether filename is delivered via file protocol (as opposed to http/https) -function isFileURI(filename) { - return hasPrefix(filename, fileURIPrefix); -} - - - -function createExportWrapper(name, fixedasm) { - return function() { - var displayName = name; - var asm = fixedasm; - if (!fixedasm) { - asm = Module['asm']; - } - assert(runtimeInitialized, 'native function `' + displayName + '` called before runtime initialization'); - assert(!runtimeExited, 'native function `' + displayName + '` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); - if (!asm[name]) { - assert(asm[name], 'exported native function `' + displayName + '` not found'); - } - return asm[name].apply(null, arguments); - }; -} - -var wasmBinaryFile = 'newtonraphsonwasm.wasm'; -if (!isDataURI(wasmBinaryFile)) { - wasmBinaryFile = locateFile(wasmBinaryFile); -} - -function getBinary() { - try { - if (wasmBinary) { - return new Uint8Array(wasmBinary); - } - - if (readBinary) { - return readBinary(wasmBinaryFile); - } else { - throw "both async and sync fetching of the wasm failed"; - } - } - catch (err) { - abort(err); - } -} - -function getBinaryPromise() { - // If we don't have the binary yet, and have the Fetch api, use that; - // in some environments, like Electron's render process, Fetch api may be present, but have a different context than expected, let's only use it on the Web - if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && typeof fetch === 'function' - // Let's not use fetch to get objects over file:// as it's most likely Cordova which doesn't support fetch for file:// - && !isFileURI(wasmBinaryFile) - ) { - return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) { - if (!response['ok']) { - throw "failed to load wasm binary file at '" + wasmBinaryFile + "'"; - } - return response['arrayBuffer'](); - }).catch(function () { - return getBinary(); - }); - } - // Otherwise, getBinary should be able to get it synchronously - return new Promise(function(resolve, reject) { - resolve(getBinary()); - }); -} - - - -// Create the wasm instance. -// Receives the wasm imports, returns the exports. -function createWasm() { - // prepare imports - var info = { - 'env': asmLibraryArg, - 'wasi_snapshot_preview1': asmLibraryArg - }; - // 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) { - var exports = instance.exports; - Module['asm'] = exports; - removeRunDependency('wasm-instantiate'); - } - // we can't run yet (except in a pthread, where we have a custom sync instantiator) - addRunDependency('wasm-instantiate'); - - - // Async compilation can be confusing when an error on the page overwrites Module - // (for example, if the order of elements is wrong, and the one defining Module is - // later), so we save Module and check it later. - var trueModule = Module; - function receiveInstantiatedSource(output) { - // 'output' is a WebAssemblyInstantiatedSource object which has both the module and instance. - // receiveInstance() will swap in the exports (to Module.asm) so they can be called - assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?'); - trueModule = null; - // 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, can restore the above USE_PTHREADS-enabled path. - receiveInstance(output['instance']); - } - - - function instantiateArrayBuffer(receiver) { - return getBinaryPromise().then(function(binary) { - return WebAssembly.instantiate(binary, info); - }).then(receiver, function(reason) { - err('failed to asynchronously prepare wasm: ' + reason); - abort(reason); - }); - } - - // Prefer streaming instantiation if available. - function instantiateAsync() { - if (!wasmBinary && - typeof WebAssembly.instantiateStreaming === 'function' && - !isDataURI(wasmBinaryFile) && - // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously. - !isFileURI(wasmBinaryFile) && - typeof fetch === 'function') { - fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function (response) { - var result = WebAssembly.instantiateStreaming(response, info); - return result.then(receiveInstantiatedSource, function(reason) { - // We expect the most common failure cause to be a bad MIME type for the binary, - // in which case falling back to ArrayBuffer instantiation should work. - err('wasm streaming compile failed: ' + reason); - err('falling back to ArrayBuffer instantiation'); - return instantiateArrayBuffer(receiveInstantiatedSource); - }); - }); - } else { - return instantiateArrayBuffer(receiveInstantiatedSource); - } - } - // 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. - if (Module['instantiateWasm']) { - try { - var exports = Module['instantiateWasm'](info, receiveInstance); - return exports; - } catch(e) { - err('Module.instantiateWasm callback failed with error: ' + e); - return false; - } - } - - instantiateAsync(); - return {}; // no exports yet; we'll fill them in later -} - - -// Globals used by JS i64 conversions -var tempDouble; -var tempI64; - -// === Body === - -var ASM_CONSTS = { - -}; - - - - -// STATICTOP = STATIC_BASE + 3472; -/* global initializers */ __ATINIT__.push({ func: function() { ___wasm_call_ctors() } }); - - - - -/* no memory initializer */ -// {{PRE_LIBRARY}} - - - function abortStackOverflow(allocSize) { - abort('Stack overflow! Attempted to allocate ' + allocSize + ' bytes on the stack, but stack has only ' + (STACK_MAX - stackSave() + allocSize) + ' bytes available!'); - } - - function demangle(func) { - warnOnce('warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling'); - return func; - } - - function demangleAll(text) { - var regex = - /\b_Z[\w\d_]+/g; - return text.replace(regex, - function(x) { - var y = demangle(x); - return x === y ? x : (y + ' [' + x + ']'); - }); - } - - function jsStackTrace() { - var err = new Error(); - if (!err.stack) { - // IE10+ special cases: It does have callstack info, but it is only populated if an Error object is thrown, - // so try that as a special-case. - try { - throw new Error(); - } catch(e) { - err = e; - } - if (!err.stack) { - return '(no stack trace available)'; - } - } - return err.stack.toString(); - } - - function stackTrace() { - var js = jsStackTrace(); - if (Module['extraStackTrace']) js += '\n' + Module['extraStackTrace'](); - return demangleAll(js); - } - - function ___handle_stack_overflow() { - abort('stack overflow') - } - - - function getShiftFromSize(size) { - switch (size) { - case 1: return 0; - case 2: return 1; - case 4: return 2; - case 8: return 3; - default: - throw new TypeError('Unknown type size: ' + size); - } - } - - - - function 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=undefined;function readLatin1String(ptr) { - var ret = ""; - var c = ptr; - while (HEAPU8[c]) { - ret += embind_charCodes[HEAPU8[c++]]; - } - return ret; - } - - - var awaitingDependencies={}; - - var registeredTypes={}; - - var typeDependencies={}; - - - - - - - var char_0=48; - - var char_9=57;function makeLegalFunctionName(name) { - if (undefined === name) { - return '_unknown'; - } - name = name.replace(/[^a-zA-Z0-9_]/g, '$'); - var f = name.charCodeAt(0); - if (f >= char_0 && f <= char_9) { - return '_' + name; - } else { - return name; - } - }function createNamedFunction(name, body) { - name = makeLegalFunctionName(name); - /*jshint evil:true*/ - return new Function( - "body", - "return function " + name + "() {\n" + - " \"use strict\";" + - " return body.apply(this, arguments);\n" + - "};\n" - )(body); - }function 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 BindingError=undefined;function throwBindingError(message) { - throw new BindingError(message); - } - - - - var InternalError=undefined;function throwInternalError(message) { - throw new InternalError(message); - }function whenDependentTypesAreResolved(myTypes, dependentTypes, getTypeConverters) { - myTypes.forEach(function(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(function(dt, i) { - if (registeredTypes.hasOwnProperty(dt)) { - typeConverters[i] = registeredTypes[dt]; - } else { - unregisteredTypes.push(dt); - if (!awaitingDependencies.hasOwnProperty(dt)) { - awaitingDependencies[dt] = []; - } - awaitingDependencies[dt].push(function() { - typeConverters[i] = registeredTypes[dt]; - ++registered; - if (registered === unregisteredTypes.length) { - onComplete(typeConverters); - } - }); - } - }); - if (0 === unregisteredTypes.length) { - onComplete(typeConverters); - } - }/** @param {Object=} options */ - function registerType(rawType, registeredInstance, options) { - options = options || {}; - - if (!('argPackAdvance' in registeredInstance)) { - throw new TypeError('registerType registeredInstance requires argPackAdvance'); - } - - 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(function(cb) { - cb(); - }); - } - }function __embind_register_bool(rawType, name, size, trueValue, falseValue) { - var shift = getShiftFromSize(size); - - name = readLatin1String(name); - registerType(rawType, { - name: 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': 8, - 'readValueFromPointer': function(pointer) { - // TODO: if heap is fixed (like in asm.js) this could be executed outside - var heap; - if (size === 1) { - heap = HEAP8; - } else if (size === 2) { - heap = HEAP16; - } else if (size === 4) { - heap = HEAP32; - } else { - throw new TypeError("Unknown boolean type size: " + name); - } - return this['fromWireType'](heap[pointer >> shift]); - }, - destructorFunction: null, // This type does not need a destructor - }); - } - - - - - function ClassHandle_isAliasOf(other) { - if (!(this instanceof ClassHandle)) { - return false; - } - if (!(other instanceof ClassHandle)) { - return false; - } - - var leftClass = this.$$.ptrType.registeredClass; - var left = this.$$.ptr; - 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; - } - - - function shallowCopyInternalPointer(o) { - return { - count: o.count, - deleteScheduled: o.deleteScheduled, - preservePointerOnDelete: o.preservePointerOnDelete, - ptr: o.ptr, - ptrType: o.ptrType, - smartPtr: o.smartPtr, - smartPtrType: o.smartPtrType, - }; - } - - function throwInstanceAlreadyDeleted(obj) { - function getInstanceTypeName(handle) { - return handle.$$.ptrType.registeredClass.name; - } - throwBindingError(getInstanceTypeName(obj) + ' instance already deleted'); - } - - - var finalizationGroup=false; - - function detachFinalizer(handle) {} - - - function runDestructor($$) { - if ($$.smartPtr) { - $$.smartPtrType.rawDestructor($$.smartPtr); - } else { - $$.ptrType.registeredClass.rawDestructor($$.ptr); - } - }function releaseClassHandle($$) { - $$.count.value -= 1; - var toDelete = 0 === $$.count.value; - if (toDelete) { - runDestructor($$); - } - }function attachFinalizer(handle) { - if ('undefined' === typeof FinalizationGroup) { - attachFinalizer = function (handle) { return handle; }; - return handle; - } - // If the running environment has a FinalizationGroup (see - // https://github.com/tc39/proposal-weakrefs), then attach finalizers - // for class handles. We check for the presence of FinalizationGroup - // at run-time, not build-time. - finalizationGroup = new FinalizationGroup(function (iter) { - for (var result = iter.next(); !result.done; result = iter.next()) { - var $$ = result.value; - if (!$$.ptr) { - console.warn('object already deleted: ' + $$.ptr); - } else { - releaseClassHandle($$); - } - } - }); - attachFinalizer = function(handle) { - finalizationGroup.register(handle, handle.$$, handle.$$); - return handle; - }; - detachFinalizer = function(handle) { - finalizationGroup.unregister(handle.$$); - }; - return attachFinalizer(handle); - }function ClassHandle_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; - } - } - - function ClassHandle_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; - } - } - - function ClassHandle_isDeleted() { - return !this.$$.ptr; - } - - - var delayFunction=undefined; - - var deletionQueue=[]; - - function flushPendingDeletes() { - while (deletionQueue.length) { - var obj = deletionQueue.pop(); - obj.$$.deleteScheduled = false; - obj['delete'](); - } - }function ClassHandle_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; - }function init_ClassHandle() { - ClassHandle.prototype['isAliasOf'] = ClassHandle_isAliasOf; - ClassHandle.prototype['clone'] = ClassHandle_clone; - ClassHandle.prototype['delete'] = ClassHandle_delete; - ClassHandle.prototype['isDeleted'] = ClassHandle_isDeleted; - ClassHandle.prototype['deleteLater'] = ClassHandle_deleteLater; - }function ClassHandle() { - } - - var registeredPointers={}; - - - function 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() { - // TODO This check can be removed in -O3 level "unsafe" optimizations. - if (!proto[methodName].overloadTable.hasOwnProperty(arguments.length)) { - throwBindingError("Function '" + humanName + "' called with an invalid number of arguments (" + arguments.length + ") - expects one of (" + proto[methodName].overloadTable + ")!"); - } - return proto[methodName].overloadTable[arguments.length].apply(this, arguments); - }; - // Move the previous function into the overload table. - proto[methodName].overloadTable = []; - proto[methodName].overloadTable[prevFunc.argCount] = prevFunc; - } - }/** @param {number=} numArguments */ - function 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.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; - if (undefined !== numArguments) { - Module[name].numArguments = numArguments; - } - } - } - - /** @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 = []; - } - - - - function 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; - }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 "' + _embind_repr(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; - } - - 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.$$) { - throwBindingError('Cannot pass "' + _embind_repr(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_register(function() { - clonedHandle['delete'](); - }) - ); - if (destructors !== null) { - destructors.push(this.rawDestructor, ptr); - } - } - break; - - default: - throwBindingError('Unsupporting sharing policy'); - } - } - return ptr; - } - - 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 "' + _embind_repr(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; - } - - - function simpleReadValueFromPointer(pointer) { - return this['fromWireType'](HEAPU32[pointer >> 2]); - } - - function RegisteredPointer_getPointee(ptr) { - if (this.rawGetPointee) { - ptr = this.rawGetPointee(ptr); - } - return ptr; - } - - function RegisteredPointer_destructor(ptr) { - if (this.rawDestructor) { - this.rawDestructor(ptr); - } - } - - function RegisteredPointer_deleteObject(handle) { - if (handle !== null) { - handle['delete'](); - } - } - - - function 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); - } - - - - - function getInheritedInstanceCount() { - return Object.keys(registeredInstances).length; - } - - function getLiveInheritedInstances() { - var rv = []; - for (var k in registeredInstances) { - if (registeredInstances.hasOwnProperty(k)) { - rv.push(registeredInstances[k]); - } - } - return rv; - } - - function setDelayFunction(fn) { - delayFunction = fn; - if (deletionQueue.length && delayFunction) { - delayFunction(flushPendingDeletes); - } - }function init_embind() { - Module['getInheritedInstanceCount'] = getInheritedInstanceCount; - Module['getLiveInheritedInstances'] = getLiveInheritedInstances; - Module['flushPendingDeletes'] = flushPendingDeletes; - Module['setDelayFunction'] = setDelayFunction; - }var registeredInstances={}; - - function getBasestPointer(class_, ptr) { - if (ptr === undefined) { - throwBindingError('ptr should not be undefined'); - } - while (class_.baseClass) { - ptr = class_.upcast(ptr); - class_ = class_.baseClass; - } - return ptr; - }function getInheritedInstance(class_, ptr) { - ptr = getBasestPointer(class_, ptr); - return registeredInstances[ptr]; - } - - function 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, - }, - })); - }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: 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, - }); - } - }function init_RegisteredPointer() { - RegisteredPointer.prototype.getPointee = RegisteredPointer_getPointee; - RegisteredPointer.prototype.destructor = RegisteredPointer_destructor; - RegisteredPointer.prototype['argPackAdvance'] = 8; - RegisteredPointer.prototype['readValueFromPointer'] = simpleReadValueFromPointer; - RegisteredPointer.prototype['deleteObject'] = RegisteredPointer_deleteObject; - RegisteredPointer.prototype['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 */ - function replacePublicSymbol(name, value, numArguments) { - if (!Module.hasOwnProperty(name)) { - throwInternalError('Replacing nonexistant 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; - } - } - - function embind__requireFunction(signature, rawFunction) { - signature = readLatin1String(signature); - - function makeDynCaller(dynCall) { - var args = []; - for (var i = 1; i < signature.length; ++i) { - args.push('a' + i); - } - - var name = 'dynCall_' + signature + '_' + rawFunction; - var body = 'return function ' + name + '(' + args.join(', ') + ') {\n'; - body += ' return dynCall(rawFunction' + (args.length ? ', ' : '') + args.join(', ') + ');\n'; - body += '};\n'; - - return (new Function('dynCall', 'rawFunction', body))(dynCall, rawFunction); - } - - var dc = Module['dynCall_' + signature]; - var fp = makeDynCaller(dc); - - if (typeof fp !== "function") { - throwBindingError("unknown function pointer with signature " + signature + ": " + rawFunction); - } - return fp; - } - - - var UnboundTypeError=undefined; - - function getTypeName(type) { - var ptr = ___getTypeName(type); - var rv = readLatin1String(ptr); - _free(ptr); - return rv; - }function 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([', '])); - }function __embind_register_class( - rawType, - rawPointerType, - rawConstPointerType, - baseClassRawType, - getActualTypeSignature, - getActualType, - upcastSignature, - upcast, - downcastSignature, - downcast, - name, - destructorSignature, - rawDestructor - ) { - name = readLatin1String(name); - getActualType = embind__requireFunction(getActualTypeSignature, getActualType); - if (upcast) { - upcast = embind__requireFunction(upcastSignature, upcast); - } - if (downcast) { - 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] : [], - function(base) { - base = base[0]; - - var baseClass; - var basePrototype; - if (baseClassRawType) { - baseClass = base.registeredClass; - basePrototype = baseClass.instancePrototype; - } else { - basePrototype = ClassHandle.prototype; - } - - var constructor = createNamedFunction(legalFunctionName, function() { - 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[arguments.length]; - if (undefined === body) { - throw new BindingError("Tried to invoke ctor of " + name + " with invalid number of parameters (" + arguments.length + ") - expected (" + Object.keys(registeredClass.constructor_body).toString() + ") parameters instead!"); - } - return body.apply(this, arguments); - }); - - var instancePrototype = Object.create(basePrototype, { - constructor: { value: constructor }, - }); - - constructor.prototype = instancePrototype; - - var registeredClass = new RegisteredClass( - name, - constructor, - instancePrototype, - rawDestructor, - baseClass, - getActualType, - upcast, - downcast); - - 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]; - } - ); - } - - - function heap32VectorToArray(count, firstElement) { - var array = []; - for (var i = 0; i < count; i++) { - array.push(HEAP32[(firstElement >> 2) + i]); - } - return array; - } - - function runDestructors(destructors) { - while (destructors.length) { - var ptr = destructors.pop(); - var del = destructors.pop(); - del(ptr); - } - }function __embind_register_class_constructor( - rawClassType, - argCount, - rawArgTypesAddr, - invokerSignature, - invoker, - rawConstructor - ) { - assert(argCount > 0); - var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); - invoker = embind__requireFunction(invokerSignature, invoker); - var args = [rawConstructor]; - var destructors = []; - - whenDependentTypesAreResolved([], [rawClassType], function(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] = function unboundTypeHandler() { - throwUnboundTypeError('Cannot construct ' + classType.name + ' due to unbound types', rawArgTypes); - }; - - whenDependentTypesAreResolved([], rawArgTypes, function(argTypes) { - classType.registeredClass.constructor_body[argCount - 1] = function constructor_body() { - if (arguments.length !== argCount - 1) { - throwBindingError(humanName + ' called with ' + arguments.length + ' arguments, expected ' + (argCount-1)); - } - destructors.length = 0; - args.length = argCount; - for (var i = 1; i < argCount; ++i) { - args[i] = argTypes[i]['toWireType'](destructors, arguments[i - 1]); - } - - var ptr = invoker.apply(null, args); - runDestructors(destructors); - - return argTypes[0]['fromWireType'](ptr); - }; - return []; - }); - return []; - }); - } - - - - function new_(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. Doublely-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 craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cppTargetFunc) { - // 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. - 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 = false; - - for(var i = 1; i < argTypes.length; ++i) { // Skip return value at index 0 - it's not deleted here. - if (argTypes[i] !== null && argTypes[i].destructorFunction === undefined) { // The type does not define a destructor function - must use dynamic stack - needsDestructorStack = true; - break; - } - } - - var returns = (argTypes[0].name !== "void"); - - var argsList = ""; - var argsListWired = ""; - for(var i = 0; i < argCount - 2; ++i) { - argsList += (i!==0?", ":"")+"arg"+i; - argsListWired += (i!==0?", ":"")+"arg"+i+"Wired"; - } - - var invokerFnBody = - "return function "+makeLegalFunctionName(humanName)+"("+argsList+") {\n" + - "if (arguments.length !== "+(argCount - 2)+") {\n" + - "throwBindingError('function "+humanName+" called with ' + arguments.length + ' arguments, expected "+(argCount - 2)+" args!');\n" + - "}\n"; - - - if (needsDestructorStack) { - invokerFnBody += - "var destructors = [];\n"; - } - - var dtorStack = needsDestructorStack ? "destructors" : "null"; - var args1 = ["throwBindingError", "invoker", "fn", "runDestructors", "retType", "classParam"]; - var args2 = [throwBindingError, cppInvokerFunc, cppTargetFunc, runDestructors, argTypes[0], argTypes[1]]; - - - if (isClassMethodFunc) { - invokerFnBody += "var thisWired = classParam.toWireType("+dtorStack+", this);\n"; - } - - for(var i = 0; i < argCount - 2; ++i) { - invokerFnBody += "var arg"+i+"Wired = argType"+i+".toWireType("+dtorStack+", arg"+i+"); // "+argTypes[i+2].name+"\n"; - args1.push("argType"+i); - args2.push(argTypes[i+2]); - } - - if (isClassMethodFunc) { - argsListWired = "thisWired" + (argsListWired.length > 0 ? ", " : "") + argsListWired; - } - - invokerFnBody += - (returns?"var rv = ":"") + "invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n"; - - 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+"); // "+argTypes[i].name+"\n"; - args1.push(paramName+"_dtor"); - args2.push(argTypes[i].destructorFunction); - } - } - } - - if (returns) { - invokerFnBody += "var ret = retType.fromWireType(rv);\n" + - "return ret;\n"; - } else { - } - invokerFnBody += "}\n"; - - args1.push(invokerFnBody); - - var invokerFunction = new_(Function, args1).apply(null, args2); - return invokerFunction; - }function __embind_register_class_function( - rawClassType, - methodName, - argCount, - rawArgTypesAddr, // [ReturnType, ThisType, Args...] - invokerSignature, - rawInvoker, - context, - isPureVirtual - ) { - var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); - methodName = readLatin1String(methodName); - rawInvoker = embind__requireFunction(invokerSignature, rawInvoker); - - whenDependentTypesAreResolved([], [rawClassType], function(classType) { - classType = classType[0]; - var humanName = classType.name + '.' + methodName; - - 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, function(argTypes) { - - var memberFunction = craftInvokerFunction(humanName, argTypes, classType, rawInvoker, context); - - // 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_free_list=[]; - - var emval_handle_array=[{},{value:undefined},{value:null},{value:true},{value:false}];function __emval_decref(handle) { - if (handle > 4 && 0 === --emval_handle_array[handle].refcount) { - emval_handle_array[handle] = undefined; - emval_free_list.push(handle); - } - } - - - - function count_emval_handles() { - var count = 0; - for (var i = 5; i < emval_handle_array.length; ++i) { - if (emval_handle_array[i] !== undefined) { - ++count; - } - } - return count; - } - - function get_first_emval() { - for (var i = 5; i < emval_handle_array.length; ++i) { - if (emval_handle_array[i] !== undefined) { - return emval_handle_array[i]; - } - } - return null; - }function init_emval() { - Module['count_emval_handles'] = count_emval_handles; - Module['get_first_emval'] = get_first_emval; - }function __emval_register(value) { - - switch(value){ - case undefined :{ return 1; } - case null :{ return 2; } - case true :{ return 3; } - case false :{ return 4; } - default:{ - var handle = emval_free_list.length ? - emval_free_list.pop() : - emval_handle_array.length; - - emval_handle_array[handle] = {refcount: 1, value: value}; - return handle; - } - } - }function __embind_register_emval(rawType, name) { - name = readLatin1String(name); - registerType(rawType, { - name: name, - 'fromWireType': function(handle) { - var rv = emval_handle_array[handle].value; - __emval_decref(handle); - return rv; - }, - 'toWireType': function(destructors, value) { - return __emval_register(value); - }, - 'argPackAdvance': 8, - 'readValueFromPointer': simpleReadValueFromPointer, - 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 - }); - } - - - function _embind_repr(v) { - if (v === null) { - return 'null'; - } - var t = typeof v; - if (t === 'object' || t === 'array' || t === 'function') { - return v.toString(); - } else { - return '' + v; - } - } - - function floatReadValueFromPointer(name, shift) { - switch (shift) { - case 2: return function(pointer) { - return this['fromWireType'](HEAPF32[pointer >> 2]); - }; - case 3: return function(pointer) { - return this['fromWireType'](HEAPF64[pointer >> 3]); - }; - default: - throw new TypeError("Unknown float type: " + name); - } - }function __embind_register_float(rawType, name, size) { - var shift = getShiftFromSize(size); - name = readLatin1String(name); - registerType(rawType, { - name: name, - 'fromWireType': function(value) { - return value; - }, - 'toWireType': function(destructors, value) { - // todo: Here we have an opportunity for -O3 level "unsafe" optimizations: we could - // avoid the following if() and assume value is of proper type. - if (typeof value !== "number" && typeof value !== "boolean") { - throw new TypeError('Cannot convert "' + _embind_repr(value) + '" to ' + this.name); - } - return value; - }, - 'argPackAdvance': 8, - 'readValueFromPointer': floatReadValueFromPointer(name, shift), - destructorFunction: null, // This type does not need a destructor - }); - } - - - function integerReadValueFromPointer(name, shift, signed) { - // integers are quite common, so generate very specialized functions - switch (shift) { - case 0: return signed ? - function readS8FromPointer(pointer) { return HEAP8[pointer]; } : - function readU8FromPointer(pointer) { return HEAPU8[pointer]; }; - case 1: return signed ? - function readS16FromPointer(pointer) { return HEAP16[pointer >> 1]; } : - function readU16FromPointer(pointer) { return HEAPU16[pointer >> 1]; }; - case 2: return signed ? - function readS32FromPointer(pointer) { return HEAP32[pointer >> 2]; } : - function readU32FromPointer(pointer) { return HEAPU32[pointer >> 2]; }; - default: - throw new TypeError("Unknown integer type: " + name); - } - }function __embind_register_integer(primitiveType, name, size, minRange, maxRange) { - name = readLatin1String(name); - if (maxRange === -1) { // LLVM doesn't have signed and unsigned 32-bit types, so u32 literals come out as 'i32 -1'. Always treat those as max u32. - maxRange = 4294967295; - } - - var shift = getShiftFromSize(size); - - var fromWireType = function(value) { - return value; - }; - - if (minRange === 0) { - var bitshift = 32 - 8*size; - fromWireType = function(value) { - return (value << bitshift) >>> bitshift; - }; - } - - var isUnsignedType = (name.indexOf('unsigned') != -1); - - registerType(primitiveType, { - name: name, - 'fromWireType': fromWireType, - 'toWireType': function(destructors, value) { - // todo: Here we have an opportunity for -O3 level "unsafe" optimizations: we could - // avoid the following two if()s and assume value is of proper type. - if (typeof value !== "number" && typeof value !== "boolean") { - throw new TypeError('Cannot convert "' + _embind_repr(value) + '" to ' + this.name); - } - if (value < minRange || value > maxRange) { - throw new TypeError('Passing a number "' + _embind_repr(value) + '" from JS side to C/C++ side to an argument of type "' + name + '", which is outside the valid range [' + minRange + ', ' + maxRange + ']!'); - } - return isUnsignedType ? (value >>> 0) : (value | 0); - }, - 'argPackAdvance': 8, - 'readValueFromPointer': integerReadValueFromPointer(name, shift, minRange !== 0), - destructorFunction: null, // This type does not need a destructor - }); - } - - function __embind_register_memory_view(rawType, dataTypeIndex, name) { - var typeMapping = [ - Int8Array, - Uint8Array, - Int16Array, - Uint16Array, - Int32Array, - Uint32Array, - Float32Array, - Float64Array, - ]; - - var TA = typeMapping[dataTypeIndex]; - - function decodeMemoryView(handle) { - handle = handle >> 2; - var heap = HEAPU32; - var size = heap[handle]; // in elements - var data = heap[handle + 1]; // byte offset into emscripten heap - return new TA(buffer, data, size); - } - - name = readLatin1String(name); - registerType(rawType, { - name: name, - 'fromWireType': decodeMemoryView, - 'argPackAdvance': 8, - 'readValueFromPointer': decodeMemoryView, - }, { - ignoreDuplicateRegistrations: true, - }); - } - - function __embind_register_std_string(rawType, name) { - name = readLatin1String(name); - var stdStringIsUTF8 - //process only std::string bindings with UTF8 support, in contrast to e.g. std::basic_string - = (name === "std::string"); - - registerType(rawType, { - name: name, - 'fromWireType': function(value) { - var length = HEAPU32[value >> 2]; - - var str; - if (stdStringIsUTF8) { - var decodeStartPtr = value + 4; - // Looping here to support possible embedded '0' bytes - for (var i = 0; i <= length; ++i) { - var currentBytePtr = value + 4 + i; - if (HEAPU8[currentBytePtr] == 0 || i == length) { - 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[value + 4 + i]); - } - str = a.join(''); - } - - _free(value); - - return str; - }, - 'toWireType': function(destructors, value) { - if (value instanceof ArrayBuffer) { - value = new Uint8Array(value); - } - - var getLength; - 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) { - getLength = function() {return lengthBytesUTF8(value);}; - } else { - getLength = function() {return value.length;}; - } - - // assumes 4-byte alignment - var length = getLength(); - var ptr = _malloc(4 + length + 1); - HEAPU32[ptr >> 2] = length; - if (stdStringIsUTF8 && valueIsOfTypeString) { - stringToUTF8(value, ptr + 4, 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 + 4 + i] = charCode; - } - } else { - for (var i = 0; i < length; ++i) { - HEAPU8[ptr + 4 + i] = value[i]; - } - } - } - - if (destructors !== null) { - destructors.push(_free, ptr); - } - return ptr; - }, - 'argPackAdvance': 8, - 'readValueFromPointer': simpleReadValueFromPointer, - destructorFunction: function(ptr) { _free(ptr); }, - }); - } - - function __embind_register_std_wstring(rawType, charSize, name) { - name = readLatin1String(name); - var decodeString, encodeString, getHeap, lengthBytesUTF, shift; - if (charSize === 2) { - decodeString = UTF16ToString; - encodeString = stringToUTF16; - lengthBytesUTF = lengthBytesUTF16; - getHeap = function() { return HEAPU16; }; - shift = 1; - } else if (charSize === 4) { - decodeString = UTF32ToString; - encodeString = stringToUTF32; - lengthBytesUTF = lengthBytesUTF32; - getHeap = function() { return HEAPU32; }; - shift = 2; - } - registerType(rawType, { - name: name, - 'fromWireType': function(value) { - // Code mostly taken from _embind_register_std_string fromWireType - var length = HEAPU32[value >> 2]; - var HEAP = getHeap(); - 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 (HEAP[currentBytePtr >> shift] == 0 || i == length) { - 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': function(destructors, value) { - if (!(typeof value === 'string')) { - throwBindingError('Cannot pass non-string to C++ string type ' + name); - } - - // assumes 4-byte alignment - var length = lengthBytesUTF(value); - var ptr = _malloc(4 + length + charSize); - HEAPU32[ptr >> 2] = length >> shift; - - encodeString(value, ptr + 4, length + charSize); - - if (destructors !== null) { - destructors.push(_free, ptr); - } - return ptr; - }, - 'argPackAdvance': 8, - 'readValueFromPointer': simpleReadValueFromPointer, - destructorFunction: function(ptr) { _free(ptr); }, - }); - } - - function __embind_register_void(rawType, name) { - name = readLatin1String(name); - registerType(rawType, { - isVoid: true, // void return values can be optimized out sometimes - name: name, - 'argPackAdvance': 0, - 'fromWireType': function() { - return undefined; - }, - 'toWireType': function(destructors, o) { - // TODO: assert if anything else is given? - return undefined; - }, - }); - } - - function _abort() { - abort(); - } - - function _emscripten_get_sbrk_ptr() { - return 4336; - } - - function _emscripten_memcpy_big(dest, src, num) { - HEAPU8.copyWithin(dest, src, src + num); - } - - - function _emscripten_get_heap_size() { - return HEAPU8.length; - } - - function abortOnCannotGrowMemory(requestedSize) { - abort('Cannot enlarge memory arrays to size ' + requestedSize + ' bytes (OOM). Either (1) compile with -s INITIAL_MEMORY=X with X higher than the current value ' + HEAP8.length + ', (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 '); - }function _emscripten_resize_heap(requestedSize) { - requestedSize = requestedSize >>> 0; - abortOnCannotGrowMemory(requestedSize); - } -embind_init_charCodes(); -BindingError = Module['BindingError'] = extendError(Error, 'BindingError');; -InternalError = Module['InternalError'] = extendError(Error, 'InternalError');; -init_ClassHandle(); -init_RegisteredPointer(); -init_embind();; -UnboundTypeError = Module['UnboundTypeError'] = extendError(Error, 'UnboundTypeError');; -init_emval();; -var ASSERTIONS = true; - - - -/** @type {function(string, boolean=, number=)} */ -function intArrayFromString(stringy, dontAddNull, length) { - var len = length > 0 ? length : lengthBytesUTF8(stringy)+1; - var u8array = new Array(len); - var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length); - if (dontAddNull) u8array.length = numBytesWritten; - return u8array; -} - -function intArrayToString(array) { - var ret = []; - for (var i = 0; i < array.length; i++) { - var chr = array[i]; - if (chr > 0xFF) { - if (ASSERTIONS) { - assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.'); - } - chr &= 0xFF; - } - ret.push(String.fromCharCode(chr)); - } - return ret.join(''); -} - - -var asmGlobalArg = {}; -var asmLibraryArg = { "__handle_stack_overflow": ___handle_stack_overflow, "_embind_register_bool": __embind_register_bool, "_embind_register_class": __embind_register_class, "_embind_register_class_constructor": __embind_register_class_constructor, "_embind_register_class_function": __embind_register_class_function, "_embind_register_emval": __embind_register_emval, "_embind_register_float": __embind_register_float, "_embind_register_integer": __embind_register_integer, "_embind_register_memory_view": __embind_register_memory_view, "_embind_register_std_string": __embind_register_std_string, "_embind_register_std_wstring": __embind_register_std_wstring, "_embind_register_void": __embind_register_void, "abort": _abort, "emscripten_get_sbrk_ptr": _emscripten_get_sbrk_ptr, "emscripten_memcpy_big": _emscripten_memcpy_big, "emscripten_resize_heap": _emscripten_resize_heap, "memory": wasmMemory, "table": wasmTable }; -var asm = createWasm(); -/** @type {function(...*):?} */ -var ___wasm_call_ctors = Module["___wasm_call_ctors"] = createExportWrapper("__wasm_call_ctors"); - -/** @type {function(...*):?} */ -var ___getTypeName = Module["___getTypeName"] = createExportWrapper("__getTypeName"); - -/** @type {function(...*):?} */ -var ___embind_register_native_and_builtin_types = Module["___embind_register_native_and_builtin_types"] = createExportWrapper("__embind_register_native_and_builtin_types"); - -/** @type {function(...*):?} */ -var ___errno_location = Module["___errno_location"] = createExportWrapper("__errno_location"); - -/** @type {function(...*):?} */ -var _malloc = Module["_malloc"] = createExportWrapper("malloc"); - -/** @type {function(...*):?} */ -var _fflush = Module["_fflush"] = createExportWrapper("fflush"); - -/** @type {function(...*):?} */ -var stackSave = Module["stackSave"] = createExportWrapper("stackSave"); - -/** @type {function(...*):?} */ -var stackRestore = Module["stackRestore"] = createExportWrapper("stackRestore"); - -/** @type {function(...*):?} */ -var stackAlloc = Module["stackAlloc"] = createExportWrapper("stackAlloc"); - -/** @type {function(...*):?} */ -var _free = Module["_free"] = createExportWrapper("free"); - -/** @type {function(...*):?} */ -var ___set_stack_limit = Module["___set_stack_limit"] = createExportWrapper("__set_stack_limit"); - -/** @type {function(...*):?} */ -var __growWasmMemory = Module["__growWasmMemory"] = createExportWrapper("__growWasmMemory"); - -/** @type {function(...*):?} */ -var dynCall_ii = Module["dynCall_ii"] = createExportWrapper("dynCall_ii"); - -/** @type {function(...*):?} */ -var dynCall_vi = Module["dynCall_vi"] = createExportWrapper("dynCall_vi"); - -/** @type {function(...*):?} */ -var dynCall_did = Module["dynCall_did"] = createExportWrapper("dynCall_did"); - -/** @type {function(...*):?} */ -var dynCall_iid = Module["dynCall_iid"] = createExportWrapper("dynCall_iid"); - -/** @type {function(...*):?} */ -var dynCall_diid = Module["dynCall_diid"] = createExportWrapper("dynCall_diid"); - -/** @type {function(...*):?} */ -var dynCall_iiii = Module["dynCall_iiii"] = createExportWrapper("dynCall_iiii"); - -/** @type {function(...*):?} */ -var dynCall_viiiiii = Module["dynCall_viiiiii"] = createExportWrapper("dynCall_viiiiii"); - -/** @type {function(...*):?} */ -var dynCall_viiiii = Module["dynCall_viiiii"] = createExportWrapper("dynCall_viiiii"); - -/** @type {function(...*):?} */ -var dynCall_viiii = Module["dynCall_viiii"] = createExportWrapper("dynCall_viiii"); - - - - - -// === Auto-generated postamble setup entry stuff === - - -if (!Object.getOwnPropertyDescriptor(Module, "intArrayFromString")) Module["intArrayFromString"] = function() { abort("'intArrayFromString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "intArrayToString")) Module["intArrayToString"] = function() { abort("'intArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ccall")) Module["ccall"] = function() { abort("'ccall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "cwrap")) Module["cwrap"] = function() { abort("'cwrap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setValue")) Module["setValue"] = function() { abort("'setValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getValue")) Module["getValue"] = function() { abort("'getValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "allocate")) Module["allocate"] = function() { abort("'allocate' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getMemory")) Module["getMemory"] = function() { abort("'getMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "UTF8ArrayToString")) Module["UTF8ArrayToString"] = function() { abort("'UTF8ArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "UTF8ToString")) Module["UTF8ToString"] = function() { abort("'UTF8ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8Array")) Module["stringToUTF8Array"] = function() { abort("'stringToUTF8Array' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8")) Module["stringToUTF8"] = function() { abort("'stringToUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF8")) Module["lengthBytesUTF8"] = function() { abort("'lengthBytesUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addOnPreRun")) Module["addOnPreRun"] = function() { abort("'addOnPreRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addOnInit")) Module["addOnInit"] = function() { abort("'addOnInit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addOnPreMain")) Module["addOnPreMain"] = function() { abort("'addOnPreMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addOnExit")) Module["addOnExit"] = function() { abort("'addOnExit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addOnPostRun")) Module["addOnPostRun"] = function() { abort("'addOnPostRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeStringToMemory")) Module["writeStringToMemory"] = function() { abort("'writeStringToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeArrayToMemory")) Module["writeArrayToMemory"] = function() { abort("'writeArrayToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeAsciiToMemory")) Module["writeAsciiToMemory"] = function() { abort("'writeAsciiToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addRunDependency")) Module["addRunDependency"] = function() { abort("'addRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "removeRunDependency")) Module["removeRunDependency"] = function() { abort("'removeRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createFolder")) Module["FS_createFolder"] = function() { abort("'FS_createFolder' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createPath")) Module["FS_createPath"] = function() { abort("'FS_createPath' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createDataFile")) Module["FS_createDataFile"] = function() { abort("'FS_createDataFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createPreloadedFile")) Module["FS_createPreloadedFile"] = function() { abort("'FS_createPreloadedFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createLazyFile")) Module["FS_createLazyFile"] = function() { abort("'FS_createLazyFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createLink")) Module["FS_createLink"] = function() { abort("'FS_createLink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createDevice")) Module["FS_createDevice"] = function() { abort("'FS_createDevice' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_unlink")) Module["FS_unlink"] = function() { abort("'FS_unlink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "dynamicAlloc")) Module["dynamicAlloc"] = function() { abort("'dynamicAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "loadDynamicLibrary")) Module["loadDynamicLibrary"] = function() { abort("'loadDynamicLibrary' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "loadWebAssemblyModule")) Module["loadWebAssemblyModule"] = function() { abort("'loadWebAssemblyModule' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getLEB")) Module["getLEB"] = function() { abort("'getLEB' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getFunctionTables")) Module["getFunctionTables"] = function() { abort("'getFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "alignFunctionTables")) Module["alignFunctionTables"] = function() { abort("'alignFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerFunctions")) Module["registerFunctions"] = function() { abort("'registerFunctions' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addFunction")) Module["addFunction"] = function() { abort("'addFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "removeFunction")) Module["removeFunction"] = function() { abort("'removeFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getFuncWrapper")) Module["getFuncWrapper"] = function() { abort("'getFuncWrapper' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "prettyPrint")) Module["prettyPrint"] = function() { abort("'prettyPrint' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "makeBigInt")) Module["makeBigInt"] = function() { abort("'makeBigInt' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "dynCall")) Module["dynCall"] = function() { abort("'dynCall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getCompilerSetting")) Module["getCompilerSetting"] = function() { abort("'getCompilerSetting' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "print")) Module["print"] = function() { abort("'print' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "printErr")) Module["printErr"] = function() { abort("'printErr' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getTempRet0")) Module["getTempRet0"] = function() { abort("'getTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setTempRet0")) Module["setTempRet0"] = function() { abort("'setTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "callMain")) Module["callMain"] = function() { abort("'callMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "abort")) Module["abort"] = function() { abort("'abort' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToNewUTF8")) Module["stringToNewUTF8"] = function() { abort("'stringToNewUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "abortOnCannotGrowMemory")) Module["abortOnCannotGrowMemory"] = function() { abort("'abortOnCannotGrowMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscripten_realloc_buffer")) Module["emscripten_realloc_buffer"] = function() { abort("'emscripten_realloc_buffer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ENV")) Module["ENV"] = function() { abort("'ENV' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_CODES")) Module["ERRNO_CODES"] = function() { abort("'ERRNO_CODES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_MESSAGES")) Module["ERRNO_MESSAGES"] = function() { abort("'ERRNO_MESSAGES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setErrNo")) Module["setErrNo"] = function() { abort("'setErrNo' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "DNS")) Module["DNS"] = function() { abort("'DNS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GAI_ERRNO_MESSAGES")) Module["GAI_ERRNO_MESSAGES"] = function() { abort("'GAI_ERRNO_MESSAGES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "Protocols")) Module["Protocols"] = function() { abort("'Protocols' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "Sockets")) Module["Sockets"] = function() { abort("'Sockets' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "UNWIND_CACHE")) Module["UNWIND_CACHE"] = function() { abort("'UNWIND_CACHE' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "readAsmConstArgs")) Module["readAsmConstArgs"] = function() { abort("'readAsmConstArgs' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "jstoi_q")) Module["jstoi_q"] = function() { abort("'jstoi_q' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "jstoi_s")) Module["jstoi_s"] = function() { abort("'jstoi_s' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "abortStackOverflow")) Module["abortStackOverflow"] = function() { abort("'abortStackOverflow' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "reallyNegative")) Module["reallyNegative"] = function() { abort("'reallyNegative' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "formatString")) Module["formatString"] = function() { abort("'formatString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "PATH")) Module["PATH"] = function() { abort("'PATH' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "PATH_FS")) Module["PATH_FS"] = function() { abort("'PATH_FS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SYSCALLS")) Module["SYSCALLS"] = function() { abort("'SYSCALLS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "syscallMmap2")) Module["syscallMmap2"] = function() { abort("'syscallMmap2' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "syscallMunmap")) Module["syscallMunmap"] = function() { abort("'syscallMunmap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "flush_NO_FILESYSTEM")) Module["flush_NO_FILESYSTEM"] = function() { abort("'flush_NO_FILESYSTEM' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "JSEvents")) Module["JSEvents"] = function() { abort("'JSEvents' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "specialHTMLTargets")) Module["specialHTMLTargets"] = function() { abort("'specialHTMLTargets' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "demangle")) Module["demangle"] = function() { abort("'demangle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "demangleAll")) Module["demangleAll"] = function() { abort("'demangleAll' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "jsStackTrace")) Module["jsStackTrace"] = function() { abort("'jsStackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getEnvStrings")) Module["getEnvStrings"] = function() { abort("'getEnvStrings' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "checkWasiClock")) Module["checkWasiClock"] = function() { abort("'checkWasiClock' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64")) Module["writeI53ToI64"] = function() { abort("'writeI53ToI64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Clamped")) Module["writeI53ToI64Clamped"] = function() { abort("'writeI53ToI64Clamped' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Signaling")) Module["writeI53ToI64Signaling"] = function() { abort("'writeI53ToI64Signaling' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Clamped")) Module["writeI53ToU64Clamped"] = function() { abort("'writeI53ToU64Clamped' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Signaling")) Module["writeI53ToU64Signaling"] = function() { abort("'writeI53ToU64Signaling' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "readI53FromI64")) Module["readI53FromI64"] = function() { abort("'readI53FromI64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "readI53FromU64")) Module["readI53FromU64"] = function() { abort("'readI53FromU64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "convertI32PairToI53")) Module["convertI32PairToI53"] = function() { abort("'convertI32PairToI53' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "convertU32PairToI53")) Module["convertU32PairToI53"] = function() { abort("'convertU32PairToI53' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "Browser")) Module["Browser"] = function() { abort("'Browser' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS")) Module["FS"] = function() { abort("'FS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "MEMFS")) Module["MEMFS"] = function() { abort("'MEMFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "TTY")) Module["TTY"] = function() { abort("'TTY' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "PIPEFS")) Module["PIPEFS"] = function() { abort("'PIPEFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SOCKFS")) Module["SOCKFS"] = function() { abort("'SOCKFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GL")) Module["GL"] = function() { abort("'GL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGet")) Module["emscriptenWebGLGet"] = function() { abort("'emscriptenWebGLGet' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetTexPixelData")) Module["emscriptenWebGLGetTexPixelData"] = function() { abort("'emscriptenWebGLGetTexPixelData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetUniform")) Module["emscriptenWebGLGetUniform"] = function() { abort("'emscriptenWebGLGetUniform' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetVertexAttrib")) Module["emscriptenWebGLGetVertexAttrib"] = function() { abort("'emscriptenWebGLGetVertexAttrib' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "AL")) Module["AL"] = function() { abort("'AL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SDL_unicode")) Module["SDL_unicode"] = function() { abort("'SDL_unicode' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SDL_ttfContext")) Module["SDL_ttfContext"] = function() { abort("'SDL_ttfContext' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SDL_audio")) Module["SDL_audio"] = function() { abort("'SDL_audio' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SDL")) Module["SDL"] = function() { abort("'SDL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SDL_gfx")) Module["SDL_gfx"] = function() { abort("'SDL_gfx' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GLUT")) Module["GLUT"] = function() { abort("'GLUT' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "EGL")) Module["EGL"] = function() { abort("'EGL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GLFW_Window")) Module["GLFW_Window"] = function() { abort("'GLFW_Window' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GLFW")) Module["GLFW"] = function() { abort("'GLFW' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GLEW")) Module["GLEW"] = function() { abort("'GLEW' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "IDBStore")) Module["IDBStore"] = function() { abort("'IDBStore' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "runAndAbortIfError")) Module["runAndAbortIfError"] = function() { abort("'runAndAbortIfError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emval_handle_array")) Module["emval_handle_array"] = function() { abort("'emval_handle_array' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emval_free_list")) Module["emval_free_list"] = function() { abort("'emval_free_list' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emval_symbols")) Module["emval_symbols"] = function() { abort("'emval_symbols' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "init_emval")) Module["init_emval"] = function() { abort("'init_emval' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "count_emval_handles")) Module["count_emval_handles"] = function() { abort("'count_emval_handles' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "get_first_emval")) Module["get_first_emval"] = function() { abort("'get_first_emval' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getStringOrSymbol")) Module["getStringOrSymbol"] = function() { abort("'getStringOrSymbol' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "requireHandle")) Module["requireHandle"] = function() { abort("'requireHandle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emval_newers")) Module["emval_newers"] = function() { abort("'emval_newers' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "craftEmvalAllocator")) Module["craftEmvalAllocator"] = function() { abort("'craftEmvalAllocator' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emval_get_global")) Module["emval_get_global"] = function() { abort("'emval_get_global' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emval_methodCallers")) Module["emval_methodCallers"] = function() { abort("'emval_methodCallers' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "InternalError")) Module["InternalError"] = function() { abort("'InternalError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "BindingError")) Module["BindingError"] = function() { abort("'BindingError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "UnboundTypeError")) Module["UnboundTypeError"] = function() { abort("'UnboundTypeError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "PureVirtualError")) Module["PureVirtualError"] = function() { abort("'PureVirtualError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "init_embind")) Module["init_embind"] = function() { abort("'init_embind' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "throwInternalError")) Module["throwInternalError"] = function() { abort("'throwInternalError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "throwBindingError")) Module["throwBindingError"] = function() { abort("'throwBindingError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "throwUnboundTypeError")) Module["throwUnboundTypeError"] = function() { abort("'throwUnboundTypeError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ensureOverloadTable")) Module["ensureOverloadTable"] = function() { abort("'ensureOverloadTable' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "exposePublicSymbol")) Module["exposePublicSymbol"] = function() { abort("'exposePublicSymbol' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "replacePublicSymbol")) Module["replacePublicSymbol"] = function() { abort("'replacePublicSymbol' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "extendError")) Module["extendError"] = function() { abort("'extendError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "createNamedFunction")) Module["createNamedFunction"] = function() { abort("'createNamedFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registeredInstances")) Module["registeredInstances"] = function() { abort("'registeredInstances' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getBasestPointer")) Module["getBasestPointer"] = function() { abort("'getBasestPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerInheritedInstance")) Module["registerInheritedInstance"] = function() { abort("'registerInheritedInstance' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "unregisterInheritedInstance")) Module["unregisterInheritedInstance"] = function() { abort("'unregisterInheritedInstance' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getInheritedInstance")) Module["getInheritedInstance"] = function() { abort("'getInheritedInstance' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getInheritedInstanceCount")) Module["getInheritedInstanceCount"] = function() { abort("'getInheritedInstanceCount' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getLiveInheritedInstances")) Module["getLiveInheritedInstances"] = function() { abort("'getLiveInheritedInstances' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registeredTypes")) Module["registeredTypes"] = function() { abort("'registeredTypes' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "awaitingDependencies")) Module["awaitingDependencies"] = function() { abort("'awaitingDependencies' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "typeDependencies")) Module["typeDependencies"] = function() { abort("'typeDependencies' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registeredPointers")) Module["registeredPointers"] = function() { abort("'registeredPointers' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerType")) Module["registerType"] = function() { abort("'registerType' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "whenDependentTypesAreResolved")) Module["whenDependentTypesAreResolved"] = function() { abort("'whenDependentTypesAreResolved' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "embind_charCodes")) Module["embind_charCodes"] = function() { abort("'embind_charCodes' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "embind_init_charCodes")) Module["embind_init_charCodes"] = function() { abort("'embind_init_charCodes' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "readLatin1String")) Module["readLatin1String"] = function() { abort("'readLatin1String' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getTypeName")) Module["getTypeName"] = function() { abort("'getTypeName' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "heap32VectorToArray")) Module["heap32VectorToArray"] = function() { abort("'heap32VectorToArray' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "requireRegisteredType")) Module["requireRegisteredType"] = function() { abort("'requireRegisteredType' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getShiftFromSize")) Module["getShiftFromSize"] = function() { abort("'getShiftFromSize' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "integerReadValueFromPointer")) Module["integerReadValueFromPointer"] = function() { abort("'integerReadValueFromPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "enumReadValueFromPointer")) Module["enumReadValueFromPointer"] = function() { abort("'enumReadValueFromPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "floatReadValueFromPointer")) Module["floatReadValueFromPointer"] = function() { abort("'floatReadValueFromPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "simpleReadValueFromPointer")) Module["simpleReadValueFromPointer"] = function() { abort("'simpleReadValueFromPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "runDestructors")) Module["runDestructors"] = function() { abort("'runDestructors' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "new_")) Module["new_"] = function() { abort("'new_' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "craftInvokerFunction")) Module["craftInvokerFunction"] = function() { abort("'craftInvokerFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "embind__requireFunction")) Module["embind__requireFunction"] = function() { abort("'embind__requireFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "tupleRegistrations")) Module["tupleRegistrations"] = function() { abort("'tupleRegistrations' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "structRegistrations")) Module["structRegistrations"] = function() { abort("'structRegistrations' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "genericPointerToWireType")) Module["genericPointerToWireType"] = function() { abort("'genericPointerToWireType' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "constNoSmartPtrRawPointerToWireType")) Module["constNoSmartPtrRawPointerToWireType"] = function() { abort("'constNoSmartPtrRawPointerToWireType' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "nonConstNoSmartPtrRawPointerToWireType")) Module["nonConstNoSmartPtrRawPointerToWireType"] = function() { abort("'nonConstNoSmartPtrRawPointerToWireType' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "init_RegisteredPointer")) Module["init_RegisteredPointer"] = function() { abort("'init_RegisteredPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "RegisteredPointer")) Module["RegisteredPointer"] = function() { abort("'RegisteredPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "RegisteredPointer_getPointee")) Module["RegisteredPointer_getPointee"] = function() { abort("'RegisteredPointer_getPointee' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "RegisteredPointer_destructor")) Module["RegisteredPointer_destructor"] = function() { abort("'RegisteredPointer_destructor' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "RegisteredPointer_deleteObject")) Module["RegisteredPointer_deleteObject"] = function() { abort("'RegisteredPointer_deleteObject' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "RegisteredPointer_fromWireType")) Module["RegisteredPointer_fromWireType"] = function() { abort("'RegisteredPointer_fromWireType' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "runDestructor")) Module["runDestructor"] = function() { abort("'runDestructor' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "releaseClassHandle")) Module["releaseClassHandle"] = function() { abort("'releaseClassHandle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "finalizationGroup")) Module["finalizationGroup"] = function() { abort("'finalizationGroup' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "detachFinalizer_deps")) Module["detachFinalizer_deps"] = function() { abort("'detachFinalizer_deps' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "detachFinalizer")) Module["detachFinalizer"] = function() { abort("'detachFinalizer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "attachFinalizer")) Module["attachFinalizer"] = function() { abort("'attachFinalizer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "makeClassHandle")) Module["makeClassHandle"] = function() { abort("'makeClassHandle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "init_ClassHandle")) Module["init_ClassHandle"] = function() { abort("'init_ClassHandle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ClassHandle")) Module["ClassHandle"] = function() { abort("'ClassHandle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ClassHandle_isAliasOf")) Module["ClassHandle_isAliasOf"] = function() { abort("'ClassHandle_isAliasOf' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "throwInstanceAlreadyDeleted")) Module["throwInstanceAlreadyDeleted"] = function() { abort("'throwInstanceAlreadyDeleted' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ClassHandle_clone")) Module["ClassHandle_clone"] = function() { abort("'ClassHandle_clone' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ClassHandle_delete")) Module["ClassHandle_delete"] = function() { abort("'ClassHandle_delete' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "deletionQueue")) Module["deletionQueue"] = function() { abort("'deletionQueue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ClassHandle_isDeleted")) Module["ClassHandle_isDeleted"] = function() { abort("'ClassHandle_isDeleted' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ClassHandle_deleteLater")) Module["ClassHandle_deleteLater"] = function() { abort("'ClassHandle_deleteLater' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "flushPendingDeletes")) Module["flushPendingDeletes"] = function() { abort("'flushPendingDeletes' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "delayFunction")) Module["delayFunction"] = function() { abort("'delayFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setDelayFunction")) Module["setDelayFunction"] = function() { abort("'setDelayFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "RegisteredClass")) Module["RegisteredClass"] = function() { abort("'RegisteredClass' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "shallowCopyInternalPointer")) Module["shallowCopyInternalPointer"] = function() { abort("'shallowCopyInternalPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "downcastPointer")) Module["downcastPointer"] = function() { abort("'downcastPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "upcastPointer")) Module["upcastPointer"] = function() { abort("'upcastPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "validateThis")) Module["validateThis"] = function() { abort("'validateThis' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "char_0")) Module["char_0"] = function() { abort("'char_0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "char_9")) Module["char_9"] = function() { abort("'char_9' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "makeLegalFunctionName")) Module["makeLegalFunctionName"] = function() { abort("'makeLegalFunctionName' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "warnOnce")) Module["warnOnce"] = function() { abort("'warnOnce' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stackSave")) Module["stackSave"] = function() { abort("'stackSave' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stackRestore")) Module["stackRestore"] = function() { abort("'stackRestore' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stackAlloc")) Module["stackAlloc"] = function() { abort("'stackAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "AsciiToString")) Module["AsciiToString"] = function() { abort("'AsciiToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToAscii")) Module["stringToAscii"] = function() { abort("'stringToAscii' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "UTF16ToString")) Module["UTF16ToString"] = function() { abort("'UTF16ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF16")) Module["stringToUTF16"] = function() { abort("'stringToUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF16")) Module["lengthBytesUTF16"] = function() { abort("'lengthBytesUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "UTF32ToString")) Module["UTF32ToString"] = function() { abort("'UTF32ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF32")) Module["stringToUTF32"] = function() { abort("'stringToUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF32")) Module["lengthBytesUTF32"] = function() { abort("'lengthBytesUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8")) Module["allocateUTF8"] = function() { abort("'allocateUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8OnStack")) Module["allocateUTF8OnStack"] = function() { abort("'allocateUTF8OnStack' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -Module["writeStackCookie"] = writeStackCookie; -Module["checkStackCookie"] = checkStackCookie;if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_NORMAL")) Object.defineProperty(Module, "ALLOC_NORMAL", { configurable: true, get: function() { abort("'ALLOC_NORMAL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); -if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_STACK")) Object.defineProperty(Module, "ALLOC_STACK", { configurable: true, get: function() { abort("'ALLOC_STACK' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); -if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_DYNAMIC")) Object.defineProperty(Module, "ALLOC_DYNAMIC", { configurable: true, get: function() { abort("'ALLOC_DYNAMIC' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); -if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_NONE")) Object.defineProperty(Module, "ALLOC_NONE", { configurable: true, get: function() { abort("'ALLOC_NONE' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); - - - -var calledRun; - -/** - * @constructor - * @this {ExitStatus} - */ -function ExitStatus(status) { - this.name = "ExitStatus"; - this.message = "Program terminated with exit(" + status + ")"; - this.status = status; -} - -var calledMain = false; - - -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 -}; - - - - - -/** @type {function(Array=)} */ -function run(args) { - args = args || arguments_; - - if (runDependencies > 0) { - return; - } - - writeStackCookie(); - - preRun(); - - if (runDependencies > 0) return; // a preRun added a dependency, run will be called later - - 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(); - - preMain(); - - readyPromiseResolve(Module); - if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized'](); - - assert(!Module['_main'], 'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]'); - - postRun(); - } - - if (Module['setStatus']) { - Module['setStatus']('Running...'); - setTimeout(function() { - setTimeout(function() { - Module['setStatus'](''); - }, 1); - doRun(); - }, 1); - } else - { - doRun(); - } - checkStackCookie(); -} -Module['run'] = run; - -function checkUnflushedContent() { - // Compiler settings do not allow exiting the runtime, so flushing - // the streams is not possible. but in ASSERTIONS mode we check - // if there was something to flush, and if so tell the user they - // should request that the runtime be exitable. - // Normally we would not even include flush() at all, but in ASSERTIONS - // builds we do so just for this check, and here we see if there is any - // content to flush, that is, we check if there would have been - // something a non-ASSERTIONS build would have not seen. - // How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0 - // mode (which has its own special function for this; otherwise, all - // the code is inside libc) - var print = out; - var printErr = err; - var has = false; - out = err = function(x) { - has = true; - } - try { // it doesn't matter if it fails - var flush = null; - if (flush) flush(); - } catch(e) {} - out = print; - err = printErr; - if (has) { - warnOnce('stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the FAQ), or make sure to emit a newline when you printf etc.'); - warnOnce('(this may also be due to not including full filesystem support - try building with -s FORCE_FILESYSTEM=1)'); - } -} - -/** @param {boolean|number=} implicit */ -function exit(status, implicit) { - checkUnflushedContent(); - - // if this is just main exit-ing implicitly, and the status is 0, then we - // don't need to do anything here and can just leave. if the status is - // non-zero, though, then we need to report it. - // (we may have warned about this earlier, if a situation justifies doing so) - if (implicit && noExitRuntime && status === 0) { - return; - } - - if (noExitRuntime) { - // if exit() was called, we may warn the user if the runtime isn't actually being shut down - if (!implicit) { - var msg = 'program exited (with status: ' + status + '), but EXIT_RUNTIME is not set, so halting execution but not exiting the runtime or preventing further async execution (build with EXIT_RUNTIME=1, if you want a true shutdown)'; - readyPromiseReject(msg); - } - } else { - - ABORT = true; - EXITSTATUS = status; - - exitRuntime(); - - if (Module['onExit']) Module['onExit'](status); - } - - quit_(status, new ExitStatus(status)); -} - -if (Module['preInit']) { - if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']]; - while (Module['preInit'].length > 0) { - Module['preInit'].pop()(); - } -} - - - noExitRuntime = true; - -run(); - - - - - - -// {{MODULE_ADDITIONS}} - - - - - - return createModule.ready -} -); -})(); -if (typeof exports === 'object' && typeof module === 'object') - module.exports = createModule; - else if (typeof define === 'function' && define['amd']) - define([], function() { return createModule; }); - else if (typeof exports === 'object') - exports["createModule"] = createModule; - \ No newline at end of file diff --git a/src/js/newtonraphsonwasm.wasm b/src/js/newtonraphsonwasm.wasm deleted file mode 100644 index 0d74f8ca980ef276baf4dcae3620d20b46a792ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26547 zcmeI5dw^Wkec$h6W_EV&?CxDXSJJL@?;yhh0!tt-4^yn`fH2`<$98O-I9*oK3hhH$ z?L#X$#jI=-o3w7~IyAK#+F~2mu8R}ex-m`MhPI@kiPN|ZZg4{q($bbD#HBT9ofw;b zzQ1#4=I-nRfvf(Nh2fri9>3r3{NCp=gEuyR-1j`s|CGP=PS0Pu(_ixVP$)0y&%4v} z?ku@d#cHSuDbOQOGyl=3yZyT<-c3=B)}>i>w;NAWmjgg^H7`-@X%_97j}(}Dmi&7} ziW?8K;JL6r96zzRWpw=bp@|bmM(4)wnwVc0pBp_qJvKk@ZBS!l^~TY|GbiR3=1v`6 zn3?k`>bPr-jz>?OIJ_`1bHX!Rn^*K&oS8V{RRv*X+o746X)jdUjuqqP7mkcV!NiHX z+~~nodz{X@)CFYaM8}UWj!nDq11rW)oLCsYYkbZTuyX9t>6x(w&j7E)eSG}*%-s7% z7bnI~yDsIiLo;&=UdiYfKR$nWZsO#^_z8GEKk?(^qsPX_PI`fHq0k7F!zbT2dT8P< zuS;!PM@Ns1oj5W*&dkRSPmRtjj?Y2HX$Q9AkOuzQ;H-fvFN__U9`{drJHzkzf9iXs zS}p3Wm4Z@$f}*7Q3;Zf?UJwO=SL5FvoM_hvl#mhGC^rVIDzOSK#^d_nE1Nbys^fZt06FVP#Xe4k|CqYLz(_udrKd2a5+%;@yYVLGAqf8zw4QcI#wr}d;esedZ%NqUmfgK2Nl+ZP=L zVfQ)+bKKPf!dAe&KGITB`*a$CE&3El>wVE1gA$IKc?HZXOoAkwVlt(~8wu(>{A)rl zDGdj8u#_$hz0|;~vfLNlAE4$N+~A}&I5?1$8qo#8&7}izZaB^^HPM}Y(WMA3=oH*C5y9V2GJiO@#SfOU zr-o7#HT4rO@%saBdtdaSQgHcFa1T=PvlkFeu5KU<8<({ZUM7Tyek2%3!r@>bEg?cF zLwOQ0g-K;3*qfcLO8=6skzh|ekOiyW<@x+L+Wvf+P!3jxdQv zg28wwt;ajlo_JT<8z;yF6vJsuYdjL{k5dF=H5>HUjWoh!<4ACI+(0B&vssTM-9p2b zk>ENSwz?Xlb`KJueGmzR$@Y=pKzsr0x0=DEjve$$?#Twp6;TZ&+a#3OV~RtJ7@ACX z^4K{N+@L`>q`P?AH4@yKmC}S_G7`K+4Y#JL9&bq-Nh5w;=A{?VcmcYdmDAl6caH>c zHpKNM$+_OlLn;O)sK+(MWKN$Au%o5gxA_3GP(CW9hIS zccvHXaU{Kjwo68W_wu-SB)CKH?@0IZw)ZLwhraQJ66>YZTsoQVL9BZkm$$@vxfx7f z6ncHpkNVw9rUh-EV@gnM^{%#*pf2Qf8E<@1T82-i1CwbNBf1*htr6WCf$l}VzXU_P z1U$v^`~BWkarU$z^ZbKiwosT+T|wYb%^VqN`=Gug9fZO^+S}cvJXKfH8B5 zeOwn-ob*kmF*A=F8(PRW80&x6_qU14fR4>bK*v&JTdU(XCwZq`rKEy(C0)q63PsK- zCbcx;wVwFHfw;t@1R)ks26*(21e`PVIi#bgT zc$h^jmrOl&flK!Dil;j(K4yyLdhGT~osi+P0W@)dqA&WGAN07mu!6rGmL>HoIVWC$ zzs9=dvD2buj5Pb=y>P9R#EPJ#7laQa(H-wgYp_FcH(K4$l3HJst|XfP(Xwi2e!E}o zoS4~6SBte>ur{A-e8sW=M8`^_!%qRyO!Sf5Dt|2KS{W)0L#2hGl4EEkR~TS?W!haZ z7DkjC9W-_KMdu_Iqv!KEJr@$XEg33$2~Dqs+(h}ZA8cDHDa40xSqv*prDdaHxzdsU zp#_6Hdk&%J$xh92YkY0Gi#dtbfys0msJ1nBv}CbEve>n{=7ise=DhKoHRrKh zQfGa?XI0hg$j6)+!UcszT)B%A)9eW69o{CsUI63A30+LY^1sQn z%0#M-T1%KU36qIj<5xOSIEyAR8V-zeVvr@4EwWMHzUb#e{|!soFZGeWKF~+1`e(hw zj&Jm06<_W}qCeA18uBMS(D3!1v@83$9s0vnRXLM)sTC=>^%Zb*H{q(e;rIaQ+r`On9L8CC2~C$K7bcg^rh6z}mRyuvHk)3aT$1cgUYG1iE{{ve z1@W87DSseI;~SDBzA@PqA53<}Hzh;yTd=R2lO6F7Cfnm%l5O#=@ol7+uV>v+j&COs z+>4!+c$@=Jr zlb-lpNj-iyaq^C&7QY97|0DRsA0<6`Ctl@;k^H;R_IHzK-jM{f`|*1dFaEJSx%!Lk zBq|<^k2|dey9yh9ExYQ&uF#og9F32* ziMk7-UiKZUX4CHY7S;y}$xZHaRg)tg_jQ$Up|<> zjGq%rnxuXR7Zl&CjK{fY+%D=I*ItP!uMW#k2+N1hHhBam{oOVD z8mI@?Y&KAz%0UhI;Zpo*^(D13vSvkAUt|rRS*5{-Ka>wQRG(F^c+E-uy)~N+)aPVAWfG^|#?ByR6Umh;Le6jfQbH$gRFTOldeEEmPmw!}z`NzeV zFBM<@N%7?uiZ5TzUrceHh&vSL!TyelZ+BKaxuK)SBO5y^o-R}vJ08tZ7PqXe;h(P6 z@QcNUylf+Wsn`$*vD=@Dzfx=n3l0CQ*ib4o{PSW%xzO;-#fIXD$BGTb5&xptP$_`= zm&JxI*I)-o-_QY4w^J~8fb{NHvvKDVgi`z_G~QPE93KU%@7|f5pDy?VSxctWWo;Lb zz3i>kY~Wt}e+%xp0=TUhAPf9eJ%PN#iUuR-><;l3cCz`q%jS0$Tn6$)gV8y(pwmiPZWUk>CodWe`lN)*!#=;stgA@O$x-esqZk%`izd@z-G@uM{CV;{`m|Q-6K@YyORfj-5w4 zLOK|I)yEWr0~dJNW8PFFY?NCYBISI;#X&MO5(29>AGWwc_SDwwz5&{P+i$2g39}`g zMA^D7wmxCzPHePS&(>!)FqwJTMez&FKFp}QI`Jt~CzAk?WH6KmoA>=?fN{{BX%4zS z!S22`kV(Nbw-9nC8y&|PrRa%()2P;LN}Z<{0QMT??CwdP92JzaGgi{MQ0NZOAV>#4 zMsg_$Ael*U-JwV}N3O`)4h$-YSp3)2OKvu7#A!B2B11Mw#ip~VzoH5{*^~~VvpP;_ z_AT@r=+|WoW=PLHy}A#@aTEM-V}~>U;0{-0tF>9&tD-@4<6s&Zs9}3`RfBs3;-ZxR zK*>OoT#Az=<7CH)k{{iPebI_E;zkKz=s9;9Br6@c_+m{gEfa(!kc{ZcO$gy}olrXl zUF(hTptlCm1yUvf6h*r{hT14toU>3v5q10&HhcBD?b2y>(Hj8J2)*Q56a9$nm>2di zj68E4X<7V6GTN>|QnQknG!9ux8OjFF%i)zLQLuo1!R(GA=u^38(nQ)+=QKdIqe_YALB0Q57KAKx$$!_PkPMLR88Zt4+2;s2GVf3pd4klVA5_Xt~a2OsxdwhFK zE`e-Vo|JhAnjinJ`2dX3m?+!V(Kc+cjvx|cX8%Urb8R0X=PJfG$|eGx)M*SOBu`HE z^r&P@^RrpkY)^oZF3l&E+3XpQH`oAg*&kQ$y3xmdM~KqfqiurK>WDJ*4{W3BZ~Hf< zrMmc`Mz9-w3@(d*O$v=FW3qIFOFxDw{(TS^#|D~PbL>+NyqnR=vCkC85|?Z&GA{T| z)fyrZ?b?m-f^S93&xdbi35NijC~_Zb+w2HiQAQdNNN5FyxIl#<$t?Y@(d0<7UL$j3sm#G9hjsYQ3!S#vP_#@MDvY-Xq| z17hTWGYz=?V>fi9H;_l82yPB=HRxcQ;2bO<3{J}`(4$y2#5q})!T!82czC@x2)e>- zXueTZ`(0Js2n}iOPfKloD#v906UUvG%z;`o$G(8%Knyf+PX;%!;U$?i*z!@~^1+TE z+_1W|{BM%OYJ2ZN7dFg$4@S{%l`Jzzn2^{}>hRJ3$&w7{v38u5Yj@5=oCy?z7`jP> z<9v-OsRt8J6dV*v5;vheSxLQfuW8mSCmABp3LoxT=^uP03#qr7%k$po@0W4nb?^#c zf0pT)_Y}m-yf+|OSK4pt#Wp##3}}jQ8K~T7!oH60U z(``jI#>>`$@zT>M3l%#2q|8OYM9SNP8bFk?3F9{bmv}dvvp$z@Gfw8xH3bH+O&>ZH z4Vck?0jvue9GO_qfLam}-HBjoaEbUQ(!DnH2p$<5aGc8l5m7jUC!*AGwq&6I5V>A^ zfYXkH^115{ZI1B8-#oc65{$ddf34xfvbQ#aGcKN3j9?STO3U`Vq|2gl*Rp8LHOom% zBcP|^v4sdGubj$aqc~9_tplDG*kuz<9^ET0)msLy;-Wje1)7Bu04VQ@J{Wiau(|yI zQFua-^w^2gm~P6f3jWm$p(od7EC++xqgPbgS2Xf7%zw{oQ@D2Sw2TGO&-$;(1IM9r zHF?aSZSuKc$nu#k+LPOdrny{|oPRS5X-zcxTwuvdQ$*$EJ_(!o1La_17={c7b-NHA ztqeh~!YKe$I-_@#XabE|QV}JNj-(1DpvQ{4l5Wcj8B!5Q zvOJp~?x*>-Kf2z7qFj;J;1cX9>cBFyN?&1k6mgCJnW5<8d$})U$z(j$@H=j8%S)~H z58QjvzeVmjgNA2^8bKCQ7fohoX7#*z2jMMTY?KypZ=quunFD5>lqS`*fU)1dQMT@xb3&pC28&r~wo#fxS~g*S5x=zj-EY0KwP#H!?xBJ|rsJVE;W z5bPI*=Y|^HN)EfJ@18mz?9GCO?Eb_wi*-p!3K{B)8(bS!`oZj3&&Lf94pg#D){hJm zJBGTvH^N1-tlb)w9a^jquP9($X(j*0gI!dt0gFPtL2M`W3CtEyPU^5qti#+_Qod<#TL7%dEfC|j=J*V2lzfJ(|hL{#j@j^45}q|MNUqFrf-Uv1 z4<}+$Ok`TlhGeP`?>x^zwg!?wJFi;PdpChBfglqP5}N~JkVGx7z?Wy7h#(g)v9|W2 zDsm3xSMMC!oJqCcsr)oNP*hDOeY4%DMP1#tj_0PxLXSD(6nDT6h*ts2WNtPiedk9S z&#>n)PoEAH^lop$wmPCAs1*Nv^ z(Bf7J9s?#8rf;f+j-90 zso8}DiylHFr=%x*z_?rSg3U;?*gRe|eQUjz)AYg+EDCQEO(232yxt22YB+dlh_R4? zt9yy)gfcm&OJxpU`#~tBfVnAtB{hQ_4jxb0m(WuE%}ZAWPozB0KByCn(pAA@ypdnj zC$p2Y*;8Nm`WMRcBf(dw6!~AvpAV+l*#zm!Ol-EVC&8E`BJ(!Yh-Pt5P~EL&hxviD z!4?xRhJ*W444Q<5Z%y3RQ{#eS>6RWm3F!?`OS3&CXR+$a6m8T)Y3i9JQs>E2%5zwz zRwBi}rN`~gpgOW6met?%k^R!a9@I;_@&ff(ilZQ~q5zf}psQ0*US?ZaW;JQ+a1qV5 z@a%ieJC$3so8xk{v+#xIN$Iv8+){$et)NN5h=f?D)menF62g-ZN}GTfV>HRAoV+Iw zYLf_i3l1Qzy=-G6yrlHxY*<+~Gj%C+0qgf37wuCnOu?j;Wp&(Z*Td z(aM9l;uXVec#;Gshjf1`CZR9)rx0ntKan~urt%ZA|FwjSnu|$rm`ABmg;C7P`~quG z7F%Lja6t6FhylpKFao+XX)N-^A?K?%nBT`jvDfxX;QX!6RuX z63Grr$__CjC4x#?D1L$pD-vWB+Y<6aAquiPEYvZ1wi|^6Q=_z_f%-E*HVR$jofs_E zNodcl6JjT`VRA!9$ycG|?9RGUfy=x)NuJFI<&u7zn#-*Q>;*6Yg3h1{4x_R#!>9ud zA#ng-7!vEjLSPgf($SWGLfcoM_N7O}JL6{+7cI)gN7R#i3v(d$XR^Si(A+bGYtrV* zLAUQ_*5@_}nsc$8j`eKUnR0Hucq&igl}d^G{DTI#xkKQY6}+BoD3NffcZK#!&Kb4{ zj5A_GG=n{|6q2=ZkuWh|A`4!z6YbaX&|+@0sg4cpv8`nPNsG`ExIr2Om5T_ssm#~U>?lguUH06NOol6^*`}l$z|3X`K2&NGNb8`SuaD@PXBO@iMBHR_N=LT= z1en)1F$=29546xExq3(B=ZirYFi- zt%e!fjW`*%yg^)UdBbM8cZt7CI<7~B|}CotsQN0X=M}5T$+1c z9l5mCv~y`Kfe~FHmo8f_Eozc7ximS%0yLD0xinPaiuA>)%A38bbk3Pe${j5^!4Pk4 zdim;&z{~WW(|3cJh~Wae6?hg zT~u&3?{Us1`ypJ2@h+ZZE25h15D2BDnRjvUaC#MNK=Usq7+s}PKwhf2^@kOrIztsw ze!uR4c9ePWl~l2`jKYZl7(ThLeQ7P%QSd4c3-Wp3Lf{dKql*R7(m-xT z%XM3Z7qwJktgzy8T1sx))Y3{zOUZZ85NWBYg;w9DrKYo0ZHIfQLxz@CoR$h@Q%h|% z*Iw~8*LQ6#1^=pAiZwVb#Q+yD=VdECI8kb<=b&@KbZ{=kEdvXR3eHYNwYf<12VBJ0 zbOX~>u%WBinihuey{)ShO;hl2_YF+es8WDf>&vQk!u02taJ873v5bH1dY@Y&_U`c{^3w%s%5$JqzhMGV!H{=cFvqHyWq?tIrFNV zx$A4roG|X3d2^{J*UW_2{!=%cxmJX72`(R$Kc_jzH~?{wSIPRM`qEk!P0b}3nu9%i(y+6Cat&KunHm`a3(k&XVxz1Uc(Mm$rx8Pn<4nkC%6W_l$pNFh zmfh5v%4@NH5a+l;d5I3Fk120A%FAA9Q*~>my0umw;(D6uR`o+3tvtlk)Ar+}x^z<> zQdC{(aZ`1z**INtstfr=)kQojRhLbITy-hgIyH|0sGm!6BsnIF_|V%GTd|%HB3Nz2 zCORX;R4F*kU9lA_r$V!-EWSi?uxZ&=EOugBvFO3`Lz<_!jY6}zK{*mDaoFmA)u_omDi?8SaHl{)y z3A`>g*;r?@4B;nqM2d7px3S=b4ry%dXD84&PM3BQ11Sj*yR{pK$B<8qBz@o13W^F|S_AFopQ8c;T9$U>t4-aBQG8huPtEtV zxyDfR)XbNR*{M6Q;|8g?908NzSU>mFG;C6X_7Tu^B_?^BY**PI(q_e^`w!?IBx~ys z3AyZBI^ldVC1)y}+=Yp+6>~n?j>~L@fgN)@Eg-YYVRDh6uv(T8*~+f~+G)*AJ)zbe zqQE`BJ)|oYxk|Nxt+pmC04vZbJlxQu@MEwey85T7Y&1z{Tuvgbi8cZ{R-=Ue<@k+JB7R|S?=hxIz)5LW& zRnBkOLJ>)ukmaeIVzE#p5lMoDM(%tOXESZk8rv-tnJTs_=gY+yc?{@t4>=BZp~`S6 zZ@>u27!+F9$QVGjGGkaZ0~ay2PQ(doofs4|2Dv+zD)=11>!=vMv!MzZk0W#Q~gD1UG(#%BJ&icyz(EDINXOc|AL<_}0W zUoqk=mf?_eb0+dArVv((rxv3{l1r&c>RK#UppzP~vB=&s9q-+l`0)GTH1)#+E;QM) z4FTbU>1?}@QS>f-8L6*5tRD3D=cnP?453;km1quMz9QSa9i*5qVLMZK!Gmn?e6Lz?DyE@x04y}-* z5bNIcU@9ouWgd4RBpkcC&L9ll-K&zvW_ltt)I4-KSm?E(b$|q#DCa;hT_akYfs5#q z#lc*Y@kQdS)$y}t3K|L*x)fz4ZgLN}(xA2@tS-@&5G(E0MPn-s>*kb|_UPt|l~}9n zb*26MV45pkt!w1gdL2KB#>5^YX@FsRYKIJVb042cu)VyDelF0sj%@JK%v4*qqexhF z%+=y0{LrBTJJij}6%2)f%RDanfmx;CT2Cj3l)`I0lyx~SqX|A6=X0*EE*N42)O*pl z0{xE8JsP8Utjvh$vNV~15}Mot2})pLc2BXMyLQ?8ixo1kF4ytyV!Z;iu9wJI*?LAD zIJaQc;j>7Z%|7tKd#ls34iJE!9c<|ctb;es7)x%nnI>y4RiYatfv!2o7Fr#*8G6<8 z%XNC_YXdy=TX;NBpX_97*mSFOtW`SF1jXb^v)RC0LnjznBDnq+88YI>LNN1avnW&-HwN>A#tj3r{=Q@O*f`L;A4nL+Bb8SLBV@Oz%IWhHo+uW zqysNY;+B@nXX(Jz0Jjw`+(328CRc&n<{|s#?|$d>2F6KyxCubXcTcy<;(wyi^FBu*Q zl=g4rWlyH@|M9b@Q++Rn^0)oy7ks1M#1l#}wG`09l4F90Kl{yNm_Z+$C;94TH{Oz69hs z1K_Ui3K!fT4z6}bhVh^A8bnh@w(1Lm<=|DdyT8lBkJ5&JUvl4+QMSq~w1^1Iz|o3e z>fy}lhWj^pWM2%Iv+@XyD32a2cfF_r(A|MO4tP;Fip1BB;Avj+k(KI@CO-+)E^|I2 zHKm?Kaz7F+ymfie#%3FlkJX5$yN>;2W@Z+S@>9|L>hiuTm-V^P^PcVTyiFy~d)q5?e7x85 zuA`s+_N)IbuP}gq8Z%8_KOe)-%`STUi0yl+dlJ0*$yz;|??+T&KP_#)A$|DR*qk>% zao36QBZ-wyohZJ|AJcC$x9Z$0KmXjW(#!M=zct_ppVR);&+xkev$gxYxCcm zw(_B|`H92%k5pgR8YukNyUxvDr?%dw_Kg$=pStpj{I&gq(AQq8pQ|pu7k+2@ItO^I z*1~+RUlT+Jk!!*dzs>=QF>>vGFm>(57AfoYk`&GX#`@jBaP{bVq`XoG+V_pT5`^`8 z0OHCkUJ1ndJxm$bW`@(!>%H6Gv2f++=oR~}D5~ephi`w!=)QeYq0xo8v5AHGn-AZ3 zBX!rRR^NwM+ztbg4ceZ43cwrOJ9Aj_3G2f>y#ns(PPkMw;XZoKaBrAj0r-abPRObeXrnpq z*6h!P7dK3-ggvnWHZ?8S)2qSWx3_J?SK>W#Km7!KZ!fm(+gETU61DT^&#vEZtl6(# zTNfTubMW@B-w#%~e(zns-$JwBz3cabJr3T(>-U>%_Iq;ue$&l zZT7o${eDN9{TAr=j)iOVYxAQMCyvfYmt<=XxbdT-htHfDJ2bJl4{tL%e{ABo{V=_C zg%h4v#~!~#--lQ9zlyQ?-##oKp#IO&_o>zTpTq%-uk62xq;+NgYeq*;&fw+v-%GTp zztQNqf&N$XK_A=nUqQL~zm6yl$mg)I8jdT9IA%ss=tIk~x%q!S$0vRa!#hODeG}UF z@ai$;4qEV+&~k+T9l(i&vFRc?;*SPtzKax}2grWjZ#dz~2PhxP>u;reI4|Ep`B+{) zLU}ANpQJpWm+z*$keBbHJdv00r#zXLAEZ2;mmj8lJTE^=`Dk8#obr*p{58t@)6b`C z-hF(U^NuO^^Vz^>BOm>}lliINCO*Y}n|a^DXDgo-a+{x6O_fa6dw?h0`g> -function Heading() { - const title = 'Root finding web application'; - return

{title}

-} - -// this JavaScript snippet is later referred to as <> -function Plot({roots}) { - const container = React.useRef(null); - - function didUpdate() { - if (container.current === null) { - return; - } - // this JavaScript snippet is later referred to as <> - const spec = { - "$schema": "https://vega.github.io/schema/vega-lite/v4.json", - "data": { "values": roots }, - "mark": "point", - "encoding": { - "x": { "field": "epsilon", "type": "quantitative" }, - "y": { "field": "duration", "type": "quantitative", "title": "Duration (ms)" } - }, - "width": 800, - "height": 600 - }; - vegaEmbed(container.current, spec); - } - const dependencies = [container, roots]; - React.useEffect(didUpdate, dependencies); - - return
; -} - -function App() { - const Form = JSONSchemaForm.default; - const uiSchema = { - "guess": { - "ui:widget": "range" - } - } - const [formData, setFormData] = React.useState({ - - }); - - function handleChange(event) { - setFormData(event.formData); - } - - // this JavaScript snippet is later referred to as <> - const schema = { - "type": "object", - "properties": { - "epsilon": { - "title": "Epsilon", - "type": "object", - "properties": { - "min": { - "type": "number", - "minimum": 0, - "default": 0.0001 - }, - "max": { - "type": "number", - "minimum": 0, - "default": 0.001 - }, - "step": { - "type": "number", - "minimum": 0, - "default": 0.0001 - } - }, - "required": ["min", "max", "step"], - "additionalProperties": false - }, - "guess": { - "title": "Initial guess", - "type": "number", - "minimum": -100, - "maximum": 100, - "default": -20 - } - }, - "required": ["epsilon", "guess"], - "additionalProperties": false - } - // this JavaScript snippet is appended to <> - const [roots, setRoots] = React.useState([]); - - function handleSubmit(submission, event) { - event.preventDefault(); - const worker = new Worker('worker-sweep.js'); - worker.postMessage({ - type: 'CALCULATE', - payload: submission.formData - }); - worker.onmessage = function(message) { - if (message.data.type === 'RESULT') { - const result = message.data.payload.roots; - setRoots(result); - worker.terminate(); - } - }; - } - - return ( -
- - { /* this JavaScript snippet is later referred to as <> */} - - -
- ); -} - -ReactDOM.render( - , - document.getElementById('container') -); \ No newline at end of file diff --git a/src/js/worker-sweep.js b/src/js/worker-sweep.js deleted file mode 100644 index d7947e7..0000000 --- a/src/js/worker-sweep.js +++ /dev/null @@ -1,36 +0,0 @@ -// this JavaScript snippet stored as src/js/worker-sweep.js -importScripts('newtonraphsonwasm.js'); - -onmessage = function(message) { - if (message.data.type === 'CALCULATE') { - createModule().then((module) => { - // this JavaScript snippet is later referred to as <> - const {min, max, step} = message.data.payload.epsilon; - const guess = message.data.payload.guess; - // this JavaScript snippet appended to <> - const roots = []; - // this JavaScript snippet appended to <> - for (let epsilon = min; epsilon <= max; epsilon += step) { - // this JavaScript snippet appended to <> - const t0 = performance.now(); - const finder = new module.NewtonRaphson(epsilon); - const root = finder.solve(guess); - const duration = performance.now() - t0; - // this JavaScript snippet appended to <> - roots.push({ - epsilon, - guess, - root, - duration - }); - // this JavaScript snippet appended to <> - } - postMessage({ - type: 'RESULT', - payload: { - roots - } - }); - }); - } -}; \ No newline at end of file diff --git a/src/js/worker.js b/src/js/worker.js deleted file mode 100644 index 0477666..0000000 --- a/src/js/worker.js +++ /dev/null @@ -1,23 +0,0 @@ -// this JavaScript snippet is stored as src/js/worker.js -importScripts('newtonraphsonwasm.js'); - -// this JavaScript snippet is later referred to as <> -onmessage = function(message) { - // this JavaScript snippet is before referred to as <> - if (message.data.type === 'CALCULATE') { - createModule().then((module) => { - // this JavaScript snippet is before referred to as <> - const epsilon = message.data.payload.epsilon; - const finder = new module.NewtonRaphson(epsilon); - const guess = message.data.payload.guess; - const root = finder.solve(guess); - // this JavaScript snippet is before referred to as <> - postMessage({ - type: 'RESULT', - payload: { - root: root - } - }); - }); - } -}; \ No newline at end of file From 2ab618ef5ca75a72e56c46bf83d192e08cbd70df Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 18:29:02 +0200 Subject: [PATCH 29/48] updated host-files task --- Makefile | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 77d35a3..b74f00a 100644 --- a/Makefile +++ b/Makefile @@ -91,7 +91,7 @@ webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm: webassembly emcc -Icli/ --bind -o webassembly/newtonraphsonwasm.js -s MODULARIZE=1 -s EXPORT_NAME=createModule webassembly/wasm-newtonraphson.cpp host-files: build-wasm - cd flask && python3 -m http.server 8000 && cd - + python3 -m http.server 8000 test-wasm: npx cypress run --config-file false diff --git a/README.md b/README.md index 838ad34..3a823c4 100644 --- a/README.md +++ b/README.md @@ -814,7 +814,7 @@ The web browser can only load the `newtonraphsonwasm.js` file when hosted by a w Python ships with a built-in web server, we will use it to host the all files of the repository on port 8000. ```{.awk #host-files} -cd flask && python3 -m http.server 8000 && cd - +python3 -m http.server 8000 ``` Visit [http://localhost:8000/webassembly/example.html](http://localhost:8000/webassembly/example.html) to see the result of the calculation. From 1b93061ae72bc66b9c7296d74bfde76291d04368 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 18:43:09 +0200 Subject: [PATCH 30/48] added linking of wasm file --- INSTALL.md | 3 +++ Makefile | 5 ++++- README.md | 8 +++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 1ff5492..87b0dcf 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -107,6 +107,9 @@ build-wasm: webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm: webassembly/wasm-newtonraphson.cpp <> +react/newtonraphsonwasm.js react/newtonraphsonwasm.wasm: webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm + <> + host-files: build-wasm <> diff --git a/Makefile b/Makefile index b74f00a..a15ec1f 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ openapi/newtonraphsonpy.*.so: openapi/py-newtonraphson.cpp openapi/py-newtonraphson.cpp -o openapi/newtonraphsonpy`python3-config --extension-suffix` flask/newtonraphsonpy.*.so: openapi/newtonraphsonpy.*.so - cd flask && ln -s ../openapi/newtonraphsonpy`python3-config --extension-suffix` . && cd - + cd flask && ln -s ../openapi/newtonraphsonpy`python3-config --extension-suffix` . && cd - test-py: openapi/example.py openapi/newtonraphsonpy.*.so python openapi/example.py @@ -90,6 +90,9 @@ build-wasm: webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm: webassembly/wasm-newtonraphson.cpp emcc -Icli/ --bind -o webassembly/newtonraphsonwasm.js -s MODULARIZE=1 -s EXPORT_NAME=createModule webassembly/wasm-newtonraphson.cpp +react/newtonraphsonwasm.js react/newtonraphsonwasm.wasm: webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm + cd react && ln -s ../webassembly/newtonraphsonwasm.js . && ln -s ../webassembly/newtonraphsonwasm.wasm . && cd - + host-files: build-wasm python3 -m http.server 8000 diff --git a/README.md b/README.md index 3a823c4..e028021 100644 --- a/README.md +++ b/README.md @@ -406,7 +406,7 @@ pip install flask We'll use the shared library that the openapi example also uses: ```{.awk #flask-link-newtonraphsonpy} - cd flask && ln -s ../openapi/newtonraphsonpy`python3-config --extension-suffix` . && cd - +cd flask && ln -s ../openapi/newtonraphsonpy`python3-config --extension-suffix` . && cd - ``` The web application has 3 kinds of pages: @@ -1177,6 +1177,12 @@ ReactDOM.render( ); ``` +Make sure that the App can find the WebAssembly files by + +```{.awk #link-wasm} +cd react && ln -s ../webassembly/newtonraphsonwasm.js . && ln -s ../webassembly/newtonraphsonwasm.wasm . && cd - +``` + Like before we also need to host the files in a web server with ```shell From e553fc987dbaa4963efae6d1668cd582b8116def Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 19:18:43 +0200 Subject: [PATCH 31/48] webassembly should work; react almost works --- .github/workflows/main.yml | 8 ++++---- .gitignore | 2 ++ INSTALL.md | 7 +++++-- Makefile | 7 +++++-- TESTING.md | 20 +++++++++++-------- .../{ => react}/example-app_spec.js | 0 .../example-jsonschema-form_spec.js | 0 .../{ => react}/example-plot_spec.js | 0 .../example-web-worker_spec.js | 0 .../{ => webassembly}/example_spec.js | 0 10 files changed, 28 insertions(+), 16 deletions(-) rename cypress/integration/{ => react}/example-app_spec.js (100%) rename cypress/integration/{ => react}/example-jsonschema-form_spec.js (100%) rename cypress/integration/{ => react}/example-plot_spec.js (100%) rename cypress/integration/{ => webassembly}/example-web-worker_spec.js (100%) rename cypress/integration/{ => webassembly}/example_spec.js (100%) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 38f3fec..6138307 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -157,7 +157,7 @@ jobs: run: make host-files 2>&1 | tee ./web-server.log & - name: Run tests - run: make test-wasm + run: make test-wasm-webassembly - name: Upload log of web server if: ${{ always() }} @@ -173,14 +173,14 @@ jobs: - name: Install emscripten uses: mymindstorm/setup-emsdk@v4 - - name: Build WebAssembly module - run: make build-wasm + - name: Build WebAssembly module and link to it from react/ + run: make build-wasm && make react/newtonraphsonwasm.js - name: Start web server for hosting files in background run: make host-files 2>&1 | tee ./web-server.log & - name: Run tests - run: make test-wasm + run: make test-wasm-react - name: Upload log of web server if: ${{ always() }} diff --git a/.gitignore b/.gitignore index 945a084..b8d53a9 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,8 @@ cypress/videos /flask/newtonraphsonpy.*.so /webassembly/newtonraphsonwasm.js /webassembly/newtonraphsonwasm.wasm +/react/newtonraphsonwasm.js +/react/newtonraphsonwasm.wasm # Ignore entangled db .entangled/db.sqlite diff --git a/INSTALL.md b/INSTALL.md index 87b0dcf..a86041c 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -113,8 +113,11 @@ react/newtonraphsonwasm.js react/newtonraphsonwasm.wasm: webassembly/newtonraphs host-files: build-wasm <> -test-wasm: - <> +test-wasm-webassembly: + <> + +test-wasm-react: + <> init-git-hook: <> diff --git a/Makefile b/Makefile index a15ec1f..110c5ab 100644 --- a/Makefile +++ b/Makefile @@ -96,8 +96,11 @@ react/newtonraphsonwasm.js react/newtonraphsonwasm.wasm: webassembly/newtonraphs host-files: build-wasm python3 -m http.server 8000 -test-wasm: - npx cypress run --config-file false +test-wasm-webassembly: + npx cypress run --config-file false --spec 'cypress/integration/webassembly/*_spec.js' + +test-wasm-react: + npx cypress run --config-file false --spec 'cypress/integration/react/*_spec.js' init-git-hook: chmod +x .githooks/pre-commit diff --git a/TESTING.md b/TESTING.md index d601b85..1d0ea10 100644 --- a/TESTING.md +++ b/TESTING.md @@ -15,7 +15,7 @@ python3 -m http.server 8000 Let's, first write a test for the [direct WebAssembly example](http://localhost:8000/webassembly/example.html). -```{.js file=cypress/integration/example_spec.js} +```{.js file=cypress/integration/webassembly/example_spec.js} // this JavaScript snippet is run by cypress and is stored as cypress/integration/example_spec.js describe('webassembly/example.html', () => { it('should render -1.00', () => { @@ -27,7 +27,7 @@ describe('webassembly/example.html', () => { Second, a test for the WebAssembly called through a [web worker](http://localhost:8000/webassembly/example-web-worker.html). -```{.js file=cypress/integration/example-web-worker_spec.js} +```{.js file=cypress/integration/webassembly/example-web-worker_spec.js} // this JavaScript snippet is run by cypress and is stored as cypress/integration/example-web-worker_spec.js describe('webassembly/example-web-worker.html', () => { it('should render -1.00', () => { @@ -40,7 +40,7 @@ describe('webassembly/example-web-worker.html', () => { Third, a test for the [React/form/Web worker/WebAssembly combination](http://localhost:8000/react/example-app.html). Let us also change the initial guess value. -```{.js file=cypress/integration/example-app_spec.js} +```{.js file=cypress/integration/react/example-app_spec.js} describe('react/example-app.html', () => { it('should render -1.00', () => { cy.visit('http://localhost:8000/react/example-app.html'); @@ -54,7 +54,7 @@ describe('react/example-app.html', () => { And similar test to the previous one, but now with [JSON schema powered form](http://localhost:8000/react/example-jsonschema-form.html). -```{.js file=cypress/integration/example-jsonschema-form_spec.js} +```{.js file=cypress/integration/react/example-jsonschema-form_spec.js} describe('react/example-jsonschema-form.html', () => { it('should render -1.00', () => { cy.visit('http://localhost:8000/react/example-jsonschema-form.html'); @@ -71,7 +71,7 @@ describe('react/example-jsonschema-form.html', () => { And lastly a test for the [web application with a plot](http://localhost:8000/react/example-plot.html). -```{.js file=cypress/integration/example-plot_spec.js} +```{.js file=cypress/integration/react/example-plot_spec.js} describe('react/example-plot.html', () => { it('should render -1.00', () => { cy.visit('http://localhost:8000/react/example-plot.html'); @@ -81,10 +81,14 @@ describe('react/example-plot.html', () => { }); ``` -The test can be run with the following command: +The test can be run with the one of the following commands: -```{.awk #test-wasm} -npx cypress run --config-file false +```{.awk #test-wasm-webassembly} +npx cypress run --config-file false --spec 'cypress/integration/webassembly/*_spec.js' +``` + +```{.awk #test-wasm-react} +npx cypress run --config-file false --spec 'cypress/integration/react/*_spec.js' ``` The [`npx`](https://www.npmjs.com/package/npx) command ships with NodeJS which is included in the Emscripten SDK and can be used to run commands available on [npm repository](https://npmjs.com/). diff --git a/cypress/integration/example-app_spec.js b/cypress/integration/react/example-app_spec.js similarity index 100% rename from cypress/integration/example-app_spec.js rename to cypress/integration/react/example-app_spec.js diff --git a/cypress/integration/example-jsonschema-form_spec.js b/cypress/integration/react/example-jsonschema-form_spec.js similarity index 100% rename from cypress/integration/example-jsonschema-form_spec.js rename to cypress/integration/react/example-jsonschema-form_spec.js diff --git a/cypress/integration/example-plot_spec.js b/cypress/integration/react/example-plot_spec.js similarity index 100% rename from cypress/integration/example-plot_spec.js rename to cypress/integration/react/example-plot_spec.js diff --git a/cypress/integration/example-web-worker_spec.js b/cypress/integration/webassembly/example-web-worker_spec.js similarity index 100% rename from cypress/integration/example-web-worker_spec.js rename to cypress/integration/webassembly/example-web-worker_spec.js diff --git a/cypress/integration/example_spec.js b/cypress/integration/webassembly/example_spec.js similarity index 100% rename from cypress/integration/example_spec.js rename to cypress/integration/webassembly/example_spec.js From 9548718d3ee22badb7479d428260d9efa0db4a5c Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Tue, 9 Jun 2020 19:23:07 +0200 Subject: [PATCH 32/48] added missing file but is now duplicated --- react/worker.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 react/worker.js diff --git a/react/worker.js b/react/worker.js new file mode 100644 index 0000000..641ae7a --- /dev/null +++ b/react/worker.js @@ -0,0 +1,23 @@ +// this JavaScript snippet is stored as webassembly/worker.js +importScripts('newtonraphsonwasm.js'); + +// this JavaScript snippet is later referred to as <> +onmessage = function(message) { + // this JavaScript snippet is before referred to as <> + if (message.data.type === 'CALCULATE') { + createModule().then((module) => { + // this JavaScript snippet is before referred to as <> + const epsilon = message.data.payload.epsilon; + const finder = new module.NewtonRaphson(epsilon); + const guess = message.data.payload.guess; + const root = finder.solve(guess); + // this JavaScript snippet is before referred to as <> + postMessage({ + type: 'RESULT', + payload: { + root: root + } + }); + }); + } +}; \ No newline at end of file From 765e9686beafeb83b025d0dc186afc8b9d5c7745 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 10 Jun 2020 06:09:50 +0200 Subject: [PATCH 33/48] Dont ignore wasm files, they are needed to online examples See #35 --- .gitignore | 4 - react/newtonraphsonwasm.js | 1 + react/newtonraphsonwasm.wasm | 1 + webassembly/newtonraphsonwasm.js | 4146 ++++++++++++++++++++++++++++ webassembly/newtonraphsonwasm.wasm | Bin 0 -> 26547 bytes 5 files changed, 4148 insertions(+), 4 deletions(-) create mode 120000 react/newtonraphsonwasm.js create mode 120000 react/newtonraphsonwasm.wasm create mode 100644 webassembly/newtonraphsonwasm.js create mode 100644 webassembly/newtonraphsonwasm.wasm diff --git a/.gitignore b/.gitignore index b8d53a9..558929a 100644 --- a/.gitignore +++ b/.gitignore @@ -11,10 +11,6 @@ cypress/videos /cgi/apache2/cgi-bin/newtonraphson /openapi/newtonraphsonpy.*.so /flask/newtonraphsonpy.*.so -/webassembly/newtonraphsonwasm.js -/webassembly/newtonraphsonwasm.wasm -/react/newtonraphsonwasm.js -/react/newtonraphsonwasm.wasm # Ignore entangled db .entangled/db.sqlite diff --git a/react/newtonraphsonwasm.js b/react/newtonraphsonwasm.js new file mode 120000 index 0000000..3b823c2 --- /dev/null +++ b/react/newtonraphsonwasm.js @@ -0,0 +1 @@ +../webassembly/newtonraphsonwasm.js \ No newline at end of file diff --git a/react/newtonraphsonwasm.wasm b/react/newtonraphsonwasm.wasm new file mode 120000 index 0000000..fd9eaad --- /dev/null +++ b/react/newtonraphsonwasm.wasm @@ -0,0 +1 @@ +../webassembly/newtonraphsonwasm.wasm \ No newline at end of file diff --git a/webassembly/newtonraphsonwasm.js b/webassembly/newtonraphsonwasm.js new file mode 100644 index 0000000..31054d0 --- /dev/null +++ b/webassembly/newtonraphsonwasm.js @@ -0,0 +1,4146 @@ + +var createModule = (function() { + var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; + if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename; + return ( +function(createModule) { + createModule = createModule || {}; + + + +// 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(Module) { ..generated code.. } +// 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 = typeof createModule !== 'undefined' ? createModule : {}; + + +// Set up the promise that indicates the Module is initialized +var readyPromiseResolve, readyPromiseReject; +Module['ready'] = new Promise(function(resolve, reject) { + readyPromiseResolve = resolve; + readyPromiseReject = reject; +}); + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_main')) { + Object.defineProperty(Module['ready'], '_main', { configurable: true, get: function() { abort('You are getting _main on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_main', { configurable: true, set: function() { abort('You are setting _main on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_malloc')) { + Object.defineProperty(Module['ready'], '_malloc', { configurable: true, get: function() { abort('You are getting _malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_malloc', { configurable: true, set: function() { abort('You are setting _malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_free')) { + Object.defineProperty(Module['ready'], '_free', { configurable: true, get: function() { abort('You are getting _free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_free', { configurable: true, set: function() { abort('You are setting _free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_stackSave')) { + Object.defineProperty(Module['ready'], '_stackSave', { configurable: true, get: function() { abort('You are getting _stackSave on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_stackSave', { configurable: true, set: function() { abort('You are setting _stackSave on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_stackRestore')) { + Object.defineProperty(Module['ready'], '_stackRestore', { configurable: true, get: function() { abort('You are getting _stackRestore on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_stackRestore', { configurable: true, set: function() { abort('You are setting _stackRestore on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_stackAlloc')) { + Object.defineProperty(Module['ready'], '_stackAlloc', { configurable: true, get: function() { abort('You are getting _stackAlloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_stackAlloc', { configurable: true, set: function() { abort('You are setting _stackAlloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '___data_end')) { + Object.defineProperty(Module['ready'], '___data_end', { configurable: true, get: function() { abort('You are getting ___data_end on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '___data_end', { configurable: true, set: function() { abort('You are setting ___data_end on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '___wasm_call_ctors')) { + Object.defineProperty(Module['ready'], '___wasm_call_ctors', { configurable: true, get: function() { abort('You are getting ___wasm_call_ctors on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '___wasm_call_ctors', { configurable: true, set: function() { abort('You are setting ___wasm_call_ctors on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_fflush')) { + Object.defineProperty(Module['ready'], '_fflush', { configurable: true, get: function() { abort('You are getting _fflush on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_fflush', { configurable: true, set: function() { abort('You are setting _fflush on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '___errno_location')) { + Object.defineProperty(Module['ready'], '___errno_location', { configurable: true, get: function() { abort('You are getting ___errno_location on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '___errno_location', { configurable: true, set: function() { abort('You are setting ___errno_location on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], 'onRuntimeInitialized')) { + Object.defineProperty(Module['ready'], 'onRuntimeInitialized', { configurable: true, get: function() { abort('You are getting onRuntimeInitialized on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], 'onRuntimeInitialized', { configurable: true, set: function() { abort('You are setting onRuntimeInitialized on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + +// --pre-jses are emitted after the Module integration code, so that they can +// refer to Module (if they choose; they can also define Module) +// {{PRE_JSES}} + +// 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 = {}; +var key; +for (key in Module) { + if (Module.hasOwnProperty(key)) { + moduleOverrides[key] = Module[key]; + } +} + +var arguments_ = []; +var thisProgram = './this.program'; +var quit_ = function(status, toThrow) { + throw toThrow; +}; + +// 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 = false; +var ENVIRONMENT_IS_SHELL = false; +ENVIRONMENT_IS_WEB = typeof window === 'object'; +ENVIRONMENT_IS_WORKER = typeof importScripts === 'function'; +// N.b. Electron.js environment is simultaneously a NODE-environment, but +// also a web environment. +ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string'; +ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; + +if (Module['ENVIRONMENT']) { + throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -s ENVIRONMENT=web or -s ENVIRONMENT=node)'); +} + + + +// `/` 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 read_, + readAsync, + readBinary, + setWindowTitle; + +var nodeFS; +var nodePath; + +if (ENVIRONMENT_IS_NODE) { + if (ENVIRONMENT_IS_WORKER) { + scriptDirectory = require('path').dirname(scriptDirectory) + '/'; + } else { + scriptDirectory = __dirname + '/'; + } + + + + + read_ = function shell_read(filename, binary) { + if (!nodeFS) nodeFS = require('fs'); + if (!nodePath) nodePath = require('path'); + filename = nodePath['normalize'](filename); + return nodeFS['readFileSync'](filename, binary ? null : 'utf8'); + }; + + readBinary = function readBinary(filename) { + var ret = read_(filename, true); + if (!ret.buffer) { + ret = new Uint8Array(ret); + } + assert(ret.buffer); + return ret; + }; + + + + + if (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 + + process['on']('uncaughtException', function(ex) { + // suppress ExitStatus exceptions from showing an error + if (!(ex instanceof ExitStatus)) { + throw ex; + } + }); + + process['on']('unhandledRejection', abort); + + quit_ = function(status) { + process['exit'](status); + }; + + Module['inspect'] = function () { return '[Emscripten Module object]'; }; + + + +} else +if (ENVIRONMENT_IS_SHELL) { + + + if (typeof read != 'undefined') { + read_ = function shell_read(f) { + return read(f); + }; + } + + readBinary = function readBinary(f) { + var data; + if (typeof readbuffer === 'function') { + return new Uint8Array(readbuffer(f)); + } + data = read(f, 'binary'); + assert(typeof data === 'object'); + return data; + }; + + if (typeof scriptArgs != 'undefined') { + arguments_ = scriptArgs; + } else if (typeof arguments != 'undefined') { + arguments_ = arguments; + } + + if (typeof quit === 'function') { + quit_ = function(status) { + quit(status); + }; + } + + if (typeof print !== 'undefined') { + // Prefer to use print/printErr where they exist, as they usually work better. + if (typeof console === 'undefined') console = /** @type{!Console} */({}); + console.log = /** @type{!function(this:Console, ...*): undefined} */ (print); + console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr !== 'undefined' ? printErr : print); + } + + +} 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. +if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { + if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled + scriptDirectory = self.location.href; + } else if (document.currentScript) { // web + scriptDirectory = document.currentScript.src; + } + // When MODULARIZE, this JS may be executed later, after document.currentScript + // is gone, so we saved it, and we use it here instead of any other info. + if (_scriptDir) { + scriptDirectory = _scriptDir; + } + // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them. + // otherwise, slice off the final part of the url to find the script directory. + // if scriptDirectory does not contain a slash, lastIndexOf will return -1, + // and scriptDirectory will correctly be replaced with an empty string. + if (scriptDirectory.indexOf('blob:') !== 0) { + scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf('/')+1); + } else { + scriptDirectory = ''; + } + + + // Differentiate the Web Worker from the Node Worker case, as reading must + // be done differently. + { + + + + + read_ = function shell_read(url) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + xhr.send(null); + return xhr.responseText; + }; + + if (ENVIRONMENT_IS_WORKER) { + readBinary = function readBinary(url) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + xhr.responseType = 'arraybuffer'; + xhr.send(null); + return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response)); + }; + } + + readAsync = function readAsync(url, onload, onerror) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.responseType = 'arraybuffer'; + xhr.onload = function xhr_onload() { + if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0 + onload(xhr.response); + return; + } + onerror(); + }; + xhr.onerror = onerror; + xhr.send(null); + }; + + + + + } + + setWindowTitle = function(title) { document.title = title }; +} else +{ + throw new Error('environment detection error'); +} + + +// Set up the out() and err() hooks, which are how we can print to stdout or +// stderr, respectively. +var out = Module['print'] || console.log.bind(console); +var err = Module['printErr'] || console.warn.bind(console); + +// Merge back in the overrides +for (key in moduleOverrides) { + if (moduleOverrides.hasOwnProperty(key)) { + Module[key] = moduleOverrides[key]; + } +} +// Free the object hierarchy contained in the overrides, this lets the GC +// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array. +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 (!Object.getOwnPropertyDescriptor(Module, 'arguments')) Object.defineProperty(Module, 'arguments', { configurable: true, get: function() { abort('Module.arguments has been replaced with plain arguments_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); +if (Module['thisProgram']) thisProgram = Module['thisProgram'];if (!Object.getOwnPropertyDescriptor(Module, 'thisProgram')) Object.defineProperty(Module, 'thisProgram', { configurable: true, get: function() { abort('Module.thisProgram has been replaced with plain thisProgram (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); +if (Module['quit']) quit_ = Module['quit'];if (!Object.getOwnPropertyDescriptor(Module, 'quit')) Object.defineProperty(Module, 'quit', { configurable: true, get: function() { abort('Module.quit has been replaced with plain quit_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); + +// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message +// Assertions on removed incoming Module JS APIs. +assert(typeof Module['memoryInitializerPrefixURL'] === 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead'); +assert(typeof Module['pthreadMainPrefixURL'] === 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead'); +assert(typeof Module['cdInitializerPrefixURL'] === 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead'); +assert(typeof Module['filePackagePrefixURL'] === 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead'); +assert(typeof Module['read'] === 'undefined', 'Module.read option was removed (modify read_ in JS)'); +assert(typeof Module['readAsync'] === 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)'); +assert(typeof Module['readBinary'] === 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)'); +assert(typeof Module['setWindowTitle'] === 'undefined', 'Module.setWindowTitle option was removed (modify setWindowTitle in JS)'); +assert(typeof Module['TOTAL_MEMORY'] === 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY'); +if (!Object.getOwnPropertyDescriptor(Module, 'read')) Object.defineProperty(Module, 'read', { configurable: true, get: function() { abort('Module.read has been replaced with plain read_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); +if (!Object.getOwnPropertyDescriptor(Module, 'readAsync')) Object.defineProperty(Module, 'readAsync', { configurable: true, get: function() { abort('Module.readAsync has been replaced with plain readAsync (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); +if (!Object.getOwnPropertyDescriptor(Module, 'readBinary')) Object.defineProperty(Module, 'readBinary', { configurable: true, get: function() { abort('Module.readBinary has been replaced with plain readBinary (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); +if (!Object.getOwnPropertyDescriptor(Module, 'setWindowTitle')) Object.defineProperty(Module, 'setWindowTitle', { configurable: true, get: function() { abort('Module.setWindowTitle has been replaced with plain setWindowTitle (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); +var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js'; +var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js'; +var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js'; +var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js'; + + + + + + +// {{PREAMBLE_ADDITIONS}} + +var STACK_ALIGN = 16; + +function dynamicAlloc(size) { + assert(DYNAMICTOP_PTR); + var ret = HEAP32[DYNAMICTOP_PTR>>2]; + var end = (ret + size + 15) & -16; + assert(end <= HEAP8.length, 'failure to dynamicAlloc - memory growth etc. is not supported there, call malloc/sbrk directly'); + HEAP32[DYNAMICTOP_PTR>>2] = end; + return ret; +} + +function alignMemory(size, factor) { + if (!factor) factor = STACK_ALIGN; // stack alignment (16-byte) by default + return Math.ceil(size / factor) * factor; +} + +function getNativeTypeSize(type) { + switch (type) { + case 'i1': case 'i8': return 1; + case 'i16': return 2; + case 'i32': return 4; + case 'i64': return 8; + case 'float': return 4; + case 'double': return 8; + default: { + if (type[type.length-1] === '*') { + return 4; // A pointer + } else if (type[0] === 'i') { + var bits = Number(type.substr(1)); + assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type); + return bits / 8; + } else { + return 0; + } + } + } +} + +function warnOnce(text) { + if (!warnOnce.shown) warnOnce.shown = {}; + if (!warnOnce.shown[text]) { + warnOnce.shown[text] = 1; + err(text); + } +} + + + + + + + + +// Wraps a JS function as a wasm function with a given signature. +function convertJsFunctionToWasm(func, sig) { + + // If the type reflection proposal is available, use the new + // "WebAssembly.Function" constructor. + // Otherwise, construct a minimal wasm module importing the JS function and + // re-exporting it. + if (typeof WebAssembly.Function === "function") { + var typeNames = { + 'i': 'i32', + 'j': 'i64', + 'f': 'f32', + 'd': 'f64' + }; + var type = { + parameters: [], + results: sig[0] == 'v' ? [] : [typeNames[sig[0]]] + }; + for (var i = 1; i < sig.length; ++i) { + type.parameters.push(typeNames[sig[i]]); + } + return new WebAssembly.Function(type, func); + } + + // The module is static, with the exception of the type section, which is + // generated based on the signature passed in. + var typeSection = [ + 0x01, // id: section, + 0x00, // length: 0 (placeholder) + 0x01, // count: 1 + 0x60, // form: func + ]; + var sigRet = sig.slice(0, 1); + var sigParam = sig.slice(1); + var typeCodes = { + 'i': 0x7f, // i32 + 'j': 0x7e, // i64 + 'f': 0x7d, // f32 + 'd': 0x7c, // f64 + }; + + // Parameters, length + signatures + typeSection.push(sigParam.length); + for (var i = 0; i < sigParam.length; ++i) { + typeSection.push(typeCodes[sigParam[i]]); + } + + // Return values, length + signatures + // With no multi-return in MVP, either 0 (void) or 1 (anything else) + if (sigRet == 'v') { + typeSection.push(0x00); + } else { + typeSection = typeSection.concat([0x01, typeCodes[sigRet]]); + } + + // Write the overall length of the type section back into the section header + // (excepting the 2 bytes for the section id and length) + typeSection[1] = typeSection.length - 2; + + // Rest of the module is static + var bytes = new Uint8Array([ + 0x00, 0x61, 0x73, 0x6d, // magic ("\0asm") + 0x01, 0x00, 0x00, 0x00, // version: 1 + ].concat(typeSection, [ + 0x02, 0x07, // import section + // (import "e" "f" (func 0 (type 0))) + 0x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00, + 0x07, 0x05, // export section + // (export "f" (func 0 (type 0))) + 0x01, 0x01, 0x66, 0x00, 0x00, + ])); + + // We can compile this wasm module synchronously because it is very small. + // This accepts an import (at "e.f"), that it reroutes to an export (at "f") + var module = new WebAssembly.Module(bytes); + var instance = new WebAssembly.Instance(module, { + 'e': { + 'f': func + } + }); + var wrappedFunc = instance.exports['f']; + return wrappedFunc; +} + +var freeTableIndexes = []; + +// Weak map of functions in the table to their indexes, created on first use. +var functionsInTableMap; + +// Add a wasm function to the table. +function addFunctionWasm(func, sig) { + var table = wasmTable; + + // Check if the function is already in the table, to ensure each function + // gets a unique index. First, create the map if this is the first use. + if (!functionsInTableMap) { + functionsInTableMap = new WeakMap(); + for (var i = 0; i < table.length; i++) { + var item = table.get(i); + // Ignore null values. + if (item) { + functionsInTableMap.set(item, i); + } + } + } + if (functionsInTableMap.has(func)) { + return functionsInTableMap.get(func); + } + + // It's not in the table, add it now. + + + var ret; + // Reuse a free index if there is one, otherwise grow. + if (freeTableIndexes.length) { + ret = freeTableIndexes.pop(); + } else { + ret = table.length; + // Grow the table + try { + table.grow(1); + } catch (err) { + if (!(err instanceof RangeError)) { + throw err; + } + throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.'; + } + } + + // Set the new value. + try { + // Attempting to call this with JS function will cause of table.set() to fail + table.set(ret, func); + } catch (err) { + if (!(err instanceof TypeError)) { + throw err; + } + assert(typeof sig !== 'undefined', 'Missing signature argument to addFunction'); + var wrapped = convertJsFunctionToWasm(func, sig); + table.set(ret, wrapped); + } + + functionsInTableMap.set(func, ret); + + return ret; +} + +function removeFunctionWasm(index) { + functionsInTableMap.delete(wasmTable.get(index)); + freeTableIndexes.push(index); +} + +// 'sig' parameter is required for the llvm backend but only when func is not +// already a WebAssembly function. +function addFunction(func, sig) { + assert(typeof func !== 'undefined'); + + return addFunctionWasm(func, sig); +} + +function removeFunction(index) { + removeFunctionWasm(index); +} + + + +var funcWrappers = {}; + +function getFuncWrapper(func, sig) { + if (!func) return; // on null pointer, return undefined + assert(sig); + if (!funcWrappers[sig]) { + funcWrappers[sig] = {}; + } + var sigCache = funcWrappers[sig]; + if (!sigCache[func]) { + // optimize away arguments usage in common cases + if (sig.length === 1) { + sigCache[func] = function dynCall_wrapper() { + return dynCall(sig, func); + }; + } else if (sig.length === 2) { + sigCache[func] = function dynCall_wrapper(arg) { + return dynCall(sig, func, [arg]); + }; + } else { + // general case + sigCache[func] = function dynCall_wrapper() { + return dynCall(sig, func, Array.prototype.slice.call(arguments)); + }; + } + } + return sigCache[func]; +} + + + + + + + +function makeBigInt(low, high, unsigned) { + return unsigned ? ((+((low>>>0)))+((+((high>>>0)))*4294967296.0)) : ((+((low>>>0)))+((+((high|0)))*4294967296.0)); +} + +/** @param {Array=} args */ +function dynCall(sig, ptr, args) { + if (args && args.length) { + // j (64-bit integer) must be passed in as two numbers [low 32, high 32]. + assert(args.length === sig.substring(1).replace(/j/g, '--').length); + assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\''); + return Module['dynCall_' + sig].apply(null, [ptr].concat(args)); + } else { + assert(sig.length == 1); + assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\''); + return Module['dynCall_' + sig].call(null, ptr); + } +} + +var tempRet0 = 0; + +var setTempRet0 = function(value) { + tempRet0 = value; +}; + +var getTempRet0 = function() { + return tempRet0; +}; + +function getCompilerSetting(name) { + throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for getCompilerSetting or emscripten_get_compiler_setting to work'; +} + +// The address globals begin at. Very low in memory, for code size and optimization opportunities. +// Above 0 is static memory, starting with globals. +// Then the stack. +// Then 'dynamic' memory for sbrk. +var GLOBAL_BASE = 1024; + + + + + +// === 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;if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];if (!Object.getOwnPropertyDescriptor(Module, 'wasmBinary')) Object.defineProperty(Module, 'wasmBinary', { configurable: true, get: function() { abort('Module.wasmBinary has been replaced with plain wasmBinary (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); +var noExitRuntime;if (Module['noExitRuntime']) noExitRuntime = Module['noExitRuntime'];if (!Object.getOwnPropertyDescriptor(Module, 'noExitRuntime')) Object.defineProperty(Module, 'noExitRuntime', { configurable: true, get: function() { abort('Module.noExitRuntime has been replaced with plain noExitRuntime (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); + + +if (typeof WebAssembly !== 'object') { + abort('No WebAssembly support found. Build with -s WASM=0 to target JavaScript instead.'); +} + + + + +// In MINIMAL_RUNTIME, setValue() and getValue() are only available when building with safe heap enabled, for heap safety checking. +// In traditional runtime, setValue() and getValue() are always available (although their use is highly discouraged due to perf penalties) + +/** @param {number} ptr + @param {number} value + @param {string} type + @param {number|boolean=} noSafe */ +function setValue(ptr, value, type, noSafe) { + type = type || 'i8'; + if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit + switch(type) { + case 'i1': HEAP8[((ptr)>>0)]=value; break; + case 'i8': HEAP8[((ptr)>>0)]=value; break; + case 'i16': HEAP16[((ptr)>>1)]=value; break; + case 'i32': HEAP32[((ptr)>>2)]=value; break; + case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break; + case 'float': HEAPF32[((ptr)>>2)]=value; break; + case 'double': HEAPF64[((ptr)>>3)]=value; break; + default: abort('invalid type for setValue: ' + type); + } +} + +/** @param {number} ptr + @param {string} type + @param {number|boolean=} noSafe */ +function getValue(ptr, type, noSafe) { + type = type || 'i8'; + if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit + switch(type) { + case 'i1': return HEAP8[((ptr)>>0)]; + case 'i8': return HEAP8[((ptr)>>0)]; + case 'i16': return HEAP16[((ptr)>>1)]; + case 'i32': return HEAP32[((ptr)>>2)]; + case 'i64': return HEAP32[((ptr)>>2)]; + case 'float': return HEAPF32[((ptr)>>2)]; + case 'double': return HEAPF64[((ptr)>>3)]; + default: abort('invalid type for getValue: ' + type); + } + return null; +} + + + + + + +// Wasm globals + +var wasmMemory; + +// In fastcomp asm.js, we don't need a wasm Table at all. +// In the wasm backend, we polyfill the WebAssembly object, +// so this creates a (non-native-wasm) table for us. +var wasmTable = new WebAssembly.Table({ + 'initial': 30, + 'maximum': 30 + 0, + 'element': 'anyfunc' +}); + + +//======================================== +// 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 = 0; + +/** @type {function(*, string=)} */ +function assert(condition, text) { + if (!condition) { + abort('Assertion failed: ' + text); + } +} + +// Returns the C function with a specified identifier (for C++, you need to do manual name mangling) +function getCFunc(ident) { + var func = Module['_' + ident]; // closure exported function + assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported'); + return func; +} + +// C calling interface. +/** @param {string|null=} returnType + @param {Array=} argTypes + @param {Arguments|Array=} args + @param {Object=} opts */ +function ccall(ident, returnType, argTypes, args, opts) { + // For fast lookup of conversion functions + var toC = { + 'string': function(str) { + var ret = 0; + if (str !== null && str !== undefined && str !== 0) { // null string + // at most 4 bytes per UTF-8 code point, +1 for the trailing '\0' + var len = (str.length << 2) + 1; + ret = stackAlloc(len); + stringToUTF8(str, ret, len); + } + return ret; + }, + 'array': function(arr) { + var ret = stackAlloc(arr.length); + writeArrayToMemory(arr, ret); + return ret; + } + }; + + function convertReturnValue(ret) { + if (returnType === 'string') return UTF8ToString(ret); + if (returnType === 'boolean') return Boolean(ret); + return ret; + } + + var func = getCFunc(ident); + var cArgs = []; + var stack = 0; + assert(returnType !== 'array', 'Return type should not be "array".'); + if (args) { + for (var i = 0; i < args.length; i++) { + var converter = toC[argTypes[i]]; + if (converter) { + if (stack === 0) stack = stackSave(); + cArgs[i] = converter(args[i]); + } else { + cArgs[i] = args[i]; + } + } + } + var ret = func.apply(null, cArgs); + + ret = convertReturnValue(ret); + if (stack !== 0) stackRestore(stack); + return ret; +} + +/** @param {string=} returnType + @param {Array=} argTypes + @param {Object=} opts */ +function cwrap(ident, returnType, argTypes, opts) { + return function() { + return ccall(ident, returnType, argTypes, arguments, opts); + } +} + +var ALLOC_NORMAL = 0; // Tries to use _malloc() +var ALLOC_STACK = 1; // Lives for the duration of the current function call +var ALLOC_DYNAMIC = 2; // Cannot be freed except through sbrk +var ALLOC_NONE = 3; // Do not allocate + +// allocate(): This is for internal use. You can use it yourself as well, but the interface +// is a little tricky (see docs right below). The reason is that it is optimized +// for multiple syntaxes to save space in generated code. So you should +// normally not use allocate(), and instead allocate memory using _malloc(), +// initialize it with setValue(), and so forth. +// @slab: An array of data, or a number. If a number, then the size of the block to allocate, +// in *bytes* (note that this is sometimes confusing: the next parameter does not +// affect this!) +// @types: Either an array of types, one for each byte (or 0 if no type at that position), +// or a single type which is used for the entire block. This only matters if there +// is initial data - if @slab is a number, then this does not matter at all and is +// ignored. +// @allocator: How to allocate memory, see ALLOC_* +/** @type {function((TypedArray|Array|number), string, number, number=)} */ +function allocate(slab, types, allocator, ptr) { + var zeroinit, size; + if (typeof slab === 'number') { + zeroinit = true; + size = slab; + } else { + zeroinit = false; + size = slab.length; + } + + var singleType = typeof types === 'string' ? types : null; + + var ret; + if (allocator == ALLOC_NONE) { + ret = ptr; + } else { + ret = [_malloc, + stackAlloc, + dynamicAlloc][allocator](Math.max(size, singleType ? 1 : types.length)); + } + + if (zeroinit) { + var stop; + ptr = ret; + assert((ret & 3) == 0); + stop = ret + (size & ~3); + for (; ptr < stop; ptr += 4) { + HEAP32[((ptr)>>2)]=0; + } + stop = ret + size; + while (ptr < stop) { + HEAP8[((ptr++)>>0)]=0; + } + return ret; + } + + if (singleType === 'i8') { + if (slab.subarray || slab.slice) { + HEAPU8.set(/** @type {!Uint8Array} */ (slab), ret); + } else { + HEAPU8.set(new Uint8Array(slab), ret); + } + return ret; + } + + var i = 0, type, typeSize, previousType; + while (i < size) { + var curr = slab[i]; + + type = singleType || types[i]; + if (type === 0) { + i++; + continue; + } + assert(type, 'Must know what type to store in allocate!'); + + if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later + + setValue(ret+i, curr, type); + + // no need to look up size unless type changes, so cache it + if (previousType !== type) { + typeSize = getNativeTypeSize(type); + previousType = type; + } + i += typeSize; + } + + return ret; +} + +// Allocate memory during any stage of startup - static memory early on, dynamic memory later, malloc when ready +function getMemory(size) { + if (!runtimeInitialized) return dynamicAlloc(size); + return _malloc(size); +} + + + + +// runtime_strings.js: Strings related runtime functions that are part of both MINIMAL_RUNTIME and regular runtime. + +// Given a pointer 'ptr' 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. + +var UTF8Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined; + +/** + * @param {number} idx + * @param {number=} maxBytesToRead + * @return {string} + */ +function UTF8ArrayToString(heap, idx, maxBytesToRead) { + 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 means Infinity) + while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr; + + if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) { + return UTF8Decoder.decode(heap.subarray(idx, endPtr)); + } else { + 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 = heap[idx++]; + if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; } + var u1 = heap[idx++] & 63; + if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; } + var u2 = heap[idx++] & 63; + if ((u0 & 0xF0) == 0xE0) { + u0 = ((u0 & 15) << 12) | (u1 << 6) | u2; + } else { + if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte 0x' + u0.toString(16) + ' encountered when deserializing a UTF-8 string on the asm.js/wasm heap to a JS string!'); + u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heap[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. +// 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 +// style or the other. +/** + * @param {number} ptr + * @param {number=} maxBytesToRead + * @return {string} + */ +function UTF8ToString(ptr, maxBytesToRead) { + return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ''; +} + +// Copies the given Javascript String object 'str' to the given byte array at address 'outIdx', +// encoded in UTF8 form and null-terminated. The copy will require at most str.length*4+1 bytes of space in the HEAP. +// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write. +// Parameters: +// str: the Javascript string to copy. +// heap: the array to copy to. Each index in this array is assumed to be one 8-byte element. +// outIdx: The starting offset in the array to begin the copying. +// maxBytesToWrite: The maximum number of bytes this function can write to the array. +// This count should include the null terminator, +// i.e. if maxBytesToWrite=1, only the null terminator will be written and nothing else. +// maxBytesToWrite=0 does not write any bytes to the output, not even the null terminator. +// Returns the number of bytes written, EXCLUDING the null terminator. + +function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) { + if (!(maxBytesToWrite > 0)) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes. + 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; + if (u >= 0x200000) warnOnce('Invalid Unicode code point 0x' + u.toString(16) + ' encountered when serializing a JS string to an UTF-8 string on the asm.js/wasm heap! (Valid unicode code points should be in range 0-0x1FFFFF).'); + 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; +} + +// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', +// null-terminated and encoded in UTF8 form. The copy will require at most str.length*4+1 bytes of space in the HEAP. +// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write. +// Returns the number of bytes written, EXCLUDING the null terminator. + +function stringToUTF8(str, outPtr, maxBytesToWrite) { + assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); + return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite); +} + +// Returns the number of bytes the given Javascript string takes if encoded as a UTF8 byte array, EXCLUDING the null terminator byte. +function 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 u = str.charCodeAt(i); // possibly a lead surrogate + if (u >= 0xD800 && u <= 0xDFFF) u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); + if (u <= 0x7F) ++len; + else if (u <= 0x7FF) len += 2; + else if (u <= 0xFFFF) len += 3; + else len += 4; + } + return len; +} + + + + + +// runtime_strings_extra.js: Strings related runtime functions that are available only in regular runtime. + +// Given a pointer 'ptr' to a null-terminated ASCII-encoded string in the emscripten HEAP, returns +// a copy of that string as a Javascript String object. + +function AsciiToString(ptr) { + var str = ''; + while (1) { + var ch = HEAPU8[((ptr++)>>0)]; + if (!ch) return str; + str += String.fromCharCode(ch); + } +} + +// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', +// null-terminated and encoded in ASCII form. The copy will require at most str.length+1 bytes of space in the HEAP. + +function stringToAscii(str, outPtr) { + return writeAsciiToMemory(str, outPtr, false); +} + +// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns +// a copy of that string as a Javascript String object. + +var UTF16Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-16le') : undefined; + +function UTF16ToString(ptr, maxBytesToRead) { + assert(ptr % 2 == 0, 'Pointer passed to UTF16ToString must be aligned to two bytes!'); + 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)); + } else { + var i = 0; + + var str = ''; + while (1) { + var codeUnit = HEAP16[(((ptr)+(i*2))>>1)]; + if (codeUnit == 0 || i == maxBytesToRead / 2) return str; + ++i; + // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through. + str += String.fromCharCode(codeUnit); + } + } +} + +// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', +// null-terminated and encoded in UTF16 form. The copy will require at most str.length*4+2 bytes of space in the HEAP. +// Use the function lengthBytesUTF16() to compute the exact number of bytes (excluding null terminator) that this function will write. +// Parameters: +// str: the Javascript string to copy. +// outPtr: Byte address in Emscripten HEAP where to write the string to. +// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null +// terminator, i.e. if maxBytesToWrite=2, only the null terminator will be written and nothing else. +// maxBytesToWrite<2 does not write any bytes to the output, not even the null terminator. +// Returns the number of bytes written, EXCLUDING the null terminator. + +function stringToUTF16(str, outPtr, maxBytesToWrite) { + assert(outPtr % 2 == 0, 'Pointer passed to stringToUTF16 must be aligned to two bytes!'); + assert(typeof maxBytesToWrite == 'number', 'stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); + // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. + if (maxBytesToWrite === undefined) { + 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; +} + +// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte. + +function lengthBytesUTF16(str) { + return str.length*2; +} + +function UTF32ToString(ptr, maxBytesToRead) { + assert(ptr % 4 == 0, 'Pointer passed to UTF32ToString must be aligned to four bytes!'); + 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; +} + +// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', +// null-terminated and encoded in UTF32 form. The copy will require at most str.length*4+4 bytes of space in the HEAP. +// Use the function lengthBytesUTF32() to compute the exact number of bytes (excluding null terminator) that this function will write. +// Parameters: +// str: the Javascript string to copy. +// outPtr: Byte address in Emscripten HEAP where to write the string to. +// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null +// terminator, i.e. if maxBytesToWrite=4, only the null terminator will be written and nothing else. +// maxBytesToWrite<4 does not write any bytes to the output, not even the null terminator. +// Returns the number of bytes written, EXCLUDING the null terminator. + +function stringToUTF32(str, outPtr, maxBytesToWrite) { + assert(outPtr % 4 == 0, 'Pointer passed to stringToUTF32 must be aligned to four bytes!'); + assert(typeof maxBytesToWrite == 'number', 'stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); + // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. + if (maxBytesToWrite === undefined) { + 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; +} + +// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte. + +function 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; +} + +// Allocate heap space for a JS string, and write it there. +// It is the responsibility of the caller to free() that memory. +function allocateUTF8(str) { + var size = lengthBytesUTF8(str) + 1; + var ret = _malloc(size); + if (ret) stringToUTF8Array(str, HEAP8, ret, size); + return ret; +} + +// Allocate stack space for a JS string, and write it there. +function allocateUTF8OnStack(str) { + var size = lengthBytesUTF8(str) + 1; + var ret = stackAlloc(size); + stringToUTF8Array(str, HEAP8, ret, size); + return ret; +} + +// Deprecated: This function should not be called because it is unsafe and does not provide +// a maximum length limit of how many bytes it is allowed to write. Prefer calling the +// function stringToUTF8Array() instead, which takes in a maximum length that can be used +// to be secure from out of bounds writes. +/** @deprecated + @param {boolean=} dontAddNull */ +function writeStringToMemory(string, buffer, dontAddNull) { + warnOnce('writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!'); + + var /** @type {number} */ lastChar, /** @type {number} */ end; + if (dontAddNull) { + // stringToUTF8Array always appends null. If we don't want to do that, remember the + // character that existed at the location where the null will be placed, and restore + // that after the write (below). + end = buffer + lengthBytesUTF8(string); + lastChar = HEAP8[end]; + } + stringToUTF8(string, buffer, Infinity); + if (dontAddNull) HEAP8[end] = lastChar; // Restore the value under the null character. +} + +function writeArrayToMemory(array, buffer) { + assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)') + HEAP8.set(array, buffer); +} + +/** @param {boolean=} dontAddNull */ +function writeAsciiToMemory(str, buffer, dontAddNull) { + for (var i = 0; i < str.length; ++i) { + assert(str.charCodeAt(i) === str.charCodeAt(i)&0xff); + HEAP8[((buffer++)>>0)]=str.charCodeAt(i); + } + // Null-terminate the pointer to the HEAP. + if (!dontAddNull) HEAP8[((buffer)>>0)]=0; +} + + + +// Memory management + +var PAGE_SIZE = 16384; +var WASM_PAGE_SIZE = 65536; +var ASMJS_PAGE_SIZE = 16777216; + +function alignUp(x, multiple) { + if (x % multiple > 0) { + x += multiple - (x % multiple); + } + return x; +} + +var HEAP, +/** @type {ArrayBuffer} */ + buffer, +/** @type {Int8Array} */ + HEAP8, +/** @type {Uint8Array} */ + HEAPU8, +/** @type {Int16Array} */ + HEAP16, +/** @type {Uint16Array} */ + HEAPU16, +/** @type {Int32Array} */ + HEAP32, +/** @type {Uint32Array} */ + HEAPU32, +/** @type {Float32Array} */ + HEAPF32, +/** @type {Float64Array} */ + HEAPF64; + +function updateGlobalBufferAndViews(buf) { + buffer = buf; + Module['HEAP8'] = HEAP8 = new Int8Array(buf); + Module['HEAP16'] = HEAP16 = new Int16Array(buf); + Module['HEAP32'] = HEAP32 = new Int32Array(buf); + Module['HEAPU8'] = HEAPU8 = new Uint8Array(buf); + Module['HEAPU16'] = HEAPU16 = new Uint16Array(buf); + Module['HEAPU32'] = HEAPU32 = new Uint32Array(buf); + Module['HEAPF32'] = HEAPF32 = new Float32Array(buf); + Module['HEAPF64'] = HEAPF64 = new Float64Array(buf); +} + +var STATIC_BASE = 1024, + STACK_BASE = 5247376, + STACKTOP = STACK_BASE, + STACK_MAX = 4496, + DYNAMIC_BASE = 5247376, + DYNAMICTOP_PTR = 4336; + +assert(STACK_BASE % 16 === 0, 'stack must start aligned'); +assert(DYNAMIC_BASE % 16 === 0, 'heap must start aligned'); + + +var TOTAL_STACK = 5242880; +if (Module['TOTAL_STACK']) assert(TOTAL_STACK === Module['TOTAL_STACK'], 'the stack size can no longer be determined at runtime') + +var INITIAL_INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 16777216;if (!Object.getOwnPropertyDescriptor(Module, 'INITIAL_MEMORY')) Object.defineProperty(Module, 'INITIAL_MEMORY', { configurable: true, get: function() { abort('Module.INITIAL_MEMORY has been replaced with plain INITIAL_INITIAL_MEMORY (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } }); + +assert(INITIAL_INITIAL_MEMORY >= TOTAL_STACK, 'INITIAL_MEMORY should be larger than TOTAL_STACK, was ' + INITIAL_INITIAL_MEMORY + '! (TOTAL_STACK=' + TOTAL_STACK + ')'); + +// check for full engine support (use string 'subarray' to avoid closure compiler confusion) +assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray !== undefined && Int32Array.prototype.set !== undefined, + 'JS engine does not provide full typed array support'); + + + + + + + + +// In non-standalone/normal mode, we create the memory here. + + + +// Create the main memory. (Note: this isn't used in STANDALONE_WASM mode since the wasm +// memory is created in the wasm, not in JS.) + + if (Module['wasmMemory']) { + wasmMemory = Module['wasmMemory']; + } else + { + wasmMemory = new WebAssembly.Memory({ + 'initial': INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE + , + 'maximum': INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE + }); + } + + +if (wasmMemory) { + buffer = wasmMemory.buffer; +} + +// If the user provides an incorrect length, just use that length instead rather than providing the user to +// specifically provide the memory length with Module['INITIAL_MEMORY']. +INITIAL_INITIAL_MEMORY = buffer.byteLength; +assert(INITIAL_INITIAL_MEMORY % WASM_PAGE_SIZE === 0); +updateGlobalBufferAndViews(buffer); + +HEAP32[DYNAMICTOP_PTR>>2] = DYNAMIC_BASE; + + + + + + +// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode. +function writeStackCookie() { + assert((STACK_MAX & 3) == 0); + // The stack grows downwards + HEAPU32[(STACK_MAX >> 2)+1] = 0x2135467; + HEAPU32[(STACK_MAX >> 2)+2] = 0x89BACDFE; + // Also test the global address 0 for integrity. + // We don't do this with ASan because ASan does its own checks for this. + HEAP32[0] = 0x63736d65; /* 'emsc' */ +} + +function checkStackCookie() { + var cookie1 = HEAPU32[(STACK_MAX >> 2)+1]; + var cookie2 = HEAPU32[(STACK_MAX >> 2)+2]; + if (cookie1 != 0x2135467 || cookie2 != 0x89BACDFE) { + abort('Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x2135467, but received 0x' + cookie2.toString(16) + ' ' + cookie1.toString(16)); + } + // Also test the global address 0 for integrity. + // We don't do this with ASan because ASan does its own checks for this. + if (HEAP32[0] !== 0x63736d65 /* 'emsc' */) abort('Runtime error: The application has corrupted its heap memory area (address zero)!'); +} + + + + + +// Endianness check (note: assumes compiler arch was little-endian) +(function() { + var h16 = new Int16Array(1); + var h8 = new Int8Array(h16.buffer); + h16[0] = 0x6373; + if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian!'; +})(); + +function abortFnPtrError(ptr, sig) { + abort("Invalid function pointer " + ptr + " called with signature '" + sig + "'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this). Build with ASSERTIONS=2 for more info."); +} + + + +function callRuntimeCallbacks(callbacks) { + while(callbacks.length > 0) { + var callback = callbacks.shift(); + if (typeof callback == 'function') { + callback(Module); // Pass the module as the first argument. + continue; + } + var func = callback.func; + if (typeof func === 'number') { + if (callback.arg === undefined) { + Module['dynCall_v'](func); + } else { + Module['dynCall_vi'](func, callback.arg); + } + } else { + func(callback.arg === undefined ? null : callback.arg); + } + } +} + +var __ATPRERUN__ = []; // functions called before the runtime is initialized +var __ATINIT__ = []; // functions called during startup +var __ATMAIN__ = []; // functions called when main() is to be run +var __ATEXIT__ = []; // functions called during shutdown +var __ATPOSTRUN__ = []; // functions called after the main() is called + +var runtimeInitialized = false; +var runtimeExited = 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() { + checkStackCookie(); + assert(!runtimeInitialized); + runtimeInitialized = true; + + callRuntimeCallbacks(__ATINIT__); +} + +function preMain() { + checkStackCookie(); + + callRuntimeCallbacks(__ATMAIN__); +} + +function exitRuntime() { + checkStackCookie(); + runtimeExited = true; +} + +function postRun() { + checkStackCookie(); + + 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 addOnPreMain(cb) { + __ATMAIN__.unshift(cb); +} + +function addOnExit(cb) { +} + +function addOnPostRun(cb) { + __ATPOSTRUN__.unshift(cb); +} + +/** @param {number|boolean=} ignore */ +function unSign(value, bits, ignore) { + if (value >= 0) { + return value; + } + return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts + : Math.pow(2, bits) + value; +} +/** @param {number|boolean=} ignore */ +function reSign(value, bits, ignore) { + if (value <= 0) { + return value; + } + var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32 + : Math.pow(2, bits-1); + if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that + // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors + // TODO: In i64 mode 1, resign the two parts separately and safely + value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts + } + return value; +} + + + + +// 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 + +assert(Math.imul, 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); +assert(Math.fround, 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); +assert(Math.clz32, 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); +assert(Math.trunc, 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); + +var Math_abs = Math.abs; +var Math_cos = Math.cos; +var Math_sin = Math.sin; +var Math_tan = Math.tan; +var Math_acos = Math.acos; +var Math_asin = Math.asin; +var Math_atan = Math.atan; +var Math_atan2 = Math.atan2; +var Math_exp = Math.exp; +var Math_log = Math.log; +var Math_sqrt = Math.sqrt; +var Math_ceil = Math.ceil; +var Math_floor = Math.floor; +var Math_pow = Math.pow; +var Math_imul = Math.imul; +var Math_fround = Math.fround; +var Math_round = Math.round; +var Math_min = Math.min; +var Math_max = Math.max; +var Math_clz32 = Math.clz32; +var Math_trunc = Math.trunc; + + + +// 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 runDependencyWatcher = null; +var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled +var runDependencyTracking = {}; + +function getUniqueRunDependency(id) { + var orig = id; + while (1) { + if (!runDependencyTracking[id]) return id; + id = orig + Math.random(); + } +} + +function addRunDependency(id) { + runDependencies++; + + if (Module['monitorRunDependencies']) { + Module['monitorRunDependencies'](runDependencies); + } + + if (id) { + assert(!runDependencyTracking[id]); + runDependencyTracking[id] = 1; + if (runDependencyWatcher === null && typeof setInterval !== 'undefined') { + // Check for missing dependencies every few seconds + runDependencyWatcher = setInterval(function() { + if (ABORT) { + clearInterval(runDependencyWatcher); + runDependencyWatcher = null; + return; + } + var shown = false; + for (var dep in runDependencyTracking) { + if (!shown) { + shown = true; + err('still waiting on run dependencies:'); + } + err('dependency: ' + dep); + } + if (shown) { + err('(end of list)'); + } + }, 10000); + } + } else { + err('warning: run dependency added without ID'); + } +} + +function removeRunDependency(id) { + runDependencies--; + + if (Module['monitorRunDependencies']) { + Module['monitorRunDependencies'](runDependencies); + } + + if (id) { + assert(runDependencyTracking[id]); + delete runDependencyTracking[id]; + } else { + err('warning: run dependency removed without ID'); + } + if (runDependencies == 0) { + if (runDependencyWatcher !== null) { + clearInterval(runDependencyWatcher); + runDependencyWatcher = null; + } + if (dependenciesFulfilled) { + var callback = dependenciesFulfilled; + dependenciesFulfilled = null; + callback(); // can add another dependenciesFulfilled + } + } +} + +Module["preloadedImages"] = {}; // maps url to image data +Module["preloadedAudios"] = {}; // maps url to audio data + +/** @param {string|number=} what */ +function abort(what) { + if (Module['onAbort']) { + Module['onAbort'](what); + } + + what += ''; + out(what); + err(what); + + ABORT = true; + EXITSTATUS = 1; + + var output = 'abort(' + what + ') at ' + stackTrace(); + what = output; + + // Throw 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. + throw new WebAssembly.RuntimeError(what); +} + + +var memoryInitializer = null; + + + + + + + +// show errors on likely calls to FS when it was not included +var FS = { + error: function() { + abort('Filesystem support (FS) was not included. The problem is that you are using files from JS, but files were not used from C/C++, so filesystem support was not auto-included. You can force-include filesystem support with -s FORCE_FILESYSTEM=1'); + }, + init: function() { FS.error() }, + createDataFile: function() { FS.error() }, + createPreloadedFile: function() { FS.error() }, + createLazyFile: function() { FS.error() }, + open: function() { FS.error() }, + mkdev: function() { FS.error() }, + registerDevice: function() { FS.error() }, + analyzePath: function() { FS.error() }, + loadFilesFromDB: function() { FS.error() }, + + ErrnoError: function ErrnoError() { FS.error() }, +}; +Module['FS_createDataFile'] = FS.createDataFile; +Module['FS_createPreloadedFile'] = FS.createPreloadedFile; + + + + + +function hasPrefix(str, prefix) { + return String.prototype.startsWith ? + str.startsWith(prefix) : + str.indexOf(prefix) === 0; +} + +// 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. +function isDataURI(filename) { + return hasPrefix(filename, dataURIPrefix); +} + +var fileURIPrefix = "file://"; + +// Indicates whether filename is delivered via file protocol (as opposed to http/https) +function isFileURI(filename) { + return hasPrefix(filename, fileURIPrefix); +} + + + +function createExportWrapper(name, fixedasm) { + return function() { + var displayName = name; + var asm = fixedasm; + if (!fixedasm) { + asm = Module['asm']; + } + assert(runtimeInitialized, 'native function `' + displayName + '` called before runtime initialization'); + assert(!runtimeExited, 'native function `' + displayName + '` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + if (!asm[name]) { + assert(asm[name], 'exported native function `' + displayName + '` not found'); + } + return asm[name].apply(null, arguments); + }; +} + +var wasmBinaryFile = 'newtonraphsonwasm.wasm'; +if (!isDataURI(wasmBinaryFile)) { + wasmBinaryFile = locateFile(wasmBinaryFile); +} + +function getBinary() { + try { + if (wasmBinary) { + return new Uint8Array(wasmBinary); + } + + if (readBinary) { + return readBinary(wasmBinaryFile); + } else { + throw "both async and sync fetching of the wasm failed"; + } + } + catch (err) { + abort(err); + } +} + +function getBinaryPromise() { + // If we don't have the binary yet, and have the Fetch api, use that; + // in some environments, like Electron's render process, Fetch api may be present, but have a different context than expected, let's only use it on the Web + if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && typeof fetch === 'function' + // Let's not use fetch to get objects over file:// as it's most likely Cordova which doesn't support fetch for file:// + && !isFileURI(wasmBinaryFile) + ) { + return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) { + if (!response['ok']) { + throw "failed to load wasm binary file at '" + wasmBinaryFile + "'"; + } + return response['arrayBuffer'](); + }).catch(function () { + return getBinary(); + }); + } + // Otherwise, getBinary should be able to get it synchronously + return new Promise(function(resolve, reject) { + resolve(getBinary()); + }); +} + + + +// Create the wasm instance. +// Receives the wasm imports, returns the exports. +function createWasm() { + // prepare imports + var info = { + 'env': asmLibraryArg, + 'wasi_snapshot_preview1': asmLibraryArg + }; + // 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) { + var exports = instance.exports; + Module['asm'] = exports; + removeRunDependency('wasm-instantiate'); + } + // we can't run yet (except in a pthread, where we have a custom sync instantiator) + addRunDependency('wasm-instantiate'); + + + // Async compilation can be confusing when an error on the page overwrites Module + // (for example, if the order of elements is wrong, and the one defining Module is + // later), so we save Module and check it later. + var trueModule = Module; + function receiveInstantiatedSource(output) { + // 'output' is a WebAssemblyInstantiatedSource object which has both the module and instance. + // receiveInstance() will swap in the exports (to Module.asm) so they can be called + assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?'); + trueModule = null; + // 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, can restore the above USE_PTHREADS-enabled path. + receiveInstance(output['instance']); + } + + + function instantiateArrayBuffer(receiver) { + return getBinaryPromise().then(function(binary) { + return WebAssembly.instantiate(binary, info); + }).then(receiver, function(reason) { + err('failed to asynchronously prepare wasm: ' + reason); + abort(reason); + }); + } + + // Prefer streaming instantiation if available. + function instantiateAsync() { + if (!wasmBinary && + typeof WebAssembly.instantiateStreaming === 'function' && + !isDataURI(wasmBinaryFile) && + // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously. + !isFileURI(wasmBinaryFile) && + typeof fetch === 'function') { + fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function (response) { + var result = WebAssembly.instantiateStreaming(response, info); + return result.then(receiveInstantiatedSource, function(reason) { + // We expect the most common failure cause to be a bad MIME type for the binary, + // in which case falling back to ArrayBuffer instantiation should work. + err('wasm streaming compile failed: ' + reason); + err('falling back to ArrayBuffer instantiation'); + return instantiateArrayBuffer(receiveInstantiatedSource); + }); + }); + } else { + return instantiateArrayBuffer(receiveInstantiatedSource); + } + } + // 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. + if (Module['instantiateWasm']) { + try { + var exports = Module['instantiateWasm'](info, receiveInstance); + return exports; + } catch(e) { + err('Module.instantiateWasm callback failed with error: ' + e); + return false; + } + } + + instantiateAsync(); + return {}; // no exports yet; we'll fill them in later +} + + +// Globals used by JS i64 conversions +var tempDouble; +var tempI64; + +// === Body === + +var ASM_CONSTS = { + +}; + + + + +// STATICTOP = STATIC_BASE + 3472; +/* global initializers */ __ATINIT__.push({ func: function() { ___wasm_call_ctors() } }); + + + + +/* no memory initializer */ +// {{PRE_LIBRARY}} + + + function abortStackOverflow(allocSize) { + abort('Stack overflow! Attempted to allocate ' + allocSize + ' bytes on the stack, but stack has only ' + (STACK_MAX - stackSave() + allocSize) + ' bytes available!'); + } + + function demangle(func) { + warnOnce('warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling'); + return func; + } + + function demangleAll(text) { + var regex = + /\b_Z[\w\d_]+/g; + return text.replace(regex, + function(x) { + var y = demangle(x); + return x === y ? x : (y + ' [' + x + ']'); + }); + } + + function jsStackTrace() { + var err = new Error(); + if (!err.stack) { + // IE10+ special cases: It does have callstack info, but it is only populated if an Error object is thrown, + // so try that as a special-case. + try { + throw new Error(); + } catch(e) { + err = e; + } + if (!err.stack) { + return '(no stack trace available)'; + } + } + return err.stack.toString(); + } + + function stackTrace() { + var js = jsStackTrace(); + if (Module['extraStackTrace']) js += '\n' + Module['extraStackTrace'](); + return demangleAll(js); + } + + function ___handle_stack_overflow() { + abort('stack overflow') + } + + + function getShiftFromSize(size) { + switch (size) { + case 1: return 0; + case 2: return 1; + case 4: return 2; + case 8: return 3; + default: + throw new TypeError('Unknown type size: ' + size); + } + } + + + + function 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=undefined;function readLatin1String(ptr) { + var ret = ""; + var c = ptr; + while (HEAPU8[c]) { + ret += embind_charCodes[HEAPU8[c++]]; + } + return ret; + } + + + var awaitingDependencies={}; + + var registeredTypes={}; + + var typeDependencies={}; + + + + + + + var char_0=48; + + var char_9=57;function makeLegalFunctionName(name) { + if (undefined === name) { + return '_unknown'; + } + name = name.replace(/[^a-zA-Z0-9_]/g, '$'); + var f = name.charCodeAt(0); + if (f >= char_0 && f <= char_9) { + return '_' + name; + } else { + return name; + } + }function createNamedFunction(name, body) { + name = makeLegalFunctionName(name); + /*jshint evil:true*/ + return new Function( + "body", + "return function " + name + "() {\n" + + " \"use strict\";" + + " return body.apply(this, arguments);\n" + + "};\n" + )(body); + }function 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 BindingError=undefined;function throwBindingError(message) { + throw new BindingError(message); + } + + + + var InternalError=undefined;function throwInternalError(message) { + throw new InternalError(message); + }function whenDependentTypesAreResolved(myTypes, dependentTypes, getTypeConverters) { + myTypes.forEach(function(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(function(dt, i) { + if (registeredTypes.hasOwnProperty(dt)) { + typeConverters[i] = registeredTypes[dt]; + } else { + unregisteredTypes.push(dt); + if (!awaitingDependencies.hasOwnProperty(dt)) { + awaitingDependencies[dt] = []; + } + awaitingDependencies[dt].push(function() { + typeConverters[i] = registeredTypes[dt]; + ++registered; + if (registered === unregisteredTypes.length) { + onComplete(typeConverters); + } + }); + } + }); + if (0 === unregisteredTypes.length) { + onComplete(typeConverters); + } + }/** @param {Object=} options */ + function registerType(rawType, registeredInstance, options) { + options = options || {}; + + if (!('argPackAdvance' in registeredInstance)) { + throw new TypeError('registerType registeredInstance requires argPackAdvance'); + } + + 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(function(cb) { + cb(); + }); + } + }function __embind_register_bool(rawType, name, size, trueValue, falseValue) { + var shift = getShiftFromSize(size); + + name = readLatin1String(name); + registerType(rawType, { + name: 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': 8, + 'readValueFromPointer': function(pointer) { + // TODO: if heap is fixed (like in asm.js) this could be executed outside + var heap; + if (size === 1) { + heap = HEAP8; + } else if (size === 2) { + heap = HEAP16; + } else if (size === 4) { + heap = HEAP32; + } else { + throw new TypeError("Unknown boolean type size: " + name); + } + return this['fromWireType'](heap[pointer >> shift]); + }, + destructorFunction: null, // This type does not need a destructor + }); + } + + + + + function ClassHandle_isAliasOf(other) { + if (!(this instanceof ClassHandle)) { + return false; + } + if (!(other instanceof ClassHandle)) { + return false; + } + + var leftClass = this.$$.ptrType.registeredClass; + var left = this.$$.ptr; + 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; + } + + + function shallowCopyInternalPointer(o) { + return { + count: o.count, + deleteScheduled: o.deleteScheduled, + preservePointerOnDelete: o.preservePointerOnDelete, + ptr: o.ptr, + ptrType: o.ptrType, + smartPtr: o.smartPtr, + smartPtrType: o.smartPtrType, + }; + } + + function throwInstanceAlreadyDeleted(obj) { + function getInstanceTypeName(handle) { + return handle.$$.ptrType.registeredClass.name; + } + throwBindingError(getInstanceTypeName(obj) + ' instance already deleted'); + } + + + var finalizationGroup=false; + + function detachFinalizer(handle) {} + + + function runDestructor($$) { + if ($$.smartPtr) { + $$.smartPtrType.rawDestructor($$.smartPtr); + } else { + $$.ptrType.registeredClass.rawDestructor($$.ptr); + } + }function releaseClassHandle($$) { + $$.count.value -= 1; + var toDelete = 0 === $$.count.value; + if (toDelete) { + runDestructor($$); + } + }function attachFinalizer(handle) { + if ('undefined' === typeof FinalizationGroup) { + attachFinalizer = function (handle) { return handle; }; + return handle; + } + // If the running environment has a FinalizationGroup (see + // https://github.com/tc39/proposal-weakrefs), then attach finalizers + // for class handles. We check for the presence of FinalizationGroup + // at run-time, not build-time. + finalizationGroup = new FinalizationGroup(function (iter) { + for (var result = iter.next(); !result.done; result = iter.next()) { + var $$ = result.value; + if (!$$.ptr) { + console.warn('object already deleted: ' + $$.ptr); + } else { + releaseClassHandle($$); + } + } + }); + attachFinalizer = function(handle) { + finalizationGroup.register(handle, handle.$$, handle.$$); + return handle; + }; + detachFinalizer = function(handle) { + finalizationGroup.unregister(handle.$$); + }; + return attachFinalizer(handle); + }function ClassHandle_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; + } + } + + function ClassHandle_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; + } + } + + function ClassHandle_isDeleted() { + return !this.$$.ptr; + } + + + var delayFunction=undefined; + + var deletionQueue=[]; + + function flushPendingDeletes() { + while (deletionQueue.length) { + var obj = deletionQueue.pop(); + obj.$$.deleteScheduled = false; + obj['delete'](); + } + }function ClassHandle_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; + }function init_ClassHandle() { + ClassHandle.prototype['isAliasOf'] = ClassHandle_isAliasOf; + ClassHandle.prototype['clone'] = ClassHandle_clone; + ClassHandle.prototype['delete'] = ClassHandle_delete; + ClassHandle.prototype['isDeleted'] = ClassHandle_isDeleted; + ClassHandle.prototype['deleteLater'] = ClassHandle_deleteLater; + }function ClassHandle() { + } + + var registeredPointers={}; + + + function 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() { + // TODO This check can be removed in -O3 level "unsafe" optimizations. + if (!proto[methodName].overloadTable.hasOwnProperty(arguments.length)) { + throwBindingError("Function '" + humanName + "' called with an invalid number of arguments (" + arguments.length + ") - expects one of (" + proto[methodName].overloadTable + ")!"); + } + return proto[methodName].overloadTable[arguments.length].apply(this, arguments); + }; + // Move the previous function into the overload table. + proto[methodName].overloadTable = []; + proto[methodName].overloadTable[prevFunc.argCount] = prevFunc; + } + }/** @param {number=} numArguments */ + function 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.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; + if (undefined !== numArguments) { + Module[name].numArguments = numArguments; + } + } + } + + /** @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 = []; + } + + + + function 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; + }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 "' + _embind_repr(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; + } + + 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.$$) { + throwBindingError('Cannot pass "' + _embind_repr(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_register(function() { + clonedHandle['delete'](); + }) + ); + if (destructors !== null) { + destructors.push(this.rawDestructor, ptr); + } + } + break; + + default: + throwBindingError('Unsupporting sharing policy'); + } + } + return ptr; + } + + 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 "' + _embind_repr(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; + } + + + function simpleReadValueFromPointer(pointer) { + return this['fromWireType'](HEAPU32[pointer >> 2]); + } + + function RegisteredPointer_getPointee(ptr) { + if (this.rawGetPointee) { + ptr = this.rawGetPointee(ptr); + } + return ptr; + } + + function RegisteredPointer_destructor(ptr) { + if (this.rawDestructor) { + this.rawDestructor(ptr); + } + } + + function RegisteredPointer_deleteObject(handle) { + if (handle !== null) { + handle['delete'](); + } + } + + + function 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); + } + + + + + function getInheritedInstanceCount() { + return Object.keys(registeredInstances).length; + } + + function getLiveInheritedInstances() { + var rv = []; + for (var k in registeredInstances) { + if (registeredInstances.hasOwnProperty(k)) { + rv.push(registeredInstances[k]); + } + } + return rv; + } + + function setDelayFunction(fn) { + delayFunction = fn; + if (deletionQueue.length && delayFunction) { + delayFunction(flushPendingDeletes); + } + }function init_embind() { + Module['getInheritedInstanceCount'] = getInheritedInstanceCount; + Module['getLiveInheritedInstances'] = getLiveInheritedInstances; + Module['flushPendingDeletes'] = flushPendingDeletes; + Module['setDelayFunction'] = setDelayFunction; + }var registeredInstances={}; + + function getBasestPointer(class_, ptr) { + if (ptr === undefined) { + throwBindingError('ptr should not be undefined'); + } + while (class_.baseClass) { + ptr = class_.upcast(ptr); + class_ = class_.baseClass; + } + return ptr; + }function getInheritedInstance(class_, ptr) { + ptr = getBasestPointer(class_, ptr); + return registeredInstances[ptr]; + } + + function 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, + }, + })); + }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: 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, + }); + } + }function init_RegisteredPointer() { + RegisteredPointer.prototype.getPointee = RegisteredPointer_getPointee; + RegisteredPointer.prototype.destructor = RegisteredPointer_destructor; + RegisteredPointer.prototype['argPackAdvance'] = 8; + RegisteredPointer.prototype['readValueFromPointer'] = simpleReadValueFromPointer; + RegisteredPointer.prototype['deleteObject'] = RegisteredPointer_deleteObject; + RegisteredPointer.prototype['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 */ + function replacePublicSymbol(name, value, numArguments) { + if (!Module.hasOwnProperty(name)) { + throwInternalError('Replacing nonexistant 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; + } + } + + function embind__requireFunction(signature, rawFunction) { + signature = readLatin1String(signature); + + function makeDynCaller(dynCall) { + var args = []; + for (var i = 1; i < signature.length; ++i) { + args.push('a' + i); + } + + var name = 'dynCall_' + signature + '_' + rawFunction; + var body = 'return function ' + name + '(' + args.join(', ') + ') {\n'; + body += ' return dynCall(rawFunction' + (args.length ? ', ' : '') + args.join(', ') + ');\n'; + body += '};\n'; + + return (new Function('dynCall', 'rawFunction', body))(dynCall, rawFunction); + } + + var dc = Module['dynCall_' + signature]; + var fp = makeDynCaller(dc); + + if (typeof fp !== "function") { + throwBindingError("unknown function pointer with signature " + signature + ": " + rawFunction); + } + return fp; + } + + + var UnboundTypeError=undefined; + + function getTypeName(type) { + var ptr = ___getTypeName(type); + var rv = readLatin1String(ptr); + _free(ptr); + return rv; + }function 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([', '])); + }function __embind_register_class( + rawType, + rawPointerType, + rawConstPointerType, + baseClassRawType, + getActualTypeSignature, + getActualType, + upcastSignature, + upcast, + downcastSignature, + downcast, + name, + destructorSignature, + rawDestructor + ) { + name = readLatin1String(name); + getActualType = embind__requireFunction(getActualTypeSignature, getActualType); + if (upcast) { + upcast = embind__requireFunction(upcastSignature, upcast); + } + if (downcast) { + 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] : [], + function(base) { + base = base[0]; + + var baseClass; + var basePrototype; + if (baseClassRawType) { + baseClass = base.registeredClass; + basePrototype = baseClass.instancePrototype; + } else { + basePrototype = ClassHandle.prototype; + } + + var constructor = createNamedFunction(legalFunctionName, function() { + 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[arguments.length]; + if (undefined === body) { + throw new BindingError("Tried to invoke ctor of " + name + " with invalid number of parameters (" + arguments.length + ") - expected (" + Object.keys(registeredClass.constructor_body).toString() + ") parameters instead!"); + } + return body.apply(this, arguments); + }); + + var instancePrototype = Object.create(basePrototype, { + constructor: { value: constructor }, + }); + + constructor.prototype = instancePrototype; + + var registeredClass = new RegisteredClass( + name, + constructor, + instancePrototype, + rawDestructor, + baseClass, + getActualType, + upcast, + downcast); + + 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]; + } + ); + } + + + function heap32VectorToArray(count, firstElement) { + var array = []; + for (var i = 0; i < count; i++) { + array.push(HEAP32[(firstElement >> 2) + i]); + } + return array; + } + + function runDestructors(destructors) { + while (destructors.length) { + var ptr = destructors.pop(); + var del = destructors.pop(); + del(ptr); + } + }function __embind_register_class_constructor( + rawClassType, + argCount, + rawArgTypesAddr, + invokerSignature, + invoker, + rawConstructor + ) { + assert(argCount > 0); + var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); + invoker = embind__requireFunction(invokerSignature, invoker); + var args = [rawConstructor]; + var destructors = []; + + whenDependentTypesAreResolved([], [rawClassType], function(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] = function unboundTypeHandler() { + throwUnboundTypeError('Cannot construct ' + classType.name + ' due to unbound types', rawArgTypes); + }; + + whenDependentTypesAreResolved([], rawArgTypes, function(argTypes) { + classType.registeredClass.constructor_body[argCount - 1] = function constructor_body() { + if (arguments.length !== argCount - 1) { + throwBindingError(humanName + ' called with ' + arguments.length + ' arguments, expected ' + (argCount-1)); + } + destructors.length = 0; + args.length = argCount; + for (var i = 1; i < argCount; ++i) { + args[i] = argTypes[i]['toWireType'](destructors, arguments[i - 1]); + } + + var ptr = invoker.apply(null, args); + runDestructors(destructors); + + return argTypes[0]['fromWireType'](ptr); + }; + return []; + }); + return []; + }); + } + + + + function new_(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. Doublely-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 craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cppTargetFunc) { + // 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. + 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 = false; + + for(var i = 1; i < argTypes.length; ++i) { // Skip return value at index 0 - it's not deleted here. + if (argTypes[i] !== null && argTypes[i].destructorFunction === undefined) { // The type does not define a destructor function - must use dynamic stack + needsDestructorStack = true; + break; + } + } + + var returns = (argTypes[0].name !== "void"); + + var argsList = ""; + var argsListWired = ""; + for(var i = 0; i < argCount - 2; ++i) { + argsList += (i!==0?", ":"")+"arg"+i; + argsListWired += (i!==0?", ":"")+"arg"+i+"Wired"; + } + + var invokerFnBody = + "return function "+makeLegalFunctionName(humanName)+"("+argsList+") {\n" + + "if (arguments.length !== "+(argCount - 2)+") {\n" + + "throwBindingError('function "+humanName+" called with ' + arguments.length + ' arguments, expected "+(argCount - 2)+" args!');\n" + + "}\n"; + + + if (needsDestructorStack) { + invokerFnBody += + "var destructors = [];\n"; + } + + var dtorStack = needsDestructorStack ? "destructors" : "null"; + var args1 = ["throwBindingError", "invoker", "fn", "runDestructors", "retType", "classParam"]; + var args2 = [throwBindingError, cppInvokerFunc, cppTargetFunc, runDestructors, argTypes[0], argTypes[1]]; + + + if (isClassMethodFunc) { + invokerFnBody += "var thisWired = classParam.toWireType("+dtorStack+", this);\n"; + } + + for(var i = 0; i < argCount - 2; ++i) { + invokerFnBody += "var arg"+i+"Wired = argType"+i+".toWireType("+dtorStack+", arg"+i+"); // "+argTypes[i+2].name+"\n"; + args1.push("argType"+i); + args2.push(argTypes[i+2]); + } + + if (isClassMethodFunc) { + argsListWired = "thisWired" + (argsListWired.length > 0 ? ", " : "") + argsListWired; + } + + invokerFnBody += + (returns?"var rv = ":"") + "invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n"; + + 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+"); // "+argTypes[i].name+"\n"; + args1.push(paramName+"_dtor"); + args2.push(argTypes[i].destructorFunction); + } + } + } + + if (returns) { + invokerFnBody += "var ret = retType.fromWireType(rv);\n" + + "return ret;\n"; + } else { + } + invokerFnBody += "}\n"; + + args1.push(invokerFnBody); + + var invokerFunction = new_(Function, args1).apply(null, args2); + return invokerFunction; + }function __embind_register_class_function( + rawClassType, + methodName, + argCount, + rawArgTypesAddr, // [ReturnType, ThisType, Args...] + invokerSignature, + rawInvoker, + context, + isPureVirtual + ) { + var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); + methodName = readLatin1String(methodName); + rawInvoker = embind__requireFunction(invokerSignature, rawInvoker); + + whenDependentTypesAreResolved([], [rawClassType], function(classType) { + classType = classType[0]; + var humanName = classType.name + '.' + methodName; + + 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, function(argTypes) { + + var memberFunction = craftInvokerFunction(humanName, argTypes, classType, rawInvoker, context); + + // 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_free_list=[]; + + var emval_handle_array=[{},{value:undefined},{value:null},{value:true},{value:false}];function __emval_decref(handle) { + if (handle > 4 && 0 === --emval_handle_array[handle].refcount) { + emval_handle_array[handle] = undefined; + emval_free_list.push(handle); + } + } + + + + function count_emval_handles() { + var count = 0; + for (var i = 5; i < emval_handle_array.length; ++i) { + if (emval_handle_array[i] !== undefined) { + ++count; + } + } + return count; + } + + function get_first_emval() { + for (var i = 5; i < emval_handle_array.length; ++i) { + if (emval_handle_array[i] !== undefined) { + return emval_handle_array[i]; + } + } + return null; + }function init_emval() { + Module['count_emval_handles'] = count_emval_handles; + Module['get_first_emval'] = get_first_emval; + }function __emval_register(value) { + + switch(value){ + case undefined :{ return 1; } + case null :{ return 2; } + case true :{ return 3; } + case false :{ return 4; } + default:{ + var handle = emval_free_list.length ? + emval_free_list.pop() : + emval_handle_array.length; + + emval_handle_array[handle] = {refcount: 1, value: value}; + return handle; + } + } + }function __embind_register_emval(rawType, name) { + name = readLatin1String(name); + registerType(rawType, { + name: name, + 'fromWireType': function(handle) { + var rv = emval_handle_array[handle].value; + __emval_decref(handle); + return rv; + }, + 'toWireType': function(destructors, value) { + return __emval_register(value); + }, + 'argPackAdvance': 8, + 'readValueFromPointer': simpleReadValueFromPointer, + 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 + }); + } + + + function _embind_repr(v) { + if (v === null) { + return 'null'; + } + var t = typeof v; + if (t === 'object' || t === 'array' || t === 'function') { + return v.toString(); + } else { + return '' + v; + } + } + + function floatReadValueFromPointer(name, shift) { + switch (shift) { + case 2: return function(pointer) { + return this['fromWireType'](HEAPF32[pointer >> 2]); + }; + case 3: return function(pointer) { + return this['fromWireType'](HEAPF64[pointer >> 3]); + }; + default: + throw new TypeError("Unknown float type: " + name); + } + }function __embind_register_float(rawType, name, size) { + var shift = getShiftFromSize(size); + name = readLatin1String(name); + registerType(rawType, { + name: name, + 'fromWireType': function(value) { + return value; + }, + 'toWireType': function(destructors, value) { + // todo: Here we have an opportunity for -O3 level "unsafe" optimizations: we could + // avoid the following if() and assume value is of proper type. + if (typeof value !== "number" && typeof value !== "boolean") { + throw new TypeError('Cannot convert "' + _embind_repr(value) + '" to ' + this.name); + } + return value; + }, + 'argPackAdvance': 8, + 'readValueFromPointer': floatReadValueFromPointer(name, shift), + destructorFunction: null, // This type does not need a destructor + }); + } + + + function integerReadValueFromPointer(name, shift, signed) { + // integers are quite common, so generate very specialized functions + switch (shift) { + case 0: return signed ? + function readS8FromPointer(pointer) { return HEAP8[pointer]; } : + function readU8FromPointer(pointer) { return HEAPU8[pointer]; }; + case 1: return signed ? + function readS16FromPointer(pointer) { return HEAP16[pointer >> 1]; } : + function readU16FromPointer(pointer) { return HEAPU16[pointer >> 1]; }; + case 2: return signed ? + function readS32FromPointer(pointer) { return HEAP32[pointer >> 2]; } : + function readU32FromPointer(pointer) { return HEAPU32[pointer >> 2]; }; + default: + throw new TypeError("Unknown integer type: " + name); + } + }function __embind_register_integer(primitiveType, name, size, minRange, maxRange) { + name = readLatin1String(name); + if (maxRange === -1) { // LLVM doesn't have signed and unsigned 32-bit types, so u32 literals come out as 'i32 -1'. Always treat those as max u32. + maxRange = 4294967295; + } + + var shift = getShiftFromSize(size); + + var fromWireType = function(value) { + return value; + }; + + if (minRange === 0) { + var bitshift = 32 - 8*size; + fromWireType = function(value) { + return (value << bitshift) >>> bitshift; + }; + } + + var isUnsignedType = (name.indexOf('unsigned') != -1); + + registerType(primitiveType, { + name: name, + 'fromWireType': fromWireType, + 'toWireType': function(destructors, value) { + // todo: Here we have an opportunity for -O3 level "unsafe" optimizations: we could + // avoid the following two if()s and assume value is of proper type. + if (typeof value !== "number" && typeof value !== "boolean") { + throw new TypeError('Cannot convert "' + _embind_repr(value) + '" to ' + this.name); + } + if (value < minRange || value > maxRange) { + throw new TypeError('Passing a number "' + _embind_repr(value) + '" from JS side to C/C++ side to an argument of type "' + name + '", which is outside the valid range [' + minRange + ', ' + maxRange + ']!'); + } + return isUnsignedType ? (value >>> 0) : (value | 0); + }, + 'argPackAdvance': 8, + 'readValueFromPointer': integerReadValueFromPointer(name, shift, minRange !== 0), + destructorFunction: null, // This type does not need a destructor + }); + } + + function __embind_register_memory_view(rawType, dataTypeIndex, name) { + var typeMapping = [ + Int8Array, + Uint8Array, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + Float32Array, + Float64Array, + ]; + + var TA = typeMapping[dataTypeIndex]; + + function decodeMemoryView(handle) { + handle = handle >> 2; + var heap = HEAPU32; + var size = heap[handle]; // in elements + var data = heap[handle + 1]; // byte offset into emscripten heap + return new TA(buffer, data, size); + } + + name = readLatin1String(name); + registerType(rawType, { + name: name, + 'fromWireType': decodeMemoryView, + 'argPackAdvance': 8, + 'readValueFromPointer': decodeMemoryView, + }, { + ignoreDuplicateRegistrations: true, + }); + } + + function __embind_register_std_string(rawType, name) { + name = readLatin1String(name); + var stdStringIsUTF8 + //process only std::string bindings with UTF8 support, in contrast to e.g. std::basic_string + = (name === "std::string"); + + registerType(rawType, { + name: name, + 'fromWireType': function(value) { + var length = HEAPU32[value >> 2]; + + var str; + if (stdStringIsUTF8) { + var decodeStartPtr = value + 4; + // Looping here to support possible embedded '0' bytes + for (var i = 0; i <= length; ++i) { + var currentBytePtr = value + 4 + i; + if (HEAPU8[currentBytePtr] == 0 || i == length) { + 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[value + 4 + i]); + } + str = a.join(''); + } + + _free(value); + + return str; + }, + 'toWireType': function(destructors, value) { + if (value instanceof ArrayBuffer) { + value = new Uint8Array(value); + } + + var getLength; + 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) { + getLength = function() {return lengthBytesUTF8(value);}; + } else { + getLength = function() {return value.length;}; + } + + // assumes 4-byte alignment + var length = getLength(); + var ptr = _malloc(4 + length + 1); + HEAPU32[ptr >> 2] = length; + if (stdStringIsUTF8 && valueIsOfTypeString) { + stringToUTF8(value, ptr + 4, 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 + 4 + i] = charCode; + } + } else { + for (var i = 0; i < length; ++i) { + HEAPU8[ptr + 4 + i] = value[i]; + } + } + } + + if (destructors !== null) { + destructors.push(_free, ptr); + } + return ptr; + }, + 'argPackAdvance': 8, + 'readValueFromPointer': simpleReadValueFromPointer, + destructorFunction: function(ptr) { _free(ptr); }, + }); + } + + function __embind_register_std_wstring(rawType, charSize, name) { + name = readLatin1String(name); + var decodeString, encodeString, getHeap, lengthBytesUTF, shift; + if (charSize === 2) { + decodeString = UTF16ToString; + encodeString = stringToUTF16; + lengthBytesUTF = lengthBytesUTF16; + getHeap = function() { return HEAPU16; }; + shift = 1; + } else if (charSize === 4) { + decodeString = UTF32ToString; + encodeString = stringToUTF32; + lengthBytesUTF = lengthBytesUTF32; + getHeap = function() { return HEAPU32; }; + shift = 2; + } + registerType(rawType, { + name: name, + 'fromWireType': function(value) { + // Code mostly taken from _embind_register_std_string fromWireType + var length = HEAPU32[value >> 2]; + var HEAP = getHeap(); + 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 (HEAP[currentBytePtr >> shift] == 0 || i == length) { + 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': function(destructors, value) { + if (!(typeof value === 'string')) { + throwBindingError('Cannot pass non-string to C++ string type ' + name); + } + + // assumes 4-byte alignment + var length = lengthBytesUTF(value); + var ptr = _malloc(4 + length + charSize); + HEAPU32[ptr >> 2] = length >> shift; + + encodeString(value, ptr + 4, length + charSize); + + if (destructors !== null) { + destructors.push(_free, ptr); + } + return ptr; + }, + 'argPackAdvance': 8, + 'readValueFromPointer': simpleReadValueFromPointer, + destructorFunction: function(ptr) { _free(ptr); }, + }); + } + + function __embind_register_void(rawType, name) { + name = readLatin1String(name); + registerType(rawType, { + isVoid: true, // void return values can be optimized out sometimes + name: name, + 'argPackAdvance': 0, + 'fromWireType': function() { + return undefined; + }, + 'toWireType': function(destructors, o) { + // TODO: assert if anything else is given? + return undefined; + }, + }); + } + + function _abort() { + abort(); + } + + function _emscripten_get_sbrk_ptr() { + return 4336; + } + + function _emscripten_memcpy_big(dest, src, num) { + HEAPU8.copyWithin(dest, src, src + num); + } + + + function _emscripten_get_heap_size() { + return HEAPU8.length; + } + + function abortOnCannotGrowMemory(requestedSize) { + abort('Cannot enlarge memory arrays to size ' + requestedSize + ' bytes (OOM). Either (1) compile with -s INITIAL_MEMORY=X with X higher than the current value ' + HEAP8.length + ', (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 '); + }function _emscripten_resize_heap(requestedSize) { + requestedSize = requestedSize >>> 0; + abortOnCannotGrowMemory(requestedSize); + } +embind_init_charCodes(); +BindingError = Module['BindingError'] = extendError(Error, 'BindingError');; +InternalError = Module['InternalError'] = extendError(Error, 'InternalError');; +init_ClassHandle(); +init_RegisteredPointer(); +init_embind();; +UnboundTypeError = Module['UnboundTypeError'] = extendError(Error, 'UnboundTypeError');; +init_emval();; +var ASSERTIONS = true; + + + +/** @type {function(string, boolean=, number=)} */ +function intArrayFromString(stringy, dontAddNull, length) { + var len = length > 0 ? length : lengthBytesUTF8(stringy)+1; + var u8array = new Array(len); + var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length); + if (dontAddNull) u8array.length = numBytesWritten; + return u8array; +} + +function intArrayToString(array) { + var ret = []; + for (var i = 0; i < array.length; i++) { + var chr = array[i]; + if (chr > 0xFF) { + if (ASSERTIONS) { + assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.'); + } + chr &= 0xFF; + } + ret.push(String.fromCharCode(chr)); + } + return ret.join(''); +} + + +var asmGlobalArg = {}; +var asmLibraryArg = { "__handle_stack_overflow": ___handle_stack_overflow, "_embind_register_bool": __embind_register_bool, "_embind_register_class": __embind_register_class, "_embind_register_class_constructor": __embind_register_class_constructor, "_embind_register_class_function": __embind_register_class_function, "_embind_register_emval": __embind_register_emval, "_embind_register_float": __embind_register_float, "_embind_register_integer": __embind_register_integer, "_embind_register_memory_view": __embind_register_memory_view, "_embind_register_std_string": __embind_register_std_string, "_embind_register_std_wstring": __embind_register_std_wstring, "_embind_register_void": __embind_register_void, "abort": _abort, "emscripten_get_sbrk_ptr": _emscripten_get_sbrk_ptr, "emscripten_memcpy_big": _emscripten_memcpy_big, "emscripten_resize_heap": _emscripten_resize_heap, "memory": wasmMemory, "table": wasmTable }; +var asm = createWasm(); +/** @type {function(...*):?} */ +var ___wasm_call_ctors = Module["___wasm_call_ctors"] = createExportWrapper("__wasm_call_ctors"); + +/** @type {function(...*):?} */ +var ___getTypeName = Module["___getTypeName"] = createExportWrapper("__getTypeName"); + +/** @type {function(...*):?} */ +var ___embind_register_native_and_builtin_types = Module["___embind_register_native_and_builtin_types"] = createExportWrapper("__embind_register_native_and_builtin_types"); + +/** @type {function(...*):?} */ +var ___errno_location = Module["___errno_location"] = createExportWrapper("__errno_location"); + +/** @type {function(...*):?} */ +var _malloc = Module["_malloc"] = createExportWrapper("malloc"); + +/** @type {function(...*):?} */ +var _fflush = Module["_fflush"] = createExportWrapper("fflush"); + +/** @type {function(...*):?} */ +var stackSave = Module["stackSave"] = createExportWrapper("stackSave"); + +/** @type {function(...*):?} */ +var stackRestore = Module["stackRestore"] = createExportWrapper("stackRestore"); + +/** @type {function(...*):?} */ +var stackAlloc = Module["stackAlloc"] = createExportWrapper("stackAlloc"); + +/** @type {function(...*):?} */ +var _free = Module["_free"] = createExportWrapper("free"); + +/** @type {function(...*):?} */ +var ___set_stack_limit = Module["___set_stack_limit"] = createExportWrapper("__set_stack_limit"); + +/** @type {function(...*):?} */ +var __growWasmMemory = Module["__growWasmMemory"] = createExportWrapper("__growWasmMemory"); + +/** @type {function(...*):?} */ +var dynCall_ii = Module["dynCall_ii"] = createExportWrapper("dynCall_ii"); + +/** @type {function(...*):?} */ +var dynCall_vi = Module["dynCall_vi"] = createExportWrapper("dynCall_vi"); + +/** @type {function(...*):?} */ +var dynCall_did = Module["dynCall_did"] = createExportWrapper("dynCall_did"); + +/** @type {function(...*):?} */ +var dynCall_iid = Module["dynCall_iid"] = createExportWrapper("dynCall_iid"); + +/** @type {function(...*):?} */ +var dynCall_diid = Module["dynCall_diid"] = createExportWrapper("dynCall_diid"); + +/** @type {function(...*):?} */ +var dynCall_iiii = Module["dynCall_iiii"] = createExportWrapper("dynCall_iiii"); + +/** @type {function(...*):?} */ +var dynCall_viiiiii = Module["dynCall_viiiiii"] = createExportWrapper("dynCall_viiiiii"); + +/** @type {function(...*):?} */ +var dynCall_viiiii = Module["dynCall_viiiii"] = createExportWrapper("dynCall_viiiii"); + +/** @type {function(...*):?} */ +var dynCall_viiii = Module["dynCall_viiii"] = createExportWrapper("dynCall_viiii"); + + + + + +// === Auto-generated postamble setup entry stuff === + + +if (!Object.getOwnPropertyDescriptor(Module, "intArrayFromString")) Module["intArrayFromString"] = function() { abort("'intArrayFromString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "intArrayToString")) Module["intArrayToString"] = function() { abort("'intArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ccall")) Module["ccall"] = function() { abort("'ccall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "cwrap")) Module["cwrap"] = function() { abort("'cwrap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setValue")) Module["setValue"] = function() { abort("'setValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getValue")) Module["getValue"] = function() { abort("'getValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "allocate")) Module["allocate"] = function() { abort("'allocate' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getMemory")) Module["getMemory"] = function() { abort("'getMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "UTF8ArrayToString")) Module["UTF8ArrayToString"] = function() { abort("'UTF8ArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "UTF8ToString")) Module["UTF8ToString"] = function() { abort("'UTF8ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8Array")) Module["stringToUTF8Array"] = function() { abort("'stringToUTF8Array' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8")) Module["stringToUTF8"] = function() { abort("'stringToUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF8")) Module["lengthBytesUTF8"] = function() { abort("'lengthBytesUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addOnPreRun")) Module["addOnPreRun"] = function() { abort("'addOnPreRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addOnInit")) Module["addOnInit"] = function() { abort("'addOnInit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addOnPreMain")) Module["addOnPreMain"] = function() { abort("'addOnPreMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addOnExit")) Module["addOnExit"] = function() { abort("'addOnExit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addOnPostRun")) Module["addOnPostRun"] = function() { abort("'addOnPostRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeStringToMemory")) Module["writeStringToMemory"] = function() { abort("'writeStringToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeArrayToMemory")) Module["writeArrayToMemory"] = function() { abort("'writeArrayToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeAsciiToMemory")) Module["writeAsciiToMemory"] = function() { abort("'writeAsciiToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addRunDependency")) Module["addRunDependency"] = function() { abort("'addRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "removeRunDependency")) Module["removeRunDependency"] = function() { abort("'removeRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createFolder")) Module["FS_createFolder"] = function() { abort("'FS_createFolder' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createPath")) Module["FS_createPath"] = function() { abort("'FS_createPath' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createDataFile")) Module["FS_createDataFile"] = function() { abort("'FS_createDataFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createPreloadedFile")) Module["FS_createPreloadedFile"] = function() { abort("'FS_createPreloadedFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createLazyFile")) Module["FS_createLazyFile"] = function() { abort("'FS_createLazyFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createLink")) Module["FS_createLink"] = function() { abort("'FS_createLink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createDevice")) Module["FS_createDevice"] = function() { abort("'FS_createDevice' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_unlink")) Module["FS_unlink"] = function() { abort("'FS_unlink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "dynamicAlloc")) Module["dynamicAlloc"] = function() { abort("'dynamicAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "loadDynamicLibrary")) Module["loadDynamicLibrary"] = function() { abort("'loadDynamicLibrary' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "loadWebAssemblyModule")) Module["loadWebAssemblyModule"] = function() { abort("'loadWebAssemblyModule' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getLEB")) Module["getLEB"] = function() { abort("'getLEB' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getFunctionTables")) Module["getFunctionTables"] = function() { abort("'getFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "alignFunctionTables")) Module["alignFunctionTables"] = function() { abort("'alignFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerFunctions")) Module["registerFunctions"] = function() { abort("'registerFunctions' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addFunction")) Module["addFunction"] = function() { abort("'addFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "removeFunction")) Module["removeFunction"] = function() { abort("'removeFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getFuncWrapper")) Module["getFuncWrapper"] = function() { abort("'getFuncWrapper' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "prettyPrint")) Module["prettyPrint"] = function() { abort("'prettyPrint' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "makeBigInt")) Module["makeBigInt"] = function() { abort("'makeBigInt' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "dynCall")) Module["dynCall"] = function() { abort("'dynCall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getCompilerSetting")) Module["getCompilerSetting"] = function() { abort("'getCompilerSetting' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "print")) Module["print"] = function() { abort("'print' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "printErr")) Module["printErr"] = function() { abort("'printErr' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getTempRet0")) Module["getTempRet0"] = function() { abort("'getTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setTempRet0")) Module["setTempRet0"] = function() { abort("'setTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "callMain")) Module["callMain"] = function() { abort("'callMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "abort")) Module["abort"] = function() { abort("'abort' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToNewUTF8")) Module["stringToNewUTF8"] = function() { abort("'stringToNewUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "abortOnCannotGrowMemory")) Module["abortOnCannotGrowMemory"] = function() { abort("'abortOnCannotGrowMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscripten_realloc_buffer")) Module["emscripten_realloc_buffer"] = function() { abort("'emscripten_realloc_buffer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ENV")) Module["ENV"] = function() { abort("'ENV' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_CODES")) Module["ERRNO_CODES"] = function() { abort("'ERRNO_CODES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_MESSAGES")) Module["ERRNO_MESSAGES"] = function() { abort("'ERRNO_MESSAGES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setErrNo")) Module["setErrNo"] = function() { abort("'setErrNo' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "DNS")) Module["DNS"] = function() { abort("'DNS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GAI_ERRNO_MESSAGES")) Module["GAI_ERRNO_MESSAGES"] = function() { abort("'GAI_ERRNO_MESSAGES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "Protocols")) Module["Protocols"] = function() { abort("'Protocols' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "Sockets")) Module["Sockets"] = function() { abort("'Sockets' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "UNWIND_CACHE")) Module["UNWIND_CACHE"] = function() { abort("'UNWIND_CACHE' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "readAsmConstArgs")) Module["readAsmConstArgs"] = function() { abort("'readAsmConstArgs' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "jstoi_q")) Module["jstoi_q"] = function() { abort("'jstoi_q' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "jstoi_s")) Module["jstoi_s"] = function() { abort("'jstoi_s' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "abortStackOverflow")) Module["abortStackOverflow"] = function() { abort("'abortStackOverflow' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "reallyNegative")) Module["reallyNegative"] = function() { abort("'reallyNegative' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "formatString")) Module["formatString"] = function() { abort("'formatString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "PATH")) Module["PATH"] = function() { abort("'PATH' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "PATH_FS")) Module["PATH_FS"] = function() { abort("'PATH_FS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SYSCALLS")) Module["SYSCALLS"] = function() { abort("'SYSCALLS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "syscallMmap2")) Module["syscallMmap2"] = function() { abort("'syscallMmap2' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "syscallMunmap")) Module["syscallMunmap"] = function() { abort("'syscallMunmap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "flush_NO_FILESYSTEM")) Module["flush_NO_FILESYSTEM"] = function() { abort("'flush_NO_FILESYSTEM' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "JSEvents")) Module["JSEvents"] = function() { abort("'JSEvents' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "specialHTMLTargets")) Module["specialHTMLTargets"] = function() { abort("'specialHTMLTargets' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "demangle")) Module["demangle"] = function() { abort("'demangle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "demangleAll")) Module["demangleAll"] = function() { abort("'demangleAll' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "jsStackTrace")) Module["jsStackTrace"] = function() { abort("'jsStackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getEnvStrings")) Module["getEnvStrings"] = function() { abort("'getEnvStrings' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "checkWasiClock")) Module["checkWasiClock"] = function() { abort("'checkWasiClock' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64")) Module["writeI53ToI64"] = function() { abort("'writeI53ToI64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Clamped")) Module["writeI53ToI64Clamped"] = function() { abort("'writeI53ToI64Clamped' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Signaling")) Module["writeI53ToI64Signaling"] = function() { abort("'writeI53ToI64Signaling' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Clamped")) Module["writeI53ToU64Clamped"] = function() { abort("'writeI53ToU64Clamped' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Signaling")) Module["writeI53ToU64Signaling"] = function() { abort("'writeI53ToU64Signaling' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "readI53FromI64")) Module["readI53FromI64"] = function() { abort("'readI53FromI64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "readI53FromU64")) Module["readI53FromU64"] = function() { abort("'readI53FromU64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "convertI32PairToI53")) Module["convertI32PairToI53"] = function() { abort("'convertI32PairToI53' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "convertU32PairToI53")) Module["convertU32PairToI53"] = function() { abort("'convertU32PairToI53' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "Browser")) Module["Browser"] = function() { abort("'Browser' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS")) Module["FS"] = function() { abort("'FS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "MEMFS")) Module["MEMFS"] = function() { abort("'MEMFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "TTY")) Module["TTY"] = function() { abort("'TTY' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "PIPEFS")) Module["PIPEFS"] = function() { abort("'PIPEFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SOCKFS")) Module["SOCKFS"] = function() { abort("'SOCKFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GL")) Module["GL"] = function() { abort("'GL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGet")) Module["emscriptenWebGLGet"] = function() { abort("'emscriptenWebGLGet' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetTexPixelData")) Module["emscriptenWebGLGetTexPixelData"] = function() { abort("'emscriptenWebGLGetTexPixelData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetUniform")) Module["emscriptenWebGLGetUniform"] = function() { abort("'emscriptenWebGLGetUniform' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetVertexAttrib")) Module["emscriptenWebGLGetVertexAttrib"] = function() { abort("'emscriptenWebGLGetVertexAttrib' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "AL")) Module["AL"] = function() { abort("'AL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SDL_unicode")) Module["SDL_unicode"] = function() { abort("'SDL_unicode' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SDL_ttfContext")) Module["SDL_ttfContext"] = function() { abort("'SDL_ttfContext' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SDL_audio")) Module["SDL_audio"] = function() { abort("'SDL_audio' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SDL")) Module["SDL"] = function() { abort("'SDL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SDL_gfx")) Module["SDL_gfx"] = function() { abort("'SDL_gfx' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GLUT")) Module["GLUT"] = function() { abort("'GLUT' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "EGL")) Module["EGL"] = function() { abort("'EGL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GLFW_Window")) Module["GLFW_Window"] = function() { abort("'GLFW_Window' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GLFW")) Module["GLFW"] = function() { abort("'GLFW' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GLEW")) Module["GLEW"] = function() { abort("'GLEW' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "IDBStore")) Module["IDBStore"] = function() { abort("'IDBStore' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "runAndAbortIfError")) Module["runAndAbortIfError"] = function() { abort("'runAndAbortIfError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emval_handle_array")) Module["emval_handle_array"] = function() { abort("'emval_handle_array' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emval_free_list")) Module["emval_free_list"] = function() { abort("'emval_free_list' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emval_symbols")) Module["emval_symbols"] = function() { abort("'emval_symbols' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "init_emval")) Module["init_emval"] = function() { abort("'init_emval' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "count_emval_handles")) Module["count_emval_handles"] = function() { abort("'count_emval_handles' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "get_first_emval")) Module["get_first_emval"] = function() { abort("'get_first_emval' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getStringOrSymbol")) Module["getStringOrSymbol"] = function() { abort("'getStringOrSymbol' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "requireHandle")) Module["requireHandle"] = function() { abort("'requireHandle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emval_newers")) Module["emval_newers"] = function() { abort("'emval_newers' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "craftEmvalAllocator")) Module["craftEmvalAllocator"] = function() { abort("'craftEmvalAllocator' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emval_get_global")) Module["emval_get_global"] = function() { abort("'emval_get_global' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emval_methodCallers")) Module["emval_methodCallers"] = function() { abort("'emval_methodCallers' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "InternalError")) Module["InternalError"] = function() { abort("'InternalError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "BindingError")) Module["BindingError"] = function() { abort("'BindingError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "UnboundTypeError")) Module["UnboundTypeError"] = function() { abort("'UnboundTypeError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "PureVirtualError")) Module["PureVirtualError"] = function() { abort("'PureVirtualError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "init_embind")) Module["init_embind"] = function() { abort("'init_embind' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "throwInternalError")) Module["throwInternalError"] = function() { abort("'throwInternalError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "throwBindingError")) Module["throwBindingError"] = function() { abort("'throwBindingError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "throwUnboundTypeError")) Module["throwUnboundTypeError"] = function() { abort("'throwUnboundTypeError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ensureOverloadTable")) Module["ensureOverloadTable"] = function() { abort("'ensureOverloadTable' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "exposePublicSymbol")) Module["exposePublicSymbol"] = function() { abort("'exposePublicSymbol' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "replacePublicSymbol")) Module["replacePublicSymbol"] = function() { abort("'replacePublicSymbol' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "extendError")) Module["extendError"] = function() { abort("'extendError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "createNamedFunction")) Module["createNamedFunction"] = function() { abort("'createNamedFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registeredInstances")) Module["registeredInstances"] = function() { abort("'registeredInstances' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getBasestPointer")) Module["getBasestPointer"] = function() { abort("'getBasestPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerInheritedInstance")) Module["registerInheritedInstance"] = function() { abort("'registerInheritedInstance' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "unregisterInheritedInstance")) Module["unregisterInheritedInstance"] = function() { abort("'unregisterInheritedInstance' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getInheritedInstance")) Module["getInheritedInstance"] = function() { abort("'getInheritedInstance' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getInheritedInstanceCount")) Module["getInheritedInstanceCount"] = function() { abort("'getInheritedInstanceCount' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getLiveInheritedInstances")) Module["getLiveInheritedInstances"] = function() { abort("'getLiveInheritedInstances' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registeredTypes")) Module["registeredTypes"] = function() { abort("'registeredTypes' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "awaitingDependencies")) Module["awaitingDependencies"] = function() { abort("'awaitingDependencies' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "typeDependencies")) Module["typeDependencies"] = function() { abort("'typeDependencies' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registeredPointers")) Module["registeredPointers"] = function() { abort("'registeredPointers' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerType")) Module["registerType"] = function() { abort("'registerType' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "whenDependentTypesAreResolved")) Module["whenDependentTypesAreResolved"] = function() { abort("'whenDependentTypesAreResolved' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "embind_charCodes")) Module["embind_charCodes"] = function() { abort("'embind_charCodes' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "embind_init_charCodes")) Module["embind_init_charCodes"] = function() { abort("'embind_init_charCodes' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "readLatin1String")) Module["readLatin1String"] = function() { abort("'readLatin1String' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getTypeName")) Module["getTypeName"] = function() { abort("'getTypeName' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "heap32VectorToArray")) Module["heap32VectorToArray"] = function() { abort("'heap32VectorToArray' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "requireRegisteredType")) Module["requireRegisteredType"] = function() { abort("'requireRegisteredType' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getShiftFromSize")) Module["getShiftFromSize"] = function() { abort("'getShiftFromSize' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "integerReadValueFromPointer")) Module["integerReadValueFromPointer"] = function() { abort("'integerReadValueFromPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "enumReadValueFromPointer")) Module["enumReadValueFromPointer"] = function() { abort("'enumReadValueFromPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "floatReadValueFromPointer")) Module["floatReadValueFromPointer"] = function() { abort("'floatReadValueFromPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "simpleReadValueFromPointer")) Module["simpleReadValueFromPointer"] = function() { abort("'simpleReadValueFromPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "runDestructors")) Module["runDestructors"] = function() { abort("'runDestructors' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "new_")) Module["new_"] = function() { abort("'new_' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "craftInvokerFunction")) Module["craftInvokerFunction"] = function() { abort("'craftInvokerFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "embind__requireFunction")) Module["embind__requireFunction"] = function() { abort("'embind__requireFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "tupleRegistrations")) Module["tupleRegistrations"] = function() { abort("'tupleRegistrations' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "structRegistrations")) Module["structRegistrations"] = function() { abort("'structRegistrations' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "genericPointerToWireType")) Module["genericPointerToWireType"] = function() { abort("'genericPointerToWireType' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "constNoSmartPtrRawPointerToWireType")) Module["constNoSmartPtrRawPointerToWireType"] = function() { abort("'constNoSmartPtrRawPointerToWireType' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "nonConstNoSmartPtrRawPointerToWireType")) Module["nonConstNoSmartPtrRawPointerToWireType"] = function() { abort("'nonConstNoSmartPtrRawPointerToWireType' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "init_RegisteredPointer")) Module["init_RegisteredPointer"] = function() { abort("'init_RegisteredPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "RegisteredPointer")) Module["RegisteredPointer"] = function() { abort("'RegisteredPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "RegisteredPointer_getPointee")) Module["RegisteredPointer_getPointee"] = function() { abort("'RegisteredPointer_getPointee' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "RegisteredPointer_destructor")) Module["RegisteredPointer_destructor"] = function() { abort("'RegisteredPointer_destructor' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "RegisteredPointer_deleteObject")) Module["RegisteredPointer_deleteObject"] = function() { abort("'RegisteredPointer_deleteObject' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "RegisteredPointer_fromWireType")) Module["RegisteredPointer_fromWireType"] = function() { abort("'RegisteredPointer_fromWireType' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "runDestructor")) Module["runDestructor"] = function() { abort("'runDestructor' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "releaseClassHandle")) Module["releaseClassHandle"] = function() { abort("'releaseClassHandle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "finalizationGroup")) Module["finalizationGroup"] = function() { abort("'finalizationGroup' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "detachFinalizer_deps")) Module["detachFinalizer_deps"] = function() { abort("'detachFinalizer_deps' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "detachFinalizer")) Module["detachFinalizer"] = function() { abort("'detachFinalizer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "attachFinalizer")) Module["attachFinalizer"] = function() { abort("'attachFinalizer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "makeClassHandle")) Module["makeClassHandle"] = function() { abort("'makeClassHandle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "init_ClassHandle")) Module["init_ClassHandle"] = function() { abort("'init_ClassHandle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ClassHandle")) Module["ClassHandle"] = function() { abort("'ClassHandle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ClassHandle_isAliasOf")) Module["ClassHandle_isAliasOf"] = function() { abort("'ClassHandle_isAliasOf' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "throwInstanceAlreadyDeleted")) Module["throwInstanceAlreadyDeleted"] = function() { abort("'throwInstanceAlreadyDeleted' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ClassHandle_clone")) Module["ClassHandle_clone"] = function() { abort("'ClassHandle_clone' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ClassHandle_delete")) Module["ClassHandle_delete"] = function() { abort("'ClassHandle_delete' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "deletionQueue")) Module["deletionQueue"] = function() { abort("'deletionQueue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ClassHandle_isDeleted")) Module["ClassHandle_isDeleted"] = function() { abort("'ClassHandle_isDeleted' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ClassHandle_deleteLater")) Module["ClassHandle_deleteLater"] = function() { abort("'ClassHandle_deleteLater' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "flushPendingDeletes")) Module["flushPendingDeletes"] = function() { abort("'flushPendingDeletes' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "delayFunction")) Module["delayFunction"] = function() { abort("'delayFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setDelayFunction")) Module["setDelayFunction"] = function() { abort("'setDelayFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "RegisteredClass")) Module["RegisteredClass"] = function() { abort("'RegisteredClass' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "shallowCopyInternalPointer")) Module["shallowCopyInternalPointer"] = function() { abort("'shallowCopyInternalPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "downcastPointer")) Module["downcastPointer"] = function() { abort("'downcastPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "upcastPointer")) Module["upcastPointer"] = function() { abort("'upcastPointer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "validateThis")) Module["validateThis"] = function() { abort("'validateThis' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "char_0")) Module["char_0"] = function() { abort("'char_0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "char_9")) Module["char_9"] = function() { abort("'char_9' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "makeLegalFunctionName")) Module["makeLegalFunctionName"] = function() { abort("'makeLegalFunctionName' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "warnOnce")) Module["warnOnce"] = function() { abort("'warnOnce' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stackSave")) Module["stackSave"] = function() { abort("'stackSave' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stackRestore")) Module["stackRestore"] = function() { abort("'stackRestore' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stackAlloc")) Module["stackAlloc"] = function() { abort("'stackAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "AsciiToString")) Module["AsciiToString"] = function() { abort("'AsciiToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToAscii")) Module["stringToAscii"] = function() { abort("'stringToAscii' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "UTF16ToString")) Module["UTF16ToString"] = function() { abort("'UTF16ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF16")) Module["stringToUTF16"] = function() { abort("'stringToUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF16")) Module["lengthBytesUTF16"] = function() { abort("'lengthBytesUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "UTF32ToString")) Module["UTF32ToString"] = function() { abort("'UTF32ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF32")) Module["stringToUTF32"] = function() { abort("'stringToUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF32")) Module["lengthBytesUTF32"] = function() { abort("'lengthBytesUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8")) Module["allocateUTF8"] = function() { abort("'allocateUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8OnStack")) Module["allocateUTF8OnStack"] = function() { abort("'allocateUTF8OnStack' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +Module["writeStackCookie"] = writeStackCookie; +Module["checkStackCookie"] = checkStackCookie;if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_NORMAL")) Object.defineProperty(Module, "ALLOC_NORMAL", { configurable: true, get: function() { abort("'ALLOC_NORMAL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); +if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_STACK")) Object.defineProperty(Module, "ALLOC_STACK", { configurable: true, get: function() { abort("'ALLOC_STACK' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); +if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_DYNAMIC")) Object.defineProperty(Module, "ALLOC_DYNAMIC", { configurable: true, get: function() { abort("'ALLOC_DYNAMIC' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); +if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_NONE")) Object.defineProperty(Module, "ALLOC_NONE", { configurable: true, get: function() { abort("'ALLOC_NONE' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); + + + +var calledRun; + +/** + * @constructor + * @this {ExitStatus} + */ +function ExitStatus(status) { + this.name = "ExitStatus"; + this.message = "Program terminated with exit(" + status + ")"; + this.status = status; +} + +var calledMain = false; + + +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 +}; + + + + + +/** @type {function(Array=)} */ +function run(args) { + args = args || arguments_; + + if (runDependencies > 0) { + return; + } + + writeStackCookie(); + + preRun(); + + if (runDependencies > 0) return; // a preRun added a dependency, run will be called later + + 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(); + + preMain(); + + readyPromiseResolve(Module); + if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized'](); + + assert(!Module['_main'], 'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]'); + + postRun(); + } + + if (Module['setStatus']) { + Module['setStatus']('Running...'); + setTimeout(function() { + setTimeout(function() { + Module['setStatus'](''); + }, 1); + doRun(); + }, 1); + } else + { + doRun(); + } + checkStackCookie(); +} +Module['run'] = run; + +function checkUnflushedContent() { + // Compiler settings do not allow exiting the runtime, so flushing + // the streams is not possible. but in ASSERTIONS mode we check + // if there was something to flush, and if so tell the user they + // should request that the runtime be exitable. + // Normally we would not even include flush() at all, but in ASSERTIONS + // builds we do so just for this check, and here we see if there is any + // content to flush, that is, we check if there would have been + // something a non-ASSERTIONS build would have not seen. + // How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0 + // mode (which has its own special function for this; otherwise, all + // the code is inside libc) + var print = out; + var printErr = err; + var has = false; + out = err = function(x) { + has = true; + } + try { // it doesn't matter if it fails + var flush = null; + if (flush) flush(); + } catch(e) {} + out = print; + err = printErr; + if (has) { + warnOnce('stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the FAQ), or make sure to emit a newline when you printf etc.'); + warnOnce('(this may also be due to not including full filesystem support - try building with -s FORCE_FILESYSTEM=1)'); + } +} + +/** @param {boolean|number=} implicit */ +function exit(status, implicit) { + checkUnflushedContent(); + + // if this is just main exit-ing implicitly, and the status is 0, then we + // don't need to do anything here and can just leave. if the status is + // non-zero, though, then we need to report it. + // (we may have warned about this earlier, if a situation justifies doing so) + if (implicit && noExitRuntime && status === 0) { + return; + } + + if (noExitRuntime) { + // if exit() was called, we may warn the user if the runtime isn't actually being shut down + if (!implicit) { + var msg = 'program exited (with status: ' + status + '), but EXIT_RUNTIME is not set, so halting execution but not exiting the runtime or preventing further async execution (build with EXIT_RUNTIME=1, if you want a true shutdown)'; + readyPromiseReject(msg); + } + } else { + + ABORT = true; + EXITSTATUS = status; + + exitRuntime(); + + if (Module['onExit']) Module['onExit'](status); + } + + quit_(status, new ExitStatus(status)); +} + +if (Module['preInit']) { + if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']]; + while (Module['preInit'].length > 0) { + Module['preInit'].pop()(); + } +} + + + noExitRuntime = true; + +run(); + + + + + + +// {{MODULE_ADDITIONS}} + + + + + + return createModule.ready +} +); +})(); +if (typeof exports === 'object' && typeof module === 'object') + module.exports = createModule; + else if (typeof define === 'function' && define['amd']) + define([], function() { return createModule; }); + else if (typeof exports === 'object') + exports["createModule"] = createModule; + \ No newline at end of file diff --git a/webassembly/newtonraphsonwasm.wasm b/webassembly/newtonraphsonwasm.wasm new file mode 100644 index 0000000000000000000000000000000000000000..0d74f8ca980ef276baf4dcae3620d20b46a792ff GIT binary patch literal 26547 zcmeI5dw^Wkec$h6W_EV&?CxDXSJJL@?;yhh0!tt-4^yn`fH2`<$98O-I9*oK3hhH$ z?L#X$#jI=-o3w7~IyAK#+F~2mu8R}ex-m`MhPI@kiPN|ZZg4{q($bbD#HBT9ofw;b zzQ1#4=I-nRfvf(Nh2fri9>3r3{NCp=gEuyR-1j`s|CGP=PS0Pu(_ixVP$)0y&%4v} z?ku@d#cHSuDbOQOGyl=3yZyT<-c3=B)}>i>w;NAWmjgg^H7`-@X%_97j}(}Dmi&7} ziW?8K;JL6r96zzRWpw=bp@|bmM(4)wnwVc0pBp_qJvKk@ZBS!l^~TY|GbiR3=1v`6 zn3?k`>bPr-jz>?OIJ_`1bHX!Rn^*K&oS8V{RRv*X+o746X)jdUjuqqP7mkcV!NiHX z+~~nodz{X@)CFYaM8}UWj!nDq11rW)oLCsYYkbZTuyX9t>6x(w&j7E)eSG}*%-s7% z7bnI~yDsIiLo;&=UdiYfKR$nWZsO#^_z8GEKk?(^qsPX_PI`fHq0k7F!zbT2dT8P< zuS;!PM@Ns1oj5W*&dkRSPmRtjj?Y2HX$Q9AkOuzQ;H-fvFN__U9`{drJHzkzf9iXs zS}p3Wm4Z@$f}*7Q3;Zf?UJwO=SL5FvoM_hvl#mhGC^rVIDzOSK#^d_nE1Nbys^fZt06FVP#Xe4k|CqYLz(_udrKd2a5+%;@yYVLGAqf8zw4QcI#wr}d;esedZ%NqUmfgK2Nl+ZP=L zVfQ)+bKKPf!dAe&KGITB`*a$CE&3El>wVE1gA$IKc?HZXOoAkwVlt(~8wu(>{A)rl zDGdj8u#_$hz0|;~vfLNlAE4$N+~A}&I5?1$8qo#8&7}izZaB^^HPM}Y(WMA3=oH*C5y9V2GJiO@#SfOU zr-o7#HT4rO@%saBdtdaSQgHcFa1T=PvlkFeu5KU<8<({ZUM7Tyek2%3!r@>bEg?cF zLwOQ0g-K;3*qfcLO8=6skzh|ekOiyW<@x+L+Wvf+P!3jxdQv zg28wwt;ajlo_JT<8z;yF6vJsuYdjL{k5dF=H5>HUjWoh!<4ACI+(0B&vssTM-9p2b zk>ENSwz?Xlb`KJueGmzR$@Y=pKzsr0x0=DEjve$$?#Twp6;TZ&+a#3OV~RtJ7@ACX z^4K{N+@L`>q`P?AH4@yKmC}S_G7`K+4Y#JL9&bq-Nh5w;=A{?VcmcYdmDAl6caH>c zHpKNM$+_OlLn;O)sK+(MWKN$Au%o5gxA_3GP(CW9hIS zccvHXaU{Kjwo68W_wu-SB)CKH?@0IZw)ZLwhraQJ66>YZTsoQVL9BZkm$$@vxfx7f z6ncHpkNVw9rUh-EV@gnM^{%#*pf2Qf8E<@1T82-i1CwbNBf1*htr6WCf$l}VzXU_P z1U$v^`~BWkarU$z^ZbKiwosT+T|wYb%^VqN`=Gug9fZO^+S}cvJXKfH8B5 zeOwn-ob*kmF*A=F8(PRW80&x6_qU14fR4>bK*v&JTdU(XCwZq`rKEy(C0)q63PsK- zCbcx;wVwFHfw;t@1R)ks26*(21e`PVIi#bgT zc$h^jmrOl&flK!Dil;j(K4yyLdhGT~osi+P0W@)dqA&WGAN07mu!6rGmL>HoIVWC$ zzs9=dvD2buj5Pb=y>P9R#EPJ#7laQa(H-wgYp_FcH(K4$l3HJst|XfP(Xwi2e!E}o zoS4~6SBte>ur{A-e8sW=M8`^_!%qRyO!Sf5Dt|2KS{W)0L#2hGl4EEkR~TS?W!haZ z7DkjC9W-_KMdu_Iqv!KEJr@$XEg33$2~Dqs+(h}ZA8cDHDa40xSqv*prDdaHxzdsU zp#_6Hdk&%J$xh92YkY0Gi#dtbfys0msJ1nBv}CbEve>n{=7ise=DhKoHRrKh zQfGa?XI0hg$j6)+!UcszT)B%A)9eW69o{CsUI63A30+LY^1sQn z%0#M-T1%KU36qIj<5xOSIEyAR8V-zeVvr@4EwWMHzUb#e{|!soFZGeWKF~+1`e(hw zj&Jm06<_W}qCeA18uBMS(D3!1v@83$9s0vnRXLM)sTC=>^%Zb*H{q(e;rIaQ+r`On9L8CC2~C$K7bcg^rh6z}mRyuvHk)3aT$1cgUYG1iE{{ve z1@W87DSseI;~SDBzA@PqA53<}Hzh;yTd=R2lO6F7Cfnm%l5O#=@ol7+uV>v+j&COs z+>4!+c$@=Jr zlb-lpNj-iyaq^C&7QY97|0DRsA0<6`Ctl@;k^H;R_IHzK-jM{f`|*1dFaEJSx%!Lk zBq|<^k2|dey9yh9ExYQ&uF#og9F32* ziMk7-UiKZUX4CHY7S;y}$xZHaRg)tg_jQ$Up|<> zjGq%rnxuXR7Zl&CjK{fY+%D=I*ItP!uMW#k2+N1hHhBam{oOVD z8mI@?Y&KAz%0UhI;Zpo*^(D13vSvkAUt|rRS*5{-Ka>wQRG(F^c+E-uy)~N+)aPVAWfG^|#?ByR6Umh;Le6jfQbH$gRFTOldeEEmPmw!}z`NzeV zFBM<@N%7?uiZ5TzUrceHh&vSL!TyelZ+BKaxuK)SBO5y^o-R}vJ08tZ7PqXe;h(P6 z@QcNUylf+Wsn`$*vD=@Dzfx=n3l0CQ*ib4o{PSW%xzO;-#fIXD$BGTb5&xptP$_`= zm&JxI*I)-o-_QY4w^J~8fb{NHvvKDVgi`z_G~QPE93KU%@7|f5pDy?VSxctWWo;Lb zz3i>kY~Wt}e+%xp0=TUhAPf9eJ%PN#iUuR-><;l3cCz`q%jS0$Tn6$)gV8y(pwmiPZWUk>CodWe`lN)*!#=;stgA@O$x-esqZk%`izd@z-G@uM{CV;{`m|Q-6K@YyORfj-5w4 zLOK|I)yEWr0~dJNW8PFFY?NCYBISI;#X&MO5(29>AGWwc_SDwwz5&{P+i$2g39}`g zMA^D7wmxCzPHePS&(>!)FqwJTMez&FKFp}QI`Jt~CzAk?WH6KmoA>=?fN{{BX%4zS z!S22`kV(Nbw-9nC8y&|PrRa%()2P;LN}Z<{0QMT??CwdP92JzaGgi{MQ0NZOAV>#4 zMsg_$Ael*U-JwV}N3O`)4h$-YSp3)2OKvu7#A!B2B11Mw#ip~VzoH5{*^~~VvpP;_ z_AT@r=+|WoW=PLHy}A#@aTEM-V}~>U;0{-0tF>9&tD-@4<6s&Zs9}3`RfBs3;-ZxR zK*>OoT#Az=<7CH)k{{iPebI_E;zkKz=s9;9Br6@c_+m{gEfa(!kc{ZcO$gy}olrXl zUF(hTptlCm1yUvf6h*r{hT14toU>3v5q10&HhcBD?b2y>(Hj8J2)*Q56a9$nm>2di zj68E4X<7V6GTN>|QnQknG!9ux8OjFF%i)zLQLuo1!R(GA=u^38(nQ)+=QKdIqe_YALB0Q57KAKx$$!_PkPMLR88Zt4+2;s2GVf3pd4klVA5_Xt~a2OsxdwhFK zE`e-Vo|JhAnjinJ`2dX3m?+!V(Kc+cjvx|cX8%Urb8R0X=PJfG$|eGx)M*SOBu`HE z^r&P@^RrpkY)^oZF3l&E+3XpQH`oAg*&kQ$y3xmdM~KqfqiurK>WDJ*4{W3BZ~Hf< zrMmc`Mz9-w3@(d*O$v=FW3qIFOFxDw{(TS^#|D~PbL>+NyqnR=vCkC85|?Z&GA{T| z)fyrZ?b?m-f^S93&xdbi35NijC~_Zb+w2HiQAQdNNN5FyxIl#<$t?Y@(d0<7UL$j3sm#G9hjsYQ3!S#vP_#@MDvY-Xq| z17hTWGYz=?V>fi9H;_l82yPB=HRxcQ;2bO<3{J}`(4$y2#5q})!T!82czC@x2)e>- zXueTZ`(0Js2n}iOPfKloD#v906UUvG%z;`o$G(8%Knyf+PX;%!;U$?i*z!@~^1+TE z+_1W|{BM%OYJ2ZN7dFg$4@S{%l`Jzzn2^{}>hRJ3$&w7{v38u5Yj@5=oCy?z7`jP> z<9v-OsRt8J6dV*v5;vheSxLQfuW8mSCmABp3LoxT=^uP03#qr7%k$po@0W4nb?^#c zf0pT)_Y}m-yf+|OSK4pt#Wp##3}}jQ8K~T7!oH60U z(``jI#>>`$@zT>M3l%#2q|8OYM9SNP8bFk?3F9{bmv}dvvp$z@Gfw8xH3bH+O&>ZH z4Vck?0jvue9GO_qfLam}-HBjoaEbUQ(!DnH2p$<5aGc8l5m7jUC!*AGwq&6I5V>A^ zfYXkH^115{ZI1B8-#oc65{$ddf34xfvbQ#aGcKN3j9?STO3U`Vq|2gl*Rp8LHOom% zBcP|^v4sdGubj$aqc~9_tplDG*kuz<9^ET0)msLy;-Wje1)7Bu04VQ@J{Wiau(|yI zQFua-^w^2gm~P6f3jWm$p(od7EC++xqgPbgS2Xf7%zw{oQ@D2Sw2TGO&-$;(1IM9r zHF?aSZSuKc$nu#k+LPOdrny{|oPRS5X-zcxTwuvdQ$*$EJ_(!o1La_17={c7b-NHA ztqeh~!YKe$I-_@#XabE|QV}JNj-(1DpvQ{4l5Wcj8B!5Q zvOJp~?x*>-Kf2z7qFj;J;1cX9>cBFyN?&1k6mgCJnW5<8d$})U$z(j$@H=j8%S)~H z58QjvzeVmjgNA2^8bKCQ7fohoX7#*z2jMMTY?KypZ=quunFD5>lqS`*fU)1dQMT@xb3&pC28&r~wo#fxS~g*S5x=zj-EY0KwP#H!?xBJ|rsJVE;W z5bPI*=Y|^HN)EfJ@18mz?9GCO?Eb_wi*-p!3K{B)8(bS!`oZj3&&Lf94pg#D){hJm zJBGTvH^N1-tlb)w9a^jquP9($X(j*0gI!dt0gFPtL2M`W3CtEyPU^5qti#+_Qod<#TL7%dEfC|j=J*V2lzfJ(|hL{#j@j^45}q|MNUqFrf-Uv1 z4<}+$Ok`TlhGeP`?>x^zwg!?wJFi;PdpChBfglqP5}N~JkVGx7z?Wy7h#(g)v9|W2 zDsm3xSMMC!oJqCcsr)oNP*hDOeY4%DMP1#tj_0PxLXSD(6nDT6h*ts2WNtPiedk9S z&#>n)PoEAH^lop$wmPCAs1*Nv^ z(Bf7J9s?#8rf;f+j-90 zso8}DiylHFr=%x*z_?rSg3U;?*gRe|eQUjz)AYg+EDCQEO(232yxt22YB+dlh_R4? zt9yy)gfcm&OJxpU`#~tBfVnAtB{hQ_4jxb0m(WuE%}ZAWPozB0KByCn(pAA@ypdnj zC$p2Y*;8Nm`WMRcBf(dw6!~AvpAV+l*#zm!Ol-EVC&8E`BJ(!Yh-Pt5P~EL&hxviD z!4?xRhJ*W444Q<5Z%y3RQ{#eS>6RWm3F!?`OS3&CXR+$a6m8T)Y3i9JQs>E2%5zwz zRwBi}rN`~gpgOW6met?%k^R!a9@I;_@&ff(ilZQ~q5zf}psQ0*US?ZaW;JQ+a1qV5 z@a%ieJC$3so8xk{v+#xIN$Iv8+){$et)NN5h=f?D)menF62g-ZN}GTfV>HRAoV+Iw zYLf_i3l1Qzy=-G6yrlHxY*<+~Gj%C+0qgf37wuCnOu?j;Wp&(Z*Td z(aM9l;uXVec#;Gshjf1`CZR9)rx0ntKan~urt%ZA|FwjSnu|$rm`ABmg;C7P`~quG z7F%Lja6t6FhylpKFao+XX)N-^A?K?%nBT`jvDfxX;QX!6RuX z63Grr$__CjC4x#?D1L$pD-vWB+Y<6aAquiPEYvZ1wi|^6Q=_z_f%-E*HVR$jofs_E zNodcl6JjT`VRA!9$ycG|?9RGUfy=x)NuJFI<&u7zn#-*Q>;*6Yg3h1{4x_R#!>9ud zA#ng-7!vEjLSPgf($SWGLfcoM_N7O}JL6{+7cI)gN7R#i3v(d$XR^Si(A+bGYtrV* zLAUQ_*5@_}nsc$8j`eKUnR0Hucq&igl}d^G{DTI#xkKQY6}+BoD3NffcZK#!&Kb4{ zj5A_GG=n{|6q2=ZkuWh|A`4!z6YbaX&|+@0sg4cpv8`nPNsG`ExIr2Om5T_ssm#~U>?lguUH06NOol6^*`}l$z|3X`K2&NGNb8`SuaD@PXBO@iMBHR_N=LT= z1en)1F$=29546xExq3(B=ZirYFi- zt%e!fjW`*%yg^)UdBbM8cZt7CI<7~B|}CotsQN0X=M}5T$+1c z9l5mCv~y`Kfe~FHmo8f_Eozc7ximS%0yLD0xinPaiuA>)%A38bbk3Pe${j5^!4Pk4 zdim;&z{~WW(|3cJh~Wae6?hg zT~u&3?{Us1`ypJ2@h+ZZE25h15D2BDnRjvUaC#MNK=Usq7+s}PKwhf2^@kOrIztsw ze!uR4c9ePWl~l2`jKYZl7(ThLeQ7P%QSd4c3-Wp3Lf{dKql*R7(m-xT z%XM3Z7qwJktgzy8T1sx))Y3{zOUZZ85NWBYg;w9DrKYo0ZHIfQLxz@CoR$h@Q%h|% z*Iw~8*LQ6#1^=pAiZwVb#Q+yD=VdECI8kb<=b&@KbZ{=kEdvXR3eHYNwYf<12VBJ0 zbOX~>u%WBinihuey{)ShO;hl2_YF+es8WDf>&vQk!u02taJ873v5bH1dY@Y&_U`c{^3w%s%5$JqzhMGV!H{=cFvqHyWq?tIrFNV zx$A4roG|X3d2^{J*UW_2{!=%cxmJX72`(R$Kc_jzH~?{wSIPRM`qEk!P0b}3nu9%i(y+6Cat&KunHm`a3(k&XVxz1Uc(Mm$rx8Pn<4nkC%6W_l$pNFh zmfh5v%4@NH5a+l;d5I3Fk120A%FAA9Q*~>my0umw;(D6uR`o+3tvtlk)Ar+}x^z<> zQdC{(aZ`1z**INtstfr=)kQojRhLbITy-hgIyH|0sGm!6BsnIF_|V%GTd|%HB3Nz2 zCORX;R4F*kU9lA_r$V!-EWSi?uxZ&=EOugBvFO3`Lz<_!jY6}zK{*mDaoFmA)u_omDi?8SaHl{)y z3A`>g*;r?@4B;nqM2d7px3S=b4ry%dXD84&PM3BQ11Sj*yR{pK$B<8qBz@o13W^F|S_AFopQ8c;T9$U>t4-aBQG8huPtEtV zxyDfR)XbNR*{M6Q;|8g?908NzSU>mFG;C6X_7Tu^B_?^BY**PI(q_e^`w!?IBx~ys z3AyZBI^ldVC1)y}+=Yp+6>~n?j>~L@fgN)@Eg-YYVRDh6uv(T8*~+f~+G)*AJ)zbe zqQE`BJ)|oYxk|Nxt+pmC04vZbJlxQu@MEwey85T7Y&1z{Tuvgbi8cZ{R-=Ue<@k+JB7R|S?=hxIz)5LW& zRnBkOLJ>)ukmaeIVzE#p5lMoDM(%tOXESZk8rv-tnJTs_=gY+yc?{@t4>=BZp~`S6 zZ@>u27!+F9$QVGjGGkaZ0~ay2PQ(doofs4|2Dv+zD)=11>!=vMv!MzZk0W#Q~gD1UG(#%BJ&icyz(EDINXOc|AL<_}0W zUoqk=mf?_eb0+dArVv((rxv3{l1r&c>RK#UppzP~vB=&s9q-+l`0)GTH1)#+E;QM) z4FTbU>1?}@QS>f-8L6*5tRD3D=cnP?453;km1quMz9QSa9i*5qVLMZK!Gmn?e6Lz?DyE@x04y}-* z5bNIcU@9ouWgd4RBpkcC&L9ll-K&zvW_ltt)I4-KSm?E(b$|q#DCa;hT_akYfs5#q z#lc*Y@kQdS)$y}t3K|L*x)fz4ZgLN}(xA2@tS-@&5G(E0MPn-s>*kb|_UPt|l~}9n zb*26MV45pkt!w1gdL2KB#>5^YX@FsRYKIJVb042cu)VyDelF0sj%@JK%v4*qqexhF z%+=y0{LrBTJJij}6%2)f%RDanfmx;CT2Cj3l)`I0lyx~SqX|A6=X0*EE*N42)O*pl z0{xE8JsP8Utjvh$vNV~15}Mot2})pLc2BXMyLQ?8ixo1kF4ytyV!Z;iu9wJI*?LAD zIJaQc;j>7Z%|7tKd#ls34iJE!9c<|ctb;es7)x%nnI>y4RiYatfv!2o7Fr#*8G6<8 z%XNC_YXdy=TX;NBpX_97*mSFOtW`SF1jXb^v)RC0LnjznBDnq+88YI>LNN1avnW&-HwN>A#tj3r{=Q@O*f`L;A4nL+Bb8SLBV@Oz%IWhHo+uW zqysNY;+B@nXX(Jz0Jjw`+(328CRc&n<{|s#?|$d>2F6KyxCubXcTcy<;(wyi^FBu*Q zl=g4rWlyH@|M9b@Q++Rn^0)oy7ks1M#1l#}wG`09l4F90Kl{yNm_Z+$C;94TH{Oz69hs z1K_Ui3K!fT4z6}bhVh^A8bnh@w(1Lm<=|DdyT8lBkJ5&JUvl4+QMSq~w1^1Iz|o3e z>fy}lhWj^pWM2%Iv+@XyD32a2cfF_r(A|MO4tP;Fip1BB;Avj+k(KI@CO-+)E^|I2 zHKm?Kaz7F+ymfie#%3FlkJX5$yN>;2W@Z+S@>9|L>hiuTm-V^P^PcVTyiFy~d)q5?e7x85 zuA`s+_N)IbuP}gq8Z%8_KOe)-%`STUi0yl+dlJ0*$yz;|??+T&KP_#)A$|DR*qk>% zao36QBZ-wyohZJ|AJcC$x9Z$0KmXjW(#!M=zct_ppVR);&+xkev$gxYxCcm zw(_B|`H92%k5pgR8YukNyUxvDr?%dw_Kg$=pStpj{I&gq(AQq8pQ|pu7k+2@ItO^I z*1~+RUlT+Jk!!*dzs>=QF>>vGFm>(57AfoYk`&GX#`@jBaP{bVq`XoG+V_pT5`^`8 z0OHCkUJ1ndJxm$bW`@(!>%H6Gv2f++=oR~}D5~ephi`w!=)QeYq0xo8v5AHGn-AZ3 zBX!rRR^NwM+ztbg4ceZ43cwrOJ9Aj_3G2f>y#ns(PPkMw;XZoKaBrAj0r-abPRObeXrnpq z*6h!P7dK3-ggvnWHZ?8S)2qSWx3_J?SK>W#Km7!KZ!fm(+gETU61DT^&#vEZtl6(# zTNfTubMW@B-w#%~e(zns-$JwBz3cabJr3T(>-U>%_Iq;ue$&l zZT7o${eDN9{TAr=j)iOVYxAQMCyvfYmt<=XxbdT-htHfDJ2bJl4{tL%e{ABo{V=_C zg%h4v#~!~#--lQ9zlyQ?-##oKp#IO&_o>zTpTq%-uk62xq;+NgYeq*;&fw+v-%GTp zztQNqf&N$XK_A=nUqQL~zm6yl$mg)I8jdT9IA%ss=tIk~x%q!S$0vRa!#hODeG}UF z@ai$;4qEV+&~k+T9l(i&vFRc?;*SPtzKax}2grWjZ#dz~2PhxP>u;reI4|Ep`B+{) zLU}ANpQJpWm+z*$keBbHJdv00r#zXLAEZ2;mmj8lJTE^=`Dk8#obr*p{58t@)6b`C z-hF(U^NuO^^Vz^>BOm>}lliINCO*Y}n|a^DXDgo-a+{x6O_fa6dw?h0`g Date: Wed, 10 Jun 2020 06:11:00 +0200 Subject: [PATCH 34/48] Break connection between tangled files and compiled files Fixes #61 --- .github/workflows/main.yml | 17 +++++++++++------ INSTALL.md | 24 ++++++++++++++++-------- Makefile | 24 ++++++++++++++++-------- README.md | 10 ++++++++-- 4 files changed, 51 insertions(+), 24 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6138307..e15393f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -58,7 +58,7 @@ jobs: run: which python - name: Install Python dependencies - run: make pip-pybind11 && make pip-connexion + run: make openapi-deps - name: Run Python example run: make test-py @@ -66,7 +66,9 @@ jobs: - name: Start web service in background run: | make run-webservice 2>&1 | tee ./run-webservice.log & - sleep 2 + # Wait for web service to spin up + sleep 1 + - name: Test web service run: make test-webservice @@ -104,7 +106,7 @@ jobs: run: which python - name: Install Python dependencies - run: make pip-pybind11 && make pip-flask && make pip-celery && pip install httpie + run: make flask-deps && pip install httpie - name: Build shared library and link to it run: | @@ -113,7 +115,8 @@ jobs: - name: Start web application in background run: | make run-webapp 2>&1 | tee ./run-webapp.log & - sleep 2 + # Wait for web application to spin up + sleep 1 - name: Test web application run: http --ignore-stdin -f localhost:5001 epsilon=0.001 guess=-20 @@ -130,6 +133,8 @@ jobs: - name: Test Celery web app run: | + # Wait for web celery app and worker to spin up + sleep 1 http --ignore-stdin -hf localhost:5000 epsilon=0.001 guess=-20 | tee response.txt # Parse result url from response RESULT_URL=$(cat response.txt |grep Location |awk '{print $2}') @@ -174,10 +179,10 @@ jobs: uses: mymindstorm/setup-emsdk@v4 - name: Build WebAssembly module and link to it from react/ - run: make build-wasm && make react/newtonraphsonwasm.js + run: make react/newtonraphsonwasm.js react/newtonraphsonwasm.wasm - name: Start web server for hosting files in background - run: make host-files 2>&1 | tee ./web-server.log & + run: make host-react-files 2>&1 | tee ./web-server.log & - name: Run tests run: make test-wasm-react diff --git a/INSTALL.md b/INSTALL.md index a86041c..89f7a51 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -32,7 +32,9 @@ $(ENTANGLED): entangle entangled-list: @echo $(ENTANGLED) -py-deps: pip-pybind11 pip-flask pip-celery pip-connexion +flask-deps: pip-pybind11 pip-flask + +openapi-deps: pip-pybind11 pip-celery pip-connexion pip-pybind11: <> @@ -46,25 +48,25 @@ pip-celery: pip-connexion: <> -cli/newtonraphson.exe: cli/cli-newtonraphson.cpp +cli/newtonraphson.exe: <> test-cli: cli/newtonraphson.exe <> -cgi/apache2/cgi-bin/newtonraphson: cgi/cgi-newtonraphson.cpp +cgi/apache2/cgi-bin/newtonraphson: <> test-cgi: cgi/apache2/cgi-bin/newtonraphson <> -openapi/newtonraphsonpy.*.so: openapi/py-newtonraphson.cpp +openapi/newtonraphsonpy.*.so: <> flask/newtonraphsonpy.*.so: openapi/newtonraphsonpy.*.so <> -test-py: openapi/example.py openapi/newtonraphsonpy.*.so +test-py: openapi/newtonraphsonpy.*.so <> test: test-cli test-cgi test-py test-webservice @@ -104,15 +106,21 @@ run-celery-webapp: flask/newtonraphsonpy.*.so build-wasm: webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm -webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm: webassembly/wasm-newtonraphson.cpp +webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm: <> -react/newtonraphsonwasm.js react/newtonraphsonwasm.wasm: webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm - <> +react/newtonraphsonwasm.wasm: webassembly/newtonraphsonwasm.wasm + <> + +react/newtonraphsonwasm.js: webassembly/newtonraphsonwasm.js + <> host-files: build-wasm <> +host-react-files: react/newtonraphsonwasm.js react/newtonraphsonwasm.wasm + <> + test-wasm-webassembly: <> diff --git a/Makefile b/Makefile index 110c5ab..e565444 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,9 @@ $(ENTANGLED): entangle entangled-list: @echo $(ENTANGLED) -py-deps: pip-pybind11 pip-flask pip-celery pip-connexion +flask-deps: pip-pybind11 pip-flask + +openapi-deps: pip-pybind11 pip-celery pip-connexion pip-pybind11: pip install pybind11 @@ -28,26 +30,26 @@ pip-celery: pip-connexion: pip install connexion[swagger-ui] -cli/newtonraphson.exe: cli/cli-newtonraphson.cpp +cli/newtonraphson.exe: g++ cli/cli-newtonraphson.cpp -o cli/newtonraphson.exe test-cli: cli/newtonraphson.exe ./cli/newtonraphson.exe -cgi/apache2/cgi-bin/newtonraphson: cgi/cgi-newtonraphson.cpp +cgi/apache2/cgi-bin/newtonraphson: g++ -Icgi/deps/ -Icli/ cgi/cgi-newtonraphson.cpp -o cgi/apache2/cgi-bin/newtonraphson test-cgi: cgi/apache2/cgi-bin/newtonraphson echo '{"guess":-20, "epsilon":0.001}' | cgi/apache2/cgi-bin/newtonraphson -openapi/newtonraphsonpy.*.so: openapi/py-newtonraphson.cpp +openapi/newtonraphsonpy.*.so: g++ -O3 -Wall -shared -std=c++14 -fPIC -Icli/ `python3 -m pybind11 --includes` \ openapi/py-newtonraphson.cpp -o openapi/newtonraphsonpy`python3-config --extension-suffix` flask/newtonraphsonpy.*.so: openapi/newtonraphsonpy.*.so cd flask && ln -s ../openapi/newtonraphsonpy`python3-config --extension-suffix` . && cd - -test-py: openapi/example.py openapi/newtonraphsonpy.*.so +test-py: openapi/newtonraphsonpy.*.so python openapi/example.py test: test-cli test-cgi test-py test-webservice @@ -87,15 +89,21 @@ run-celery-webapp: flask/newtonraphsonpy.*.so build-wasm: webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm -webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm: webassembly/wasm-newtonraphson.cpp +webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm: emcc -Icli/ --bind -o webassembly/newtonraphsonwasm.js -s MODULARIZE=1 -s EXPORT_NAME=createModule webassembly/wasm-newtonraphson.cpp -react/newtonraphsonwasm.js react/newtonraphsonwasm.wasm: webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm - cd react && ln -s ../webassembly/newtonraphsonwasm.js . && ln -s ../webassembly/newtonraphsonwasm.wasm . && cd - +react/newtonraphsonwasm.wasm: webassembly/newtonraphsonwasm.wasm + cd react && ln -s ../webassembly/newtonraphsonwasm.wasm . && cd - + +react/newtonraphsonwasm.js: webassembly/newtonraphsonwasm.js + cd react && ln -s ../webassembly/newtonraphsonwasm.js . && cd - host-files: build-wasm python3 -m http.server 8000 +host-react-files: react/newtonraphsonwasm.js react/newtonraphsonwasm.wasm + python3 -m http.server 8000 + test-wasm-webassembly: npx cypress run --config-file false --spec 'cypress/integration/webassembly/*_spec.js' diff --git a/README.md b/README.md index e028021..cc1565f 100644 --- a/README.md +++ b/README.md @@ -1179,8 +1179,14 @@ ReactDOM.render( Make sure that the App can find the WebAssembly files by -```{.awk #link-wasm} -cd react && ln -s ../webassembly/newtonraphsonwasm.js . && ln -s ../webassembly/newtonraphsonwasm.wasm . && cd - +```{.awk #link-wasm-wasm} +cd react && ln -s ../webassembly/newtonraphsonwasm.wasm . && cd - +``` + +and + +```{.awk #link-wasm-js} +cd react && ln -s ../webassembly/newtonraphsonwasm.js . && cd - ``` Like before we also need to host the files in a web server with From 32c63f883c8f056623665d7e4875c652f46083d7 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 10 Jun 2020 06:23:22 +0200 Subject: [PATCH 35/48] Shorten js test names + update phony make targets + host-files make target renamed to host-webassembly-files --- .github/workflows/main.yml | 6 +++--- INSTALL.md | 14 ++++++++------ Makefile | 10 ++++++---- TESTING.md | 4 ++-- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e15393f..3b9fc17 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -159,10 +159,10 @@ jobs: run: make build-wasm - name: Start web server for hosting files in background - run: make host-files 2>&1 | tee ./web-server.log & + run: make host-webassembly-files 2>&1 | tee ./web-server.log & - name: Run tests - run: make test-wasm-webassembly + run: make test-webassembly - name: Upload log of web server if: ${{ always() }} @@ -185,7 +185,7 @@ jobs: run: make host-react-files 2>&1 | tee ./web-server.log & - name: Run tests - run: make test-wasm-react + run: make test-react - name: Upload log of web server if: ${{ always() }} diff --git a/INSTALL.md b/INSTALL.md index 89f7a51..68dfc5c 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -17,7 +17,7 @@ All the commands in the [README.md](README.md) and [CONTRIBUTING.md](CONTRIBUTIN ```{.makefile file=Makefile} # this Makefile snippet is stored as Makefile -.PHONY: clean clean-compiled clean-entangled test all check entangle entangle-list py-deps start-redis stop-redis run-webservice run-celery-webapp run-webapp build-wasm host-files test-wasm +.PHONY: clean clean-compiled clean-entangled test all entangle entangle-list py-deps test-cgi test-cli test-py start-redis stop-redis run-webservice test-webservice run-celery-worker run-celery-webapp run-webapp build-wasm host-webassembly-files host-react-files test-webassembly test-react init-git-hook check UID := $(shell id -u) # Prevent suicide by excluding Makefile @@ -36,6 +36,8 @@ flask-deps: pip-pybind11 pip-flask openapi-deps: pip-pybind11 pip-celery pip-connexion +py-deps: flask-deps openapi-deps + pip-pybind11: <> @@ -115,17 +117,17 @@ react/newtonraphsonwasm.wasm: webassembly/newtonraphsonwasm.wasm react/newtonraphsonwasm.js: webassembly/newtonraphsonwasm.js <> -host-files: build-wasm +host-webassembly-files: build-wasm <> host-react-files: react/newtonraphsonwasm.js react/newtonraphsonwasm.wasm <> -test-wasm-webassembly: - <> +test-webassembly: + <> -test-wasm-react: - <> +test-react: + <> init-git-hook: <> diff --git a/Makefile b/Makefile index e565444..8c73d69 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # this Makefile snippet is stored as Makefile -.PHONY: clean clean-compiled clean-entangled test all check entangle entangle-list py-deps start-redis stop-redis run-webservice run-celery-webapp run-webapp build-wasm host-files test-wasm +.PHONY: clean clean-compiled clean-entangled test all entangle entangle-list py-deps test-cgi test-cli test-py start-redis stop-redis run-webservice test-webservice run-celery-worker run-celery-webapp run-webapp build-wasm host-webassembly-files host-react-files test-webassembly test-react init-git-hook check UID := $(shell id -u) # Prevent suicide by excluding Makefile @@ -18,6 +18,8 @@ flask-deps: pip-pybind11 pip-flask openapi-deps: pip-pybind11 pip-celery pip-connexion +py-deps: flask-deps openapi-deps + pip-pybind11: pip install pybind11 @@ -98,16 +100,16 @@ react/newtonraphsonwasm.wasm: webassembly/newtonraphsonwasm.wasm react/newtonraphsonwasm.js: webassembly/newtonraphsonwasm.js cd react && ln -s ../webassembly/newtonraphsonwasm.js . && cd - -host-files: build-wasm +host-webassembly-files: build-wasm python3 -m http.server 8000 host-react-files: react/newtonraphsonwasm.js react/newtonraphsonwasm.wasm python3 -m http.server 8000 -test-wasm-webassembly: +test-webassembly: npx cypress run --config-file false --spec 'cypress/integration/webassembly/*_spec.js' -test-wasm-react: +test-react: npx cypress run --config-file false --spec 'cypress/integration/react/*_spec.js' init-git-hook: diff --git a/TESTING.md b/TESTING.md index 1d0ea10..10ce01a 100644 --- a/TESTING.md +++ b/TESTING.md @@ -83,11 +83,11 @@ describe('react/example-plot.html', () => { The test can be run with the one of the following commands: -```{.awk #test-wasm-webassembly} +```{.awk #test-webassembly} npx cypress run --config-file false --spec 'cypress/integration/webassembly/*_spec.js' ``` -```{.awk #test-wasm-react} +```{.awk #test-react} npx cypress run --config-file false --spec 'cypress/integration/react/*_spec.js' ``` From 532ca807b5179519243da6a695d7936d15138faa Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 10 Jun 2020 06:31:38 +0200 Subject: [PATCH 36/48] celery is needed in flask chapter --- INSTALL.md | 4 ++-- Makefile | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 68dfc5c..5aedc95 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -32,9 +32,9 @@ $(ENTANGLED): entangle entangled-list: @echo $(ENTANGLED) -flask-deps: pip-pybind11 pip-flask +flask-deps: pip-pybind11 pip-celery pip-flask -openapi-deps: pip-pybind11 pip-celery pip-connexion +openapi-deps: pip-pybind11 pip-connexion py-deps: flask-deps openapi-deps diff --git a/Makefile b/Makefile index 8c73d69..fdf5d1f 100644 --- a/Makefile +++ b/Makefile @@ -14,9 +14,9 @@ $(ENTANGLED): entangle entangled-list: @echo $(ENTANGLED) -flask-deps: pip-pybind11 pip-flask +flask-deps: pip-pybind11 pip-celery pip-flask -openapi-deps: pip-pybind11 pip-celery pip-connexion +openapi-deps: pip-pybind11 pip-connexion py-deps: flask-deps openapi-deps From 14de6f15c6ad37f13b08947b880f67b266d2ca08 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 10 Jun 2020 06:34:19 +0200 Subject: [PATCH 37/48] One more src/js -> webassembly --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b9dfbd8..650519b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -50,7 +50,7 @@ jobs: run: ./build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output make all - name: Restore wasm # As we want to analyse files in git not files we just build - run: git restore src/js/newtonraphsonwasm.js src/js/newtonraphsonwasm.wasm + run: git restore webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm - name: Relativize bw-output # Build wrapper runs on CI server while sonar-scanner runs in Docker container need to adjust paths run: perl -pi -e 's@/home/runner/work/cpp2wasm/cpp2wasm@/github/workspace@g' bw-output/build-wrapper-dump.json From c8e3007cbf5a17e193dd13d1c52f738ffb797cf2 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 10 Jun 2020 06:38:46 +0200 Subject: [PATCH 38/48] Update sonarcloud exclude --- sonar-project.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sonar-project.properties b/sonar-project.properties index a8284af..04c65c9 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -2,8 +2,8 @@ sonar.organization=nlesc-jcer sonar.projectKey=NLESC-JCER_cpp2wasm # excluded files generated by emscripten and 3rd party dependencies -sonar.exclusions=src/js/newtonraphsonwasm.js,deps/nlohmann/json.hpp,emsdk-cache/** -sonar.cpd.exclusions=src/js/newtonraphsonwasm.js,deps/nlohmann/json.hpp,emsdk-cache/** +sonar.exclusions=webassembly/newtonraphsonwasm.js,react/newtonraphsonwasm.js,cgi/deps/nlohmann/json.hpp,emsdk-cache/** +sonar.cpd.exclusions=webassembly/newtonraphsonwasm.js,react/newtonraphsonwasm.js,cgi/deps/nlohmann/json.hpp,emsdk-cache/** # Ignore C++ until sonar.cfamily.build-wrapper-output is configured sonar.cfamily.build-wrapper-output=bw-output From d93a2c71c5367fb8d3dddc66aeac5a4c99cccb62 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 10 Jun 2020 06:43:47 +0200 Subject: [PATCH 39/48] Unique names for artifacts of each job --- .github/workflows/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 650519b..5ce564e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -121,7 +121,7 @@ jobs: if: ${{ always() }} uses: actions/upload-artifact@v2 with: - name: service-logs + name: openapi-service-logs path: ./run-*.log flask: # The type of runner that the job will run on @@ -190,7 +190,7 @@ jobs: if: ${{ always() }} uses: actions/upload-artifact@v2 with: - name: service-logs + name: flask-service-logs path: ./run-*.log webassembly: runs-on: ubuntu-latest @@ -216,7 +216,7 @@ jobs: if: ${{ always() }} uses: actions/upload-artifact@v2 with: - name: web-server-log + name: webassembly-service-log path: ./web-server.log react: runs-on: ubuntu-latest @@ -239,5 +239,5 @@ jobs: if: ${{ always() }} uses: actions/upload-artifact@v2 with: - name: web-server-log + name: react-service-log path: ./web-server.log From 872a3a2971ed62b516ebc49dafba0c625d114a67 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 10 Jun 2020 06:56:33 +0200 Subject: [PATCH 40/48] Document react/worker.js --- INSTALL.md | 5 ++++- Makefile | 5 ++++- README.md | 6 ++++++ react/worker.js | 24 +----------------------- 4 files changed, 15 insertions(+), 25 deletions(-) mode change 100644 => 120000 react/worker.js diff --git a/INSTALL.md b/INSTALL.md index 5aedc95..6c5e349 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -126,7 +126,10 @@ host-react-files: react/newtonraphsonwasm.js react/newtonraphsonwasm.wasm test-webassembly: <> -test-react: +react/worker.js: + <> + +test-react: react/worker.js <> init-git-hook: diff --git a/Makefile b/Makefile index fdf5d1f..47b548e 100644 --- a/Makefile +++ b/Makefile @@ -109,7 +109,10 @@ host-react-files: react/newtonraphsonwasm.js react/newtonraphsonwasm.wasm test-webassembly: npx cypress run --config-file false --spec 'cypress/integration/webassembly/*_spec.js' -test-react: +react/worker.js: + cd react && ln -s ../webassembly/worker.js . && cd - + +test-react: react/worker.js npx cypress run --config-file false --spec 'cypress/integration/react/*_spec.js' init-git-hook: diff --git a/README.md b/README.md index 87d76e9..4d539d4 100644 --- a/README.md +++ b/README.md @@ -1106,6 +1106,12 @@ Like we did in the previous chapter we have to construct a web worker. const worker = new Worker('worker.js'); ``` +The `worker.js` is the same as in the previous chapter so we re-use it by + +```{.awk #link-worker} +cd react && ln -s ../webassembly/worker.js . && cd - +``` + We have to post a message to the worker with the values from the form. ```{.jsx #handle-submit} diff --git a/react/worker.js b/react/worker.js deleted file mode 100644 index 641ae7a..0000000 --- a/react/worker.js +++ /dev/null @@ -1,23 +0,0 @@ -// this JavaScript snippet is stored as webassembly/worker.js -importScripts('newtonraphsonwasm.js'); - -// this JavaScript snippet is later referred to as <> -onmessage = function(message) { - // this JavaScript snippet is before referred to as <> - if (message.data.type === 'CALCULATE') { - createModule().then((module) => { - // this JavaScript snippet is before referred to as <> - const epsilon = message.data.payload.epsilon; - const finder = new module.NewtonRaphson(epsilon); - const guess = message.data.payload.guess; - const root = finder.solve(guess); - // this JavaScript snippet is before referred to as <> - postMessage({ - type: 'RESULT', - payload: { - root: root - } - }); - }); - } -}; \ No newline at end of file diff --git a/react/worker.js b/react/worker.js new file mode 120000 index 0000000..e8d5ac7 --- /dev/null +++ b/react/worker.js @@ -0,0 +1 @@ +../webassembly/worker.js \ No newline at end of file From 12e5e7dc676a11a09555adb1b1e3de55fc28ce80 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 10 Jun 2020 06:57:15 +0200 Subject: [PATCH 41/48] Dont check react/worker.js for dups As it is a symlink to webassembly/worker.js --- sonar-project.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonar-project.properties b/sonar-project.properties index 04c65c9..f4dfe73 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -3,7 +3,7 @@ sonar.projectKey=NLESC-JCER_cpp2wasm # excluded files generated by emscripten and 3rd party dependencies sonar.exclusions=webassembly/newtonraphsonwasm.js,react/newtonraphsonwasm.js,cgi/deps/nlohmann/json.hpp,emsdk-cache/** -sonar.cpd.exclusions=webassembly/newtonraphsonwasm.js,react/newtonraphsonwasm.js,cgi/deps/nlohmann/json.hpp,emsdk-cache/** +sonar.cpd.exclusions=webassembly/newtonraphsonwasm.js,react/newtonraphsonwasm.js,cgi/deps/nlohmann/json.hpp,emsdk-cache/**,react/worker.js # Ignore C++ until sonar.cfamily.build-wrapper-output is configured sonar.cfamily.build-wrapper-output=bw-output From 4283086501fc6c990997c6fce2da2f768b72f677 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 10 Jun 2020 07:05:04 +0200 Subject: [PATCH 42/48] Updated CHANGELOG + also clean flask/newtonraphsonpy.*.so on `make clean` --- CHANGELOG.md | 4 ++++ INSTALL.md | 2 +- Makefile | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d181f90..dccad22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +* Directory structure ([#67](https://github.com/NLESC-JCER/cpp2wasm/issues/67)) + ## [0.3.0] - 2020-06-09 ### Added diff --git a/INSTALL.md b/INSTALL.md index 6c5e349..69c3836 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -22,7 +22,7 @@ All the commands in the [README.md](README.md) and [CONTRIBUTING.md](CONTRIBUTIN UID := $(shell id -u) # Prevent suicide by excluding Makefile ENTANGLED := $(shell perl -ne 'print $$1,"\n" if /^```\{.*file=(.*)\}/' *.md | grep -v Makefile | sort -u) -COMPILED := cli/newtonraphson.exe openapi/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm +COMPILED := cli/newtonraphson.exe openapi/newtonraphsonpy.*.so flask/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm entangle: *.md <> diff --git a/Makefile b/Makefile index 47b548e..558c960 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ UID := $(shell id -u) # Prevent suicide by excluding Makefile ENTANGLED := $(shell perl -ne 'print $$1,"\n" if /^```\{.*file=(.*)\}/' *.md | grep -v Makefile | sort -u) -COMPILED := cli/newtonraphson.exe openapi/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm +COMPILED := cli/newtonraphson.exe openapi/newtonraphsonpy.*.so flask/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm entangle: *.md docker run --rm --user ${UID} -v ${PWD}:/data nlesc/pandoc-tangle:0.5.0 --preserve-tabs *.md From 5e181dbe1ce47d2a6c2754b09d89096cc523c756 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 10 Jun 2020 07:09:48 +0200 Subject: [PATCH 43/48] Correct apache command --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4d539d4..6694349 100644 --- a/README.md +++ b/README.md @@ -299,7 +299,7 @@ ScriptAlias "/cgi-bin/" "cgi-bin/" Start Apache httpd web server using ```shell -/usr/sbin/apache2 -X -d ./apache2 +/usr/sbin/apache2 -X -d ./cgi/apache2 ``` And in another shell call CGI script using curl From 67e855f0e4e03dc203e34de1b0a7d459729cd576 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 10 Jun 2020 07:13:40 +0200 Subject: [PATCH 44/48] Updated CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1541ccd..545ad4f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,7 +81,7 @@ Ready to contribute? Here's how to set up `cpp2wasm` for local development. make entangle ``` -7. When `src/js/newtonraphsonwasm.js` changes, the WebAssembly module also has to be rebuilt. This will require [emscripten](README.md#accessing-c-function-from-JavaScript-in-web-browser). To rebuild the WebAssembly module run: +7. When `cli/*hpp` or `webassembly/wasm-newtonraphson.cpp` changes, the WebAssembly module also has to be rebuilt. This will require [emscripten](README.md#accessing-c-function-from-JavaScript-in-web-browser). To rebuild the WebAssembly module run: ```shell make build-wasm From 9637562fe841d27ed84b0920e10c68ac03efe644 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 10 Jun 2020 07:16:17 +0200 Subject: [PATCH 45/48] Remove `react/newtonraphsonwasm*` on `make clean-compiled` --- INSTALL.md | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 69c3836..6869430 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -22,7 +22,7 @@ All the commands in the [README.md](README.md) and [CONTRIBUTING.md](CONTRIBUTIN UID := $(shell id -u) # Prevent suicide by excluding Makefile ENTANGLED := $(shell perl -ne 'print $$1,"\n" if /^```\{.*file=(.*)\}/' *.md | grep -v Makefile | sort -u) -COMPILED := cli/newtonraphson.exe openapi/newtonraphsonpy.*.so flask/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm +COMPILED := cli/newtonraphson.exe openapi/newtonraphsonpy.*.so flask/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm react/newtonraphsonwasm.js react/newtonraphsonwasm.wasm entangle: *.md <> diff --git a/Makefile b/Makefile index 558c960..05105a1 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ UID := $(shell id -u) # Prevent suicide by excluding Makefile ENTANGLED := $(shell perl -ne 'print $$1,"\n" if /^```\{.*file=(.*)\}/' *.md | grep -v Makefile | sort -u) -COMPILED := cli/newtonraphson.exe openapi/newtonraphsonpy.*.so flask/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm +COMPILED := cli/newtonraphson.exe openapi/newtonraphsonpy.*.so flask/newtonraphsonpy.*.so cgi/apache2/cgi-bin/newtonraphson webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm react/newtonraphsonwasm.js react/newtonraphsonwasm.wasm entangle: *.md docker run --rm --user ${UID} -v ${PWD}:/data nlesc/pandoc-tangle:0.5.0 --preserve-tabs *.md From e4b10962dda91cc63eff2172086dd782d8e35306 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 10 Jun 2020 07:17:58 +0200 Subject: [PATCH 46/48] Use chapter dir name in anchors --- INSTALL.md | 4 ++-- README.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 6869430..f6b93f8 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -112,10 +112,10 @@ webassembly/newtonraphsonwasm.js webassembly/newtonraphsonwasm.wasm: <> react/newtonraphsonwasm.wasm: webassembly/newtonraphsonwasm.wasm - <> + <> react/newtonraphsonwasm.js: webassembly/newtonraphsonwasm.js - <> + <> host-webassembly-files: build-wasm <> diff --git a/README.md b/README.md index 6694349..654a42a 100644 --- a/README.md +++ b/README.md @@ -1195,13 +1195,13 @@ ReactDOM.render( Make sure that the App can find the WebAssembly files by -```{.awk #link-wasm-wasm} +```{.awk #link-webassembly-wasm} cd react && ln -s ../webassembly/newtonraphsonwasm.wasm . && cd - ``` and -```{.awk #link-wasm-js} +```{.awk #link-webassembly-js} cd react && ln -s ../webassembly/newtonraphsonwasm.js . && cd - ``` From 88fe8ac806fa8e3a638b1d49412410a95550382d Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 10 Jun 2020 07:28:50 +0200 Subject: [PATCH 47/48] Updated README.outline.md --- README.outline.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.outline.md b/README.outline.md index a3c91a7..cdb65c0 100644 --- a/README.outline.md +++ b/README.outline.md @@ -35,7 +35,7 @@ Introduce the example algorithm, as a CLI. # Python web application - web app v web service difference -- explanation of what is a web framework +- explanation of what is a web framework using @route decorator - long running tasks, celery # JavaScript web service From c81f7cacb376d83e4f8f2648d2665903d3d984d3 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 10 Jun 2020 07:36:07 +0200 Subject: [PATCH 48/48] Updated CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dccad22..97e71be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed * Directory structure ([#67](https://github.com/NLESC-JCER/cpp2wasm/issues/67)) +* Makefile does less entangles ([#61](https://github.com/NLESC-JCER/cpp2wasm/issues/61)) ## [0.3.0] - 2020-06-09