UNPKG

img2num

Version:

Img2Num is a raster vectorization library - it converts images to SVGs

3,272 lines 110 kB
import { fileURLToPath as __i2nFileURLToPath } from "node:url";
import { dirname as __i2nDirname } from "node:path";
const __filename = __i2nFileURLToPath(import.meta.url);
const __dirname = __i2nDirname(__filename);
import { createRequire } from "node:module";
//#region \0rolldown/runtime.js
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
var __copyProps = (to, from, except, desc) => {
	if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
		key = keys[i];
		if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
			get: ((k) => from[k]).bind(null, key),
			enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
		});
	}
	return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
	value: mod,
	enumerable: true
}) : target, mod));
var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
//#endregion
//#region src/imageToUint8ClampedArray.js
/**
* @packageDocumentation
* Convenience image conversion utility to ensure type compatibility with the library.
*
* @file Convenience utility function.
*
* @module image-utils
* @license MIT
* @copyright Ryan Millard 2026
* @author Ryan Millard
* @since 0.0.0
*
* @exports imageToUint8ClampedArray
*/
/**
* @summary Convert an image file into a `Uint8ClampedArray` of pixel data (RGBA).
*
* @function imageToUint8ClampedArray
* @async
* @description
* Reads an image file (PNG, JPEG, etc.) and returns its pixel data as a `Uint8ClampedArray`.
* Each pixel consists of four consecutive values: red, green, blue, and alpha (RGBA).
* Also returns the image's original width and height. Useful for canvas operations,
* image processing, WebGL textures, or computer vision tasks.
*
*
* @param {File} file - The image file to process. Must be a valid `File` object, e.g., from an `<input type="file">` element.
*
* @returns {Promise<{pixels: Uint8ClampedArray, width: number, height: number}>}
* A Promise resolving to an object containing:
* - `pixels`: A `Uint8ClampedArray` of RGBA pixel values.
* - `width`: Width of the image in pixels.
* - `height`: Height of the image in pixels.
*
* @throws {Error} Will not throw in current implementation, but could reject if the image fails to load.
*
* @example
* const fileInput = document.querySelector("#fileInput");
* fileInput.addEventListener("change", async (event) => {
*   const file = event.target.files[0];
*   const { pixels, width, height } = await imageToUint8ClampedArray(file);
*   console.log("Width:", width, "Height:", height);
*   console.log("Pixels:", pixels);
* });
*
* @todo Add error handling for invalid or corrupt image files.
* @variation Standard image file input
*/
function imageToUint8ClampedArray(file) {
	return new Promise((resolve, reject) => {
		const img = new Image();
		const objectUrl = URL.createObjectURL(file);
		img.onload = () => {
			URL.revokeObjectURL(objectUrl);
			const canvas = document.createElement("canvas");
			canvas.width = img.width;
			canvas.height = img.height;
			const ctx = canvas.getContext("2d");
			ctx.drawImage(img, 0, 0);
			const { data } = ctx.getImageData(0, 0, img.width, img.height);
			resolve({
				pixels: data,
				width: img.width,
				height: img.height
			});
		};
		img.onerror = () => {
			URL.revokeObjectURL(objectUrl);
			reject(/* @__PURE__ */ new Error("Failed to load image"));
		};
		img.src = objectUrl;
	});
}
//#endregion
//#region src/wasmModule.js
var import_img2num = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
	async function createImg2NumModule$1(moduleArg = {}) {
		var Module = moduleArg;
		var ENVIRONMENT_IS_NODE = true;
		var thisProgram = "./this.program";
		var quit_ = (status, toThrow) => {
			throw toThrow;
		};
		if (typeof __filename != "undefined");
		var scriptDirectory = "";
		function locateFile(path) {
			if (Module["locateFile"]) return Module["locateFile"](path, scriptDirectory);
			return scriptDirectory + path;
		}
		var readAsync, readBinary;
		if (ENVIRONMENT_IS_NODE) {
			var fs = __require("node:fs");
			scriptDirectory = __dirname + "/";
			readBinary = (filename) => {
				filename = isFileURI(filename) ? new URL(filename) : filename;
				return fs.readFileSync(filename);
			};
			readAsync = async (filename, binary = true) => {
				filename = isFileURI(filename) ? new URL(filename) : filename;
				return fs.readFileSync(filename, binary ? void 0 : "utf8");
			};
			if (process.argv.length > 1) thisProgram = process.argv[1].replace(/\\/g, "/");
			process.argv.slice(2);
			quit_ = (status, toThrow) => {
				process.exitCode = status;
				throw toThrow;
			};
		}
		var out = console.log.bind(console);
		var err = console.error.bind(console);
		var wasmBinary;
		var ABORT = false;
		var EXITSTATUS;
		function assert(condition, text) {
			if (!condition) abort(text);
		}
		var isFileURI = (filename) => filename.startsWith("file://");
		class EmscriptenEH {}
		class CppException extends EmscriptenEH {
			constructor(excPtr) {
				super();
				this.excPtr = excPtr;
			}
		}
		function getMemoryBuffer() {
			return wasmMemory.buffer;
		}
		function updateMemoryViews() {
			if (HEAP8?.buffer?.resizable) return;
			var b = getMemoryBuffer();
			HEAP8 = new Int8Array(b);
			HEAP16 = new Int16Array(b);
			Module["HEAPU8"] = HEAPU8 = new Uint8Array(b);
			Module["HEAP32"] = HEAP32 = new Int32Array(b);
			HEAPU32 = new Uint32Array(b);
			HEAPF32 = new Float32Array(b);
			HEAPF64 = new Float64Array(b);
			HEAP64 = new BigInt64Array(b);
		}
		function preRun() {
			var preRun = Module["preRun"];
			if (preRun) {
				if (typeof preRun == "function") preRun = [preRun];
				onPreRuns.push(...preRun);
			}
			callRuntimeCallbacks(onPreRuns);
		}
		function initRuntime() {
			wasmExports["ra"]();
		}
		function postRun() {
			var postRun = Module["postRun"];
			if (postRun) {
				if (typeof postRun == "function") postRun = [postRun];
				onPostRuns.push(...postRun);
			}
			callRuntimeCallbacks(onPostRuns);
		}
		function abort(what) {
			Module["onAbort"]?.(what);
			what = `Aborted(${what})`;
			err(what);
			ABORT = true;
			what += ". Build with -sASSERTIONS for more info.";
			throw new WebAssembly.RuntimeError(what);
		}
		var wasmBinaryFile;
		function findWasmBinary() {
			return locateFile("img2num.wasm");
		}
		function getBinarySync(file) {
			if (readBinary) return readBinary(file);
			throw "both async and sync fetching of the wasm failed";
		}
		async function getWasmBinary(binaryFile) {
			if (!wasmBinary) try {
				var response = await readAsync(binaryFile);
				return new Uint8Array(response);
			} catch {}
			return getBinarySync(binaryFile);
		}
		async function instantiateArrayBuffer(binaryFile, imports) {
			try {
				var binary = await getWasmBinary(binaryFile);
				return await WebAssembly.instantiate(binary, imports);
			} catch (reason) {
				err(`failed to asynchronously prepare wasm: ${reason}`);
				abort(reason);
			}
		}
		async function instantiateAsync(binary, binaryFile, imports) {
			if (!binary && !ENVIRONMENT_IS_NODE) try {
				var response = fetch(binaryFile, { credentials: "same-origin" });
				return await WebAssembly.instantiateStreaming(response, imports);
			} catch (reason) {
				err(`wasm streaming compile failed: ${reason}`);
				err("falling back to ArrayBuffer instantiation");
			}
			return instantiateArrayBuffer(binaryFile, imports);
		}
		function getWasmImports() {
			return { a: wasmImports };
		}
		async function createWasm() {
			function receiveInstance(instance) {
				wasmExports = instance.exports;
				wasmExports = Asyncify.instrumentWasmExports(wasmExports);
				wasmExports = applySignatureConversions(wasmExports);
				assignWasmExports(wasmExports);
				updateMemoryViews();
				return wasmExports;
			}
			function receiveInstantiationResult(result) {
				return receiveInstance(result["instance"]);
			}
			var info = getWasmImports();
			var instantiateWasm = Module["instantiateWasm"];
			if (instantiateWasm) return new Promise((resolve) => {
				instantiateWasm(info, (inst) => resolve(receiveInstance(inst)));
			});
			wasmBinaryFile ??= findWasmBinary();
			return receiveInstantiationResult(await instantiateAsync(wasmBinary, wasmBinaryFile, info));
		}
		class ExitStatus {
			name = "ExitStatus";
			constructor(status) {
				this.message = `Program terminated with exit(${status})`;
				this.status = status;
			}
		}
		var HEAP8;
		var callRuntimeCallbacks = (callbacks) => {
			while (callbacks.length > 0) callbacks.shift()(Module);
		};
		var onPostRuns = [];
		var onPreRuns = [];
		var dynCalls = {};
		var noExitRuntime = true;
		var stackRestore = (val) => __emscripten_stack_restore(val);
		var stackSave = () => _emscripten_stack_get_current();
		var exceptionCaught = [];
		var uncaughtExceptionCount = 0;
		var INT53_MAX = 9007199254740992;
		var INT53_MIN = -9007199254740992;
		var bigintToI53Checked = (num) => num < INT53_MIN || num > INT53_MAX ? NaN : Number(num);
		function ___cxa_begin_catch(ptr) {
			ptr >>>= 0;
			var info = new ExceptionInfo(ptr);
			if (!info.get_caught()) {
				info.set_caught(true);
				uncaughtExceptionCount--;
			}
			info.set_rethrown(false);
			exceptionCaught.push(info);
			return ___cxa_get_exception_ptr(ptr);
		}
		var exceptionLast = null;
		var ___cxa_end_catch = () => {
			_setThrew(0, 0);
			var info = exceptionCaught.pop();
			___cxa_decrement_exception_refcount(info.excPtr);
			exceptionLast = null;
		};
		var HEAPU32;
		class ExceptionInfo {
			constructor(excPtr) {
				this.excPtr = excPtr;
				this.ptr = excPtr - 24;
			}
			set_type(type) {
				HEAPU32[this.ptr + 4 >>> 2 >>> 0] = type;
			}
			get_type() {
				return HEAPU32[this.ptr + 4 >>> 2 >>> 0];
			}
			set_destructor(destructor) {
				HEAPU32[this.ptr + 8 >>> 2 >>> 0] = destructor;
			}
			get_destructor() {
				return HEAPU32[this.ptr + 8 >>> 2 >>> 0];
			}
			set_caught(caught) {
				caught = caught ? 1 : 0;
				HEAP8[this.ptr + 12 >>> 0] = caught;
			}
			get_caught() {
				return HEAP8[this.ptr + 12 >>> 0] != 0;
			}
			set_rethrown(rethrown) {
				rethrown = rethrown ? 1 : 0;
				HEAP8[this.ptr + 13 >>> 0] = rethrown;
			}
			get_rethrown() {
				return HEAP8[this.ptr + 13 >>> 0] != 0;
			}
			init(type, destructor) {
				this.set_adjusted_ptr(0);
				this.set_type(type);
				this.set_destructor(destructor);
			}
			set_adjusted_ptr(adjustedPtr) {
				HEAPU32[this.ptr + 16 >>> 2 >>> 0] = adjustedPtr;
			}
			get_adjusted_ptr() {
				return HEAPU32[this.ptr + 16 >>> 2 >>> 0];
			}
		}
		var setTempRet0 = (val) => __emscripten_tempret_set(val);
		var findMatchingCatch = (args) => {
			var thrown = exceptionLast?.excPtr;
			if (!thrown) {
				setTempRet0(0);
				return 0;
			}
			var info = new ExceptionInfo(thrown);
			info.set_adjusted_ptr(thrown);
			var thrownType = info.get_type();
			if (!thrownType) {
				setTempRet0(0);
				return thrown;
			}
			for (var caughtType of args) {
				if (!caughtType || caughtType === thrownType) break;
				var adjusted_ptr_addr = info.ptr + 16;
				if (___cxa_can_catch(caughtType, thrownType, adjusted_ptr_addr)) {
					setTempRet0(caughtType);
					return thrown;
				}
			}
			setTempRet0(thrownType);
			return thrown;
		};
		function ___cxa_find_matching_catch_2() {
			return findMatchingCatch([]);
		}
		function ___cxa_find_matching_catch_3(arg0) {
			arg0 >>>= 0;
			return findMatchingCatch([arg0]);
		}
		var __Unwind_RaiseException = (ex) => {
			throw ex;
		};
		var ___cxa_rethrow = () => {
			if (!exceptionCaught.length) abort("no exception to throw");
			var info = exceptionCaught.at(-1);
			var ptr = info.excPtr;
			info.set_rethrown(true);
			info.set_caught(false);
			uncaughtExceptionCount++;
			___cxa_increment_exception_refcount(ptr);
			ptr = exceptionLast = new CppException(ptr);
			__Unwind_RaiseException(ptr);
		};
		function ___cxa_throw(ptr, type, destructor) {
			ptr >>>= 0;
			type >>>= 0;
			destructor >>>= 0;
			new ExceptionInfo(ptr).init(type, destructor);
			___cxa_increment_exception_refcount(ptr);
			ptr = exceptionLast = new CppException(ptr);
			uncaughtExceptionCount++;
			__Unwind_RaiseException(ptr);
		}
		var ___cxa_uncaught_exceptions = () => uncaughtExceptionCount;
		var __Unwind_Resume = (ex) => {
			throw ex;
		};
		function ___resumeException(ptr) {
			ptr >>>= 0;
			ptr = exceptionLast ??= new CppException(ptr);
			__Unwind_Resume(ptr);
		}
		var __abort_js = () => abort("");
		var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
			outIdx >>>= 0;
			if (!(maxBytesToWrite > 0)) return 0;
			var startIdx = outIdx;
			var endIdx = outIdx + maxBytesToWrite - 1;
			for (var i = 0; i < str.length; ++i) {
				var u = str.codePointAt(i);
				if (u <= 127) {
					if (outIdx >= endIdx) break;
					heap[outIdx++ >>> 0] = u;
				} else if (u <= 2047) {
					if (outIdx + 1 >= endIdx) break;
					heap[outIdx++ >>> 0] = 192 | u >> 6;
					heap[outIdx++ >>> 0] = 128 | u & 63;
				} else if (u <= 65535) {
					if (outIdx + 2 >= endIdx) break;
					heap[outIdx++ >>> 0] = 224 | u >> 12;
					heap[outIdx++ >>> 0] = 128 | u >> 6 & 63;
					heap[outIdx++ >>> 0] = 128 | u & 63;
				} else {
					if (outIdx + 3 >= endIdx) break;
					heap[outIdx++ >>> 0] = 240 | u >> 18;
					heap[outIdx++ >>> 0] = 128 | u >> 12 & 63;
					heap[outIdx++ >>> 0] = 128 | u >> 6 & 63;
					heap[outIdx++ >>> 0] = 128 | u & 63;
					i++;
				}
			}
			heap[outIdx >>> 0] = 0;
			return outIdx - startIdx;
		};
		var HEAPU8;
		var stringToUTF8 = (str, outPtr, maxBytesToWrite) => stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
		var HEAP32;
		var __tzset_js = function(timezone, daylight, std_name, dst_name) {
			timezone >>>= 0;
			daylight >>>= 0;
			std_name >>>= 0;
			dst_name >>>= 0;
			var currentYear = (/* @__PURE__ */ new Date()).getFullYear();
			var winter = new Date(currentYear, 0, 1);
			var summer = new Date(currentYear, 6, 1);
			var winterOffset = winter.getTimezoneOffset();
			var summerOffset = summer.getTimezoneOffset();
			var stdTimezoneOffset = Math.max(winterOffset, summerOffset);
			HEAPU32[timezone >>> 2 >>> 0] = stdTimezoneOffset * 60;
			HEAP32[daylight >>> 2 >>> 0] = Number(winterOffset != summerOffset);
			var extractZone = (timezoneOffset) => {
				var sign = timezoneOffset >= 0 ? "-" : "+";
				var absOffset = Math.abs(timezoneOffset);
				return `UTC${sign}${String(Math.floor(absOffset / 60)).padStart(2, "0")}${String(absOffset % 60).padStart(2, "0")}`;
			};
			var winterName = extractZone(winterOffset);
			var summerName = extractZone(summerOffset);
			if (summerOffset < winterOffset) {
				stringToUTF8(winterName, std_name, 17);
				stringToUTF8(summerName, dst_name, 17);
			} else {
				stringToUTF8(winterName, dst_name, 17);
				stringToUTF8(summerName, std_name, 17);
			}
		};
		var _emscripten_has_asyncify = () => 1;
		var getHeapMax = () => 4294901760;
		var alignMemory = (size, alignment) => Math.ceil(size / alignment) * alignment;
		var growMemory = (size) => {
			var pages = (size - wasmMemory.buffer.byteLength + 65535) / 65536 | 0;
			try {
				wasmMemory.grow(pages);
				updateMemoryViews();
				return 1;
			} catch (e) {}
		};
		function _emscripten_resize_heap(requestedSize) {
			requestedSize >>>= 0;
			var oldSize = HEAPU8.length;
			var maxHeapSize = getHeapMax();
			if (requestedSize > maxHeapSize) return false;
			for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
				var overGrownHeapSize = oldSize * (1 + .2 / cutDown);
				overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296);
				if (growMemory(Math.min(maxHeapSize, alignMemory(Math.max(requestedSize, overGrownHeapSize), 65536)))) return true;
			}
			return false;
		}
		var _emscripten_sleep = function(ms) {
			let innerFunc = () => new Promise((resolve) => setTimeout(resolve, ms));
			return Asyncify.handleAsync(innerFunc);
		};
		_emscripten_sleep.isAsync = true;
		var lengthBytesUTF8 = (str) => {
			var len = 0;
			for (var i = 0; i < str.length; ++i) {
				var c = str.charCodeAt(i);
				if (c <= 127) len++;
				else if (c <= 2047) len += 2;
				else if (c >= 55296 && c <= 57343) {
					len += 4;
					++i;
				} else len += 3;
			}
			return len;
		};
		var stackAlloc = (sz) => __emscripten_stack_alloc(sz);
		var stringToUTF8OnStack = (str) => {
			var size = lengthBytesUTF8(str) + 1;
			var ret = stackAlloc(size);
			stringToUTF8(str, ret, size);
			return ret;
		};
		var UTF8Decoder = globalThis.TextDecoder && new TextDecoder();
		var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
			var maxIdx = idx + maxBytesToRead;
			if (ignoreNul) return maxIdx;
			while (heapOrArray[idx] && !(idx >= maxIdx)) ++idx;
			return idx;
		};
		var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead, ignoreNul) => {
			idx >>>= 0;
			var endPtr = findStringEnd(heapOrArray, idx, maxBytesToRead, ignoreNul);
			if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
			var str = "";
			while (idx < endPtr) {
				var u0 = heapOrArray[idx++];
				if (!(u0 & 128)) {
					str += String.fromCharCode(u0);
					continue;
				}
				var u1 = heapOrArray[idx++] & 63;
				if ((u0 & 224) == 192) {
					str += String.fromCharCode((u0 & 31) << 6 | u1);
					continue;
				}
				var u2 = heapOrArray[idx++] & 63;
				if ((u0 & 240) == 224) u0 = (u0 & 15) << 12 | u1 << 6 | u2;
				else u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heapOrArray[idx++] & 63;
				if (u0 < 65536) str += String.fromCharCode(u0);
				else {
					var ch = u0 - 65536;
					str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);
				}
			}
			return str;
		};
		var UTF8ToString = (ptr, maxBytesToRead, ignoreNul) => {
			ptr >>>= 0;
			return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead, ignoreNul) : "";
		};
		var writeI53ToI64 = (ptr, num) => {
			HEAPU32[ptr >>> 2 >>> 0] = num;
			var lower = HEAPU32[ptr >>> 2 >>> 0];
			HEAPU32[ptr + 4 >>> 2 >>> 0] = (num - lower) / 4294967296;
		};
		var stringToNewUTF8 = (str) => {
			var size = lengthBytesUTF8(str) + 1;
			var ret = _malloc(size);
			if (ret) stringToUTF8(str, ret, size);
			return ret;
		};
		var readI53FromI64 = (ptr) => HEAPU32[ptr >>> 2 >>> 0] + HEAP32[ptr + 4 >>> 2 >>> 0] * 4294967296;
		var HEAPF32;
		var HEAPF64;
		var WebGPU = {
			Internals: {
				jsObjects: [],
				jsObjectInsert: (ptr, jsObject) => {
					ptr >>>= 0;
					WebGPU.Internals.jsObjects[ptr] = jsObject;
				},
				bufferOnUnmaps: [],
				futures: [],
				futureInsert: (futureId, promise) => {
					WebGPU.Internals.futures[futureId] = new Promise((resolve) => promise.finally(() => resolve(futureId)));
				}
			},
			getJsObject: (ptr) => {
				if (!ptr) return void 0;
				ptr >>>= 0;
				return WebGPU.Internals.jsObjects[ptr];
			},
			importJsAdapter: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateAdapter(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsBindGroup: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateBindGroup(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsBindGroupLayout: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateBindGroupLayout(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsBuffer: (buffer, parentPtr = 0) => {
				assert(buffer.mapState === "unmapped");
				var bufferPtr = _emwgpuImportBuffer(parentPtr);
				WebGPU.Internals.jsObjectInsert(bufferPtr, buffer);
				return bufferPtr;
			},
			importJsCommandBuffer: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateCommandBuffer(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsCommandEncoder: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateCommandEncoder(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsComputePassEncoder: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateComputePassEncoder(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsComputePipeline: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateComputePipeline(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsDevice: (device, parentPtr = 0) => {
				var queuePtr = _emwgpuCreateQueue(parentPtr);
				var devicePtr = _emwgpuCreateDevice(parentPtr, queuePtr);
				WebGPU.Internals.jsObjectInsert(queuePtr, device.queue);
				WebGPU.Internals.jsObjectInsert(devicePtr, device);
				return devicePtr;
			},
			importJsExternalTexture: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateExternalTexture(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsPipelineLayout: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreatePipelineLayout(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsQuerySet: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateQuerySet(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsQueue: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateQueue(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsRenderBundle: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateRenderBundle(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsRenderBundleEncoder: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateRenderBundleEncoder(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsRenderPassEncoder: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateRenderPassEncoder(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsRenderPipeline: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateRenderPipeline(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsSampler: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateSampler(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsShaderModule: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateShaderModule(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsSurface: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateSurface(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsTexture: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateTexture(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			importJsTextureView: (obj, parentPtr = 0) => {
				var ptr = _emwgpuCreateTextureView(parentPtr);
				WebGPU.Internals.jsObjects[ptr] = obj;
				return ptr;
			},
			errorCallback: (callback, type, message, userdata) => {
				var sp = stackSave();
				((a1, a2, a3) => dynCall_viii(callback, a1, a2, a3))(type, stringToUTF8OnStack(message), userdata);
				stackRestore(sp);
			},
			iterateExtensions: (root, handlers) => {
				for (var ptr = HEAPU32[root >>> 2 >>> 0]; ptr; ptr = HEAPU32[ptr >>> 2 >>> 0]) handlers[HEAP32[ptr + 4 >>> 2 >>> 0]](ptr);
			},
			setStringView: (ptr, data, length) => {
				HEAPU32[ptr >>> 2 >>> 0] = data;
				HEAPU32[ptr + 4 >>> 2 >>> 0] = length;
			},
			makeStringFromStringView: (stringViewPtr) => {
				var ptr = HEAPU32[stringViewPtr >>> 2 >>> 0];
				var length = HEAPU32[stringViewPtr + 4 >>> 2 >>> 0];
				return UTF8ToString(ptr, length);
			},
			makeStringFromOptionalStringView: (stringViewPtr) => {
				var ptr = HEAPU32[stringViewPtr >>> 2 >>> 0];
				var length = HEAPU32[stringViewPtr + 4 >>> 2 >>> 0];
				if (!ptr) {
					if (length === 0) return "";
					return;
				}
				return UTF8ToString(ptr, length);
			},
			makeColor: (ptr) => ({
				r: HEAPF64[ptr >>> 3 >>> 0],
				g: HEAPF64[ptr + 8 >>> 3 >>> 0],
				b: HEAPF64[ptr + 16 >>> 3 >>> 0],
				a: HEAPF64[ptr + 24 >>> 3 >>> 0]
			}),
			makeExtent3D: (ptr) => ({
				width: HEAPU32[ptr >>> 2 >>> 0],
				height: HEAPU32[ptr + 4 >>> 2 >>> 0],
				depthOrArrayLayers: HEAPU32[ptr + 8 >>> 2 >>> 0]
			}),
			makeOrigin3D: (ptr) => ({
				x: HEAPU32[ptr >>> 2 >>> 0],
				y: HEAPU32[ptr + 4 >>> 2 >>> 0],
				z: HEAPU32[ptr + 8 >>> 2 >>> 0]
			}),
			makeTexelCopyTextureInfo: (ptr) => ({
				texture: WebGPU.getJsObject(HEAPU32[ptr >>> 2 >>> 0]),
				mipLevel: HEAPU32[ptr + 4 >>> 2 >>> 0],
				origin: WebGPU.makeOrigin3D(ptr + 8),
				aspect: WebGPU.TextureAspect[HEAP32[ptr + 20 >>> 2 >>> 0]]
			}),
			makeTexelCopyBufferLayout: (ptr) => {
				var bytesPerRow = HEAPU32[ptr + 8 >>> 2 >>> 0];
				var rowsPerImage = HEAPU32[ptr + 12 >>> 2 >>> 0];
				return {
					offset: readI53FromI64(ptr),
					bytesPerRow: bytesPerRow === 4294967295 ? void 0 : bytesPerRow,
					rowsPerImage: rowsPerImage === 4294967295 ? void 0 : rowsPerImage
				};
			},
			makeTexelCopyBufferInfo: (ptr) => {
				var layoutPtr = ptr + 0;
				var bufferCopyView = WebGPU.makeTexelCopyBufferLayout(layoutPtr);
				bufferCopyView["buffer"] = WebGPU.getJsObject(HEAPU32[ptr + 16 >>> 2 >>> 0]);
				return bufferCopyView;
			},
			makePassTimestampWrites: (ptr) => {
				if (ptr === 0) return void 0;
				return {
					querySet: WebGPU.getJsObject(HEAPU32[ptr + 4 >>> 2 >>> 0]),
					beginningOfPassWriteIndex: HEAPU32[ptr + 8 >>> 2 >>> 0],
					endOfPassWriteIndex: HEAPU32[ptr + 12 >>> 2 >>> 0]
				};
			},
			makePipelineConstants: (constantCount, constantsPtr) => {
				if (!constantCount) return;
				var constants = {};
				for (var i = 0; i < constantCount; ++i) {
					var entryPtr = constantsPtr + 24 * i;
					var key = WebGPU.makeStringFromStringView(entryPtr + 4);
					constants[key] = HEAPF64[entryPtr + 16 >>> 3 >>> 0];
				}
				return constants;
			},
			makePipelineLayout: (layoutPtr) => {
				if (!layoutPtr) return "auto";
				return WebGPU.getJsObject(layoutPtr);
			},
			makeComputeState: (ptr) => {
				if (!ptr) return void 0;
				return {
					module: WebGPU.getJsObject(HEAPU32[ptr + 4 >>> 2 >>> 0]),
					constants: WebGPU.makePipelineConstants(HEAPU32[ptr + 16 >>> 2 >>> 0], HEAPU32[ptr + 20 >>> 2 >>> 0]),
					entryPoint: WebGPU.makeStringFromOptionalStringView(ptr + 8)
				};
			},
			makeComputePipelineDesc: (descriptor) => {
				return {
					label: WebGPU.makeStringFromOptionalStringView(descriptor + 4),
					layout: WebGPU.makePipelineLayout(HEAPU32[descriptor + 12 >>> 2 >>> 0]),
					compute: WebGPU.makeComputeState(descriptor + 16)
				};
			},
			makeRenderPipelineDesc: (descriptor) => {
				function makePrimitiveState(psPtr) {
					if (!psPtr) return void 0;
					return {
						topology: WebGPU.PrimitiveTopology[HEAP32[psPtr + 4 >>> 2 >>> 0]],
						stripIndexFormat: WebGPU.IndexFormat[HEAP32[psPtr + 8 >>> 2 >>> 0]],
						frontFace: WebGPU.FrontFace[HEAP32[psPtr + 12 >>> 2 >>> 0]],
						cullMode: WebGPU.CullMode[HEAP32[psPtr + 16 >>> 2 >>> 0]],
						unclippedDepth: !!HEAPU32[psPtr + 20 >>> 2 >>> 0]
					};
				}
				function makeBlendComponent(bdPtr) {
					if (!bdPtr) return void 0;
					return {
						operation: WebGPU.BlendOperation[HEAP32[bdPtr >>> 2 >>> 0]],
						srcFactor: WebGPU.BlendFactor[HEAP32[bdPtr + 4 >>> 2 >>> 0]],
						dstFactor: WebGPU.BlendFactor[HEAP32[bdPtr + 8 >>> 2 >>> 0]]
					};
				}
				function makeBlendState(bsPtr) {
					if (!bsPtr) return void 0;
					return {
						alpha: makeBlendComponent(bsPtr + 12),
						color: makeBlendComponent(bsPtr + 0)
					};
				}
				function makeColorState(csPtr) {
					var format = WebGPU.TextureFormat[HEAP32[csPtr + 4 >>> 2 >>> 0]];
					return format ? {
						format,
						blend: makeBlendState(HEAPU32[csPtr + 8 >>> 2 >>> 0]),
						writeMask: HEAPU32[csPtr + 16 >>> 2 >>> 0]
					} : void 0;
				}
				function makeColorStates(count, csArrayPtr) {
					var states = [];
					for (var i = 0; i < count; ++i) states.push(makeColorState(csArrayPtr + 24 * i));
					return states;
				}
				function makeStencilStateFace(ssfPtr) {
					return {
						compare: WebGPU.CompareFunction[HEAP32[ssfPtr >>> 2 >>> 0]],
						failOp: WebGPU.StencilOperation[HEAP32[ssfPtr + 4 >>> 2 >>> 0]],
						depthFailOp: WebGPU.StencilOperation[HEAP32[ssfPtr + 8 >>> 2 >>> 0]],
						passOp: WebGPU.StencilOperation[HEAP32[ssfPtr + 12 >>> 2 >>> 0]]
					};
				}
				function makeDepthStencilState(dssPtr) {
					if (!dssPtr) return void 0;
					return {
						format: WebGPU.TextureFormat[HEAP32[dssPtr + 4 >>> 2 >>> 0]],
						depthWriteEnabled: !!HEAPU32[dssPtr + 8 >>> 2 >>> 0],
						depthCompare: WebGPU.CompareFunction[HEAP32[dssPtr + 12 >>> 2 >>> 0]],
						stencilFront: makeStencilStateFace(dssPtr + 16),
						stencilBack: makeStencilStateFace(dssPtr + 32),
						stencilReadMask: HEAPU32[dssPtr + 48 >>> 2 >>> 0],
						stencilWriteMask: HEAPU32[dssPtr + 52 >>> 2 >>> 0],
						depthBias: HEAP32[dssPtr + 56 >>> 2 >>> 0],
						depthBiasSlopeScale: HEAPF32[dssPtr + 60 >>> 2 >>> 0],
						depthBiasClamp: HEAPF32[dssPtr + 64 >>> 2 >>> 0]
					};
				}
				function makeVertexAttribute(vaPtr) {
					return {
						format: WebGPU.VertexFormat[HEAP32[vaPtr + 4 >>> 2 >>> 0]],
						offset: readI53FromI64(vaPtr + 8),
						shaderLocation: HEAPU32[vaPtr + 16 >>> 2 >>> 0]
					};
				}
				function makeVertexAttributes(count, vaArrayPtr) {
					var vas = [];
					for (var i = 0; i < count; ++i) vas.push(makeVertexAttribute(vaArrayPtr + i * 24));
					return vas;
				}
				function makeVertexBuffer(vbPtr) {
					if (!vbPtr) return void 0;
					var stepMode = WebGPU.VertexStepMode[HEAP32[vbPtr + 4 >>> 2 >>> 0]];
					var attributeCount = HEAPU32[vbPtr + 16 >>> 2 >>> 0];
					if (!stepMode && !attributeCount) return null;
					return {
						arrayStride: readI53FromI64(vbPtr + 8),
						stepMode,
						attributes: makeVertexAttributes(attributeCount, HEAPU32[vbPtr + 20 >>> 2 >>> 0])
					};
				}
				function makeVertexBuffers(count, vbArrayPtr) {
					if (!count) return void 0;
					var vbs = [];
					for (var i = 0; i < count; ++i) vbs.push(makeVertexBuffer(vbArrayPtr + i * 24));
					return vbs;
				}
				function makeVertexState(viPtr) {
					if (!viPtr) return void 0;
					return {
						module: WebGPU.getJsObject(HEAPU32[viPtr + 4 >>> 2 >>> 0]),
						constants: WebGPU.makePipelineConstants(HEAPU32[viPtr + 16 >>> 2 >>> 0], HEAPU32[viPtr + 20 >>> 2 >>> 0]),
						buffers: makeVertexBuffers(HEAPU32[viPtr + 24 >>> 2 >>> 0], HEAPU32[viPtr + 28 >>> 2 >>> 0]),
						entryPoint: WebGPU.makeStringFromOptionalStringView(viPtr + 8)
					};
				}
				function makeMultisampleState(msPtr) {
					if (!msPtr) return void 0;
					return {
						count: HEAPU32[msPtr + 4 >>> 2 >>> 0],
						mask: HEAPU32[msPtr + 8 >>> 2 >>> 0],
						alphaToCoverageEnabled: !!HEAPU32[msPtr + 12 >>> 2 >>> 0]
					};
				}
				function makeFragmentState(fsPtr) {
					if (!fsPtr) return void 0;
					return {
						module: WebGPU.getJsObject(HEAPU32[fsPtr + 4 >>> 2 >>> 0]),
						constants: WebGPU.makePipelineConstants(HEAPU32[fsPtr + 16 >>> 2 >>> 0], HEAPU32[fsPtr + 20 >>> 2 >>> 0]),
						targets: makeColorStates(HEAPU32[fsPtr + 24 >>> 2 >>> 0], HEAPU32[fsPtr + 28 >>> 2 >>> 0]),
						entryPoint: WebGPU.makeStringFromOptionalStringView(fsPtr + 8)
					};
				}
				return {
					label: WebGPU.makeStringFromOptionalStringView(descriptor + 4),
					layout: WebGPU.makePipelineLayout(HEAPU32[descriptor + 12 >>> 2 >>> 0]),
					vertex: makeVertexState(descriptor + 16),
					primitive: makePrimitiveState(descriptor + 48),
					depthStencil: makeDepthStencilState(HEAPU32[descriptor + 72 >>> 2 >>> 0]),
					multisample: makeMultisampleState(descriptor + 76),
					fragment: makeFragmentState(HEAPU32[descriptor + 92 >>> 2 >>> 0])
				};
			},
			fillLimitStruct: (limits, limitsOutPtr) => {
				var nextInChainPtr = HEAPU32[limitsOutPtr >>> 2 >>> 0];
				function setLimitValueU32(name, basePtr, limitOffset, fallbackValue = 0) {
					var limitValue = limits[name] ?? fallbackValue;
					HEAPU32[basePtr + limitOffset >>> 2 >>> 0] = limitValue;
				}
				function setLimitValueU64(name, basePtr, limitOffset, fallbackValue = 0) {
					var limitValue = limits[name] ?? fallbackValue;
					writeI53ToI64(basePtr + limitOffset, limitValue);
				}
				setLimitValueU32("maxTextureDimension1D", limitsOutPtr, 4);
				setLimitValueU32("maxTextureDimension2D", limitsOutPtr, 8);
				setLimitValueU32("maxTextureDimension3D", limitsOutPtr, 12);
				setLimitValueU32("maxTextureArrayLayers", limitsOutPtr, 16);
				setLimitValueU32("maxBindGroups", limitsOutPtr, 20);
				setLimitValueU32("maxBindGroupsPlusVertexBuffers", limitsOutPtr, 24);
				setLimitValueU32("maxBindingsPerBindGroup", limitsOutPtr, 28);
				setLimitValueU32("maxDynamicUniformBuffersPerPipelineLayout", limitsOutPtr, 32);
				setLimitValueU32("maxDynamicStorageBuffersPerPipelineLayout", limitsOutPtr, 36);
				setLimitValueU32("maxSampledTexturesPerShaderStage", limitsOutPtr, 40);
				setLimitValueU32("maxSamplersPerShaderStage", limitsOutPtr, 44);
				setLimitValueU32("maxStorageBuffersPerShaderStage", limitsOutPtr, 48);
				setLimitValueU32("maxStorageTexturesPerShaderStage", limitsOutPtr, 52);
				setLimitValueU32("maxUniformBuffersPerShaderStage", limitsOutPtr, 56);
				setLimitValueU32("minUniformBufferOffsetAlignment", limitsOutPtr, 80);
				setLimitValueU32("minStorageBufferOffsetAlignment", limitsOutPtr, 84);
				setLimitValueU64("maxUniformBufferBindingSize", limitsOutPtr, 64);
				setLimitValueU64("maxStorageBufferBindingSize", limitsOutPtr, 72);
				setLimitValueU32("maxVertexBuffers", limitsOutPtr, 88);
				setLimitValueU64("maxBufferSize", limitsOutPtr, 96);
				setLimitValueU32("maxVertexAttributes", limitsOutPtr, 104);
				setLimitValueU32("maxVertexBufferArrayStride", limitsOutPtr, 108);
				setLimitValueU32("maxInterStageShaderVariables", limitsOutPtr, 112);
				setLimitValueU32("maxColorAttachments", limitsOutPtr, 116);
				setLimitValueU32("maxColorAttachmentBytesPerSample", limitsOutPtr, 120);
				setLimitValueU32("maxComputeWorkgroupStorageSize", limitsOutPtr, 124);
				setLimitValueU32("maxComputeInvocationsPerWorkgroup", limitsOutPtr, 128);
				setLimitValueU32("maxComputeWorkgroupSizeX", limitsOutPtr, 132);
				setLimitValueU32("maxComputeWorkgroupSizeY", limitsOutPtr, 136);
				setLimitValueU32("maxComputeWorkgroupSizeZ", limitsOutPtr, 140);
				setLimitValueU32("maxComputeWorkgroupsPerDimension", limitsOutPtr, 144);
				setLimitValueU32("maxImmediateSize", limitsOutPtr, 148);
				if (nextInChainPtr !== 0) {
					HEAP32[nextInChainPtr + 4 >>> 2 >>> 0];
					var compatibilityModeLimitsPtr = nextInChainPtr;
					setLimitValueU32("maxStorageBuffersInVertexStage", compatibilityModeLimitsPtr, 8, limits.maxStorageBuffersPerShaderStage);
					setLimitValueU32("maxStorageBuffersInFragmentStage", compatibilityModeLimitsPtr, 16, limits.maxStorageBuffersPerShaderStage);
					setLimitValueU32("maxStorageTexturesInVertexStage", compatibilityModeLimitsPtr, 12, limits.maxStorageTexturesPerShaderStage);
					setLimitValueU32("maxStorageTexturesInFragmentStage", compatibilityModeLimitsPtr, 20, limits.maxStorageTexturesPerShaderStage);
				}
			},
			fillAdapterInfoStruct: (info, infoStruct) => {
				HEAPU32[infoStruct + 52 >>> 2 >>> 0] = info.subgroupMinSize;
				HEAPU32[infoStruct + 56 >>> 2 >>> 0] = info.subgroupMaxSize;
				var strPtr = stringToNewUTF8(info.vendor + info.architecture + info.device + info.description);
				var vendorLen = lengthBytesUTF8(info.vendor);
				WebGPU.setStringView(infoStruct + 4, strPtr, vendorLen);
				strPtr += vendorLen;
				var architectureLen = lengthBytesUTF8(info.architecture);
				WebGPU.setStringView(infoStruct + 12, strPtr, architectureLen);
				strPtr += architectureLen;
				var deviceLen = lengthBytesUTF8(info.device);
				WebGPU.setStringView(infoStruct + 20, strPtr, deviceLen);
				strPtr += deviceLen;
				var descriptionLen = lengthBytesUTF8(info.description);
				WebGPU.setStringView(infoStruct + 28, strPtr, descriptionLen);
				strPtr += descriptionLen;
				HEAP32[infoStruct + 36 >>> 2 >>> 0] = 2;
				var adapterType = info.isFallbackAdapter ? 3 : 4;
				HEAP32[infoStruct + 40 >>> 2 >>> 0] = adapterType;
				HEAPU32[infoStruct + 44 >>> 2 >>> 0] = 0;
				HEAPU32[infoStruct + 48 >>> 2 >>> 0] = 0;
			},
			AddressMode: [
				,
				"clamp-to-edge",
				"repeat",
				"mirror-repeat"
			],
			BlendFactor: [
				,
				"zero",
				"one",
				"src",
				"one-minus-src",
				"src-alpha",
				"one-minus-src-alpha",
				"dst",
				"one-minus-dst",
				"dst-alpha",
				"one-minus-dst-alpha",
				"src-alpha-saturated",
				"constant",
				"one-minus-constant",
				"src1",
				"one-minus-src1",
				"src1-alpha",
				"one-minus-src1-alpha"
			],
			BlendOperation: [
				,
				"add",
				"subtract",
				"reverse-subtract",
				"min",
				"max"
			],
			BufferBindingType: [
				,
				,
				"uniform",
				"storage",
				"read-only-storage"
			],
			BufferMapState: [
				,
				"unmapped",
				"pending",
				"mapped"
			],
			CompareFunction: [
				,
				"never",
				"less",
				"equal",
				"less-equal",
				"greater",
				"not-equal",
				"greater-equal",
				"always"
			],
			CompilationInfoRequestStatus: [
				,
				"success",
				"callback-cancelled"
			],
			ComponentSwizzle: [
				,
				"0",
				"1",
				"r",
				"g",
				"b",
				"a"
			],
			CompositeAlphaMode: [
				,
				"opaque",
				"premultiplied",
				"unpremultiplied",
				"inherit"
			],
			CullMode: [
				,
				"none",
				"front",
				"back"
			],
			ErrorFilter: [
				,
				"validation",
				"out-of-memory",
				"internal"
			],
			FeatureLevel: [
				,
				"compatibility",
				"core"
			],
			FeatureName: {
				1: "core-features-and-limits",
				2: "depth-clip-control",
				3: "depth32float-stencil8",
				4: "texture-compression-bc",
				5: "texture-compression-bc-sliced-3d",
				6: "texture-compression-etc2",
				7: "texture-compression-astc",
				8: "texture-compression-astc-sliced-3d",
				9: "timestamp-query",
				10: "indirect-first-instance",
				11: "shader-f16",
				12: "rg11b10ufloat-renderable",
				13: "bgra8unorm-storage",
				14: "float32-filterable",
				15: "float32-blendable",
				16: "clip-distances",
				17: "dual-source-blending",
				18: "subgroups",
				19: "texture-formats-tier1",
				20: "texture-formats-tier2",
				21: "primitive-index",
				22: "texture-component-swizzle",
				327692: "chromium-experimental-unorm16-texture-formats",
				327729: "chromium-experimental-multi-draw-indirect"
			},
			FilterMode: [
				,
				"nearest",
				"linear"
			],
			FrontFace: [
				,
				"ccw",
				"cw"
			],
			IndexFormat: [
				,
				"uint16",
				"uint32"
			],
			InstanceFeatureName: [
				,
				"timed-wait-any",
				"shader-source-spirv",
				"multiple-devices-per-adapter"
			],
			LoadOp: [
				,
				"load",
				"clear"
			],
			MipmapFilterMode: [
				,
				"nearest",
				"linear"
			],
			OptionalBool: ["false", "true"],
			PowerPreference: [
				,
				"low-power",
				"high-performance"
			],
			PredefinedColorSpace: [
				,
				"srgb",
				"display-p3"
			],
			PrimitiveTopology: [
				,
				"point-list",
				"line-list",
				"line-strip",
				"triangle-list",
				"triangle-strip"
			],
			QueryType: [
				,
				"occlusion",
				"timestamp"
			],
			SamplerBindingType: [
				,
				,
				"filtering",
				"non-filtering",
				"comparison"
			],
			Status: [
				,
				"success",
				"error"
			],
			StencilOperation: [
				,
				"keep",
				"zero",
				"replace",
				"invert",
				"increment-clamp",
				"decrement-clamp",
				"increment-wrap",
				"decrement-wrap"
			],
			StorageTextureAccess: [
				,
				,
				"write-only",
				"read-only",
				"read-write"
			],
			StoreOp: [
				,
				"store",
				"discard"
			],
			SurfaceGetCurrentTextureStatus: [
				,
				"success-optimal",
				"success-suboptimal",
				"timeout",
				"outdated",
				"lost",
				"error"
			],
			TextureAspect: [
				,
				"all",
				"stencil-only",
				"depth-only"
			],
			TextureDimension: [
				,
				"1d",
				"2d",
				"3d"
			],
			TextureFormat: [
				,
				"r8unorm",
				"r8snorm",
				"r8uint",
				"r8sint",
				"r16unorm",
				"r16snorm",
				"r16uint",
				"r16sint",
				"r16float",
				"rg8unorm",
				"rg8snorm",
				"rg8uint",
				"rg8sint",
				"r32float",
				"r32uint",
				"r32sint",
				"rg16unorm",
				"rg16snorm",
				"rg16uint",
				"rg16sint",
				"rg16float",
				"rgba8unorm",
				"rgba8unorm-srgb",
				"rgba8snorm",
				"rgba8uint",
				"rgba8sint",
				"bgra8unorm",
				"bgra8unorm-srgb",
				"rgb10a2uint",
				"rgb10a2unorm",
				"rg11b10ufloat",
				"rgb9e5ufloat",
				"rg32float",
				"rg32uint",
				"rg32sint",
				"rgba16unorm",
				"rgba16snorm",
				"rgba16uint",
				"rgba16sint",
				"rgba16float",
				"rgba32float",
				"rgba32uint",
				"rgba32sint",
				"stencil8",
				"depth16unorm",
				"depth24plus",
				"depth24plus-stencil8",
				"depth32float",
				"depth32float-stencil8",
				"bc1-rgba-unorm",
				"bc1-rgba-unorm-srgb",
				"bc2-rgba-unorm",
				"bc2-rgba-unorm-srgb",
				"bc3-rgba-unorm",
				"bc3-rgba-unorm-srgb",
				"bc4-r-unorm",
				"bc4-r-snorm",
				"bc5-rg-unorm",
				"bc5-rg-snorm",
				"bc6h-rgb-ufloat",
				"bc6h-rgb-float",
				"bc7-rgba-unorm",
				"bc7-rgba-unorm-srgb",
				"etc2-rgb8unorm",
				"etc2-rgb8unorm-srgb",
				"etc2-rgb8a1unorm",
				"etc2-rgb8a1unorm-srgb",
				"etc2-rgba8unorm",
				"etc2-rgba8unorm-srgb",
				"eac-r11unorm",
				"eac-r11snorm",
				"eac-rg11unorm",
				"eac-rg11snorm",
				"astc-4x4-unorm",
				"astc-4x4-unorm-srgb",
				"astc-5x4-unorm",
				"astc-5x4-unorm-srgb",
				"astc-5x5-unorm",
				"astc-5x5-unorm-srgb",
				"astc-6x5-unorm",
				"astc-6x5-unorm-srgb",
				"astc-6x6-unorm",
				"astc-6x6-unorm-srgb",
				"astc-8x5-unorm",
				"astc-8x5-unorm-srgb",
				"astc-8x6-unorm",
				"astc-8x6-unorm-srgb",
				"astc-8x8-unorm",
				"astc-8x8-unorm-srgb",
				"astc-10x5-unorm",
				"astc-10x5-unorm-srgb",
				"astc-10x6-unorm",
				"astc-10x6-unorm-srgb",
				"astc-10x8-unorm",
				"astc-10x8-unorm-srgb",
				"astc-10x10-unorm",
				"astc-10x10-unorm-srgb",
				"astc-12x10-unorm",
				"astc-12x10-unorm-srgb",
				"astc-12x12-unorm",
				"astc-12x12-unorm-srgb"
			],
			TextureSampleType: [
				,
				,
				"float",
				"unfilterable-float",
				"depth",
				"sint",
				"uint"
			],
			TextureViewDimension: [
				,
				"1d",
				"2d",
				"2d-array",
				"cube",
				"cube-array",
				"3d"
			],
			ToneMappingMode: [
				,
				"standard",
				"extended"
			],
			VertexFormat: [
				,
				"uint8",
				"uint8x2",
				"uint8x4",
				"sint8",
				"sint8x2",
				"sint8x4",
				"unorm8",
				"unorm8x2",
				"unorm8x4",
				"snorm8",
				"snorm8x2",
				"snorm8x4",
				"uint16",
				"uint16x2",
				"uint16x4",
				"sint16",
				"sint16x2",
				"sint16x4",
				"unorm16",
				"unorm16x2",
				"unorm16x4",
				"snorm16",
				"snorm16x2",
				"snorm16x4",
				"float16",
				"float16x2",
				"float16x4",
				"float32",
				"float32x2",
				"float32x3",
				"float32x4",
				"uint32",
				"uint32x2",
				"uint32x3",
				"uint32x4",
				"sint32",
				"sint32x2",
				"sint32x3",
				"sint32x4",
				"unorm10-10-10-2",
				"unorm8x4-bgra"
			],
			VertexStepMode: [
				,
				"vertex",
				"instance"
			],
			WGSLLanguageFeatureName: [
				,
				"readonly_and_readwrite_storage_textures",
				"packed_4x8_integer_dot_product",
				"unrestricted_pointer_parameters",
				"pointer_composite_access",
				"uniform_buffer_standard_layout",
				"subgroup_id",
				"texture_and_sampler_let",
				"subgroup_uniformity",
				"texture_formats_tier1",
				"linear_indexing"
			]
		};
		var emwgpuStringToInt_DeviceLostReason = {
			undefined: 1,
			unknown: 1,
			destroyed: 2
		};
		var handleException = (e) => {
			if (e instanceof ExitStatus || e == "unwind") return EXITSTATUS;
			quit_(1, e);
		};
		var runtimeKeepaliveCounter = 0;
		var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0;
		var _proc_exit = (code) => {
			EXITSTATUS = code;
			if (!keepRuntimeAlive()) {
				Module["onExit"]?.(code);
				ABORT = true;
			}
			quit_(code, new ExitStatus(code));
		};
		var exitJS = (status, implicit) => {
			EXITSTATUS = status;
			_proc_exit(status);
		};
		var _exit = exitJS;
		var maybeExit = () => {
			if (!keepRuntimeAlive()) try {
				_exit(EXITSTATUS);
			} catch (e) {
				handleException(e);
			}
		};
		var callUserCallback = (func) => {
			if (ABORT) return;
			try {
				return func();
			} catch (e) {
				handleException(e);
			} finally {
				maybeExit();
			}
		};
		function _emwgpuAdapterRequestDevice(adapterPtr, futureId, deviceLostFutureId, devicePtr, queuePtr, descriptor) {
			adapterPtr >>>= 0;
			futureId = bigintToI53Checked(futureId);
			deviceLostFutureId = bigintToI53Checked(deviceLostFutureId);
			devicePtr >>>= 0;
			queuePtr >>>= 0;
			descriptor >>>= 0;
			var adapter = WebGPU.getJsObject(adapterPtr);
			var desc = {};
			if (descriptor) {
				var requiredFeatureCount = HEAPU32[descriptor + 12 >>> 2 >>> 0];
				if (requiredFeatureCount) {
					var requiredFeaturesPtr = HEAPU32[descriptor + 16 >>> 2 >>> 0];
					desc["requiredFeatures"] = Array.from(HEAPU32.subarray(requiredFeaturesPtr >>> 2 >>> 0, requiredFeaturesPtr + requiredFeatureCount * 4 >>> 2 >>> 0), (feature) => WebGPU.FeatureName[feature]);
				}
				var limitsPtr = HEAPU32[descriptor + 20 >>> 2 >>> 0];
				if (limitsPtr) {
					var nextInChainPtr = HEAPU32[limitsPtr >>> 2 >>> 0];
					var requiredLimits = {};
					function setLimitU32IfDefined(name, basePtr, limitOffset, ignoreIfZero = false) {
						var ptr = basePtr + limitOffset;
						var value = HEAPU32[ptr >>> 2 >>> 0];
						if (value != 4294967295 && (!ignoreIfZero || value != 0)) requiredLimits[name] = value;
					}
					function setLimitU64IfDefined(name, basePtr, limitOffset) {
						var ptr = basePtr + limitOffset;
						var limitPart1 = HEAPU32[ptr >>> 2 >>> 0];
						var limitPart2 = HEAPU32[ptr + 4 >>> 2 >>> 0];
						if (limitPart1 != 4294967295 || limitPart2 != 4294967295) requiredLimits[name] = readI53FromI64(ptr);
					}
					setLimitU32IfDefined("maxTextureDimension1D", limitsPtr, 4);
					setLimitU32IfDefined("maxTextureDimension2D", limitsPtr, 8);
					setLimitU32IfDefined("maxTextureDimension3D", limitsPtr, 12);
					setLimitU32IfDefined("maxTextureArrayLayers", limitsPtr, 16);
					setLimitU32IfDefined("maxBindGroups", limitsPtr, 20);
					setLimitU32IfDefined("maxBindGroupsPlusVertexBuffers", limitsPtr, 24);
					setLimitU32IfDefined("maxBindingsPerBindGroup", limitsPtr, 28);
					setLimitU32IfDefined("maxDynamicUniformBuffersPerPipelineLayout", limitsPtr, 32);
					setLimitU32IfDefined("maxDynamicStorageBuffersPerPipelineLayout", limitsPtr, 36);
					setLimitU32IfDefined("maxSampledTexturesPerShaderStage", limitsPtr, 40);
					setLimitU32IfDefined("maxSamplersPerShaderStage", limitsPtr, 44);
					setLimitU32IfDefined("maxStorageBuffersPerShaderStage", limitsPtr, 48);
					setLimitU32IfDefined("maxStorageTexturesPerShaderStage", limitsPtr, 52);
					setLimitU32IfDefined("maxUniformBuffersPerShaderStage", limitsPtr, 56);
					setLimitU32IfDefined("minUniformBufferOffsetAlignment", limitsPtr, 80);
					setLimitU32IfDefined("minStorageBufferOffsetAlignment", limitsPtr, 84);
					setLimitU64IfDefined("maxUniformBufferBindingSize", limitsPtr, 64);
					setLimitU64IfDefined("maxStorageBufferBindingSize", limitsPtr, 72);
					setLimitU32IfDefined("maxVertexBuffers", limitsPtr, 88);
					setLimitU64IfDefined("maxBufferSize", limitsPtr, 96);
					setLimitU32IfDefined("maxVertexAttributes", limitsPtr, 104);
					setLimitU32IfDefined("maxVertexBufferArrayStride", limitsPtr, 108);
					setLimitU32IfDefined("maxInterStageShaderVariables", limitsPtr, 112);
					setLimitU32IfDefined("maxColorAttachments", limitsPtr, 116);
					setLimitU32IfDefined("maxColorAttachmentBytesPerSample", limitsPtr, 120);
					setLimitU32IfDefined("maxComputeWorkgroupStorageSize", limitsPtr, 124);
					setLimitU32IfDefined("maxComputeInvocationsPerWorkgroup", limitsPtr, 128);
					setLimitU32IfDefined("maxComputeWorkgroupSizeX", limitsPtr, 132);
					setLimitU32IfDefined("maxComputeWorkgroupSizeY", limitsPtr, 136);
					setLimitU32IfDefined("maxComputeWorkgroupSizeZ", limitsPtr, 140);
					setLimitU32IfDefined("maxComputeWorkgroupsPerDimension", limitsPtr, 144);
					setLimitU32IfDefined("maxImmediateSize", limitsPtr, 148, true);
					if (nextInChainPtr !== 0) {
						HEAP32[nextInChainPtr + 4 >>> 2 >>> 0];
						var compatibilityModeLimitsPtr = nextInChainPtr;
						if ("maxStorageBuffersInVertexStage" in GPUSupportedLimits.prototype) {
							setLimitU32IfDefined("maxStorageBuffersInVertexStage", compatibilityModeLimitsPtr, 8);
							setLimitU32IfDefined("maxStorageTexturesInVertexStage", compatibilityModeLimitsPtr, 12);
							setLimitU32IfDefined("maxStorageBuffersInFragmentStage", compatibilityModeLimitsPtr, 16);
							setLimitU32IfDefined("maxStorageTexturesInFragmentStage", compatibilityModeLimitsPtr, 20);
						}
					}
					desc["requiredLimits"] = requiredLimits;
				}
				var defaultQueuePtr = HEAPU32[descriptor + 24 >>> 2 >>> 0];
				if (defaultQueuePtr) desc["defaultQueue"] = { label: WebGPU.makeStringFromOptionalStringView(defaultQueuePtr + 4) };
				desc["label"] = WebGPU.makeStringFromOptionalStringView(descriptor + 4);
			}
			WebGPU.Internals.futureInsert(futureId, adapter.requestDevice(desc).then((device) => {
				callUserCallback(() => {
					WebGPU.Internals.jsObjectInsert(queuePtr, device.queue);
					WebGPU.Internals.jsObjectInsert(devicePtr, device);
					WebGPU.Internals.futureInsert(deviceLostFutureId, device.lost.then((info) => {
						callUserCallback(() => {
							device.onuncapturederror = (ev) => {};
							var sp = stackSave();
							var messagePtr = stringToUTF8OnStack(info.message);
							_emwgpuOnDeviceLostCompleted(deviceLostFutureId, emwgpuStringToInt_DeviceLostReason[info.reason], messagePtr);
							stackRestore(sp);
						});
					}));
					device.onuncapturederror = (ev) => {
						var type = 5;
						if (ev.error instanceof GPUValidationError) type = 2;
						else if (ev.error instanceof GPUOutOfMemoryError) type = 3;
						else if (ev.error instanceof GPUInternalError) type = 4;
						var sp = stackSave();
						var messagePtr = stringToUTF8OnStack(ev.error.message);
						_emwgpuOnUncapturedError(devicePtr, type, messagePtr);
						stackRestore(sp);
					};
					_emwgpuOnRequestDeviceCompleted(futureId, 1, devicePtr, 0);
				});
			}, (ex) => {
				callUserCallback(() => {
					var sp = stackSave();
					var messagePtr = stringToUTF8OnStack(ex.message);
					_emwgpuOnRequestDeviceCompleted(futureId, 3, devicePtr, messagePtr);
					if (deviceLostFutureId) _emwgpuOnDeviceLostCompleted(deviceLostFutureId, 4, messagePtr);
					stackRestore(sp);
				});
			}));
		}
		function _emwgpuBufferDestroy(bufferPtr) {
			bufferPtr >>>= 0;
			var buffer = WebGPU.getJsObject(bufferPtr);
			var onUnmap = WebGPU.Internals.bufferOnUnmaps[bufferPtr];
			if (onUnmap) {
				for (var i = 0; i < onUnmap.length; ++i) onUnmap[i]();
				delete WebGPU.Internals.bufferOnUnmaps[bufferPtr];
			}
			buffer.destroy();
		}
		var warnOnce = (text) => {
			warnOnce.shown ||= {};
			if (!warnOnce.shown[text]) {
				warnOnce.shown[text] = 1;
				if (ENVIRONMENT_IS_NODE) text = "warning: " + text;
				err(text);
			}
		};
		function _emwgpuBufferGetConstMappedRange(bufferPtr, offset, size) {
			bufferPtr >>>= 0;
			offset >>>= 0;
			size >>>= 0;
			var buffer = WebGPU.getJsObject(bufferPtr);
			if (size == 4294967295) size = void 0;
			var mapped;
			try {
				mapped = buffer.getMappedRange(offset, size);
			} catch (ex) {
				return 0;
			}
			var data = _memalign(16, mapped.byteLength);
			HEAPU8.set(new Uint8Array(mapped), data >>> 0);
			WebGPU.Internals.bufferOnUnmaps[bufferPtr].push(() => _free(data));
			return data;
		}
		var _emwgpuBufferMapAsync = function(bufferPtr, futureId, mode, offset, size) {
			bufferPtr >>>= 0;
			futureId = bigintToI53Checked(futureId);
			mode = bigintToI53Checked(mode);
			offset >>>= 0;
			size >>>= 0;
			var buffer = WebGPU.getJsObject(bufferPtr);
			WebGPU.Internals.bufferOnUnmaps[bufferPtr] = [];
			if (size == 4294967295) size = void 0;
			WebGPU.Internals.futureInsert(futureId, buffer.mapAsync(mode, offset, size).then(() => {
				callUserCallback(() => {
					_emwgpuOnMapAsyncCompleted(futureId, 1, 0);
				});
			}, (ex) => {
				callUserCallback(() => {
					stackSave();
					var messagePtr = stringToUTF8OnStack(ex.message);
					var status = ex.name === "AbortError" ? 4 : ex.name === "OperationError" ? 3 : 0;
					_emwgpuOnMapAsyncCompleted(futureId, status, messagePtr);
					delete WebGPU.Internals.bufferOnUnmaps[bufferPtr];
				});
			}));
		};
		function _emwgpuBufferUnmap(bufferPtr) {
			bufferPtr >>>= 0;
			var buffer = WebGPU.getJsObject(bufferPtr);
			var onUnmap = WebGPU.Internals.bufferOnUnmaps[bufferPtr];
			if (!onUnmap) return;
			for (var i = 0; i < onUnmap.length; ++i) onUnmap[i]();
			delete WebGPU.Internals.bufferOnUnmaps[bufferPtr];
			buffer.unmap();
		}
		function _emwgpuDelete(ptr) {
			ptr >>>= 0;
			delete WebGPU.Internals.jsObjects[ptr];
		}
		function _emwgpuDeviceCreateBuffer(devicePtr, descriptor, bufferPtr) {
			devicePtr >>>= 0;
			descriptor >>>= 0;
			bufferPtr >>>= 0;
			var mappedAtCreation = !!HEAPU32[descriptor + 32 >>> 2 >>> 0];
			var desc = {
				label: WebGPU.makeStringFromOptionalStringView(descriptor + 4),
				usage: HEAPU32[descriptor + 16 >>> 2 >>> 0],
				size: readI53FromI64(descriptor + 24),
				mappedAtCreation
			};
			var device = WebGPU.getJsObject(devicePtr);
			var buffer;
			try {
				buffer = device.createBuffer(desc);
			} catch (ex) {
				return false;
			}
			WebGPU.Internals.jsObjectInsert(bufferPtr, buffer);
			if (mappedAtCreation) WebGPU.Internals.bufferOnUnmaps[bufferPtr] = [];
			return true;
		}
		function _emwgpuDeviceCreateShaderModule(devicePtr, descriptor, shaderModulePtr) {
			devicePtr >>>= 0;
			descriptor >>>= 0;
			shaderModulePtr >>>= 0;
			var nextInChainPtr = HEAPU32[descriptor >>> 2 >>> 0];
			var sType = HEAP32[nextInChainPtr + 4 >>> 2 >>> 0];
			var desc = {
				label: WebGPU.makeStringFromOptionalStringView(descriptor + 4),
				code: ""
			};
			switch (sType) {
				case 2:
					desc["code"] = WebGPU.makeStringFromStringView(nextInChainPtr + 8);
					break;
			}
			var device = WebGPU.getJsObject(devicePtr);
			WebGPU.Internals.jsObjectInsert(shaderModulePtr, device.createShaderModule(desc));
		}
		var _emwgpuDeviceDestroy = (devicePtr) => {
			const device = WebGPU.getJsObject(devicePtr);
			device.onuncapturederror = null;
			device.destroy();
		};
		function _emwgpuInstanceRequestAdapter(instancePtr, futureId, options, adapterPtr) {
			instancePtr >>>= 0;
			futureId = bigintToI53Checked(futureId);
			options >>>= 0;
			adapterPtr >>>= 0;
			var opts;
			if (options) {
				opts = {
					featureLevel: WebGPU.FeatureLevel[HEAP32[options + 4 >>> 2 >>> 0]],
					powerPreference: WebGPU.PowerPreference[HEAP32[options + 8 >>> 2 >>> 0]],
					forceFallbackAdapter: !!HEAPU32[options + 12 >>> 2 >>> 0]
				};
				var nextInChainPtr = HEAPU32[options >>> 2 >>> 0];
				if (nextInChainPtr !== 0) {
					HEAP32[nextInChainPtr + 4 >>> 2 >>> 0];
					opts.xrCompatible = !!HEAPU32[nextInChainPtr + 8 >>> 2 >>> 0];
				}
			}
			if (!("gpu" in navigator)) {
				var sp = stackSave();
				var messagePtr = stringToUTF8OnStack("WebGPU not available on this browser (navigator.gpu is not available)");
				_emwgpuOnRequestAdapterCompleted(futureId, 3, adapterPtr, messagePtr);
				stackRestore(sp);
				return;
			}
			WebGPU.Internals.futureInsert(futureId, navigator.gpu.requestAdapter(opts).then((adapter) => {
				callUserCallback(() => {
					if (adapter) {
						WebGPU.Internals.jsObjectInsert(adapterPtr, adapter);
						_emwgpuOnRequestAdapterCompleted(futureId, 1, adapterPtr, 0);
					} else {
						var sp = stackSave();
						var messagePtr = stringToUTF8OnStack("WebGPU not available on this browser (requestAdapter returned null)");
						_emwgpuOnRequestAdapterCompleted(futureId, 3, adapterPtr, messagePtr);
						stackRestore(sp);
					}
				});
			}, (ex) => {
				callUserCallback(() => {
					var sp = stackSave();
					var messagePtr = stringToUTF8OnStack(ex.message);
					_emwgpuOnRequestAdapterCompleted(futureId, 4, adapterPtr, messagePtr);
					stackRestore(sp);
				});
			}));
		}
		var ENV = {};
		var getExecutableName = () => thisProgram;
		var getEnvStrings = () => {
			if (!getEnvStrings.strings) {
				var env = {
					USER: "web_user",
					LOGNAME: "web_user",
					PATH: "/",
					PWD: "/",
					HOME: "/home/web_user",
					LANG: (globalThis.navigator?.language ?? "C").replace("-", "_") + ".UTF-8",
					_: getExecutableName()
				};
				for (var x in ENV) if (ENV[x] === void 0) delete env[x];
				else env[x] = ENV[x];
				var strings = [];
				for (var x in env) strings.push(`${x}=${env[x]}`);
				getEnvStrings.strings = strings;
			}
			return getEnvStrings.strings;
		};
		function _environ_get(__environ, environ_buf) {
			__environ >>>= 0;
			environ_buf >>>= 0;
			var bufSize = 0;
			var envp = 0;
			for (var string of getEnvStrings()) {
				var ptr = environ_buf + bufSize;
				HEAPU32[__environ + envp >>> 2 >>> 0] = ptr;
				bufSize += stringToUTF8(string, ptr, Infinity) + 1;
				envp += 4;
			}
			return 0;
		}
		function _environ_sizes_get(penviron_count, penviron_buf_size) {
			penviron_count >>>= 0;
			penviron_buf_size >>>= 0;
			var strings = getEnvStrings();
			HEAPU32[penviron_count >>> 2 >>> 0] = strings.length;
			var bufSize = 0;
			for (var string of strings) bufSize += lengthBytesUTF8(string) + 1;
			HEAPU32[penviron_buf_size >>> 2 >>> 0] = bufSize;
			return 0;
		}
		var _fd_close = (fd) => 52;
		function _fd_read(fd, iov, iovcnt, pnum) {
			iov >>>= 0;
			iovcnt >>>= 0;
			pnum >>>= 0;
			return 52;
		}
		function _fd_seek(fd, offset, whence, newOffset) {
			offset = bigintToI53Checked(offset);
			newOffset >>>= 0;
			return 70;
		}
		var printCharBuffers = [
			null,
			[],
			[]
		];
		var printChar = (stream, curr) => {
			var buffer = printCharBuffers[stream];
			if (!curr || curr === 10) {
				(stream === 1 ? out : err)(UTF8ArrayToString(buffer));
				buffer.length = 0;
			} else buffer.push(curr);
		};
		function _fd_write(fd, iov, iovcnt, pnum) {
			iov >>>= 0;
			iovcnt >>>= 0;
			pnum >>>= 0;
			var num = 0;
			for (var i = 0; i < iovcnt; i++) {
				var ptr = HEAPU32[iov >>> 2 >>> 0];
				var len = HEAPU32[iov + 4 >>> 2 >>> 0];
				iov += 8;
				for (var j = 0; j < len; j++) printChar(fd, HEAPU8[ptr + j >>> 0]);
				num += len;
			}
			HEAPU32[pnum >>> 2 >>> 0] = num;
			return 0;
		}
		var initRandomFill = () => {
			if (ENVIRONMENT_IS_NODE) {
				var nodeCrypto = __require("node:crypto");
				return (view) => (nodeCrypto.randomFillSync(view), 0);
			}
			return (view) => (crypto.getRandomValues(view), 0);
		};
		var randomFill = (view) => (randomFill = initRandomFill())(view);
		function _random_get(buffer, size) {
			buffer >>>= 0;
			size >>>= 0;
			return randomFill(HEAPU8.subarray(buffer >>> 0, buffer + size >>> 0));
		}
		function _wgpuAdapterGetLimits(adapterPtr, limitsOutPtr) {
			adapterPtr >>>= 0;
			limitsOutPtr >>>= 0;
			var adapter = WebGPU.getJsObject(adapterPtr);
			WebGPU.fillLimitStruct(adapter.limits, limitsOutPtr);
			return 1;
		}
		function _wgpuCommandEncoderBeginComputePass(encoderPtr, descriptor) {
			encoderPtr >>>= 0;
			descriptor >>>= 0;
			var desc;
			if (descriptor) desc = {
				label: WebGPU.makeStringFromOptionalStringView(descriptor + 4),
				timestampWrites: WebGPU.makePassTimestampWrites(HEAPU32[descriptor + 12 >>> 2 >>> 0])
			};
			var commandEncoder = WebGPU.getJsObject(encoderPtr);
			var ptr = _emwgpuCreateComputePassEncoder(0);
			WebGPU.Internals.jsObjectInsert(ptr, commandEncoder.beginComputePass(desc));
			return ptr;
		}
		function _wgpuCommandEncoderCopyBufferToBuffer(encoderPtr, srcPtr, srcOffset, dstPtr, dstOffset, size) {
			encoderPtr >>>= 0;
			srcPtr >>>= 0;
			srcOffset = bigintToI53Checked(srcOffset);
			dstPtr >>>= 0;
			dstOffset = bigintToI53Checked(dstOffset);
			size = bigintToI53Checked(size);
			var commandEncoder = WebGPU.getJsObject(encoderPtr);
			var src = WebGPU.getJsObject(srcPtr);
			var dst = WebGPU.getJsObject(dstPtr);
			commandEncoder.copyBufferToBuffer(src, srcOffset, dst, dstOffset, size);
		}
		function _wgpuCommandEncoderCopyTextureToBuffer(encoderPtr, srcPtr, dstPtr, copySizePtr) {
			encoderPtr >>>= 0;
			srcPtr >>>= 0;
			dstPtr >>>= 0;
			copySizePtr >>>= 0;
			var commandEncoder = WebGPU.getJsObject(encoderPtr);
			var copySize = WebGPU.makeExtent3D(copySizePtr);
			commandEncoder.copyTextureToBuffer(WebGPU.makeTexelCopyTextureInfo(srcPtr), WebGPU.makeTexelCopyBufferInfo(dstPtr), copySize);
		}
		function _wgpuCommandEncoderFinish(encoderPtr, descriptor) {
			encoderPtr >>>= 0;
			descriptor >>>= 0;
			var commandEncoder = WebGPU.getJsObject(encoderPtr);
			var ptr = _emwgpuCreateCommandBuffer(0);
			WebGPU.Internals.jsObjectInsert(ptr, commandEncoder.finish());
			return ptr;
		}
		function _wgpuComputePassEncoderDispatchWorkgroups(passPtr, x, y, z) {
			passPtr >>>= 0;
			WebGPU.getJsObject(passPtr).dispatchWorkgroups(x, y, z);
		}
		function _wgpuComputePassEncoderEnd(passPtr) {
			passPtr >>>= 0;
			WebGPU.getJsObject(passPtr).end();
		}
		function _wgpuComputePassEncoderSetBindGroup(passPtr, groupIndex, groupPtr, dynamicOffsetCount, dynamicOffsetsPtr) {
			passPtr >>>= 0;
			groupPtr >>>= 0;
			dynamicOffsetCount >>>= 0;
			dynamicOffsetsPtr >>>= 0;
			var pass = WebGPU.getJsObject(passPtr);
			var group = WebGPU.getJsObject(groupPtr);
			if (dynamicOffsetCount == 0) pass.setBindGroup(groupIndex, group);
			else pass.setBindGroup(groupIndex, group, HEAPU32, dynamicOffsetsPtr >>> 2, dynamicOffsetCount);
		}
		function _wgpuComputePassEncoderSetPipeline(passPtr, pipelinePtr) {
			passPtr >>>= 0;
			pipelinePtr >>>= 0;
			var pass = WebGPU.getJsObject(passPtr);
			var pipeline = WebGPU.getJsObject(pipelinePtr);
			pass.setPipeline(pipeline);
		}
		function _wgpuComputePipelineGetBindGroupLayout(pipelinePtr, groupIndex) {
			pipelinePtr >>>= 0;
			var pipeline = WebGPU.getJsObject(pipelinePtr);
			var ptr = _emwgpuCreateBindGroupLayout(0);
			WebGPU.Internals.jsObjectInsert(ptr, pipeline.getBindGroupLayout(groupIndex));
			return ptr;
		}
		var _wgpuDeviceCreateBindGroup = function(devicePtr, descriptor) {
			devicePtr >>>= 0;
			descriptor >>>= 0;
			function makeEntry(entryPtr) {
				var bufferPtr = HEAPU32[entryPtr + 8 >>> 2 >>> 0];
				var samplerPtr = HEAPU32[entryPtr + 32 >>> 2 >>> 0];
				var textureViewPtr = HEAPU32[entryPtr + 36 >>> 2 >>> 0];
				var externalTexturePtr = 0;
				WebGPU.iterateExtensions(entryPtr, { 14: (ptr) => {
					externalTexturePtr = HEAPU32[ptr + 8 >>> 2 >>> 0];
				} });
				var resource;
				if (bufferPtr) {
					var size = readI53FromI64(entryPtr + 24);
					if (size == -1) size = void 0;
					resource = {
						buffer: WebGPU.getJsObject(bufferPtr),
						offset: readI53FromI64(entryPtr + 16),
						size
					};
				} else resource = WebGPU.getJsObject(samplerPtr || textureViewPtr || externalTexturePtr);
				return {
					binding: HEAPU32[entryPtr + 4 >>> 2 >>> 0],
					resource
				};
			}
			function makeEntries(count, entriesPtrs) {
				var entries = [];
				for (var i = 0; i < count; ++i) entries.push(makeEntry(entriesPtrs + 40 * i));
				return entries;
			}
			var desc = {
				label: WebGPU.makeStringFromOptionalStringView(descriptor + 4),
				layout: WebGPU.getJsObject(HEAPU32[descriptor + 12 >>> 2 >>> 0]),
				entries: makeEntries(HEAPU32[descriptor + 16 >>> 2 >>> 0], HEAPU32[descriptor + 20 >>> 2 >>> 0])
			};
			var device = WebGPU.getJsObject(devicePtr);
			var ptr = _emwgpuCreateBindGroup(0);
			WebGPU.Internals.jsObjectInsert(ptr, device.createBindGroup(desc));
			return ptr;
		};
		function _wgpuDeviceCreateCommandEncoder(devicePtr, descriptor) {
			devicePtr >>>= 0;
			descriptor >>>= 0;
			var desc;
			if (descriptor) desc = { label: WebGPU.makeStringFromOptionalStringView(descriptor + 4) };
			var device = WebGPU.getJsObject(devicePtr);
			var ptr = _emwgpuCreateCommandEncoder(0);
			WebGPU.Internals.jsObjectInsert(ptr, device.createCommandEncoder(desc));
			return ptr;
		}
		function _wgpuDeviceCreateComputePipeline(devicePtr, descriptor) {
			devicePtr >>>= 0;
			descriptor >>>= 0;
			var desc = WebGPU.makeComputePipelineDesc(descriptor);
			var device = WebGPU.getJsObject(devicePtr);
			var ptr = _emwgpuCreateComputePipeline(0);
			WebGPU.Internals.jsObjectInsert(ptr, device.createComputePipeline(desc));
			return ptr;
		}
		function _wgpuDeviceCreateTexture(devicePtr, descriptor) {
			devicePtr >>>= 0;
			descriptor >>>= 0;
			var nextInChainPtr = HEAPU32[descriptor >>> 2 >>> 0];
			var textureBindingViewDimension;
			if (nextInChainPtr !== 0) {
				HEAP32[nextInChainPtr + 4 >>> 2 >>> 0];
				var textureBindingViewDimensionDescriptor = nextInChainPtr;
				textureBindingViewDimension = WebGPU.TextureViewDimension[HEAP32[textureBindingViewDimensionDescriptor + 8 >>> 2 >>> 0]];
			}
			var desc = {
				label: WebGPU.makeStringFromOptionalStringView(descriptor + 4),
				size: WebGPU.makeExtent3D(descriptor + 28),
				mipLevelCount: HEAPU32[descriptor + 44 >>> 2 >>> 0],
				sampleCount: HEAPU32[descriptor + 48 >>> 2 >>> 0],
				dimension: WebGPU.TextureDimension[HEAP32[descriptor + 24 >>> 2 >>> 0]],
				format: WebGPU.TextureFormat[HEAP32[descriptor + 40 >>> 2 >>> 0]],
				usage: HEAPU32[descriptor + 16 >>> 2 >>> 0],
				textureBindingViewDimension
			};
			var viewFormatCount = HEAPU32[descriptor + 52 >>> 2 >>> 0];
			if (viewFormatCount) {
				var viewFormatsPtr = HEAPU32[descriptor + 56 >>> 2 >>> 0];
				desc["viewFormats"] = Array.from(HEAP32.subarray(viewFormatsPtr >>> 2 >>> 0, viewFormatsPtr + viewFormatCount * 4 >>> 2 >>> 0), (format) => WebGPU.TextureFormat[format]);
			}
			var device = WebGPU.getJsObject(devicePtr);
			var ptr = _emwgpuCreateTexture(0);
			WebGPU.Internals.jsObjectInsert(ptr, device.createTexture(desc));
			return ptr;
		}
		var _wgpuQueueSubmit = function(queuePtr, commandCount, commands) {
			queuePtr >>>= 0;
			commandCount >>>= 0;
			commands >>>= 0;
			var queue = WebGPU.getJsObject(queuePtr);
			var cmds = Array.from(HEAP32.subarray(commands >>> 2 >>> 0, commands + commandCount * 4 >>> 2 >>> 0), (id) => WebGPU.getJsObject(id));
			queue.submit(cmds);
		};
		function _wgpuQueueWriteBuffer(queuePtr, bufferPtr, bufferOffset, data, size) {
			queuePtr >>>= 0;
			bufferPtr >>>= 0;
			bufferOffset = bigintToI53Checked(bufferOffset);
			data >>>= 0;
			size >>>= 0;
			var queue = WebGPU.getJsObject(queuePtr);
			var buffer = WebGPU.getJsObject(bufferPtr);
			var subarray = HEAPU8.subarray(data >>> 0, data + size >>> 0);
			queue.writeBuffer(buffer, bufferOffset, subarray, 0, size);
		}
		function _wgpuQueueWriteTexture(queuePtr, destinationPtr, data, dataSize, dataLayoutPtr, writeSizePtr) {
			queuePtr >>>= 0;
			destinationPtr >>>= 0;
			data >>>= 0;
			dataSize >>>= 0;
			dataLayoutPtr >>>= 0;
			writeSizePtr >>>= 0;
			var queue = WebGPU.getJsObject(queuePtr);
			var destination = WebGPU.makeTexelCopyTextureInfo(destinationPtr);
			var dataLayout = WebGPU.makeTexelCopyBufferLayout(dataLayoutPtr);
			var writeSize = WebGPU.makeExtent3D(writeSizePtr);
			var subarray = HEAPU8.subarray(data >>> 0, data + dataSize >>> 0);
			queue.writeTexture(destination, subarray, dataLayout, writeSize);
		}
		function _wgpuTextureCreateView(texturePtr, descriptor) {
			texturePtr >>>= 0;
			descriptor >>>= 0;
			var desc;
			if (descriptor) {
				var swizzle;
				var nextInChainPtr = HEAPU32[descriptor >>> 2 >>> 0];
				if (nextInChainPtr !== 0) {
					HEAP32[nextInChainPtr + 4 >>> 2 >>> 0];
					var swizzlePtr = nextInChainPtr + 8;
					swizzle = `${WebGPU.ComponentSwizzle[HEAP32[swizzlePtr >>> 2 >>> 0]] || "r"}${WebGPU.ComponentSwizzle[HEAP32[swizzlePtr + 4 >>> 2 >>> 0]] || "g"}${WebGPU.ComponentSwizzle[HEAP32[swizzlePtr + 8 >>> 2 >>> 0]] || "b"}${WebGPU.ComponentSwizzle[HEAP32[swizzlePtr + 12 >>> 2 >>> 0]] || "a"}`;
				}
				var mipLevelCount = HEAPU32[descriptor + 24 >>> 2 >>> 0];
				var arrayLayerCount = HEAPU32[descriptor + 32 >>> 2 >>> 0];
				desc = {
					label: WebGPU.makeStringFromOptionalStringView(descriptor + 4),
					format: WebGPU.TextureFormat[HEAP32[descriptor + 12 >>> 2 >>> 0]],
					dimension: WebGPU.TextureViewDimension[HEAP32[descriptor + 16 >>> 2 >>> 0]],
					baseMipLevel: HEAPU32[descriptor + 20 >>> 2 >>> 0],
					mipLevelCount: mipLevelCount === 4294967295 ? void 0 : mipLevelCount,
					baseArrayLayer: HEAPU32[descriptor + 28 >>> 2 >>> 0],
					arrayLayerCount: arrayLayerCount === 4294967295 ? void 0 : arrayLayerCount,
					aspect: WebGPU.TextureAspect[HEAP32[descriptor + 36 >>> 2 >>> 0]],
					usage: HEAPU32[descriptor + 40 >>> 2 >>> 0],
					swizzle
				};
			}
			var texture = WebGPU.getJsObject(texturePtr);
			var ptr = _emwgpuCreateTextureView(0);
			WebGPU.Internals.jsObjectInsert(ptr, texture.createView(desc));
			return ptr;
		}
		function _wgpuTextureDestroy(texturePtr) {
			texturePtr >>>= 0;
			WebGPU.getJsObject(texturePtr).destroy();
		}
		var runAndAbortIfError = (func) => {
			try {
				return func();
			} catch (e) {
				abort(e);
			}
		};
		var runtimeKeepalivePush = () => {
			runtimeKeepaliveCounter += 1;
		};
		var runtimeKeepalivePop = () => {
			runtimeKeepaliveCounter -= 1;
		};
		var Asyncify = {
			instrumentWasmImports(imports) {
				var importPattern = /^(invoke_.*|__asyncjs__.*)$/;
				for (let [x, original] of Object.entries(imports)) if (typeof original == "function") original.isAsync || importPattern.test(x);
			},
			instrumentFunction(original) {
				var wrapper = (...args) => {
					Asyncify.exportCallStack.push(original);
					try {
						return original(...args);
					} finally {
						if (!ABORT) {
							Asyncify.exportCallStack.pop();
							Asyncify.maybeStopUnwind();
						}
					}
				};
				Asyncify.funcWrappers.set(original, wrapper);
				return wrapper;
			},
			instrumentWasmExports(exports$1) {
				var ret = {};
				for (let [x, original] of Object.entries(exports$1)) if (typeof original == "function") ret[x] = Asyncify.instrumentFunction(original);
				else ret[x] = original;
				return ret;
			},
			State: {
				Normal: 0,
				Unwinding: 1,
				Rewinding: 2,
				Disabled: 3
			},
			state: 0,
			StackSize: 131272,
			currData: null,
			handleSleepReturnValue: 0,
			exportCallStack: [],
			callstackFuncToId: /* @__PURE__ */ new Map(),
			callStackIdToFunc: /* @__PURE__ */ new Map(),
			funcWrappers: /* @__PURE__ */ new Map(),
			callStackId: 0,
			asyncPromiseHandlers: null,
			sleepCallbacks: [],
			getCallStackId(func) {
				if (!Asyncify.callstackFuncToId.has(func)) {
					var id = Asyncify.callStackId++;
					Asyncify.callstackFuncToId.set(func, id);
					Asyncify.callStackIdToFunc.set(id, func);
				}
				return Asyncify.callstackFuncToId.get(func);
			},
			maybeStopUnwind() {
				if (Asyncify.currData && Asyncify.state === Asyncify.State.Unwinding && !Asyncify.exportCallStack.length) {
					Asyncify.state = Asyncify.State.Normal;
					runAndAbortIfError(_asyncify_stop_unwind);
					if (typeof Fibers != "undefined") Fibers.trampoline();
				}
			},
			whenDone() {
				return new Promise((resolve, reject) => {
					Asyncify.asyncPromiseHandlers = {
						resolve,
						reject
					};
				});
			},
			allocateData() {
				var ptr = _malloc(12 + Asyncify.StackSize);
				Asyncify.setDataHeader(ptr, ptr + 12, Asyncify.StackSize);
				Asyncify.setDataRewindFunc(ptr);
				return ptr;
			},
			setDataHeader(ptr, stack, stackSize) {
				HEAPU32[ptr >>> 2 >>> 0] = stack;
				HEAPU32[ptr + 4 >>> 2 >>> 0] = stack + stackSize;
			},
			setDataRewindFunc(ptr) {
				var bottomOfCallStack = Asyncify.exportCallStack[0];
				var rewindId = Asyncify.getCallStackId(bottomOfCallStack);
				HEAP32[ptr + 8 >>> 2 >>> 0] = rewindId;
			},
			getDataRewindFunc(ptr) {
				var id = HEAP32[ptr + 8 >>> 2 >>> 0];
				return Asyncify.callStackIdToFunc.get(id);
			},
			doRewind(ptr) {
				var original = Asyncify.getDataRewindFunc(ptr);
				return callUserCallback(Asyncify.funcWrappers.get(original));
			},
			handleSleep(startAsync) {
				if (ABORT) return;
				if (Asyncify.state === Asyncify.State.Normal) {
					var reachedCallback = false;
					var reachedAfterCallback = false;
					startAsync((handleSleepReturnValue = 0) => {
						if (ABORT) return;
						Asyncify.handleSleepReturnValue = handleSleepReturnValue;
						reachedCallback = true;
						if (!reachedAfterCallback) return;
						Asyncify.state = Asyncify.State.Rewinding;
						runAndAbortIfError(() => _asyncify_start_rewind(Asyncify.currData));
						if (typeof MainLoop != "undefined" && MainLoop.func) MainLoop.resume();
						var asyncWasmReturnValue, isError = false;
						try {
							asyncWasmReturnValue = Asyncify.doRewind(Asyncify.currData);
						} catch (err) {
							asyncWasmReturnValue = err;
							isError = true;
						}
						var handled = false;
						if (!Asyncify.currData) {
							var asyncPromiseHandlers = Asyncify.asyncPromiseHandlers;
							if (asyncPromiseHandlers) {
								Asyncify.asyncPromiseHandlers = null;
								(isError ? asyncPromiseHandlers.reject : asyncPromiseHandlers.resolve)(asyncWasmReturnValue);
								handled = true;
							}
						}
						if (isError && !handled) throw asyncWasmReturnValue;
					});
					reachedAfterCallback = true;
					if (!reachedCallback) {
						Asyncify.state = Asyncify.State.Unwinding;
						Asyncify.currData = Asyncify.allocateData();
						if (typeof MainLoop != "undefined" && MainLoop.func) MainLoop.pause();
						runAndAbortIfError(() => _asyncify_start_unwind(Asyncify.currData));
					}
				} else if (Asyncify.state === Asyncify.State.Rewinding) {
					Asyncify.state = Asyncify.State.Normal;
					runAndAbortIfError(_asyncify_stop_rewind);
					_free(Asyncify.currData);
					Asyncify.currData = null;
					Asyncify.sleepCallbacks.forEach(callUserCallback);
				} else abort(`invalid state: ${Asyncify.state}`);
				return Asyncify.handleSleepReturnValue;
			},
			handleAsync: (startAsync) => Asyncify.handleSleep(async (wakeUp) => {
				wakeUp(await startAsync());
			})
		};
		var getCFunc = (ident) => {
			return Module["_" + ident];
		};
		var writeArrayToMemory = (array, buffer) => {
			HEAP8.set(array, buffer >>> 0);
		};
		var ccall = (ident, returnType, argTypes, args, opts) => {
			var toC = {
				string: (str) => {
					var ret = 0;
					if (str !== null && str !== void 0 && str !== 0) ret = stringToUTF8OnStack(str);
					return ret;
				},
				array: (arr) => {
					var ret = stackAlloc(arr.length);
					writeArrayToMemory(arr, ret);
					return ret;
				}
			};
			function convertReturnValue(ret) {
				if (returnType === "string") return UTF8ToString(ret);
				if (returnType === "pointer") return ret >>> 0;
				if (returnType === "boolean") return Boolean(ret);
				return ret;
			}
			var func = getCFunc(ident);
			var cArgs = [];
			var stack = 0;
			if (args) for (var i = 0; i < args.length; i++) {
				var converter = toC[argTypes[i]];
				if (converter) {
					if (!stack) stack = stackSave();
					cArgs[i] = converter(args[i]);
				} else cArgs[i] = args[i];
			}
			var previousAsync = Asyncify.currData;
			var ret = func(...cArgs);
			function onDone(ret) {
				runtimeKeepalivePop();
				if (stack) stackRestore(stack);
				return convertReturnValue(ret);
			}
			var asyncMode = opts?.async;
			runtimeKeepalivePush();
			if (Asyncify.currData != previousAsync) return Asyncify.whenDone().then(onDone);
			ret = onDone(ret);
			if (asyncMode) return Promise.resolve(ret);
			return ret;
		};
		var cwrap = (ident, returnType, argTypes, opts) => {
			var numericArgs = !argTypes || argTypes.every((type) => type === "number" || type === "boolean");
			if (returnType !== "string" && numericArgs && !opts) return getCFunc(ident);
			return (...args) => ccall(ident, returnType, argTypes, args, opts);
		};
		var HEAP16;
		var HEAP64;
		function getValue(ptr, type = "i8") {
			if (type.endsWith("*")) type = "*";
			switch (type) {
				case "i1": return HEAP8[ptr >>> 0];
				case "i8": return HEAP8[ptr >>> 0];
				case "i16": return HEAP16[ptr >>> 1 >>> 0];
				case "i32": return HEAP32[ptr >>> 2 >>> 0];
				case "i64": return HEAP64[ptr >>> 3 >>> 0];
				case "float": return HEAPF32[ptr >>> 2 >>> 0];
				case "double": return HEAPF64[ptr >>> 3 >>> 0];
				case "*": return HEAPU32[ptr >>> 2 >>> 0];
				default: abort(`invalid type for getValue: ${type}`);
			}
		}
		function setValue(ptr, value, type = "i8") {
			if (type.endsWith("*")) type = "*";
			switch (type) {
				case "i1":
					HEAP8[ptr >>> 0] = value;
					break;
				case "i8":
					HEAP8[ptr >>> 0] = value;
					break;
				case "i16":
					HEAP16[ptr >>> 1 >>> 0] = value;
					break;
				case "i32":
					HEAP32[ptr >>> 2 >>> 0] = value;
					break;
				case "i64":
					HEAP64[ptr >>> 3 >>> 0] = BigInt(value);
					break;
				case "float":
					HEAPF32[ptr >>> 2 >>> 0] = value;
					break;
				case "double":
					HEAPF64[ptr >>> 3 >>> 0] = value;
					break;
				case "*":
					HEAPU32[ptr >>> 2 >>> 0] = value;
					break;
				default: abort(`invalid type for setValue: ${type}`);
			}
		}
		if (Module["noExitRuntime"]) noExitRuntime = Module["noExitRuntime"];
		if (Module["print"]) out = Module["print"];
		if (Module["printErr"]) err = Module["printErr"];
		if (Module["arguments"]) Module["arguments"];
		if (Module["thisProgram"]) thisProgram = Module["thisProgram"];
		var preInit = Module["preInit"];
		if (preInit) {
			if (typeof preInit == "function") Module["preInit"] = preInit = [preInit];
			while (preInit.length > 0) preInit.shift()();
		}
		Module["ccall"] = ccall;
		Module["cwrap"] = cwrap;
		Module["setValue"] = setValue;
		Module["getValue"] = getValue;
		Module["UTF8ToString"] = UTF8ToString;
		Module["stringToUTF8"] = stringToUTF8;
		Module["lengthBytesUTF8"] = lengthBytesUTF8;
		var _malloc, _emwgpuCreateBindGroup, _emwgpuCreateBindGroupLayout, _emwgpuCreateCommandBuffer, _emwgpuCreateCommandEncoder, _emwgpuCreateComputePassEncoder, _emwgpuCreateComputePipeline, _emwgpuCreateExternalTexture, _emwgpuCreatePipelineLayout, _emwgpuCreateQuerySet, _emwgpuCreateRenderBundle, _emwgpuCreateRenderBundleEncoder, _emwgpuCreateRenderPassEncoder, _emwgpuCreateRenderPipeline, _emwgpuCreateSampler, _emwgpuCreateSurface, _emwgpuCreateTexture, _emwgpuCreateTextureView, _emwgpuCreateAdapter, _emwgpuImportBuffer, _emwgpuCreateDevice, _emwgpuCreateQueue, _emwgpuCreateShaderModule, _emwgpuOnDeviceLostCompleted, _emwgpuOnMapAsyncCompleted, _emwgpuOnRequestAdapterCompleted, _emwgpuOnRequestDeviceCompleted, _emwgpuOnUncapturedError, _free, _memalign, _setThrew, __emscripten_tempret_set, __emscripten_stack_restore, __emscripten_stack_alloc, _emscripten_stack_get_current, ___cxa_decrement_exception_refcount, ___cxa_increment_exception_refcount, ___cxa_can_catch, ___cxa_get_exception_ptr, dynCall_vi, dynCall_ii, dynCall_viii, dynCall_viiii, dynCall_vii, dynCall_iii, dynCall_iiii, dynCall_v, dynCall_iiiiiiii, dynCall_fiii, dynCall_diii, dynCall_viiiiiii, dynCall_i, dynCall_iiiii, dynCall_iiiiiii, dynCall_iiiiiiiiiiii, dynCall_viiiiiiiiii, dynCall_viiiiiiiiiiiiiii, dynCall_iiiiii, dynCall_iiiiij, dynCall_iiiiid, _asyncify_start_unwind, _asyncify_stop_unwind, _asyncify_start_rewind, _asyncify_stop_rewind, wasmMemory;
		function assignWasmExports(wasmExports) {
			Module["_gaussian_blur_fft"] = wasmExports["sa"];
			Module["_invert_image"] = wasmExports["ta"];
			Module["_threshold_image"] = wasmExports["ua"];
			Module["_black_threshold_image"] = wasmExports["va"];
			Module["_kmeans"] = wasmExports["wa"];
			Module["_bilateral_filter"] = wasmExports["xa"];
			Module["_labels_to_svg"] = wasmExports["ya"];
			Module["_image_to_svg"] = wasmExports["za"];
			_malloc = Module["_malloc"] = wasmExports["Ba"];
			_emwgpuCreateBindGroup = wasmExports["Ca"];
			_emwgpuCreateBindGroupLayout = wasmExports["Da"];
			_emwgpuCreateCommandBuffer = wasmExports["Ea"];
			_emwgpuCreateCommandEncoder = wasmExports["Fa"];
			_emwgpuCreateComputePassEncoder = wasmExports["Ga"];
			_emwgpuCreateComputePipeline = wasmExports["Ha"];
			_emwgpuCreateExternalTexture = wasmExports["Ia"];
			_emwgpuCreatePipelineLayout = wasmExports["Ja"];
			_emwgpuCreateQuerySet = wasmExports["Ka"];
			_emwgpuCreateRenderBundle = wasmExports["La"];
			_emwgpuCreateRenderBundleEncoder = wasmExports["Ma"];
			_emwgpuCreateRenderPassEncoder = wasmExports["Na"];
			_emwgpuCreateRenderPipeline = wasmExports["Oa"];
			_emwgpuCreateSampler = wasmExports["Pa"];
			_emwgpuCreateSurface = wasmExports["Qa"];
			_emwgpuCreateTexture = wasmExports["Ra"];
			_emwgpuCreateTextureView = wasmExports["Sa"];
			_emwgpuCreateAdapter = wasmExports["Ta"];
			_emwgpuImportBuffer = wasmExports["Ua"];
			_emwgpuCreateDevice = wasmExports["Va"];
			_emwgpuCreateQueue = wasmExports["Wa"];
			_emwgpuCreateShaderModule = wasmExports["Xa"];
			_emwgpuOnDeviceLostCompleted = wasmExports["Ya"];
			_emwgpuOnMapAsyncCompleted = wasmExports["Za"];
			_emwgpuOnRequestAdapterCompleted = wasmExports["_a"];
			_emwgpuOnRequestDeviceCompleted = wasmExports["$a"];
			_emwgpuOnUncapturedError = wasmExports["ab"];
			_free = Module["_free"] = wasmExports["bb"];
			_memalign = wasmExports["cb"];
			_setThrew = wasmExports["db"];
			__emscripten_tempret_set = wasmExports["eb"];
			__emscripten_stack_restore = wasmExports["fb"];
			__emscripten_stack_alloc = wasmExports["gb"];
			_emscripten_stack_get_current = wasmExports["hb"];
			___cxa_decrement_exception_refcount = wasmExports["ib"];
			___cxa_increment_exception_refcount = wasmExports["jb"];
			___cxa_can_catch = wasmExports["kb"];
			___cxa_get_exception_ptr = wasmExports["lb"];
			dynCall_vi = dynCalls["vi"] = wasmExports["mb"];
			dynCall_ii = dynCalls["ii"] = wasmExports["nb"];
			dynCalls["viiiii"] = wasmExports["ob"];
			dynCall_viii = dynCalls["viii"] = wasmExports["pb"];
			dynCall_viiii = dynCalls["viiii"] = wasmExports["qb"];
			dynCall_vii = dynCalls["vii"] = wasmExports["rb"];
			dynCall_iii = dynCalls["iii"] = wasmExports["sb"];
			dynCalls["viji"] = wasmExports["tb"];
			dynCall_iiii = dynCalls["iiii"] = wasmExports["ub"];
			dynCall_v = dynCalls["v"] = wasmExports["vb"];
			dynCalls["viijii"] = wasmExports["wb"];
			dynCalls["jiji"] = wasmExports["xb"];
			dynCalls["iidiiiii"] = wasmExports["yb"];
			dynCall_iiiiiiii = dynCalls["iiiiiiii"] = wasmExports["zb"];
			dynCalls["iiiiiiiiiiiii"] = wasmExports["Ab"];
			dynCall_fiii = dynCalls["fiii"] = wasmExports["Bb"];
			dynCall_diii = dynCalls["diii"] = wasmExports["Cb"];
			dynCall_viiiiiii = dynCalls["viiiiiii"] = wasmExports["Db"];
			dynCall_i = dynCalls["i"] = wasmExports["Eb"];
			dynCall_iiiii = dynCalls["iiiii"] = wasmExports["Fb"];
			dynCall_iiiiiii = dynCalls["iiiiiii"] = wasmExports["Gb"];
			dynCall_iiiiiiiiiiii = dynCalls["iiiiiiiiiiii"] = wasmExports["Hb"];
			dynCall_viiiiiiiiii = dynCalls["viiiiiiiiii"] = wasmExports["Ib"];
			dynCall_viiiiiiiiiiiiiii = dynCalls["viiiiiiiiiiiiiii"] = wasmExports["Jb"];
			dynCall_iiiiii = dynCalls["iiiiii"] = wasmExports["Kb"];
			dynCalls["iiiiiiiii"] = wasmExports["Lb"];
			dynCall_iiiiij = dynCalls["iiiiij"] = wasmExports["Mb"];
			dynCall_iiiiid = dynCalls["iiiiid"] = wasmExports["Nb"];
			dynCalls["iiiiijj"] = wasmExports["Ob"];
			dynCalls["iiiiiijj"] = wasmExports["Pb"];
			dynCalls["viiiiii"] = wasmExports["Qb"];
			_asyncify_start_unwind = wasmExports["Rb"];
			_asyncify_stop_unwind = wasmExports["Sb"];
			_asyncify_start_rewind = wasmExports["Tb"];
			_asyncify_stop_rewind = wasmExports["Ub"];
			wasmMemory = wasmExports["qa"];
			wasmExports["Aa"];
		}
		var wasmImports = {
			p: ___cxa_begin_catch,
			q: ___cxa_end_catch,
			b: ___cxa_find_matching_catch_2,
			f: ___cxa_find_matching_catch_3,
			ba: ___cxa_rethrow,
			r: ___cxa_throw,
			aa: ___cxa_uncaught_exceptions,
			d: ___resumeException,
			da: __abort_js,
			W: __tzset_js,
			ia: _emscripten_has_asyncify,
			ca: _emscripten_resize_heap,
			n: _emscripten_sleep,
			ha: _emwgpuAdapterRequestDevice,
			na: _emwgpuBufferDestroy,
			ma: _emwgpuBufferGetConstMappedRange,
			la: _emwgpuBufferMapAsync,
			ka: _emwgpuBufferUnmap,
			g: _emwgpuDelete,
			ga: _emwgpuDeviceCreateBuffer,
			fa: _emwgpuDeviceCreateShaderModule,
			ja: _emwgpuDeviceDestroy,
			ea: _emwgpuInstanceRequestAdapter,
			U: _environ_get,
			V: _environ_sizes_get,
			X: _fd_close,
			Y: _fd_read,
			Z: _fd_seek,
			Q: _fd_write,
			N: invoke_diii,
			O: invoke_fiii,
			k: invoke_i,
			a: invoke_ii,
			c: invoke_iii,
			j: invoke_iiii,
			i: invoke_iiiii,
			_: invoke_iiiiid,
			J: invoke_iiiiii,
			v: invoke_iiiiiii,
			P: invoke_iiiiiiii,
			I: invoke_iiiiiiiiiiii,
			$: invoke_iiiiij,
			h: invoke_v,
			m: invoke_vi,
			e: invoke_vii,
			s: invoke_viii,
			R: invoke_viiii,
			o: invoke_viiiiiii,
			E: invoke_viiiiiiiiii,
			H: invoke_viiiiiiiiiiiiiii,
			T: _random_get,
			pa: _wgpuAdapterGetLimits,
			D: _wgpuCommandEncoderBeginComputePass,
			S: _wgpuCommandEncoderCopyBufferToBuffer,
			M: _wgpuCommandEncoderCopyTextureToBuffer,
			L: _wgpuCommandEncoderFinish,
			A: _wgpuComputePassEncoderDispatchWorkgroups,
			z: _wgpuComputePassEncoderEnd,
			B: _wgpuComputePassEncoderSetBindGroup,
			C: _wgpuComputePassEncoderSetPipeline,
			x: _wgpuComputePipelineGetBindGroupLayout,
			w: _wgpuDeviceCreateBindGroup,
			F: _wgpuDeviceCreateCommandEncoder,
			oa: _wgpuDeviceCreateComputePipeline,
			t: _wgpuDeviceCreateTexture,
			K: _wgpuQueueSubmit,
			y: _wgpuQueueWriteBuffer,
			G: _wgpuQueueWriteTexture,
			l: _wgpuTextureCreateView,
			u: _wgpuTextureDestroy
		};
		function invoke_iiii(index, a1, a2, a3) {
			var sp = stackSave();
			try {
				return dynCall_iiii(index, a1, a2, a3);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_iii(index, a1, a2) {
			var sp = stackSave();
			try {
				return dynCall_iii(index, a1, a2);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_vii(index, a1, a2) {
			var sp = stackSave();
			try {
				dynCall_vii(index, a1, a2);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_ii(index, a1) {
			var sp = stackSave();
			try {
				return dynCall_ii(index, a1);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_vi(index, a1) {
			var sp = stackSave();
			try {
				dynCall_vi(index, a1);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_v(index) {
			var sp = stackSave();
			try {
				dynCall_v(index);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_iiiiiii(index, a1, a2, a3, a4, a5, a6) {
			var sp = stackSave();
			try {
				return dynCall_iiiiiii(index, a1, a2, a3, a4, a5, a6);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_viiii(index, a1, a2, a3, a4) {
			var sp = stackSave();
			try {
				dynCall_viiii(index, a1, a2, a3, a4);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_iiiiii(index, a1, a2, a3, a4, a5) {
			var sp = stackSave();
			try {
				return dynCall_iiiiii(index, a1, a2, a3, a4, a5);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_iiiiij(index, a1, a2, a3, a4, a5) {
			var sp = stackSave();
			try {
				return dynCall_iiiiij(index, a1, a2, a3, a4, a5);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_iiiiid(index, a1, a2, a3, a4, a5) {
			var sp = stackSave();
			try {
				return dynCall_iiiiid(index, a1, a2, a3, a4, a5);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_viii(index, a1, a2, a3) {
			var sp = stackSave();
			try {
				dynCall_viii(index, a1, a2, a3);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_iiiiiiii(index, a1, a2, a3, a4, a5, a6, a7) {
			var sp = stackSave();
			try {
				return dynCall_iiiiiiii(index, a1, a2, a3, a4, a5, a6, a7);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_fiii(index, a1, a2, a3) {
			var sp = stackSave();
			try {
				return dynCall_fiii(index, a1, a2, a3);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_diii(index, a1, a2, a3) {
			var sp = stackSave();
			try {
				return dynCall_diii(index, a1, a2, a3);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_iiiii(index, a1, a2, a3, a4) {
			var sp = stackSave();
			try {
				return dynCall_iiiii(index, a1, a2, a3, a4);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_viiiiiii(index, a1, a2, a3, a4, a5, a6, a7) {
			var sp = stackSave();
			try {
				dynCall_viiiiiii(index, a1, a2, a3, a4, a5, a6, a7);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_i(index) {
			var sp = stackSave();
			try {
				return dynCall_i(index);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_iiiiiiiiiiii(index, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) {
			var sp = stackSave();
			try {
				return dynCall_iiiiiiiiiiii(index, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_viiiiiiiiii(index, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
			var sp = stackSave();
			try {
				dynCall_viiiiiiiiii(index, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function invoke_viiiiiiiiiiiiiii(index, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) {
			var sp = stackSave();
			try {
				dynCall_viiiiiiiiiiiiiii(index, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15);
			} catch (e) {
				stackRestore(sp);
				if (!(e instanceof EmscriptenEH)) throw e;
				_setThrew(1, 0);
			}
		}
		function applySignatureConversions(wasmExports) {
			wasmExports = Object.assign({}, wasmExports);
			var makeWrapper_pp = (f) => (a0) => f(a0) >>> 0;
			var makeWrapper_ppp = (f) => (a0, a1) => f(a0, a1) >>> 0;
			var makeWrapper_p = (f) => () => f() >>> 0;
			wasmExports["Ba"] = makeWrapper_pp(wasmExports["Ba"]);
			wasmExports["cb"] = makeWrapper_ppp(wasmExports["cb"]);
			wasmExports["gb"] = makeWrapper_pp(wasmExports["gb"]);
			wasmExports["hb"] = makeWrapper_p(wasmExports["hb"]);
			wasmExports["lb"] = makeWrapper_pp(wasmExports["lb"]);
			return wasmExports;
		}
		async function run() {
			preRun();
			var setStatus = Module["setStatus"];
			if (setStatus) {
				setStatus("Running...");
				await new Promise((resolve) => setTimeout(resolve, 1));
				setTimeout(setStatus, 1, "");
			}
			if (ABORT) return;
			initRuntime();
			Module["onRuntimeInitialized"]?.();
			postRun();
		}
		var wasmExports = await createWasm();
		await run();
		return Module;
	}
	if (typeof exports === "object" && typeof module === "object") {
		module.exports = createImg2NumModule$1;
		module.exports.default = createImg2NumModule$1;
	} else if (typeof define === "function" && define["amd"]) define([], () => createImg2NumModule$1);
})))(), 1);
var wasmModule;
var initialized = false;
var readyPromise;
/**
* @internal
* @summary Get the initialized WASM module instance.
*
* @description
* Returns the cached Emscripten module instance. This function assumes
* {@link initWasmModule} has already completed successfully.
*
* @function getWasmModule
* @returns {Object|undefined} The initialized WASM module.
* @since 0.3.0
*/
function getWasmModule() {
	return wasmModule;
}
/**
* `@summary` Initialize the WASM module. Async as of `#433`. Previously `initWasmWorker`.
* `@function` initWasmModule
* `@since` 0.0.0
*/
async function initWasmModule() {
	if (initialized) return;
	if (!readyPromise) readyPromise = (async () => {
		try {
			const { initWebGPU } = await import("./webgpu-CxwU2TmN.js");
			await initWebGPU();
		} catch (err) {
			console.error(`[Img2Num wasmModule] WebGPU init error: ${err}\n\nFalling back to CPU.`);
			globalThis.navigator ??= {};
			globalThis.navigator.gpu ??= { requestAdapter: async () => null };
		}
		wasmModule = await (0, import_img2num.default)();
	})();
	await readyPromise;
	initialized = true;
}
/**
* @summary Release resources held by the WebAssembly module.
*
* @description
* This function is optional. In most applications, there is no need to call
* it explicitly, as resources are released when the process exits. It is
* provided for applications that need to reclaim resources—such as a WebGPU
* device—before program termination so they can be used elsewhere.
*
* @async
* @function terminateWasmModule
* @returns {Promise<void>} A promise that resolves once all resources have
* been released and the module has been reset to an uninitialized state.
* @since 0.3.0
*/
async function terminateWasmModule() {
	try {
		const { destroyWebGPU } = await import("./webgpu-CxwU2TmN.js");
		await destroyWebGPU();
	} catch (err) {
		console.error(`[Img2Num wasmModule] WebGPU cleanup error: ${err}`);
	}
	wasmModule = void 0;
	initialized = false;
	readyPromise = void 0;
}
//#endregion
//#region src/wasmTypes.js
/**
* @internal
*/
/**
* @internal
* @summary Type marshaling definitions used by the WASM client.
*
* @description
* Maps supported JavaScript types to allocation and readback handlers used
* when transferring values between JavaScript and the WebAssembly heap.
*
* Each handler exposes:
* - `alloc(value)` — allocates and writes data into WASM memory.
* - `read(ptr, length)` — reconstructs a JavaScript value from WASM memory.
*
* @constant
* @type {Object}
* @since 0.3.0
*/
var WASM_TYPES = {
	void: {
		alloc: () => null,
		read: () => void 0
	},
	Int32Array: {
		alloc: (arr) => {
			const wasmModule = getWasmModule();
			const ptr = wasmModule._malloc(arr.byteLength);
			wasmModule.HEAP32.set(arr, ptr >> 2);
			return ptr;
		},
		read: (ptr, len) => {
			const wasmModule = getWasmModule();
			return new Int32Array(wasmModule.HEAP32.buffer, ptr, len).slice();
		}
	},
	Uint8Array: {
		alloc: (arr) => {
			const wasmModule = getWasmModule();
			const ptr = wasmModule._malloc(arr.byteLength);
			wasmModule.HEAPU8.set(arr, ptr);
			return ptr;
		},
		read: (ptr, len) => {
			return getWasmModule().HEAPU8.slice(ptr, ptr + len);
		}
	},
	Uint8ClampedArray: {
		alloc: (arr) => {
			const wasmModule = getWasmModule();
			const ptr = wasmModule._malloc(arr.byteLength);
			wasmModule.HEAPU8.set(arr, ptr);
			return ptr;
		},
		read: (ptr, len) => {
			const wasmModule = getWasmModule();
			return new Uint8ClampedArray(wasmModule.HEAPU8.slice(ptr, ptr + len));
		}
	},
	string: {
		alloc: (str) => {
			const wasmModule = getWasmModule();
			const len = wasmModule.lengthBytesUTF8(str) + 1;
			const ptr = wasmModule._malloc(len);
			wasmModule.stringToUTF8(str, ptr, len);
			return ptr;
		},
		read: (ptr) => {
			const wasmModule = getWasmModule();
			return ptr ? wasmModule.UTF8ToString(ptr) : null;
		}
	}
};
//#endregion
//#region src/ccall.js
/**
* @internal
*/
/**
* @internal
* @summary Invoke an exported Emscripten function asynchronously.
*
* @description
* Wraps `Module.ccall()` using the currently initialized WASM module.
* All arguments are passed as numeric values, matching the pointer-based
* interface used internally by the library.
*
* @async
* @function ccallAsync
* @param {string} funcName - Exported function name.
* @param {Map<string, *>} argsMap - Ordered function arguments.
* @param {string} returnType - Logical return type.
* @returns {Promise<*>} The raw value returned by the exported function.
* @since 0.3.0
*/
async function ccallAsync(funcName, argsMap, returnType) {
	const wasmModule = getWasmModule();
	const argTypes = Array(argsMap.size).fill("number");
	const retType = returnType === "void" ? null : "number";
	return wasmModule.ccall(funcName, retType, argTypes, [...argsMap.values()], { async: true });
}
//#endregion
//#region src/wasmClient.js
/**
* @packageDocumentation
* Low-level interface for calling into the WASM (Img2Num) module directly.
*
* @internal
*/
/**
* @internal
* @summary Invoke a WASM function with automatic memory management.
*
* @description
* Allocates input buffers, marshals JavaScript values into WASM memory,
* invokes the requested exported function, reads modified buffers and return
* values back into JavaScript, and finally releases all temporary WASM
* allocations.
*
* @async
* @function callWasm
* @param {Object} options
* @param {string} options.funcName - Name of the exported WASM function.
* @param {Object} [options.args={}] - Function arguments.
* @param {Array<{key:string,type:string}>} [options.bufferKeys=[]] - Buffer arguments requiring allocation.
* @param {string} [options.returnType="void"] - Expected return type.
* @returns {Promise<{output:Object, returnValue:any}>}
* @throws {Error} If allocation or the WASM call fails.
* @since 0.0.0
*/
async function callWasm({ funcName, args = {}, bufferKeys = [], returnType = "void" }) {
	await initWasmModule();
	const wasmModule = getWasmModule();
	const pointers = /* @__PURE__ */ new Map();
	const argsMap = new Map(Object.entries(args));
	try {
		for (const { key, type } of bufferKeys) {
			const handler = WASM_TYPES[type];
			if (!handler) throw new Error(`Unsupported type: ${type}`);
			const value = argsMap.get(key);
			const ptr = handler.alloc(value);
			pointers.set(key, {
				ptr,
				type,
				length: value?.length
			});
			argsMap.set(key, ptr);
		}
		const result = await ccallAsync(funcName, argsMap, returnType);
		const output = Object.create(null);
		for (const { key, type } of bufferKeys) {
			const { ptr, length } = pointers.get(key);
			output[key] = WASM_TYPES[type].read(ptr, length);
		}
		let returnValue = result;
		if (returnType !== "void") returnValue = WASM_TYPES[returnType].read(result);
		if (returnType === "string" && result) wasmModule._free(result);
		return {
			output,
			returnValue
		};
	} catch (error) {
		throw new Error(`[Img2Num wasmClient] Error: ${error?.message ?? error}`, { cause: error });
	} finally {
		for (const { ptr } of pointers.values()) wasmModule._free(ptr);
	}
}
//#endregion
//#region src/safeWasmWrappers.js
/**
* @packageDocumentation
* High-level image operations exposed via WASM.
*
* The exports defined here abstract away the manual memory management required
* when importing raw WASM functions, making them more JavaScript-friendly.
*
* @file Safely wraps unsafe WASM (C++) function calls.
*
* @module image-wasm
* @license MIT
* @copyright Ryan Millard 2026
* @author Ryan Millard
* @since 0.0.0
* @description This module provides high-level image processing functions using WASM.
*              Each function handles memory management and exposes a JavaScript-friendly API.
*/
/**
* @summary Apply a Gaussian blur to an image using FFT in WASM.
*
* @description
* Takes a Uint8ClampedArray and its dimensions and applies a Gaussian blur on the Uint8ClampedArray image.
* The `sigma_pixels` parameter determines the blur radius and has a dynamic default value equal to 5% of the image's width.
* Useful for denoising images by applying a low-pass filter. Sped up by a 2-D FFT.
*
* @async
* @function gaussianBlur
* @param {Object} options - The input options.
* @param {Uint8ClampedArray} options.pixels - The image pixel data (flat RGBA array).
* @param {number} options.width - The width of the image.
* @param {number} options.height - The height of the image.
* @param {number} [options.sigma_pixels=width*0.005] - Standard deviation of the Gaussian blur (default=width*0.005; 5% of width).
* @returns {Promise<Uint8ClampedArray>} The blurred image pixels.
* @throws {Error} If the WASM function fails or memory allocation fails.
* @example
* const blurred = await gaussianBlur({ pixels, width, height });
* @todo Fix FFT zero-padding bug around edges of the image.
* @variation Standard Gaussian blur using FFT
* @since 0.0.0
*/
var gaussianBlur = async ({ pixels, width, height, sigma_pixels = width * .005 }) => {
	return (await callWasm({
		funcName: "gaussian_blur_fft",
		args: {
			pixels,
			width,
			height,
			sigma_pixels
		},
		bufferKeys: [{
			key: "pixels",
			type: "Uint8ClampedArray"
		}]
	})).output.pixels;
};
/**
* @summary Apply a bilateral filter to an image using WASM.
*
* @description
* Takes a Uint8ClampedArray and its dimensions and applies a bilateral filter on the Uint8ClampedArray image.
* The `sigma_spatial` and `sigma_range` set weights to the respective Gaussian kernels applied to spatial (x, y) and range (color) data -
* they both have recommended default values applied.
* The default `color_space` is 0, which is CIE LAB, but sRGB can be chosen by setting `color_space` = 1. CIE LAB is more
* accurate, but sRGB is slightly faster.
*
* @async
* @function bilateralFilter
* @param {Object} options - The input options.
* @param {Uint8ClampedArray} options.pixels - The image pixel data (flat RGBA array).
* @param {number} options.width - The width of the image.
* @param {number} options.height - The height of the image.
* @param {number} [options.sigma_spatial=3] - Spatial standard deviation.
* @param {number} [options.sigma_range=50] - Range (color) standard deviation.
* @param {number} [options.color_space=0] - Color space mode (0: CIE LAB; 1: sRGB).
* @returns {Promise<Uint8ClampedArray>} The filtered image pixels.
* @throws {Error} If the WASM function fails.
* @example
* const filtered = await bilateralFilter({ pixels, width, height });
* @variation Standard bilateral filter with default parameters
* @since 0.0.0
*/
var bilateralFilter = async ({ pixels, width, height, sigma_spatial = 3, sigma_range = 50, color_space = 0 }) => {
	return (await callWasm({
		funcName: "bilateral_filter",
		args: {
			pixels,
			width,
			height,
			sigma_spatial,
			sigma_range,
			color_space
		},
		bufferKeys: [{
			key: "pixels",
			type: "Uint8ClampedArray"
		}]
	})).output.pixels;
};
/**
* @summary Apply a black-biased threshold filter to reduce colors in an image.
*
* @description
* Apply a simple sRGB bin-based threshold on the Uint8ClampedArray image.
* The bins in this function are determined by the `num_colors` parameter.
*
* @async
* @function blackThreshold
* @param {Object} options - The input options.
* @param {Uint8ClampedArray} options.pixels - The image pixel data (flat RGBA array).
* @param {number} options.width - The width of the image.
* @param {number} options.height - The height of the image.
* @param {number} options.num_colors - Number of colors to reduce the image to.
* @returns {Promise<Uint8ClampedArray>} The thresholded image pixels.
* @throws {Error} If the WASM function fails.
* @example
* const thresholded = await blackThreshold({ pixels, width, height, num_colors: 16 });
* @see {@link https://en.wikipedia.org/wiki/Color_quantization|Color Quantization Wiki}
* @todo Support different bias levels for black/white thresholds.
* @variation Black-biased threshold with customizable number of colors
* @since 0.0.0
*/
var blackThreshold = async ({ pixels, width, height, num_colors }) => {
	return (await callWasm({
		funcName: "black_threshold_image",
		args: {
			pixels,
			width,
			height,
			num_colors
		},
		bufferKeys: [{
			key: "pixels",
			type: "Uint8ClampedArray"
		}]
	})).output.pixels;
};
/**
* @summary Cluster pixels using the K-Means algorithm in WASM.
*
* @description
* Apply a standard K-Means clustering algorithm to the input image in the specified `color_space`
* (default is 0: CIE LAB, but 1: sRGB can be use) using pre-specified maximum color and iteration counts.
* You can provide the `out_pixels` and `out_labels` arrays,
* however this is atypical in JavaScript (since it is modified in-place and you will need to allocate a sufficiently large array),
* so it is recommended to use the default arguments and returns.
*
* @async
* @function kmeans
* @param {Object} options - The input options.
* @param {Uint8ClampedArray} options.pixels - Original image pixels.
* @param {Uint8ClampedArray} [options.out_pixels=new Uint8ClampedArray(pixels.length)] - Output pixels array.
* @param {Int32Array} [options.out_labels=new Int32Array(pixels.length/4)] - Output labels array.
* @param {number} options.width - Image width.
* @param {number} options.height - Image height.
* @param {number} options.num_colors - Number of color clusters.
* @param {number} [options.max_iter=100] - Maximum number of iterations.
* @param {number} [options.color_space=0] - Color space mode.
* @returns {Promise<{pixels: Uint8ClampedArray, labels: Int32Array}>} Clustered pixels and labels.
* @throws {Error} If the WASM function fails or iterations do not converge.
* @example
* const { pixels: clusteredPixels, labels } = await kmeans({ pixels, width, height, num_colors: 8 });
* @variation K-means clustering with default color space
* @since 0.0.0
*/
var kmeans = async ({ pixels, out_pixels = new Uint8ClampedArray(pixels.length), out_labels = new Int32Array(pixels.length / 4), width, height, num_colors, max_iter = 100, color_space = 0 }) => {
	const result = await callWasm({
		funcName: "kmeans",
		args: {
			pixels,
			out_pixels,
			out_labels,
			width,
			height,
			num_colors,
			max_iter,
			color_space
		},
		bufferKeys: [
			{
				key: "pixels",
				type: "Uint8ClampedArray"
			},
			{
				key: "out_pixels",
				type: "Uint8ClampedArray"
			},
			{
				key: "out_labels",
				type: "Int32Array"
			}
		]
	});
	return {
		pixels: result.output.out_pixels,
		labels: result.output.out_labels
	};
};
/**
* @summary Convert labeled regions to SVG contours.
*
* @description
* Convert an input image and its labeled regions into an SVG.
*
* @async
* @function findContours
* @param {Object} options - The input options.
* @param {Uint8ClampedArray} options.pixels - Original image pixels.
* @param {Int32Array} options.labels - Label array from clustering (e.g., K-Means) or segmentation.
* @param {number} options.width - Image width.
* @param {number} options.height - Image height.
* @param {number} [options.min_area=100] - Minimum area of a region to be considered a contour.
* @param {number} [options.min_thickness=10] - Minimum thickness of a region to be considered a contour.
* @returns {Promise<{svg: string}>} Generated SVG.
* @throws {Error} If the WASM function fails or input labels are invalid.
* @example
* const { svg } = await findContours({ pixels, labels, width, height });
* @variation Converts labeled (from a clustering algorithm, e.g. K-Means) image into an SVG.
* @since 0.0.0
*/
var findContours = async ({ pixels, labels, width, height, min_area = 100, min_thickness = 10 }) => {
	return { svg: (await callWasm({
		funcName: "labels_to_svg",
		args: {
			pixels,
			labels,
			width,
			height,
			min_area,
			min_thickness
		},
		bufferKeys: [{
			key: "pixels",
			type: "Uint8ClampedArray"
		}, {
			key: "labels",
			type: "Int32Array"
		}],
		returnType: "string"
	})).returnValue };
};
/**
* @summary Convert raster images (e.g., JPEG, PNG) to SVGs.
*
* @description
* Convert an input raster image into an SVG. A unification of `bilateralFilter`, `kmeans`, and `findContours`.
*
* @async
* @function imageToSvg
* @param {Object} options - The input options.
* @param {Uint8ClampedArray} options.pixels - Original image pixels.
* @param {number} options.width - Image width.
* @param {number} options.height - Image height.
* @param {number} [options.sigma_spatial=3] - Spatial standard deviation.
* @param {number} [options.sigma_range=50] - Range (color) standard deviation.
* @param {number} [options.num_colors=16] - Number of color clusters.
* @param {number} [options.max_iter=100] - Maximum number of iterations.
* @param {number} [options.min_area=100] - Minimum area of a region to be considered a contour.
* @param {number} [options.min_thickness=10] - Minimum thickness of a region to be considered a contour.
* @param {number} [options.color_space=0] - Color space mode.
* @returns {Promise<{svg: string}>} Generated SVG.
* @throws {Error} If the WASM function fails or input labels are invalid.
* @example
* const { svg } = await findContours({ pixels, labels, width, height });
* @variation Convert a raster image (e.g., PNG, JPG) into an SVG.
* @since 0.0.0
*/
var imageToSvg = async ({ pixels, width, height, sigma_spatial = 3, sigma_range = 50, num_colors = 16, max_iter = 100, min_area = 100, min_thickness = 10, color_space = 0 }) => {
	return { svg: (await callWasm({
		funcName: "image_to_svg",
		args: {
			pixels,
			width,
			height,
			sigma_spatial,
			sigma_range,
			num_colors,
			max_iter,
			min_area,
			min_thickness,
			color_space
		},
		bufferKeys: [{
			key: "pixels",
			type: "Uint8ClampedArray"
		}],
		returnType: "string"
	})).returnValue };
};
//#endregion
export { bilateralFilter, blackThreshold, findContours, gaussianBlur, imageToSvg, imageToUint8ClampedArray, kmeans, terminateWasmModule };

//# sourceMappingURL=img2num.js.map