@mori2003/jsimgui
Version:
JavaScript bindings for Dear ImGui.
1,213 lines (1,211 loc) • 270 kB
JavaScript
var MainExport = (() => {
var _scriptName = import.meta.url;
return async function (moduleArg = {}) {
var moduleRtn;
var Module = moduleArg;
var readyPromiseResolve, readyPromiseReject;
var readyPromise = new Promise((resolve, reject) => {
readyPromiseResolve = resolve;
readyPromiseReject = reject;
});
var ENVIRONMENT_IS_WEB = true;
var ENVIRONMENT_IS_WORKER = false;
var moduleOverrides = Object.assign({}, Module);
var arguments_ = [];
var thisProgram = "./this.program";
var quit_ = (status, toThrow) => {
throw toThrow;
};
var scriptDirectory = "";
function locateFile(path) {
if (Module["locateFile"]) {
return Module["locateFile"](path, scriptDirectory);
}
return scriptDirectory + path;
}
var readAsync, readBinary;
if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
if (ENVIRONMENT_IS_WORKER) {
scriptDirectory = self.location.href;
} else if (typeof document != "undefined" && document.currentScript) {
scriptDirectory = document.currentScript.src;
}
if (_scriptName) {
scriptDirectory = _scriptName;
}
if (scriptDirectory.startsWith("blob:")) {
scriptDirectory = "";
} else {
scriptDirectory = scriptDirectory.slice(
0,
scriptDirectory.replace(/[?#].*/, "").lastIndexOf("/") + 1,
);
}
{
readAsync = async (url) => {
var response = await fetch(url, { credentials: "same-origin" });
if (response.ok) {
return response.arrayBuffer();
}
throw new Error(response.status + " : " + response.url);
};
}
} else {
}
var out = Module["print"] || console.log.bind(console);
var err = Module["printErr"] || console.error.bind(console);
Object.assign(Module, moduleOverrides);
moduleOverrides = null;
if (Module["arguments"]) arguments_ = Module["arguments"];
if (Module["thisProgram"]) thisProgram = Module["thisProgram"];
var wasmBinary = Module["wasmBinary"];
var wasmMemory;
var ABORT = false;
var EXITSTATUS;
var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAP64, HEAPU64, HEAPF64;
var runtimeInitialized = false;
function updateMemoryViews() {
var b = wasmMemory.buffer;
Module["HEAP8"] = HEAP8 = new Int8Array(b);
Module["HEAP16"] = HEAP16 = new Int16Array(b);
Module["HEAPU8"] = HEAPU8 = new Uint8Array(b);
Module["HEAPU16"] = HEAPU16 = new Uint16Array(b);
Module["HEAP32"] = HEAP32 = new Int32Array(b);
Module["HEAPU32"] = HEAPU32 = new Uint32Array(b);
Module["HEAPF32"] = HEAPF32 = new Float32Array(b);
Module["HEAPF64"] = HEAPF64 = new Float64Array(b);
Module["HEAP64"] = HEAP64 = new BigInt64Array(b);
Module["HEAPU64"] = HEAPU64 = new BigUint64Array(b);
}
function preRun() {
if (Module["preRun"]) {
if (typeof Module["preRun"] == "function") Module["preRun"] = [Module["preRun"]];
while (Module["preRun"].length) {
addOnPreRun(Module["preRun"].shift());
}
}
callRuntimeCallbacks(onPreRuns);
}
function initRuntime() {
runtimeInitialized = true;
if (!Module["noFSInit"] && !FS.initialized) FS.init();
TTY.init();
wasmExports["mb"]();
FS.ignorePermissions = false;
}
function postRun() {
if (Module["postRun"]) {
if (typeof Module["postRun"] == "function") Module["postRun"] = [Module["postRun"]];
while (Module["postRun"].length) {
addOnPostRun(Module["postRun"].shift());
}
}
callRuntimeCallbacks(onPostRuns);
}
var runDependencies = 0;
var dependenciesFulfilled = null;
function getUniqueRunDependency(id) {
return id;
}
function addRunDependency(id) {
runDependencies++;
Module["monitorRunDependencies"]?.(runDependencies);
}
function removeRunDependency(id) {
runDependencies--;
Module["monitorRunDependencies"]?.(runDependencies);
if (runDependencies == 0) {
if (dependenciesFulfilled) {
var callback = dependenciesFulfilled;
dependenciesFulfilled = null;
callback();
}
}
}
function abort(what) {
Module["onAbort"]?.(what);
what = "Aborted(" + what + ")";
err(what);
ABORT = true;
what += ". Build with -sASSERTIONS for more info.";
var e = new WebAssembly.RuntimeError(what);
readyPromiseReject(e);
throw e;
}
var wasmBinaryFile;
function findWasmBinary() {
if (Module["locateFile"]) {
return locateFile("jsimgui-em.wasm");
}
return new URL("jsimgui-em.wasm", import.meta.url).href;
}
function getBinarySync(file) {
if (file == wasmBinaryFile && wasmBinary) {
return new Uint8Array(wasmBinary);
}
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);
var instance = await WebAssembly.instantiate(binary, imports);
return instance;
} catch (reason) {
err(`failed to asynchronously prepare wasm: ${reason}`);
abort(reason);
}
}
async function instantiateAsync(binary, binaryFile, imports) {
if (!binary && typeof WebAssembly.instantiateStreaming == "function") {
try {
var response = fetch(binaryFile, { credentials: "same-origin" });
var instantiationResult = await WebAssembly.instantiateStreaming(
response,
imports,
);
return instantiationResult;
} 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, module) {
wasmExports = instance.exports;
wasmMemory = wasmExports["lb"];
updateMemoryViews();
wasmTable = wasmExports["qb"];
removeRunDependency("wasm-instantiate");
return wasmExports;
}
addRunDependency("wasm-instantiate");
function receiveInstantiationResult(result) {
return receiveInstance(result["instance"]);
}
var info = getWasmImports();
if (Module["instantiateWasm"]) {
return new Promise((resolve, reject) => {
Module["instantiateWasm"](info, (mod, inst) => {
receiveInstance(mod, inst);
resolve(mod.exports);
});
});
}
wasmBinaryFile ??= findWasmBinary();
try {
var result = await instantiateAsync(wasmBinary, wasmBinaryFile, info);
var exports = receiveInstantiationResult(result);
return exports;
} catch (e) {
readyPromiseReject(e);
return Promise.reject(e);
}
}
class ExitStatus {
name = "ExitStatus";
constructor(status) {
this.message = `Program terminated with exit(${status})`;
this.status = status;
}
}
var callRuntimeCallbacks = (callbacks) => {
while (callbacks.length > 0) {
callbacks.shift()(Module);
}
};
var onPostRuns = [];
var addOnPostRun = (cb) => onPostRuns.unshift(cb);
var onPreRuns = [];
var addOnPreRun = (cb) => onPreRuns.unshift(cb);
var noExitRuntime = Module["noExitRuntime"] || true;
var stackRestore = (val) => __emscripten_stack_restore(val);
var stackSave = () => _emscripten_stack_get_current();
var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder() : undefined;
var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead = NaN) => {
var endIdx = idx + maxBytesToRead;
var endPtr = idx;
while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;
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) =>
ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "";
var ___assert_fail = (condition, filename, line, func) =>
abort(
`Assertion failed: ${UTF8ToString(condition)}, at: ` +
[
filename ? UTF8ToString(filename) : "unknown filename",
line,
func ? UTF8ToString(func) : "unknown function",
],
);
class ExceptionInfo {
constructor(excPtr) {
this.excPtr = excPtr;
this.ptr = excPtr - 24;
}
set_type(type) {
HEAPU32[(this.ptr + 4) >> 2] = type;
}
get_type() {
return HEAPU32[(this.ptr + 4) >> 2];
}
set_destructor(destructor) {
HEAPU32[(this.ptr + 8) >> 2] = destructor;
}
get_destructor() {
return HEAPU32[(this.ptr + 8) >> 2];
}
set_caught(caught) {
caught = caught ? 1 : 0;
HEAP8[this.ptr + 12] = caught;
}
get_caught() {
return HEAP8[this.ptr + 12] != 0;
}
set_rethrown(rethrown) {
rethrown = rethrown ? 1 : 0;
HEAP8[this.ptr + 13] = rethrown;
}
get_rethrown() {
return HEAP8[this.ptr + 13] != 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] = adjustedPtr;
}
get_adjusted_ptr() {
return HEAPU32[(this.ptr + 16) >> 2];
}
}
var exceptionLast = 0;
var uncaughtExceptionCount = 0;
var ___cxa_throw = (ptr, type, destructor) => {
var info = new ExceptionInfo(ptr);
info.init(type, destructor);
exceptionLast = ptr;
uncaughtExceptionCount++;
throw exceptionLast;
};
var syscallGetVarargI = () => {
var ret = HEAP32[+SYSCALLS.varargs >> 2];
SYSCALLS.varargs += 4;
return ret;
};
var syscallGetVarargP = syscallGetVarargI;
var PATH = {
isAbs: (path) => path.charAt(0) === "/",
splitPath: (filename) => {
var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
return splitPathRe.exec(filename).slice(1);
},
normalizeArray: (parts, allowAboveRoot) => {
var up = 0;
for (var i = parts.length - 1; i >= 0; i--) {
var last = parts[i];
if (last === ".") {
parts.splice(i, 1);
} else if (last === "..") {
parts.splice(i, 1);
up++;
} else if (up) {
parts.splice(i, 1);
up--;
}
}
if (allowAboveRoot) {
for (; up; up--) {
parts.unshift("..");
}
}
return parts;
},
normalize: (path) => {
var isAbsolute = PATH.isAbs(path),
trailingSlash = path.slice(-1) === "/";
path = PATH.normalizeArray(
path.split("/").filter((p) => !!p),
!isAbsolute,
).join("/");
if (!path && !isAbsolute) {
path = ".";
}
if (path && trailingSlash) {
path += "/";
}
return (isAbsolute ? "/" : "") + path;
},
dirname: (path) => {
var result = PATH.splitPath(path),
root = result[0],
dir = result[1];
if (!root && !dir) {
return ".";
}
if (dir) {
dir = dir.slice(0, -1);
}
return root + dir;
},
basename: (path) => path && path.match(/([^\/]+|\/)\/*$/)[1],
join: (...paths) => PATH.normalize(paths.join("/")),
join2: (l, r) => PATH.normalize(l + "/" + r),
};
var initRandomFill = () => (view) => crypto.getRandomValues(view);
var randomFill = (view) => {
(randomFill = initRandomFill())(view);
};
var PATH_FS = {
resolve: (...args) => {
var resolvedPath = "",
resolvedAbsolute = false;
for (var i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
var path = i >= 0 ? args[i] : FS.cwd();
if (typeof path != "string") {
throw new TypeError("Arguments to path.resolve must be strings");
} else if (!path) {
return "";
}
resolvedPath = path + "/" + resolvedPath;
resolvedAbsolute = PATH.isAbs(path);
}
resolvedPath = PATH.normalizeArray(
resolvedPath.split("/").filter((p) => !!p),
!resolvedAbsolute,
).join("/");
return (resolvedAbsolute ? "/" : "") + resolvedPath || ".";
},
relative: (from, to) => {
from = PATH_FS.resolve(from).slice(1);
to = PATH_FS.resolve(to).slice(1);
function trim(arr) {
var start = 0;
for (; start < arr.length; start++) {
if (arr[start] !== "") break;
}
var end = arr.length - 1;
for (; end >= 0; end--) {
if (arr[end] !== "") break;
}
if (start > end) return [];
return arr.slice(start, end - start + 1);
}
var fromParts = trim(from.split("/"));
var toParts = trim(to.split("/"));
var length = Math.min(fromParts.length, toParts.length);
var samePartsLength = length;
for (var i = 0; i < length; i++) {
if (fromParts[i] !== toParts[i]) {
samePartsLength = i;
break;
}
}
var outputParts = [];
for (var i = samePartsLength; i < fromParts.length; i++) {
outputParts.push("..");
}
outputParts = outputParts.concat(toParts.slice(samePartsLength));
return outputParts.join("/");
},
};
var FS_stdin_getChar_buffer = [];
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 stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
if (!(maxBytesToWrite > 0)) return 0;
var startIdx = outIdx;
var endIdx = outIdx + maxBytesToWrite - 1;
for (var i = 0; i < str.length; ++i) {
var u = str.charCodeAt(i);
if (u >= 55296 && u <= 57343) {
var u1 = str.charCodeAt(++i);
u = (65536 + ((u & 1023) << 10)) | (u1 & 1023);
}
if (u <= 127) {
if (outIdx >= endIdx) break;
heap[outIdx++] = u;
} else if (u <= 2047) {
if (outIdx + 1 >= endIdx) break;
heap[outIdx++] = 192 | (u >> 6);
heap[outIdx++] = 128 | (u & 63);
} else if (u <= 65535) {
if (outIdx + 2 >= endIdx) break;
heap[outIdx++] = 224 | (u >> 12);
heap[outIdx++] = 128 | ((u >> 6) & 63);
heap[outIdx++] = 128 | (u & 63);
} else {
if (outIdx + 3 >= endIdx) break;
heap[outIdx++] = 240 | (u >> 18);
heap[outIdx++] = 128 | ((u >> 12) & 63);
heap[outIdx++] = 128 | ((u >> 6) & 63);
heap[outIdx++] = 128 | (u & 63);
}
}
heap[outIdx] = 0;
return outIdx - startIdx;
};
var intArrayFromString = (stringy, dontAddNull, length) => {
var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1;
var u8array = new Array(len);
var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
if (dontAddNull) u8array.length = numBytesWritten;
return u8array;
};
var FS_stdin_getChar = () => {
if (!FS_stdin_getChar_buffer.length) {
var result = null;
if (typeof window != "undefined" && typeof window.prompt == "function") {
result = window.prompt("Input: ");
if (result !== null) {
result += "\n";
}
} else {
}
if (!result) {
return null;
}
FS_stdin_getChar_buffer = intArrayFromString(result, true);
}
return FS_stdin_getChar_buffer.shift();
};
var TTY = {
ttys: [],
init() {},
shutdown() {},
register(dev, ops) {
TTY.ttys[dev] = { input: [], output: [], ops };
FS.registerDevice(dev, TTY.stream_ops);
},
stream_ops: {
open(stream) {
var tty = TTY.ttys[stream.node.rdev];
if (!tty) {
throw new FS.ErrnoError(43);
}
stream.tty = tty;
stream.seekable = false;
},
close(stream) {
stream.tty.ops.fsync(stream.tty);
},
fsync(stream) {
stream.tty.ops.fsync(stream.tty);
},
read(stream, buffer, offset, length, pos) {
if (!stream.tty || !stream.tty.ops.get_char) {
throw new FS.ErrnoError(60);
}
var bytesRead = 0;
for (var i = 0; i < length; i++) {
var result;
try {
result = stream.tty.ops.get_char(stream.tty);
} catch (e) {
throw new FS.ErrnoError(29);
}
if (result === undefined && bytesRead === 0) {
throw new FS.ErrnoError(6);
}
if (result === null || result === undefined) break;
bytesRead++;
buffer[offset + i] = result;
}
if (bytesRead) {
stream.node.atime = Date.now();
}
return bytesRead;
},
write(stream, buffer, offset, length, pos) {
if (!stream.tty || !stream.tty.ops.put_char) {
throw new FS.ErrnoError(60);
}
try {
for (var i = 0; i < length; i++) {
stream.tty.ops.put_char(stream.tty, buffer[offset + i]);
}
} catch (e) {
throw new FS.ErrnoError(29);
}
if (length) {
stream.node.mtime = stream.node.ctime = Date.now();
}
return i;
},
},
default_tty_ops: {
get_char(tty) {
return FS_stdin_getChar();
},
put_char(tty, val) {
if (val === null || val === 10) {
out(UTF8ArrayToString(tty.output));
tty.output = [];
} else {
if (val != 0) tty.output.push(val);
}
},
fsync(tty) {
if (tty.output?.length > 0) {
out(UTF8ArrayToString(tty.output));
tty.output = [];
}
},
ioctl_tcgets(tty) {
return {
c_iflag: 25856,
c_oflag: 5,
c_cflag: 191,
c_lflag: 35387,
c_cc: [
3, 28, 127, 21, 4, 0, 1, 0, 17, 19, 26, 0, 18, 15, 23, 22, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
};
},
ioctl_tcsets(tty, optional_actions, data) {
return 0;
},
ioctl_tiocgwinsz(tty) {
return [24, 80];
},
},
default_tty1_ops: {
put_char(tty, val) {
if (val === null || val === 10) {
err(UTF8ArrayToString(tty.output));
tty.output = [];
} else {
if (val != 0) tty.output.push(val);
}
},
fsync(tty) {
if (tty.output?.length > 0) {
err(UTF8ArrayToString(tty.output));
tty.output = [];
}
},
},
};
var mmapAlloc = (size) => {
abort();
};
var MEMFS = {
ops_table: null,
mount(mount) {
return MEMFS.createNode(null, "/", 16895, 0);
},
createNode(parent, name, mode, dev) {
if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
throw new FS.ErrnoError(63);
}
MEMFS.ops_table ||= {
dir: {
node: {
getattr: MEMFS.node_ops.getattr,
setattr: MEMFS.node_ops.setattr,
lookup: MEMFS.node_ops.lookup,
mknod: MEMFS.node_ops.mknod,
rename: MEMFS.node_ops.rename,
unlink: MEMFS.node_ops.unlink,
rmdir: MEMFS.node_ops.rmdir,
readdir: MEMFS.node_ops.readdir,
symlink: MEMFS.node_ops.symlink,
},
stream: { llseek: MEMFS.stream_ops.llseek },
},
file: {
node: { getattr: MEMFS.node_ops.getattr, setattr: MEMFS.node_ops.setattr },
stream: {
llseek: MEMFS.stream_ops.llseek,
read: MEMFS.stream_ops.read,
write: MEMFS.stream_ops.write,
allocate: MEMFS.stream_ops.allocate,
mmap: MEMFS.stream_ops.mmap,
msync: MEMFS.stream_ops.msync,
},
},
link: {
node: {
getattr: MEMFS.node_ops.getattr,
setattr: MEMFS.node_ops.setattr,
readlink: MEMFS.node_ops.readlink,
},
stream: {},
},
chrdev: {
node: { getattr: MEMFS.node_ops.getattr, setattr: MEMFS.node_ops.setattr },
stream: FS.chrdev_stream_ops,
},
};
var node = FS.createNode(parent, name, mode, dev);
if (FS.isDir(node.mode)) {
node.node_ops = MEMFS.ops_table.dir.node;
node.stream_ops = MEMFS.ops_table.dir.stream;
node.contents = {};
} else if (FS.isFile(node.mode)) {
node.node_ops = MEMFS.ops_table.file.node;
node.stream_ops = MEMFS.ops_table.file.stream;
node.usedBytes = 0;
node.contents = null;
} else if (FS.isLink(node.mode)) {
node.node_ops = MEMFS.ops_table.link.node;
node.stream_ops = MEMFS.ops_table.link.stream;
} else if (FS.isChrdev(node.mode)) {
node.node_ops = MEMFS.ops_table.chrdev.node;
node.stream_ops = MEMFS.ops_table.chrdev.stream;
}
node.atime = node.mtime = node.ctime = Date.now();
if (parent) {
parent.contents[name] = node;
parent.atime = parent.mtime = parent.ctime = node.atime;
}
return node;
},
getFileDataAsTypedArray(node) {
if (!node.contents) return new Uint8Array(0);
if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes);
return new Uint8Array(node.contents);
},
expandFileStorage(node, newCapacity) {
var prevCapacity = node.contents ? node.contents.length : 0;
if (prevCapacity >= newCapacity) return;
var CAPACITY_DOUBLING_MAX = 1024 * 1024;
newCapacity = Math.max(
newCapacity,
(prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125)) >>> 0,
);
if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256);
var oldContents = node.contents;
node.contents = new Uint8Array(newCapacity);
if (node.usedBytes > 0)
node.contents.set(oldContents.subarray(0, node.usedBytes), 0);
},
resizeFileStorage(node, newSize) {
if (node.usedBytes == newSize) return;
if (newSize == 0) {
node.contents = null;
node.usedBytes = 0;
} else {
var oldContents = node.contents;
node.contents = new Uint8Array(newSize);
if (oldContents) {
node.contents.set(
oldContents.subarray(0, Math.min(newSize, node.usedBytes)),
);
}
node.usedBytes = newSize;
}
},
node_ops: {
getattr(node) {
var attr = {};
attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
attr.ino = node.id;
attr.mode = node.mode;
attr.nlink = 1;
attr.uid = 0;
attr.gid = 0;
attr.rdev = node.rdev;
if (FS.isDir(node.mode)) {
attr.size = 4096;
} else if (FS.isFile(node.mode)) {
attr.size = node.usedBytes;
} else if (FS.isLink(node.mode)) {
attr.size = node.link.length;
} else {
attr.size = 0;
}
attr.atime = new Date(node.atime);
attr.mtime = new Date(node.mtime);
attr.ctime = new Date(node.ctime);
attr.blksize = 4096;
attr.blocks = Math.ceil(attr.size / attr.blksize);
return attr;
},
setattr(node, attr) {
for (const key of ["mode", "atime", "mtime", "ctime"]) {
if (attr[key] != null) {
node[key] = attr[key];
}
}
if (attr.size !== undefined) {
MEMFS.resizeFileStorage(node, attr.size);
}
},
lookup(parent, name) {
throw MEMFS.doesNotExistError;
},
mknod(parent, name, mode, dev) {
return MEMFS.createNode(parent, name, mode, dev);
},
rename(old_node, new_dir, new_name) {
var new_node;
try {
new_node = FS.lookupNode(new_dir, new_name);
} catch (e) {}
if (new_node) {
if (FS.isDir(old_node.mode)) {
for (var i in new_node.contents) {
throw new FS.ErrnoError(55);
}
}
FS.hashRemoveNode(new_node);
}
delete old_node.parent.contents[old_node.name];
new_dir.contents[new_name] = old_node;
old_node.name = new_name;
new_dir.ctime =
new_dir.mtime =
old_node.parent.ctime =
old_node.parent.mtime =
Date.now();
},
unlink(parent, name) {
delete parent.contents[name];
parent.ctime = parent.mtime = Date.now();
},
rmdir(parent, name) {
var node = FS.lookupNode(parent, name);
for (var i in node.contents) {
throw new FS.ErrnoError(55);
}
delete parent.contents[name];
parent.ctime = parent.mtime = Date.now();
},
readdir(node) {
return [".", "..", ...Object.keys(node.contents)];
},
symlink(parent, newname, oldpath) {
var node = MEMFS.createNode(parent, newname, 511 | 40960, 0);
node.link = oldpath;
return node;
},
readlink(node) {
if (!FS.isLink(node.mode)) {
throw new FS.ErrnoError(28);
}
return node.link;
},
},
stream_ops: {
read(stream, buffer, offset, length, position) {
var contents = stream.node.contents;
if (position >= stream.node.usedBytes) return 0;
var size = Math.min(stream.node.usedBytes - position, length);
if (size > 8 && contents.subarray) {
buffer.set(contents.subarray(position, position + size), offset);
} else {
for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
}
return size;
},
write(stream, buffer, offset, length, position, canOwn) {
if (!length) return 0;
var node = stream.node;
node.mtime = node.ctime = Date.now();
if (buffer.subarray && (!node.contents || node.contents.subarray)) {
if (canOwn) {
node.contents = buffer.subarray(offset, offset + length);
node.usedBytes = length;
return length;
} else if (node.usedBytes === 0 && position === 0) {
node.contents = buffer.slice(offset, offset + length);
node.usedBytes = length;
return length;
} else if (position + length <= node.usedBytes) {
node.contents.set(buffer.subarray(offset, offset + length), position);
return length;
}
}
MEMFS.expandFileStorage(node, position + length);
if (node.contents.subarray && buffer.subarray) {
node.contents.set(buffer.subarray(offset, offset + length), position);
} else {
for (var i = 0; i < length; i++) {
node.contents[position + i] = buffer[offset + i];
}
}
node.usedBytes = Math.max(node.usedBytes, position + length);
return length;
},
llseek(stream, offset, whence) {
var position = offset;
if (whence === 1) {
position += stream.position;
} else if (whence === 2) {
if (FS.isFile(stream.node.mode)) {
position += stream.node.usedBytes;
}
}
if (position < 0) {
throw new FS.ErrnoError(28);
}
return position;
},
allocate(stream, offset, length) {
MEMFS.expandFileStorage(stream.node, offset + length);
stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length);
},
mmap(stream, length, position, prot, flags) {
if (!FS.isFile(stream.node.mode)) {
throw new FS.ErrnoError(43);
}
var ptr;
var allocated;
var contents = stream.node.contents;
if (!(flags & 2) && contents && contents.buffer === HEAP8.buffer) {
allocated = false;
ptr = contents.byteOffset;
} else {
allocated = true;
ptr = mmapAlloc(length);
if (!ptr) {
throw new FS.ErrnoError(48);
}
if (contents) {
if (position > 0 || position + length < contents.length) {
if (contents.subarray) {
contents = contents.subarray(position, position + length);
} else {
contents = Array.prototype.slice.call(
contents,
position,
position + length,
);
}
}
HEAP8.set(contents, ptr);
}
}
return { ptr, allocated };
},
msync(stream, buffer, offset, length, mmapFlags) {
MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
return 0;
},
},
};
var asyncLoad = async (url) => {
var arrayBuffer = await readAsync(url);
return new Uint8Array(arrayBuffer);
};
var FS_createDataFile = (parent, name, fileData, canRead, canWrite, canOwn) => {
FS.createDataFile(parent, name, fileData, canRead, canWrite, canOwn);
};
var preloadPlugins = Module["preloadPlugins"] || [];
var FS_handledByPreloadPlugin = (byteArray, fullname, finish, onerror) => {
if (typeof Browser != "undefined") Browser.init();
var handled = false;
preloadPlugins.forEach((plugin) => {
if (handled) return;
if (plugin["canHandle"](fullname)) {
plugin["handle"](byteArray, fullname, finish, onerror);
handled = true;
}
});
return handled;
};
var FS_createPreloadedFile = (
parent,
name,
url,
canRead,
canWrite,
onload,
onerror,
dontCreateFile,
canOwn,
preFinish,
) => {
var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
var dep = getUniqueRunDependency(`cp ${fullname}`);
function processData(byteArray) {
function finish(byteArray) {
preFinish?.();
if (!dontCreateFile) {
FS_createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
}
onload?.();
removeRunDependency(dep);
}
if (
FS_handledByPreloadPlugin(byteArray, fullname, finish, () => {
onerror?.();
removeRunDependency(dep);
})
) {
return;
}
finish(byteArray);
}
addRunDependency(dep);
if (typeof url == "string") {
asyncLoad(url).then(processData, onerror);
} else {
processData(url);
}
};
var FS_modeStringToFlags = (str) => {
var flagModes = {
r: 0,
"r+": 2,
w: 512 | 64 | 1,
"w+": 512 | 64 | 2,
a: 1024 | 64 | 1,
"a+": 1024 | 64 | 2,
};
var flags = flagModes[str];
if (typeof flags == "undefined") {
throw new Error(`Unknown file open mode: ${str}`);
}
return flags;
};
var FS_getMode = (canRead, canWrite) => {
var mode = 0;
if (canRead) mode |= 292 | 73;
if (canWrite) mode |= 146;
return mode;
};
var FS = {
root: null,
mounts: [],
devices: {},
streams: [],
nextInode: 1,
nameTable: null,
currentPath: "/",
initialized: false,
ignorePermissions: true,
filesystems: null,
syncFSRequests: 0,
readFiles: {},
ErrnoError: class {
name = "ErrnoError";
constructor(errno) {
this.errno = errno;
}
},
FSStream: class {
shared = {};
get object() {
return this.node;
}
set object(val) {
this.node = val;
}
get isRead() {
return (this.flags & 2097155) !== 1;
}
get isWrite() {
return (this.flags & 2097155) !== 0;
}
get isAppend() {
return this.flags & 1024;
}
get flags() {
return this.shared.flags;
}
set flags(val) {
this.shared.flags = val;
}
get position() {
return this.shared.position;
}
set position(val) {
this.shared.position = val;
}
},
FSNode: class {
node_ops = {};
stream_ops = {};
readMode = 292 | 73;
writeMode = 146;
mounted = null;
constructor(parent, name, mode, rdev) {
if (!parent) {
parent = this;
}
this.parent = parent;
this.mount = parent.mount;
this.id = FS.nextInode++;
this.name = name;
this.mode = mode;
this.rdev = rdev;
this.atime = this.mtime = this.ctime = Date.now();
}
get read() {
return (this.mode & this.readMode) === this.readMode;
}
set read(val) {
val ? (this.mode |= this.readMode) : (this.mode &= ~this.readMode);
}
get write() {
return (this.mode & this.writeMode) === this.writeMode;
}
set write(val) {
val ? (this.mode |= this.writeMode) : (this.mode &= ~this.writeMode);
}
get isFolder() {
return FS.isDir(this.mode);
}
get isDevice() {
return FS.isChrdev(this.mode);
}
},
lookupPath(path, opts = {}) {
if (!path) {
throw new FS.ErrnoError(44);
}
opts.follow_mount ??= true;
if (!PATH.isAbs(path)) {
path = FS.cwd() + "/" + path;
}
linkloop: for (var nlinks = 0; nlinks < 40; nlinks++) {
var parts = path.split("/").filter((p) => !!p);
var current = FS.root;
var current_path = "/";
for (var i = 0; i < parts.length; i++) {
var islast = i === parts.length - 1;
if (islast && opts.parent) {
break;
}
if (parts[i] === ".") {
continue;
}
if (parts[i] === "..") {
current_path = PATH.dirname(current_path);
current = current.parent;
continue;
}
current_path = PATH.join2(current_path, parts[i]);
try {
current = FS.lookupNode(current, parts[i]);
} catch (e) {
if (e?.errno === 44 && islast && opts.noent_okay) {
return { path: current_path };
}
throw e;
}
if (FS.isMountpoint(current) && (!islast || opts.follow_mount)) {
current = current.mounted.root;
}
if (FS.isLink(current.mode) && (!islast || opts.follow)) {
if (!current.node_ops.readlink) {
throw new FS.ErrnoError(52);
}
var link = current.node_ops.readlink(current);
if (!PATH.isAbs(link)) {
link = PATH.dirname(current_path) + "/" + link;
}
path = link + "/" + parts.slice(i + 1).join("/");
continue linkloop;
}
}
return { path: current_path, node: current };
}
throw new FS.ErrnoError(32);
},
getPath(node) {
var path;
while (true) {
if (FS.isRoot(node)) {
var mount = node.mount.mountpoint;
if (!path) return mount;
return mount[mount.length - 1] !== "/" ? `${mount}/${path}` : mount + path;
}
path = path ? `${node.name}/${path}` : node.name;
node = node.parent;
}
},
hashName(parentid, name) {
var hash = 0;
for (var i = 0; i < name.length; i++) {
hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
}
return ((parentid + hash) >>> 0) % FS.nameTable.length;
},
hashAddNode(node) {
var hash = FS.hashName(node.parent.id, node.name);
node.name_next = FS.nameTable[hash];
FS.nameTable[hash] = node;
},
hashRemoveNode(node) {
var hash = FS.hashName(node.parent.id, node.name);
if (FS.nameTable[hash] === node) {
FS.nameTable[hash] = node.name_next;
} else {
var current = FS.nameTable[hash];
while (current) {
if (current.name_next === node) {
current.name_next = node.name_next;
break;
}
current = current.name_next;
}
}
},
lookupNode(parent, name) {
var errCode = FS.