woxi-wasm 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts ADDED
@@ -0,0 +1,64 @@
1
+ /** One structured output item produced by evaluating a statement. */
2
+ export interface OutputItem {
3
+ /** Kind of output this item carries. */
4
+ type:
5
+ | "text"
6
+ | "graphics"
7
+ | "print"
8
+ | "warning"
9
+ | "error"
10
+ | "sound"
11
+ | "manipulate";
12
+ /** Textual content (present for text/print/warning/error items). */
13
+ text?: string;
14
+ /** SVG markup (present for graphics items and rich text renderings). */
15
+ svg?: string;
16
+ /** Base64-encoded audio data (present for sound items). */
17
+ audio?: string;
18
+ /** MIME type of the audio data (present for sound items). */
19
+ mime?: string;
20
+ /** Label shown next to the audio player (optional on sound items). */
21
+ label?: string;
22
+ /** Additional fields (e.g. the Manipulate widget spec). */
23
+ [key: string]: unknown;
24
+ }
25
+
26
+ /**
27
+ * Evaluate one or more Wolfram Language statements and return the combined
28
+ * output (Print output followed by the final result) as a string.
29
+ * Evaluation errors are returned as a string starting with "Error: ".
30
+ */
31
+ export function evaluate(code: string): string;
32
+
33
+ /** Evaluate all top-level statements and return structured output items. */
34
+ export function evaluateAll(code: string): OutputItem[];
35
+
36
+ /** Split code into top-level statements (for progressive evaluation). */
37
+ export function splitStatements(code: string): string[];
38
+
39
+ /** Evaluate a single statement, returning structured output items. */
40
+ export function evaluateStatement(statement: string): OutputItem[];
41
+
42
+ /** SVG graphics captured by the last evaluate() call ("" when none). */
43
+ export function getGraphics(): string;
44
+
45
+ /** Base64-encoded audio captured by the last evaluate() call ("" when none). */
46
+ export function getSound(): string;
47
+
48
+ /** Warnings emitted by the last evaluate() call. */
49
+ export function getWarnings(): string[];
50
+
51
+ /** Clear all interpreter state (variables and function definitions). */
52
+ export function clear(): void;
53
+
54
+ /** Toggle dark-mode colors for SVG output. */
55
+ export function setDarkMode(enabled: boolean): void;
56
+
57
+ /** Register an in-memory file so `Import["name"]` can read it. */
58
+ export function setVirtualFile(
59
+ name: string,
60
+ data: string | Uint8Array | ArrayBuffer,
61
+ ): void;
62
+
63
+ /** Remove all files registered with setVirtualFile(). */
64
+ export function clearVirtualFiles(): void;
package/index.js ADDED
@@ -0,0 +1,174 @@
1
+ // JavaScript wrapper around the Woxi WebAssembly build (see ../src/wasm.rs).
2
+ //
3
+ // The generated bindings in pkg/ (built by `make npm-build` in the repo
4
+ // root) expose the raw wasm-bindgen functions. This module adds:
5
+ //
6
+ // - camelCase names and JSON parsing for the structured APIs
7
+ // - a Node implementation of the `__woxi_fetch_url` host hook, so
8
+ // `Import["https://..."]` works out of the box
9
+ // - panic recovery: a Rust panic leaves the wasm instance unusable, so the
10
+ // wrapper converts it into a JS Error carrying the panic message and
11
+ // transparently loads a fresh instance on the next call
12
+
13
+ "use strict"
14
+
15
+ const path = require("node:path")
16
+
17
+ const PKG_ENTRY = path.join(__dirname, "pkg", "woxi.js")
18
+
19
+ let lastPanicMessage = null
20
+
21
+ // Host hook called by the wasm panic hook right before the trap fires.
22
+ if (typeof globalThis.__woxi_report_panic !== "function") {
23
+ globalThis.__woxi_report_panic = (msg) => {
24
+ lastPanicMessage = msg
25
+ }
26
+ }
27
+
28
+ // Host hook used by `Import["https://..."]`: fetch a URL synchronously and
29
+ // return its body base64-encoded. The wasm side is fully synchronous, so we
30
+ // shell out to a child Node process that performs the async fetch.
31
+ if (typeof globalThis.__woxi_fetch_url !== "function") {
32
+ globalThis.__woxi_fetch_url = (url) => {
33
+ const { execFileSync } = require("node:child_process")
34
+ const script = `
35
+ fetch(process.argv[1])
36
+ .then((res) => {
37
+ if (!res.ok) throw new Error("HTTP status " + res.status)
38
+ return res.arrayBuffer()
39
+ })
40
+ .then((buf) => process.stdout.write(Buffer.from(buf).toString("base64")))
41
+ .catch((err) => { process.stderr.write(String(err.message || err)); process.exit(1) })
42
+ `
43
+ try {
44
+ return execFileSync(process.execPath, ["-e", script, url], {
45
+ encoding: "utf8",
46
+ maxBuffer: 512 * 1024 * 1024,
47
+ })
48
+ } catch (err) {
49
+ const stderr = err.stderr ? String(err.stderr).trim() : ""
50
+ throw new Error(stderr || `failed to fetch ${url}`)
51
+ }
52
+ }
53
+ }
54
+
55
+ let wasm = null
56
+
57
+ function getWasm() {
58
+ if (wasm === null) {
59
+ // Drop stale copies from the require cache so that a reload after a
60
+ // panic instantiates a fresh wasm instance instead of the broken one.
61
+ delete require.cache[require.resolve(PKG_ENTRY)]
62
+ wasm = require(PKG_ENTRY)
63
+ }
64
+ return wasm
65
+ }
66
+
67
+ // Run a raw wasm call, translating a Rust panic (which surfaces as a
68
+ // WebAssembly "unreachable" RuntimeError) into a descriptive JS Error and
69
+ // discarding the now-broken instance.
70
+ function guarded(fn) {
71
+ lastPanicMessage = null
72
+ try {
73
+ return fn(getWasm())
74
+ } catch (err) {
75
+ if (lastPanicMessage !== null) {
76
+ wasm = null // instance is poisoned - reload lazily on the next call
77
+ throw new Error(`Woxi crashed while evaluating: ${lastPanicMessage}`, {
78
+ cause: err,
79
+ })
80
+ }
81
+ throw err
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Evaluate one or more Wolfram Language statements and return the combined
87
+ * output (Print output followed by the final result) as a string.
88
+ */
89
+ function evaluate(code) {
90
+ return guarded((w) => w.evaluate(code))
91
+ }
92
+
93
+ /**
94
+ * Evaluate all top-level statements and return structured output items
95
+ * ({type: "text" | "graphics" | "print" | "warning" | "error" | ...}).
96
+ */
97
+ function evaluateAll(code) {
98
+ return JSON.parse(guarded((w) => w.evaluate_all(code)))
99
+ }
100
+
101
+ /** Split code into top-level statements (for progressive evaluation). */
102
+ function splitStatements(code) {
103
+ return JSON.parse(guarded((w) => w.split_statements(code)))
104
+ }
105
+
106
+ /** Evaluate a single statement, returning structured output items. */
107
+ function evaluateStatement(statement) {
108
+ return JSON.parse(guarded((w) => w.evaluate_statement(statement)))
109
+ }
110
+
111
+ /** SVG graphics captured by the last evaluate() call ("" when none). */
112
+ function getGraphics() {
113
+ return guarded((w) => w.get_graphics())
114
+ }
115
+
116
+ /** Base64-encoded audio captured by the last evaluate() call ("" when none). */
117
+ function getSound() {
118
+ return guarded((w) => w.get_sound())
119
+ }
120
+
121
+ /** Warnings emitted by the last evaluate() call. */
122
+ function getWarnings() {
123
+ const text = guarded((w) => w.get_warnings())
124
+ return text === "" ? [] : text.split("\n")
125
+ }
126
+
127
+ /** Clear all interpreter state (variables and function definitions). */
128
+ function clear() {
129
+ guarded((w) => w.clear())
130
+ }
131
+
132
+ /** Toggle dark-mode colors for SVG output. */
133
+ function setDarkMode(enabled) {
134
+ guarded((w) => w.set_dark_mode(enabled))
135
+ }
136
+
137
+ /**
138
+ * Register an in-memory file so `Import["name"]` can read it. `data` may be
139
+ * a string, Buffer, Uint8Array, or ArrayBuffer.
140
+ */
141
+ function setVirtualFile(name, data) {
142
+ let bytes
143
+ if (typeof data === "string") {
144
+ bytes = new TextEncoder().encode(data)
145
+ } else if (data instanceof Uint8Array) {
146
+ bytes = data
147
+ } else if (data instanceof ArrayBuffer) {
148
+ bytes = new Uint8Array(data)
149
+ } else {
150
+ throw new TypeError(
151
+ "setVirtualFile data must be a string, Uint8Array, Buffer, or ArrayBuffer",
152
+ )
153
+ }
154
+ guarded((w) => w.set_virtual_file(name, bytes))
155
+ }
156
+
157
+ /** Remove all files registered with setVirtualFile(). */
158
+ function clearVirtualFiles() {
159
+ guarded((w) => w.clear_virtual_files())
160
+ }
161
+
162
+ module.exports = {
163
+ evaluate,
164
+ evaluateAll,
165
+ splitStatements,
166
+ evaluateStatement,
167
+ getGraphics,
168
+ getSound,
169
+ getWarnings,
170
+ clear,
171
+ setDarkMode,
172
+ setVirtualFile,
173
+ clearVirtualFiles,
174
+ }
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "woxi-wasm",
3
+ "version": "0.1.0",
4
+ "description": "Interpreter for a subset of the Wolfram Language, compiled to WebAssembly",
5
+ "keywords": [
6
+ "wolfram",
7
+ "wolfram-language",
8
+ "mathematica",
9
+ "cas",
10
+ "math",
11
+ "interpreter",
12
+ "wasm"
13
+ ],
14
+ "license": "AGPL-3.0-or-later",
15
+ "author": "Adrian Sieber",
16
+ "homepage": "https://woxi.ad-si.com",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/ad-si/Woxi.git",
20
+ "directory": "npm"
21
+ },
22
+ "bugs": {
23
+ "url": "https://github.com/ad-si/Woxi/issues"
24
+ },
25
+ "main": "index.js",
26
+ "types": "index.d.ts",
27
+ "files": [
28
+ "index.js",
29
+ "index.d.ts",
30
+ "pkg/"
31
+ ],
32
+ "engines": {
33
+ "node": ">=18"
34
+ },
35
+ "scripts": {
36
+ "build": "make -C .. npm-build",
37
+ "test": "node --test",
38
+ "prepublishOnly": "node -e \"require('./pkg/woxi.js')\" || (echo 'pkg/ is missing - run `make npm-build` in the repo root first' && exit 1)"
39
+ }
40
+ }
package/pkg/woxi.d.ts ADDED
@@ -0,0 +1,111 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /**
4
+ * Render a Manipulate body, its extra display elements, and any pending
5
+ * interactive write-backs in one call. Used by widgets that have display
6
+ * elements (e.g. a `Checkbox` grid) that both read and rewrite shared
7
+ * state.
8
+ *
9
+ * `displays_json` and `mutations_json` are JSON string arrays. Each
10
+ * mutation is an assignment (e.g. `data[[3, 5]] = 1`) applied before the
11
+ * re-render; the updated value of every mutated variable is returned under
12
+ * `state` so the frontend can keep its binding set in sync.
13
+ *
14
+ * The result is `{"output":{svg|text|textSvg}, "displays":[<tree>…],
15
+ * "state":{name:value,…}}`.
16
+ */
17
+ export function evaluate_manipulate_full(body: string, displays_json: string, bindings_json: string, mutations_json: string): string;
18
+ /**
19
+ * Register (or replace) an in-memory file so `Import["name"]` can read it
20
+ * in the browser.
21
+ */
22
+ export function set_virtual_file(name: string, data: Uint8Array): void;
23
+ /**
24
+ * Return the captured SVG graphics from the last `evaluate()` call, if any.
25
+ * Returns an empty string when there is no graphics output.
26
+ */
27
+ export function get_graphics(): string;
28
+ /**
29
+ * Evaluate all top-level statements and return a JSON array of output items.
30
+ * Each item has a "type" field ("text", "graphics", "print", "warning", "error",
31
+ * "manipulate") and corresponding content fields.
32
+ */
33
+ export function evaluate_all(input: string): string;
34
+ /**
35
+ * Evaluate a single statement and return a JSON array of output items
36
+ * (same shape as `evaluate_all`'s elements). Use together with
37
+ * `split_statements` for progressive output.
38
+ */
39
+ export function evaluate_statement(stmt: string): string;
40
+ /**
41
+ * Split `input` into top-level statements and return a JSON array of strings.
42
+ * Lets the front-end loop one statement at a time so output (and side
43
+ * effects like `Pause[n]`) appear progressively rather than batched.
44
+ */
45
+ export function split_statements(input: string): string;
46
+ /**
47
+ * Remove all host-registered in-memory files.
48
+ */
49
+ export function clear_virtual_files(): void;
50
+ /**
51
+ * Evaluate a Manipulate body with a specific set of variable bindings
52
+ * and return a single JSON output item representing the result.
53
+ *
54
+ * `body` must be the body expression in InputForm (as produced by
55
+ * `evaluate_all`'s manipulate item). `bindings_json` must be a JSON
56
+ * object mapping variable names to InputForm-serialized values, e.g.
57
+ * `{"a": "1.5", "b": "\"foo\""}`.
58
+ *
59
+ * The result is a JSON object of the same shape as `initial` from
60
+ * the evaluate_all manipulate item: `{"svg": "...", "text": "..."}`.
61
+ */
62
+ export function evaluate_manipulate(body: string, bindings_json: string): string;
63
+ /**
64
+ * Evaluate, returning only the final expression result (no Print output).
65
+ */
66
+ export function evaluate_expr(input: string): string;
67
+ /**
68
+ * Return SVG rendering of the last text result (with superscripts etc.).
69
+ * Returns an empty string when there is no output SVG (e.g. for Graphics results).
70
+ */
71
+ export function get_output_svg(): string;
72
+ /**
73
+ * Enable or disable dark mode for SVG output colors.
74
+ */
75
+ export function set_dark_mode(enabled: boolean): void;
76
+ /**
77
+ * Evaluate a Wolfram Language expression and return the result.
78
+ * If the expression produces Print output, it is prepended to the result.
79
+ */
80
+ export function evaluate(input: string): string;
81
+ /**
82
+ * Return warnings from the last `evaluate()` call as newline-separated text.
83
+ * Returns an empty string when there are no warnings.
84
+ */
85
+ export function get_warnings(): string;
86
+ /**
87
+ * Return the playable audio (base64-encoded) from the last `evaluate()`
88
+ * call, if any. Returns an empty string when there is no sound.
89
+ */
90
+ export function get_sound(): string;
91
+ /**
92
+ * Clear all interpreter state (variables and function definitions).
93
+ */
94
+ export function clear(): void;
95
+ export function init(): void;
96
+ /**
97
+ * Evaluate each Manipulate control's `Enabled` condition against a binding
98
+ * set and return a JSON array of booleans (one per control, in order).
99
+ *
100
+ * `conditions_json` is a JSON string array aligned with the control list;
101
+ * an empty string marks a control with no condition (always enabled).
102
+ * `bindings_json` is the same JSON object of variable bindings used by
103
+ * `evaluate_manipulate`. Used by the Playground to grey out controls that a
104
+ * `Enabled -> Dynamic[…]` option has switched off for the current state.
105
+ */
106
+ export function evaluate_manipulate_enabled(conditions_json: string, bindings_json: string): string;
107
+ /**
108
+ * Return the captured GraphicsBox expression from the last `evaluate()` call.
109
+ * Returns an empty string when there is no graphics output.
110
+ */
111
+ export function get_graphicsbox(): string;
package/pkg/woxi.js ADDED
@@ -0,0 +1,858 @@
1
+
2
+ let imports = {};
3
+ imports['__wbindgen_placeholder__'] = module.exports;
4
+
5
+ function debugString(val) {
6
+ // primitive types
7
+ const type = typeof val;
8
+ if (type == 'number' || type == 'boolean' || val == null) {
9
+ return `${val}`;
10
+ }
11
+ if (type == 'string') {
12
+ return `"${val}"`;
13
+ }
14
+ if (type == 'symbol') {
15
+ const description = val.description;
16
+ if (description == null) {
17
+ return 'Symbol';
18
+ } else {
19
+ return `Symbol(${description})`;
20
+ }
21
+ }
22
+ if (type == 'function') {
23
+ const name = val.name;
24
+ if (typeof name == 'string' && name.length > 0) {
25
+ return `Function(${name})`;
26
+ } else {
27
+ return 'Function';
28
+ }
29
+ }
30
+ // objects
31
+ if (Array.isArray(val)) {
32
+ const length = val.length;
33
+ let debug = '[';
34
+ if (length > 0) {
35
+ debug += debugString(val[0]);
36
+ }
37
+ for(let i = 1; i < length; i++) {
38
+ debug += ', ' + debugString(val[i]);
39
+ }
40
+ debug += ']';
41
+ return debug;
42
+ }
43
+ // Test for built-in
44
+ const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
45
+ let className;
46
+ if (builtInMatches && builtInMatches.length > 1) {
47
+ className = builtInMatches[1];
48
+ } else {
49
+ // Failed to match the standard '[object ClassName]'
50
+ return toString.call(val);
51
+ }
52
+ if (className == 'Object') {
53
+ // we're a user defined class or Object
54
+ // JSON.stringify avoids problems with cycles, and is generally much
55
+ // easier than looping through ownProperties of `val`.
56
+ try {
57
+ return 'Object(' + JSON.stringify(val) + ')';
58
+ } catch (_) {
59
+ return 'Object';
60
+ }
61
+ }
62
+ // errors
63
+ if (val instanceof Error) {
64
+ return `${val.name}: ${val.message}\n${val.stack}`;
65
+ }
66
+ // TODO we could test for more things here, like `Set`s and `Map`s.
67
+ return className;
68
+ }
69
+
70
+ let WASM_VECTOR_LEN = 0;
71
+
72
+ let cachedUint8ArrayMemory0 = null;
73
+
74
+ function getUint8ArrayMemory0() {
75
+ if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
76
+ cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
77
+ }
78
+ return cachedUint8ArrayMemory0;
79
+ }
80
+
81
+ const cachedTextEncoder = new TextEncoder();
82
+
83
+ if (!('encodeInto' in cachedTextEncoder)) {
84
+ cachedTextEncoder.encodeInto = function (arg, view) {
85
+ const buf = cachedTextEncoder.encode(arg);
86
+ view.set(buf);
87
+ return {
88
+ read: arg.length,
89
+ written: buf.length
90
+ };
91
+ }
92
+ }
93
+
94
+ function passStringToWasm0(arg, malloc, realloc) {
95
+
96
+ if (realloc === undefined) {
97
+ const buf = cachedTextEncoder.encode(arg);
98
+ const ptr = malloc(buf.length, 1) >>> 0;
99
+ getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
100
+ WASM_VECTOR_LEN = buf.length;
101
+ return ptr;
102
+ }
103
+
104
+ let len = arg.length;
105
+ let ptr = malloc(len, 1) >>> 0;
106
+
107
+ const mem = getUint8ArrayMemory0();
108
+
109
+ let offset = 0;
110
+
111
+ for (; offset < len; offset++) {
112
+ const code = arg.charCodeAt(offset);
113
+ if (code > 0x7F) break;
114
+ mem[ptr + offset] = code;
115
+ }
116
+
117
+ if (offset !== len) {
118
+ if (offset !== 0) {
119
+ arg = arg.slice(offset);
120
+ }
121
+ ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
122
+ const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
123
+ const ret = cachedTextEncoder.encodeInto(arg, view);
124
+
125
+ offset += ret.written;
126
+ ptr = realloc(ptr, len, offset, 1) >>> 0;
127
+ }
128
+
129
+ WASM_VECTOR_LEN = offset;
130
+ return ptr;
131
+ }
132
+
133
+ let cachedDataViewMemory0 = null;
134
+
135
+ function getDataViewMemory0() {
136
+ if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
137
+ cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
138
+ }
139
+ return cachedDataViewMemory0;
140
+ }
141
+
142
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
143
+
144
+ cachedTextDecoder.decode();
145
+
146
+ function decodeText(ptr, len) {
147
+ return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
148
+ }
149
+
150
+ function getStringFromWasm0(ptr, len) {
151
+ ptr = ptr >>> 0;
152
+ return decodeText(ptr, len);
153
+ }
154
+
155
+ function addToExternrefTable0(obj) {
156
+ const idx = wasm.__externref_table_alloc();
157
+ wasm.__wbindgen_externrefs.set(idx, obj);
158
+ return idx;
159
+ }
160
+
161
+ function handleError(f, args) {
162
+ try {
163
+ return f.apply(this, args);
164
+ } catch (e) {
165
+ const idx = addToExternrefTable0(e);
166
+ wasm.__wbindgen_exn_store(idx);
167
+ }
168
+ }
169
+
170
+ function isLikeNone(x) {
171
+ return x === undefined || x === null;
172
+ }
173
+
174
+ function getArrayU8FromWasm0(ptr, len) {
175
+ ptr = ptr >>> 0;
176
+ return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
177
+ }
178
+ /**
179
+ * Render a Manipulate body, its extra display elements, and any pending
180
+ * interactive write-backs in one call. Used by widgets that have display
181
+ * elements (e.g. a `Checkbox` grid) that both read and rewrite shared
182
+ * state.
183
+ *
184
+ * `displays_json` and `mutations_json` are JSON string arrays. Each
185
+ * mutation is an assignment (e.g. `data[[3, 5]] = 1`) applied before the
186
+ * re-render; the updated value of every mutated variable is returned under
187
+ * `state` so the frontend can keep its binding set in sync.
188
+ *
189
+ * The result is `{"output":{svg|text|textSvg}, "displays":[<tree>…],
190
+ * "state":{name:value,…}}`.
191
+ * @param {string} body
192
+ * @param {string} displays_json
193
+ * @param {string} bindings_json
194
+ * @param {string} mutations_json
195
+ * @returns {string}
196
+ */
197
+ exports.evaluate_manipulate_full = function(body, displays_json, bindings_json, mutations_json) {
198
+ let deferred5_0;
199
+ let deferred5_1;
200
+ try {
201
+ const ptr0 = passStringToWasm0(body, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
202
+ const len0 = WASM_VECTOR_LEN;
203
+ const ptr1 = passStringToWasm0(displays_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
204
+ const len1 = WASM_VECTOR_LEN;
205
+ const ptr2 = passStringToWasm0(bindings_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
206
+ const len2 = WASM_VECTOR_LEN;
207
+ const ptr3 = passStringToWasm0(mutations_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
208
+ const len3 = WASM_VECTOR_LEN;
209
+ const ret = wasm.evaluate_manipulate_full(ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
210
+ deferred5_0 = ret[0];
211
+ deferred5_1 = ret[1];
212
+ return getStringFromWasm0(ret[0], ret[1]);
213
+ } finally {
214
+ wasm.__wbindgen_free(deferred5_0, deferred5_1, 1);
215
+ }
216
+ };
217
+
218
+ function passArray8ToWasm0(arg, malloc) {
219
+ const ptr = malloc(arg.length * 1, 1) >>> 0;
220
+ getUint8ArrayMemory0().set(arg, ptr / 1);
221
+ WASM_VECTOR_LEN = arg.length;
222
+ return ptr;
223
+ }
224
+ /**
225
+ * Register (or replace) an in-memory file so `Import["name"]` can read it
226
+ * in the browser.
227
+ * @param {string} name
228
+ * @param {Uint8Array} data
229
+ */
230
+ exports.set_virtual_file = function(name, data) {
231
+ const ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
232
+ const len0 = WASM_VECTOR_LEN;
233
+ const ptr1 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
234
+ const len1 = WASM_VECTOR_LEN;
235
+ wasm.set_virtual_file(ptr0, len0, ptr1, len1);
236
+ };
237
+
238
+ /**
239
+ * Return the captured SVG graphics from the last `evaluate()` call, if any.
240
+ * Returns an empty string when there is no graphics output.
241
+ * @returns {string}
242
+ */
243
+ exports.get_graphics = function() {
244
+ let deferred1_0;
245
+ let deferred1_1;
246
+ try {
247
+ const ret = wasm.get_graphics();
248
+ deferred1_0 = ret[0];
249
+ deferred1_1 = ret[1];
250
+ return getStringFromWasm0(ret[0], ret[1]);
251
+ } finally {
252
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
253
+ }
254
+ };
255
+
256
+ /**
257
+ * Evaluate all top-level statements and return a JSON array of output items.
258
+ * Each item has a "type" field ("text", "graphics", "print", "warning", "error",
259
+ * "manipulate") and corresponding content fields.
260
+ * @param {string} input
261
+ * @returns {string}
262
+ */
263
+ exports.evaluate_all = function(input) {
264
+ let deferred2_0;
265
+ let deferred2_1;
266
+ try {
267
+ const ptr0 = passStringToWasm0(input, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
268
+ const len0 = WASM_VECTOR_LEN;
269
+ const ret = wasm.evaluate_all(ptr0, len0);
270
+ deferred2_0 = ret[0];
271
+ deferred2_1 = ret[1];
272
+ return getStringFromWasm0(ret[0], ret[1]);
273
+ } finally {
274
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
275
+ }
276
+ };
277
+
278
+ /**
279
+ * Evaluate a single statement and return a JSON array of output items
280
+ * (same shape as `evaluate_all`'s elements). Use together with
281
+ * `split_statements` for progressive output.
282
+ * @param {string} stmt
283
+ * @returns {string}
284
+ */
285
+ exports.evaluate_statement = function(stmt) {
286
+ let deferred2_0;
287
+ let deferred2_1;
288
+ try {
289
+ const ptr0 = passStringToWasm0(stmt, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
290
+ const len0 = WASM_VECTOR_LEN;
291
+ const ret = wasm.evaluate_statement(ptr0, len0);
292
+ deferred2_0 = ret[0];
293
+ deferred2_1 = ret[1];
294
+ return getStringFromWasm0(ret[0], ret[1]);
295
+ } finally {
296
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
297
+ }
298
+ };
299
+
300
+ /**
301
+ * Split `input` into top-level statements and return a JSON array of strings.
302
+ * Lets the front-end loop one statement at a time so output (and side
303
+ * effects like `Pause[n]`) appear progressively rather than batched.
304
+ * @param {string} input
305
+ * @returns {string}
306
+ */
307
+ exports.split_statements = function(input) {
308
+ let deferred2_0;
309
+ let deferred2_1;
310
+ try {
311
+ const ptr0 = passStringToWasm0(input, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
312
+ const len0 = WASM_VECTOR_LEN;
313
+ const ret = wasm.split_statements(ptr0, len0);
314
+ deferred2_0 = ret[0];
315
+ deferred2_1 = ret[1];
316
+ return getStringFromWasm0(ret[0], ret[1]);
317
+ } finally {
318
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
319
+ }
320
+ };
321
+
322
+ /**
323
+ * Remove all host-registered in-memory files.
324
+ */
325
+ exports.clear_virtual_files = function() {
326
+ wasm.clear_virtual_files();
327
+ };
328
+
329
+ /**
330
+ * Evaluate a Manipulate body with a specific set of variable bindings
331
+ * and return a single JSON output item representing the result.
332
+ *
333
+ * `body` must be the body expression in InputForm (as produced by
334
+ * `evaluate_all`'s manipulate item). `bindings_json` must be a JSON
335
+ * object mapping variable names to InputForm-serialized values, e.g.
336
+ * `{"a": "1.5", "b": "\"foo\""}`.
337
+ *
338
+ * The result is a JSON object of the same shape as `initial` from
339
+ * the evaluate_all manipulate item: `{"svg": "...", "text": "..."}`.
340
+ * @param {string} body
341
+ * @param {string} bindings_json
342
+ * @returns {string}
343
+ */
344
+ exports.evaluate_manipulate = function(body, bindings_json) {
345
+ let deferred3_0;
346
+ let deferred3_1;
347
+ try {
348
+ const ptr0 = passStringToWasm0(body, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
349
+ const len0 = WASM_VECTOR_LEN;
350
+ const ptr1 = passStringToWasm0(bindings_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
351
+ const len1 = WASM_VECTOR_LEN;
352
+ const ret = wasm.evaluate_manipulate(ptr0, len0, ptr1, len1);
353
+ deferred3_0 = ret[0];
354
+ deferred3_1 = ret[1];
355
+ return getStringFromWasm0(ret[0], ret[1]);
356
+ } finally {
357
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
358
+ }
359
+ };
360
+
361
+ /**
362
+ * Evaluate, returning only the final expression result (no Print output).
363
+ * @param {string} input
364
+ * @returns {string}
365
+ */
366
+ exports.evaluate_expr = function(input) {
367
+ let deferred2_0;
368
+ let deferred2_1;
369
+ try {
370
+ const ptr0 = passStringToWasm0(input, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
371
+ const len0 = WASM_VECTOR_LEN;
372
+ const ret = wasm.evaluate_expr(ptr0, len0);
373
+ deferred2_0 = ret[0];
374
+ deferred2_1 = ret[1];
375
+ return getStringFromWasm0(ret[0], ret[1]);
376
+ } finally {
377
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
378
+ }
379
+ };
380
+
381
+ /**
382
+ * Return SVG rendering of the last text result (with superscripts etc.).
383
+ * Returns an empty string when there is no output SVG (e.g. for Graphics results).
384
+ * @returns {string}
385
+ */
386
+ exports.get_output_svg = function() {
387
+ let deferred1_0;
388
+ let deferred1_1;
389
+ try {
390
+ const ret = wasm.get_output_svg();
391
+ deferred1_0 = ret[0];
392
+ deferred1_1 = ret[1];
393
+ return getStringFromWasm0(ret[0], ret[1]);
394
+ } finally {
395
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
396
+ }
397
+ };
398
+
399
+ /**
400
+ * Enable or disable dark mode for SVG output colors.
401
+ * @param {boolean} enabled
402
+ */
403
+ exports.set_dark_mode = function(enabled) {
404
+ wasm.set_dark_mode(enabled);
405
+ };
406
+
407
+ /**
408
+ * Evaluate a Wolfram Language expression and return the result.
409
+ * If the expression produces Print output, it is prepended to the result.
410
+ * @param {string} input
411
+ * @returns {string}
412
+ */
413
+ exports.evaluate = function(input) {
414
+ let deferred2_0;
415
+ let deferred2_1;
416
+ try {
417
+ const ptr0 = passStringToWasm0(input, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
418
+ const len0 = WASM_VECTOR_LEN;
419
+ const ret = wasm.evaluate(ptr0, len0);
420
+ deferred2_0 = ret[0];
421
+ deferred2_1 = ret[1];
422
+ return getStringFromWasm0(ret[0], ret[1]);
423
+ } finally {
424
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
425
+ }
426
+ };
427
+
428
+ /**
429
+ * Return warnings from the last `evaluate()` call as newline-separated text.
430
+ * Returns an empty string when there are no warnings.
431
+ * @returns {string}
432
+ */
433
+ exports.get_warnings = function() {
434
+ let deferred1_0;
435
+ let deferred1_1;
436
+ try {
437
+ const ret = wasm.get_warnings();
438
+ deferred1_0 = ret[0];
439
+ deferred1_1 = ret[1];
440
+ return getStringFromWasm0(ret[0], ret[1]);
441
+ } finally {
442
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
443
+ }
444
+ };
445
+
446
+ /**
447
+ * Return the playable audio (base64-encoded) from the last `evaluate()`
448
+ * call, if any. Returns an empty string when there is no sound.
449
+ * @returns {string}
450
+ */
451
+ exports.get_sound = function() {
452
+ let deferred1_0;
453
+ let deferred1_1;
454
+ try {
455
+ const ret = wasm.get_sound();
456
+ deferred1_0 = ret[0];
457
+ deferred1_1 = ret[1];
458
+ return getStringFromWasm0(ret[0], ret[1]);
459
+ } finally {
460
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
461
+ }
462
+ };
463
+
464
+ /**
465
+ * Clear all interpreter state (variables and function definitions).
466
+ */
467
+ exports.clear = function() {
468
+ wasm.clear();
469
+ };
470
+
471
+ exports.init = function() {
472
+ wasm.init();
473
+ };
474
+
475
+ /**
476
+ * Evaluate each Manipulate control's `Enabled` condition against a binding
477
+ * set and return a JSON array of booleans (one per control, in order).
478
+ *
479
+ * `conditions_json` is a JSON string array aligned with the control list;
480
+ * an empty string marks a control with no condition (always enabled).
481
+ * `bindings_json` is the same JSON object of variable bindings used by
482
+ * `evaluate_manipulate`. Used by the Playground to grey out controls that a
483
+ * `Enabled -> Dynamic[…]` option has switched off for the current state.
484
+ * @param {string} conditions_json
485
+ * @param {string} bindings_json
486
+ * @returns {string}
487
+ */
488
+ exports.evaluate_manipulate_enabled = function(conditions_json, bindings_json) {
489
+ let deferred3_0;
490
+ let deferred3_1;
491
+ try {
492
+ const ptr0 = passStringToWasm0(conditions_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
493
+ const len0 = WASM_VECTOR_LEN;
494
+ const ptr1 = passStringToWasm0(bindings_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
495
+ const len1 = WASM_VECTOR_LEN;
496
+ const ret = wasm.evaluate_manipulate_enabled(ptr0, len0, ptr1, len1);
497
+ deferred3_0 = ret[0];
498
+ deferred3_1 = ret[1];
499
+ return getStringFromWasm0(ret[0], ret[1]);
500
+ } finally {
501
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
502
+ }
503
+ };
504
+
505
+ /**
506
+ * Return the captured GraphicsBox expression from the last `evaluate()` call.
507
+ * Returns an empty string when there is no graphics output.
508
+ * @returns {string}
509
+ */
510
+ exports.get_graphicsbox = function() {
511
+ let deferred1_0;
512
+ let deferred1_1;
513
+ try {
514
+ const ret = wasm.get_graphicsbox();
515
+ deferred1_0 = ret[0];
516
+ deferred1_1 = ret[1];
517
+ return getStringFromWasm0(ret[0], ret[1]);
518
+ } finally {
519
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
520
+ }
521
+ };
522
+
523
+ exports.__wbg___wbindgen_debug_string_df47ffb5e35e6763 = function(arg0, arg1) {
524
+ const ret = debugString(arg1);
525
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
526
+ const len1 = WASM_VECTOR_LEN;
527
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
528
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
529
+ };
530
+
531
+ exports.__wbg___wbindgen_is_function_ee8a6c5833c90377 = function(arg0) {
532
+ const ret = typeof(arg0) === 'function';
533
+ return ret;
534
+ };
535
+
536
+ exports.__wbg___wbindgen_is_object_c818261d21f283a4 = function(arg0) {
537
+ const val = arg0;
538
+ const ret = typeof(val) === 'object' && val !== null;
539
+ return ret;
540
+ };
541
+
542
+ exports.__wbg___wbindgen_is_string_fbb76cb2940daafd = function(arg0) {
543
+ const ret = typeof(arg0) === 'string';
544
+ return ret;
545
+ };
546
+
547
+ exports.__wbg___wbindgen_is_undefined_2d472862bd29a478 = function(arg0) {
548
+ const ret = arg0 === undefined;
549
+ return ret;
550
+ };
551
+
552
+ exports.__wbg___wbindgen_throw_b855445ff6a94295 = function(arg0, arg1) {
553
+ throw new Error(getStringFromWasm0(arg0, arg1));
554
+ };
555
+
556
+ exports.__wbg___woxi_fetch_url_b456f49aff4e3138 = function() { return handleError(function (arg0, arg1, arg2) {
557
+ const ret = __woxi_fetch_url(getStringFromWasm0(arg1, arg2));
558
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
559
+ const len1 = WASM_VECTOR_LEN;
560
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
561
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
562
+ }, arguments) };
563
+
564
+ exports.__wbg___woxi_report_panic_13444e27f27ce1cd = function() { return handleError(function (arg0, arg1) {
565
+ __woxi_report_panic(getStringFromWasm0(arg0, arg1));
566
+ }, arguments) };
567
+
568
+ exports.__wbg_append_ed363d026656dfbd = function() { return handleError(function (arg0, arg1) {
569
+ arg0.append(arg1);
570
+ }, arguments) };
571
+
572
+ exports.__wbg_body_8c26b54829a0c4cb = function(arg0) {
573
+ const ret = arg0.body;
574
+ return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
575
+ };
576
+
577
+ exports.__wbg_call_525440f72fbfc0ea = function() { return handleError(function (arg0, arg1, arg2) {
578
+ const ret = arg0.call(arg1, arg2);
579
+ return ret;
580
+ }, arguments) };
581
+
582
+ exports.__wbg_call_e762c39fa8ea36bf = function() { return handleError(function (arg0, arg1) {
583
+ const ret = arg0.call(arg1);
584
+ return ret;
585
+ }, arguments) };
586
+
587
+ exports.__wbg_createElement_964ab674a0176cd8 = function() { return handleError(function (arg0, arg1, arg2) {
588
+ const ret = arg0.createElement(getStringFromWasm0(arg1, arg2));
589
+ return ret;
590
+ }, arguments) };
591
+
592
+ exports.__wbg_crypto_574e78ad8b13b65f = function(arg0) {
593
+ const ret = arg0.crypto;
594
+ return ret;
595
+ };
596
+
597
+ exports.__wbg_document_725ae06eb442a6db = function(arg0) {
598
+ const ret = arg0.document;
599
+ return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
600
+ };
601
+
602
+ exports.__wbg_error_7534b8e9a36f1ab4 = function(arg0, arg1) {
603
+ let deferred0_0;
604
+ let deferred0_1;
605
+ try {
606
+ deferred0_0 = arg0;
607
+ deferred0_1 = arg1;
608
+ console.error(getStringFromWasm0(arg0, arg1));
609
+ } finally {
610
+ wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
611
+ }
612
+ };
613
+
614
+ exports.__wbg_getDate_5a70d2f6a482d99f = function(arg0) {
615
+ const ret = arg0.getDate();
616
+ return ret;
617
+ };
618
+
619
+ exports.__wbg_getFullYear_8240d5a15191feae = function(arg0) {
620
+ const ret = arg0.getFullYear();
621
+ return ret;
622
+ };
623
+
624
+ exports.__wbg_getHours_5e476e0b9ebc42d1 = function(arg0) {
625
+ const ret = arg0.getHours();
626
+ return ret;
627
+ };
628
+
629
+ exports.__wbg_getMilliseconds_9fc7184d90e04a16 = function(arg0) {
630
+ const ret = arg0.getMilliseconds();
631
+ return ret;
632
+ };
633
+
634
+ exports.__wbg_getMinutes_c95dfb65f1ea8f02 = function(arg0) {
635
+ const ret = arg0.getMinutes();
636
+ return ret;
637
+ };
638
+
639
+ exports.__wbg_getMonth_25c1c5a601d72773 = function(arg0) {
640
+ const ret = arg0.getMonth();
641
+ return ret;
642
+ };
643
+
644
+ exports.__wbg_getRandomValues_b8f5dbd5f3995a9e = function() { return handleError(function (arg0, arg1) {
645
+ arg0.getRandomValues(arg1);
646
+ }, arguments) };
647
+
648
+ exports.__wbg_getSeconds_8113bf8709718eb2 = function(arg0) {
649
+ const ret = arg0.getSeconds();
650
+ return ret;
651
+ };
652
+
653
+ exports.__wbg_getTime_14776bfb48a1bff9 = function(arg0) {
654
+ const ret = arg0.getTime();
655
+ return ret;
656
+ };
657
+
658
+ exports.__wbg_getTimezoneOffset_d391cb11d54969f8 = function(arg0) {
659
+ const ret = arg0.getTimezoneOffset();
660
+ return ret;
661
+ };
662
+
663
+ exports.__wbg_instanceof_HtmlElement_e20a729df22f9e1c = function(arg0) {
664
+ let result;
665
+ try {
666
+ result = arg0 instanceof HTMLElement;
667
+ } catch (_) {
668
+ result = false;
669
+ }
670
+ const ret = result;
671
+ return ret;
672
+ };
673
+
674
+ exports.__wbg_instanceof_Window_4846dbb3de56c84c = function(arg0) {
675
+ let result;
676
+ try {
677
+ result = arg0 instanceof Window;
678
+ } catch (_) {
679
+ result = false;
680
+ }
681
+ const ret = result;
682
+ return ret;
683
+ };
684
+
685
+ exports.__wbg_length_69bca3cb64fc8748 = function(arg0) {
686
+ const ret = arg0.length;
687
+ return ret;
688
+ };
689
+
690
+ exports.__wbg_msCrypto_a61aeb35a24c1329 = function(arg0) {
691
+ const ret = arg0.msCrypto;
692
+ return ret;
693
+ };
694
+
695
+ exports.__wbg_new_0_f9740686d739025c = function() {
696
+ const ret = new Date();
697
+ return ret;
698
+ };
699
+
700
+ exports.__wbg_new_8a6f238a6ece86ea = function() {
701
+ const ret = new Error();
702
+ return ret;
703
+ };
704
+
705
+ exports.__wbg_new_93d9417ed3fb115d = function(arg0) {
706
+ const ret = new Date(arg0);
707
+ return ret;
708
+ };
709
+
710
+ exports.__wbg_new_no_args_ee98eee5275000a4 = function(arg0, arg1) {
711
+ const ret = new Function(getStringFromWasm0(arg0, arg1));
712
+ return ret;
713
+ };
714
+
715
+ exports.__wbg_new_with_length_01aa0dc35aa13543 = function(arg0) {
716
+ const ret = new Uint8Array(arg0 >>> 0);
717
+ return ret;
718
+ };
719
+
720
+ exports.__wbg_new_with_year_month_day_6236812cf591750d = function(arg0, arg1, arg2) {
721
+ const ret = new Date(arg0 >>> 0, arg1, arg2);
722
+ return ret;
723
+ };
724
+
725
+ exports.__wbg_node_905d3e251edff8a2 = function(arg0) {
726
+ const ret = arg0.node;
727
+ return ret;
728
+ };
729
+
730
+ exports.__wbg_now_2c95c9de01293173 = function(arg0) {
731
+ const ret = arg0.now();
732
+ return ret;
733
+ };
734
+
735
+ exports.__wbg_now_793306c526e2e3b6 = function() {
736
+ const ret = Date.now();
737
+ return ret;
738
+ };
739
+
740
+ exports.__wbg_offsetHeight_9cb4257b24361e2a = function(arg0) {
741
+ const ret = arg0.offsetHeight;
742
+ return ret;
743
+ };
744
+
745
+ exports.__wbg_offsetWidth_16b33c540f3e9ddb = function(arg0) {
746
+ const ret = arg0.offsetWidth;
747
+ return ret;
748
+ };
749
+
750
+ exports.__wbg_performance_7a3ffd0b17f663ad = function(arg0) {
751
+ const ret = arg0.performance;
752
+ return ret;
753
+ };
754
+
755
+ exports.__wbg_process_dc0fbacc7c1c06f7 = function(arg0) {
756
+ const ret = arg0.process;
757
+ return ret;
758
+ };
759
+
760
+ exports.__wbg_prototypesetcall_2a6620b6922694b2 = function(arg0, arg1, arg2) {
761
+ Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);
762
+ };
763
+
764
+ exports.__wbg_randomFillSync_ac0988aba3254290 = function() { return handleError(function (arg0, arg1) {
765
+ arg0.randomFillSync(arg1);
766
+ }, arguments) };
767
+
768
+ exports.__wbg_remove_4ba46706a8e17d9d = function(arg0) {
769
+ arg0.remove();
770
+ };
771
+
772
+ exports.__wbg_require_60cc747a6bc5215a = function() { return handleError(function () {
773
+ const ret = module.require;
774
+ return ret;
775
+ }, arguments) };
776
+
777
+ exports.__wbg_setAttribute_9bad76f39609daac = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
778
+ arg0.setAttribute(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
779
+ }, arguments) };
780
+
781
+ exports.__wbg_set_textContent_12af0b0f84feb710 = function(arg0, arg1, arg2) {
782
+ arg0.textContent = arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2);
783
+ };
784
+
785
+ exports.__wbg_stack_0ed75d68575b0f3c = function(arg0, arg1) {
786
+ const ret = arg1.stack;
787
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
788
+ const len1 = WASM_VECTOR_LEN;
789
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
790
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
791
+ };
792
+
793
+ exports.__wbg_static_accessor_GLOBAL_89e1d9ac6a1b250e = function() {
794
+ const ret = typeof global === 'undefined' ? null : global;
795
+ return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
796
+ };
797
+
798
+ exports.__wbg_static_accessor_GLOBAL_THIS_8b530f326a9e48ac = function() {
799
+ const ret = typeof globalThis === 'undefined' ? null : globalThis;
800
+ return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
801
+ };
802
+
803
+ exports.__wbg_static_accessor_SELF_6fdf4b64710cc91b = function() {
804
+ const ret = typeof self === 'undefined' ? null : self;
805
+ return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
806
+ };
807
+
808
+ exports.__wbg_static_accessor_WINDOW_b45bfc5a37f6cfa2 = function() {
809
+ const ret = typeof window === 'undefined' ? null : window;
810
+ return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
811
+ };
812
+
813
+ exports.__wbg_subarray_480600f3d6a9f26c = function(arg0, arg1, arg2) {
814
+ const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);
815
+ return ret;
816
+ };
817
+
818
+ exports.__wbg_versions_c01dfd4722a88165 = function(arg0) {
819
+ const ret = arg0.versions;
820
+ return ret;
821
+ };
822
+
823
+ exports.__wbindgen_cast_2241b6af4c4b2941 = function(arg0, arg1) {
824
+ // Cast intrinsic for `Ref(String) -> Externref`.
825
+ const ret = getStringFromWasm0(arg0, arg1);
826
+ return ret;
827
+ };
828
+
829
+ exports.__wbindgen_cast_cb9088102bce6b30 = function(arg0, arg1) {
830
+ // Cast intrinsic for `Ref(Slice(U8)) -> NamedExternref("Uint8Array")`.
831
+ const ret = getArrayU8FromWasm0(arg0, arg1);
832
+ return ret;
833
+ };
834
+
835
+ exports.__wbindgen_cast_d6cd19b81560fd6e = function(arg0) {
836
+ // Cast intrinsic for `F64 -> Externref`.
837
+ const ret = arg0;
838
+ return ret;
839
+ };
840
+
841
+ exports.__wbindgen_init_externref_table = function() {
842
+ const table = wasm.__wbindgen_externrefs;
843
+ const offset = table.grow(4);
844
+ table.set(0, undefined);
845
+ table.set(offset + 0, undefined);
846
+ table.set(offset + 1, null);
847
+ table.set(offset + 2, true);
848
+ table.set(offset + 3, false);
849
+ ;
850
+ };
851
+
852
+ const wasmPath = `${__dirname}/woxi_bg.wasm`;
853
+ const wasmBytes = require('fs').readFileSync(wasmPath);
854
+ const wasmModule = new WebAssembly.Module(wasmBytes);
855
+ const wasm = exports.__wasm = new WebAssembly.Instance(wasmModule, imports).exports;
856
+
857
+ wasm.__wbindgen_start();
858
+
Binary file
@@ -0,0 +1,28 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ export const memory: WebAssembly.Memory;
4
+ export const clear_virtual_files: () => void;
5
+ export const evaluate: (a: number, b: number) => [number, number];
6
+ export const evaluate_all: (a: number, b: number) => [number, number];
7
+ export const evaluate_expr: (a: number, b: number) => [number, number];
8
+ export const evaluate_manipulate: (a: number, b: number, c: number, d: number) => [number, number];
9
+ export const evaluate_manipulate_enabled: (a: number, b: number, c: number, d: number) => [number, number];
10
+ export const evaluate_manipulate_full: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => [number, number];
11
+ export const evaluate_statement: (a: number, b: number) => [number, number];
12
+ export const get_graphics: () => [number, number];
13
+ export const get_graphicsbox: () => [number, number];
14
+ export const get_output_svg: () => [number, number];
15
+ export const get_sound: () => [number, number];
16
+ export const get_warnings: () => [number, number];
17
+ export const set_dark_mode: (a: number) => void;
18
+ export const set_virtual_file: (a: number, b: number, c: number, d: number) => void;
19
+ export const split_statements: (a: number, b: number) => [number, number];
20
+ export const clear: () => void;
21
+ export const init: () => void;
22
+ export const __wbindgen_malloc: (a: number, b: number) => number;
23
+ export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
24
+ export const __wbindgen_exn_store: (a: number) => void;
25
+ export const __externref_table_alloc: () => number;
26
+ export const __wbindgen_externrefs: WebAssembly.Table;
27
+ export const __wbindgen_free: (a: number, b: number, c: number) => void;
28
+ export const __wbindgen_start: () => void;
package/readme.md ADDED
@@ -0,0 +1,111 @@
1
+ # Woxi
2
+
3
+ An interpreter for a subset of the
4
+ [Wolfram Language](https://www.wolfram.com/language/)
5
+ powered by Rust and compiled to WebAssembly.
6
+
7
+ This package wraps the [Woxi](https://github.com/ad-si/Woxi) interpreter
8
+ so it can be used from Node.js — no Wolfram installation required.
9
+ Woxi is a computer algebra system (CAS): computations are solved symbolically.
10
+
11
+
12
+ ## Installation
13
+
14
+ ```sh
15
+ npm install woxi-wasm
16
+ ```
17
+
18
+ (The package is named `woxi-wasm` because the name `woxi` is not
19
+ available on npm.)
20
+
21
+
22
+ ## Usage
23
+
24
+ ```js
25
+ import { evaluate } from "woxi-wasm"
26
+
27
+ evaluate("Plus[1, 2]") //=> "3"
28
+ evaluate("1/3 + 1/6") //=> "1/2"
29
+ evaluate("Sqrt[8]") //=> "2*Sqrt[2]"
30
+ evaluate('StringReverse["hello"]') //=> "olleh"
31
+ ```
32
+
33
+ CommonJS works too:
34
+
35
+ ```js
36
+ const { evaluate } = require("woxi-wasm")
37
+ ```
38
+
39
+ Interpreter state (variables, function definitions) persists across calls:
40
+
41
+ ```js
42
+ import woxi from "woxi-wasm"
43
+
44
+ woxi.evaluate("f[x_] := x^2")
45
+ woxi.evaluate("f[5]") //=> "25"
46
+ woxi.clear() // reset all state
47
+ ```
48
+
49
+
50
+ ### Structured output
51
+
52
+ `evaluateAll` returns one item per output, including graphics as SVG:
53
+
54
+ ```js
55
+ const items = woxi.evaluateAll('Print["hi"]\nGraphics[{Disk[]}]')
56
+ //=> [
57
+ // { type: "print", text: "hi" },
58
+ // { type: "graphics", svg: "<svg …" },
59
+ // ]
60
+ ```
61
+
62
+ Item types: `text`, `print`, `graphics`, `warning`, `error`, `sound`,
63
+ and `manipulate`.
64
+
65
+
66
+ ### Virtual files
67
+
68
+ There is no filesystem access from WebAssembly, so `Import[…]` reads from
69
+ an in-memory store you populate first:
70
+
71
+ ```js
72
+ woxi.setVirtualFile("data.csv", "a,b\n1,2\n")
73
+ woxi.evaluate('Import["data.csv"]') //=> "{{a, b}, {1, 2}}"
74
+ ```
75
+
76
+ `Import["https://…"]` fetches over HTTP automatically.
77
+
78
+
79
+ ## API
80
+
81
+ | Function | Description |
82
+ |------------------------------|---------------------------------------------------|
83
+ | `evaluate(code)` | Evaluate code, return output as a string |
84
+ | `evaluateAll(code)` | Evaluate code, return structured output items |
85
+ | `splitStatements(code)` | Split code into top-level statements |
86
+ | `evaluateStatement(stmt)` | Evaluate a single statement (structured output) |
87
+ | `getGraphics()` | SVG captured by the last `evaluate()` call |
88
+ | `getSound()` | Base64 audio captured by the last call |
89
+ | `getWarnings()` | Warnings of the last call as an array |
90
+ | `clear()` | Clear all interpreter state |
91
+ | `setDarkMode(enabled)` | Toggle dark-mode colors for SVG output |
92
+ | `setVirtualFile(name, data)` | Register an in-memory file for `Import[…]` |
93
+ | `clearVirtualFiles()` | Remove all registered in-memory files |
94
+
95
+ TypeScript definitions are included.
96
+
97
+
98
+ ## Development
99
+
100
+ The wasm bundle in `pkg/` is generated from the Rust sources — build it from
101
+ the [repository](https://github.com/ad-si/Woxi) root:
102
+
103
+ ```sh
104
+ make npm-build # build pkg/ with wasm-pack
105
+ make npm-test # build + run the JS test suite
106
+ ```
107
+
108
+
109
+ ## License
110
+
111
+ [AGPL-3.0-or-later](https://github.com/ad-si/Woxi/blob/main/license.txt)