@zh-keyboard/pinyin 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,3580 @@
1
+ //#region data/rime-api.js
2
+ async function createRimeModule(moduleArg = {}) {
3
+ let moduleRtn;
4
+ const Module = moduleArg;
5
+ const ENVIRONMENT_IS_WEB = !!globalThis.window;
6
+ const ENVIRONMENT_IS_WORKER = !!globalThis.WorkerGlobalScope;
7
+ const ENVIRONMENT_IS_NODE = globalThis.process?.versions?.node && globalThis.process?.type != "renderer";
8
+ if (ENVIRONMENT_IS_NODE) {
9
+ const { createRequire } = await import("node:module");
10
+ var require = createRequire(import.meta.url);
11
+ }
12
+ if (!Module.expectedDataFileDownloads) Module.expectedDataFileDownloads = 0;
13
+ Module.expectedDataFileDownloads++;
14
+ (() => {
15
+ const isPthread = typeof ENVIRONMENT_IS_PTHREAD != "undefined" && ENVIRONMENT_IS_PTHREAD;
16
+ const isWasmWorker = typeof ENVIRONMENT_IS_WASM_WORKER != "undefined" && ENVIRONMENT_IS_WASM_WORKER;
17
+ if (isPthread || isWasmWorker) return;
18
+ const isNode = globalThis.process && globalThis.process.versions && globalThis.process.versions.node && globalThis.process.type != "renderer";
19
+ async function loadPackage(metadata) {
20
+ let PACKAGE_PATH = "";
21
+ if (typeof window === "object") PACKAGE_PATH = window.encodeURIComponent(`${window.location.pathname.substring(0, window.location.pathname.lastIndexOf("/"))}/`);
22
+ else if (typeof process === "undefined" && typeof location !== "undefined") PACKAGE_PATH = encodeURIComponent(`${location.pathname.substring(0, location.pathname.lastIndexOf("/"))}/`);
23
+ const PACKAGE_NAME = "/home/zzx/work/librime/wasm/dist/rime-api.data";
24
+ const REMOTE_PACKAGE_BASE = "rime-api.data";
25
+ const REMOTE_PACKAGE_NAME = Module.locateFile ? Module.locateFile(REMOTE_PACKAGE_BASE, "") : REMOTE_PACKAGE_BASE;
26
+ const REMOTE_PACKAGE_SIZE = metadata.remote_package_size;
27
+ async function fetchRemotePackage(packageName, packageSize) {
28
+ if (isNode) {
29
+ const contents = require("node:fs").readFileSync(packageName);
30
+ return new Uint8Array(contents).buffer;
31
+ }
32
+ if (!Module.dataFileDownloads) Module.dataFileDownloads = {};
33
+ try {
34
+ var response = await fetch(packageName);
35
+ } catch (e) {
36
+ throw new Error(`Network Error: ${packageName}`, { e });
37
+ }
38
+ if (!response.ok) throw new Error(`${response.status}: ${response.url}`);
39
+ const chunks = [];
40
+ const headers = response.headers;
41
+ const total = Number(headers.get("Content-Length") || packageSize);
42
+ let loaded = 0;
43
+ Module.setStatus && Module.setStatus("Downloading data...");
44
+ const reader = response.body.getReader();
45
+ while (1) {
46
+ const { done, value } = await reader.read();
47
+ if (done) break;
48
+ chunks.push(value);
49
+ loaded += value.length;
50
+ Module.dataFileDownloads[packageName] = {
51
+ loaded,
52
+ total
53
+ };
54
+ let totalLoaded = 0;
55
+ let totalSize = 0;
56
+ for (const download of Object.values(Module.dataFileDownloads)) {
57
+ totalLoaded += download.loaded;
58
+ totalSize += download.total;
59
+ }
60
+ Module.setStatus && Module.setStatus(`Downloading data... (${totalLoaded}/${totalSize})`);
61
+ }
62
+ const packageData = new Uint8Array(chunks.map((c) => c.length).reduce((a, b) => a + b, 0));
63
+ let offset = 0;
64
+ for (const chunk of chunks) {
65
+ packageData.set(chunk, offset);
66
+ offset += chunk.length;
67
+ }
68
+ return packageData.buffer;
69
+ }
70
+ let fetchPromise;
71
+ let fetched = Module.getPreloadedPackage && Module.getPreloadedPackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE);
72
+ if (!fetched) fetchPromise = fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE);
73
+ async function runWithFS(Module$1) {
74
+ function assert(check, msg) {
75
+ if (!check) throw new Error(msg);
76
+ }
77
+ Module$1.FS_createPath("/", "rime", true, true);
78
+ Module$1.FS_createPath("/rime", "opencc", true, true);
79
+ for (const file of metadata.files) {
80
+ const name = file.filename;
81
+ Module$1.addRunDependency(`fp ${name}`);
82
+ }
83
+ async function processPackageData(arrayBuffer) {
84
+ assert(arrayBuffer, "Loading data file failed.");
85
+ assert(arrayBuffer.constructor.name === ArrayBuffer.name, `bad input to processPackageData ${arrayBuffer.constructor.name}`);
86
+ const byteArray = new Uint8Array(arrayBuffer);
87
+ for (const file of metadata.files) {
88
+ const name = file.filename;
89
+ const data = byteArray.subarray(file.start, file.end);
90
+ Module$1.FS_createDataFile(name, null, data, true, true, true);
91
+ Module$1.removeRunDependency(`fp ${name}`);
92
+ }
93
+ Module$1.removeRunDependency("datafile_/home/zzx/work/librime/wasm/dist/rime-api.data");
94
+ }
95
+ Module$1.addRunDependency("datafile_/home/zzx/work/librime/wasm/dist/rime-api.data");
96
+ if (!Module$1.preloadResults) Module$1.preloadResults = {};
97
+ Module$1.preloadResults[PACKAGE_NAME] = { fromCache: false };
98
+ if (!fetched) fetched = await fetchPromise;
99
+ processPackageData(fetched);
100
+ }
101
+ if (Module.calledRun) runWithFS(Module);
102
+ else {
103
+ if (!Module.preRun) Module.preRun = [];
104
+ Module.preRun.push(runWithFS);
105
+ }
106
+ }
107
+ loadPackage({
108
+ files: [
109
+ {
110
+ filename: "/rime/opencc/STCharacters.ocd2",
111
+ start: 0,
112
+ end: 45310
113
+ },
114
+ {
115
+ filename: "/rime/opencc/STPhrases.ocd2",
116
+ start: 45310,
117
+ end: 971027
118
+ },
119
+ {
120
+ filename: "/rime/opencc/TSCharacters.ocd2",
121
+ start: 971027,
122
+ end: 1017153
123
+ },
124
+ {
125
+ filename: "/rime/opencc/TSPhrases.ocd2",
126
+ start: 1017153,
127
+ end: 1026935
128
+ },
129
+ {
130
+ filename: "/rime/opencc/s2t.json",
131
+ start: 1026935,
132
+ end: 1027341
133
+ },
134
+ {
135
+ filename: "/rime/opencc/t2s.json",
136
+ start: 1027341,
137
+ end: 1027747
138
+ }
139
+ ],
140
+ remote_package_size: 1027747
141
+ });
142
+ })();
143
+ let arguments_ = [];
144
+ let thisProgram = "./this.program";
145
+ let quit_ = (status, toThrow) => {
146
+ throw toThrow;
147
+ };
148
+ const _scriptName = import.meta.url;
149
+ let scriptDirectory = "";
150
+ function locateFile(path) {
151
+ if (Module.locateFile) return Module.locateFile(path, scriptDirectory);
152
+ return scriptDirectory + path;
153
+ }
154
+ let readAsync, readBinary;
155
+ if (ENVIRONMENT_IS_NODE) {
156
+ var fs = require("node:fs");
157
+ if (_scriptName.startsWith("file:")) scriptDirectory = `${require("node:path").dirname(require("node:url").fileURLToPath(_scriptName))}/`;
158
+ readBinary = (filename) => {
159
+ filename = isFileURI(filename) ? new URL(filename) : filename;
160
+ const ret = fs.readFileSync(filename);
161
+ return ret;
162
+ };
163
+ readAsync = async (filename, binary = true) => {
164
+ filename = isFileURI(filename) ? new URL(filename) : filename;
165
+ const ret = fs.readFileSync(filename, binary ? void 0 : "utf8");
166
+ return ret;
167
+ };
168
+ if (process.argv.length > 1) thisProgram = process.argv[1].replace(/\\/g, "/");
169
+ arguments_ = process.argv.slice(2);
170
+ quit_ = (status, toThrow) => {
171
+ process.exitCode = status;
172
+ throw toThrow;
173
+ };
174
+ } else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
175
+ try {
176
+ scriptDirectory = new URL(".", _scriptName).href;
177
+ } catch {}
178
+ {
179
+ if (ENVIRONMENT_IS_WORKER) readBinary = (url) => {
180
+ const xhr = new XMLHttpRequest();
181
+ xhr.open("GET", url, false);
182
+ xhr.responseType = "arraybuffer";
183
+ xhr.send(null);
184
+ return new Uint8Array(xhr.response);
185
+ };
186
+ readAsync = async (url) => {
187
+ if (isFileURI(url)) return new Promise((resolve, reject) => {
188
+ const xhr = new XMLHttpRequest();
189
+ xhr.open("GET", url, true);
190
+ xhr.responseType = "arraybuffer";
191
+ xhr.onload = () => {
192
+ if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
193
+ resolve(xhr.response);
194
+ return;
195
+ }
196
+ reject(xhr.status);
197
+ };
198
+ xhr.onerror = reject;
199
+ xhr.send(null);
200
+ });
201
+ const response = await fetch(url, { credentials: "same-origin" });
202
+ if (response.ok) return response.arrayBuffer();
203
+ throw new Error(`${response.status} : ${response.url}`);
204
+ };
205
+ }
206
+ }
207
+ let out = console.log.bind(console);
208
+ let err = console.error.bind(console);
209
+ let wasmBinary;
210
+ let ABORT = false;
211
+ let EXITSTATUS;
212
+ var isFileURI = (filename) => filename.startsWith("file://");
213
+ let readyPromiseResolve, readyPromiseReject;
214
+ let HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
215
+ let HEAP64, HEAPU64;
216
+ let runtimeInitialized = false;
217
+ function updateMemoryViews() {
218
+ const b = wasmMemory.buffer;
219
+ HEAP8 = new Int8Array(b);
220
+ HEAP16 = new Int16Array(b);
221
+ HEAPU8 = new Uint8Array(b);
222
+ HEAPU16 = new Uint16Array(b);
223
+ HEAP32 = new Int32Array(b);
224
+ HEAPU32 = new Uint32Array(b);
225
+ HEAPF32 = new Float32Array(b);
226
+ HEAPF64 = new Float64Array(b);
227
+ HEAP64 = new BigInt64Array(b);
228
+ HEAPU64 = new BigUint64Array(b);
229
+ }
230
+ function preRun() {
231
+ if (Module.preRun) {
232
+ if (typeof Module.preRun == "function") Module.preRun = [Module.preRun];
233
+ while (Module.preRun.length) addOnPreRun(Module.preRun.shift());
234
+ }
235
+ callRuntimeCallbacks(onPreRuns);
236
+ }
237
+ function initRuntime() {
238
+ runtimeInitialized = true;
239
+ if (!Module.noFSInit && !FS.initialized) FS.init();
240
+ TTY.init();
241
+ wasmExports.Q();
242
+ FS.ignorePermissions = false;
243
+ }
244
+ function postRun() {
245
+ if (Module.postRun) {
246
+ if (typeof Module.postRun == "function") Module.postRun = [Module.postRun];
247
+ while (Module.postRun.length) addOnPostRun(Module.postRun.shift());
248
+ }
249
+ callRuntimeCallbacks(onPostRuns);
250
+ }
251
+ function abort(what) {
252
+ Module.onAbort?.(what);
253
+ what = `Aborted(${what})`;
254
+ err(what);
255
+ ABORT = true;
256
+ what += ". Build with -sASSERTIONS for more info.";
257
+ if (runtimeInitialized) ___trap();
258
+ const e = new WebAssembly.RuntimeError(what);
259
+ readyPromiseReject?.(e);
260
+ throw e;
261
+ }
262
+ let wasmBinaryFile;
263
+ function findWasmBinary() {
264
+ if (Module.locateFile) return locateFile("rime-api.wasm");
265
+ return new URL("rime-api.wasm", import.meta.url).href;
266
+ }
267
+ function getBinarySync(file) {
268
+ if (file == wasmBinaryFile && wasmBinary) return new Uint8Array(wasmBinary);
269
+ if (readBinary) return readBinary(file);
270
+ throw "both async and sync fetching of the wasm failed";
271
+ }
272
+ async function getWasmBinary(binaryFile) {
273
+ if (!wasmBinary) try {
274
+ const response = await readAsync(binaryFile);
275
+ return new Uint8Array(response);
276
+ } catch {}
277
+ return getBinarySync(binaryFile);
278
+ }
279
+ async function instantiateArrayBuffer(binaryFile, imports) {
280
+ try {
281
+ const binary = await getWasmBinary(binaryFile);
282
+ const instance = await WebAssembly.instantiate(binary, imports);
283
+ return instance;
284
+ } catch (reason) {
285
+ err(`failed to asynchronously prepare wasm: ${reason}`);
286
+ abort(reason);
287
+ }
288
+ }
289
+ async function instantiateAsync(binary, binaryFile, imports) {
290
+ if (!binary && !isFileURI(binaryFile) && !ENVIRONMENT_IS_NODE) try {
291
+ const response = fetch(binaryFile, { credentials: "same-origin" });
292
+ const instantiationResult = await WebAssembly.instantiateStreaming(response, imports);
293
+ return instantiationResult;
294
+ } catch (reason) {
295
+ err(`wasm streaming compile failed: ${reason}`);
296
+ err("falling back to ArrayBuffer instantiation");
297
+ }
298
+ return instantiateArrayBuffer(binaryFile, imports);
299
+ }
300
+ function getWasmImports() {
301
+ const imports = { a: wasmImports };
302
+ return imports;
303
+ }
304
+ async function createWasm() {
305
+ function receiveInstance(instance, module) {
306
+ wasmExports = instance.exports;
307
+ wasmExports = applySignatureConversions(wasmExports);
308
+ assignWasmExports(wasmExports);
309
+ updateMemoryViews();
310
+ return wasmExports;
311
+ }
312
+ function receiveInstantiationResult(result$1) {
313
+ return receiveInstance(result$1.instance);
314
+ }
315
+ const info = getWasmImports();
316
+ if (Module.instantiateWasm) return new Promise((resolve, reject) => {
317
+ Module.instantiateWasm(info, (inst, mod) => {
318
+ resolve(receiveInstance(inst, mod));
319
+ });
320
+ });
321
+ wasmBinaryFile ??= findWasmBinary();
322
+ const result = await instantiateAsync(wasmBinary, wasmBinaryFile, info);
323
+ const exports = receiveInstantiationResult(result);
324
+ return exports;
325
+ }
326
+ class ExitStatus {
327
+ name = "ExitStatus";
328
+ constructor(status) {
329
+ this.message = `Program terminated with exit(${status})`;
330
+ this.status = status;
331
+ }
332
+ }
333
+ var callRuntimeCallbacks = (callbacks) => {
334
+ while (callbacks.length > 0) callbacks.shift()(Module);
335
+ };
336
+ var onPostRuns = [];
337
+ var addOnPostRun = (cb) => onPostRuns.push(cb);
338
+ var onPreRuns = [];
339
+ var addOnPreRun = (cb) => onPreRuns.push(cb);
340
+ let noExitRuntime = true;
341
+ var PATH = {
342
+ isAbs: (path) => path.charAt(0) === "/",
343
+ splitPath: (filename) => {
344
+ const splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^/]+?)?(\.[^./]*|))\/*$/;
345
+ return splitPathRe.exec(filename).slice(1);
346
+ },
347
+ normalizeArray: (parts, allowAboveRoot) => {
348
+ let up = 0;
349
+ for (let i = parts.length - 1; i >= 0; i--) {
350
+ const last = parts[i];
351
+ if (last === ".") parts.splice(i, 1);
352
+ else if (last === "..") {
353
+ parts.splice(i, 1);
354
+ up++;
355
+ } else if (up) {
356
+ parts.splice(i, 1);
357
+ up--;
358
+ }
359
+ }
360
+ if (allowAboveRoot) for (; up; up--) parts.unshift("..");
361
+ return parts;
362
+ },
363
+ normalize: (path) => {
364
+ const isAbsolute = PATH.isAbs(path);
365
+ const trailingSlash = path.slice(-1) === "/";
366
+ path = PATH.normalizeArray(path.split("/").filter((p) => !!p), !isAbsolute).join("/");
367
+ if (!path && !isAbsolute) path = ".";
368
+ if (path && trailingSlash) path += "/";
369
+ return (isAbsolute ? "/" : "") + path;
370
+ },
371
+ dirname: (path) => {
372
+ const result = PATH.splitPath(path);
373
+ const root = result[0];
374
+ let dir = result[1];
375
+ if (!root && !dir) return ".";
376
+ if (dir) dir = dir.slice(0, -1);
377
+ return root + dir;
378
+ },
379
+ basename: (path) => path && path.match(/([^/]+|\/)\/*$/)[1],
380
+ join: (...paths) => PATH.normalize(paths.join("/")),
381
+ join2: (l, r) => PATH.normalize(`${l}/${r}`)
382
+ };
383
+ const initRandomFill = () => {
384
+ if (ENVIRONMENT_IS_NODE) {
385
+ const nodeCrypto = require("node:crypto");
386
+ return (view) => nodeCrypto.randomFillSync(view);
387
+ }
388
+ return (view) => crypto.getRandomValues(view);
389
+ };
390
+ let randomFill = (view) => {
391
+ (randomFill = initRandomFill())(view);
392
+ };
393
+ var PATH_FS = {
394
+ resolve: (...args) => {
395
+ let resolvedPath = "";
396
+ let resolvedAbsolute = false;
397
+ for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
398
+ const path = i >= 0 ? args[i] : FS.cwd();
399
+ if (typeof path != "string") throw new TypeError("Arguments to path.resolve must be strings");
400
+ else if (!path) return "";
401
+ resolvedPath = `${path}/${resolvedPath}`;
402
+ resolvedAbsolute = PATH.isAbs(path);
403
+ }
404
+ resolvedPath = PATH.normalizeArray(resolvedPath.split("/").filter((p) => !!p), !resolvedAbsolute).join("/");
405
+ return (resolvedAbsolute ? "/" : "") + resolvedPath || ".";
406
+ },
407
+ relative: (from, to) => {
408
+ from = PATH_FS.resolve(from).slice(1);
409
+ to = PATH_FS.resolve(to).slice(1);
410
+ function trim(arr) {
411
+ let start = 0;
412
+ for (; start < arr.length; start++) if (arr[start] !== "") break;
413
+ let end = arr.length - 1;
414
+ for (; end >= 0; end--) if (arr[end] !== "") break;
415
+ if (start > end) return [];
416
+ return arr.slice(start, end - start + 1);
417
+ }
418
+ const fromParts = trim(from.split("/"));
419
+ const toParts = trim(to.split("/"));
420
+ const length = Math.min(fromParts.length, toParts.length);
421
+ let samePartsLength = length;
422
+ for (var i = 0; i < length; i++) if (fromParts[i] !== toParts[i]) {
423
+ samePartsLength = i;
424
+ break;
425
+ }
426
+ let outputParts = [];
427
+ for (var i = samePartsLength; i < fromParts.length; i++) outputParts.push("..");
428
+ outputParts = outputParts.concat(toParts.slice(samePartsLength));
429
+ return outputParts.join("/");
430
+ }
431
+ };
432
+ const UTF8Decoder = new TextDecoder();
433
+ const findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
434
+ const maxIdx = idx + maxBytesToRead;
435
+ if (ignoreNul) return maxIdx;
436
+ while (heapOrArray[idx] && !(idx >= maxIdx)) ++idx;
437
+ return idx;
438
+ };
439
+ const UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead, ignoreNul) => {
440
+ idx >>>= 0;
441
+ const endPtr = findStringEnd(heapOrArray, idx, maxBytesToRead, ignoreNul);
442
+ return UTF8Decoder.decode(heapOrArray.buffer ? heapOrArray.subarray(idx, endPtr) : new Uint8Array(heapOrArray.slice(idx, endPtr)));
443
+ };
444
+ let FS_stdin_getChar_buffer = [];
445
+ const lengthBytesUTF8 = (str) => {
446
+ let len = 0;
447
+ for (let i = 0; i < str.length; ++i) {
448
+ const c = str.charCodeAt(i);
449
+ if (c <= 127) len++;
450
+ else if (c <= 2047) len += 2;
451
+ else if (c >= 55296 && c <= 57343) {
452
+ len += 4;
453
+ ++i;
454
+ } else len += 3;
455
+ }
456
+ return len;
457
+ };
458
+ const stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
459
+ outIdx >>>= 0;
460
+ if (!(maxBytesToWrite > 0)) return 0;
461
+ const startIdx = outIdx;
462
+ const endIdx = outIdx + maxBytesToWrite - 1;
463
+ for (let i = 0; i < str.length; ++i) {
464
+ const u = str.codePointAt(i);
465
+ if (u <= 127) {
466
+ if (outIdx >= endIdx) break;
467
+ heap[outIdx++ >>> 0] = u;
468
+ } else if (u <= 2047) {
469
+ if (outIdx + 1 >= endIdx) break;
470
+ heap[outIdx++ >>> 0] = 192 | u >> 6;
471
+ heap[outIdx++ >>> 0] = 128 | u & 63;
472
+ } else if (u <= 65535) {
473
+ if (outIdx + 2 >= endIdx) break;
474
+ heap[outIdx++ >>> 0] = 224 | u >> 12;
475
+ heap[outIdx++ >>> 0] = 128 | u >> 6 & 63;
476
+ heap[outIdx++ >>> 0] = 128 | u & 63;
477
+ } else {
478
+ if (outIdx + 3 >= endIdx) break;
479
+ heap[outIdx++ >>> 0] = 240 | u >> 18;
480
+ heap[outIdx++ >>> 0] = 128 | u >> 12 & 63;
481
+ heap[outIdx++ >>> 0] = 128 | u >> 6 & 63;
482
+ heap[outIdx++ >>> 0] = 128 | u & 63;
483
+ i++;
484
+ }
485
+ }
486
+ heap[outIdx >>> 0] = 0;
487
+ return outIdx - startIdx;
488
+ };
489
+ const intArrayFromString = (stringy, dontAddNull, length) => {
490
+ const len = length > 0 ? length : lengthBytesUTF8(stringy) + 1;
491
+ const u8array = new Array(len);
492
+ const numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
493
+ if (dontAddNull) u8array.length = numBytesWritten;
494
+ return u8array;
495
+ };
496
+ const FS_stdin_getChar = () => {
497
+ if (!FS_stdin_getChar_buffer.length) {
498
+ let result = null;
499
+ if (ENVIRONMENT_IS_NODE) {
500
+ const BUFSIZE = 256;
501
+ const buf = Buffer.alloc(BUFSIZE);
502
+ let bytesRead = 0;
503
+ const fd = process.stdin.fd;
504
+ try {
505
+ bytesRead = fs.readSync(fd, buf, 0, BUFSIZE);
506
+ } catch (e) {
507
+ if (e.toString().includes("EOF")) bytesRead = 0;
508
+ else throw e;
509
+ }
510
+ if (bytesRead > 0) result = buf.slice(0, bytesRead).toString("utf-8");
511
+ } else if (globalThis.window?.prompt) {
512
+ result = window.prompt("Input: ");
513
+ if (result !== null) result += "\n";
514
+ }
515
+ if (!result) return null;
516
+ FS_stdin_getChar_buffer = intArrayFromString(result, true);
517
+ }
518
+ return FS_stdin_getChar_buffer.shift();
519
+ };
520
+ var TTY = {
521
+ ttys: [],
522
+ init() {},
523
+ shutdown() {},
524
+ register(dev, ops) {
525
+ TTY.ttys[dev] = {
526
+ input: [],
527
+ output: [],
528
+ ops
529
+ };
530
+ FS.registerDevice(dev, TTY.stream_ops);
531
+ },
532
+ stream_ops: {
533
+ open(stream) {
534
+ const tty = TTY.ttys[stream.node.rdev];
535
+ if (!tty) throw new FS.ErrnoError(43);
536
+ stream.tty = tty;
537
+ stream.seekable = false;
538
+ },
539
+ close(stream) {
540
+ stream.tty.ops.fsync(stream.tty);
541
+ },
542
+ fsync(stream) {
543
+ stream.tty.ops.fsync(stream.tty);
544
+ },
545
+ read(stream, buffer, offset, length, pos) {
546
+ if (!stream.tty || !stream.tty.ops.get_char) throw new FS.ErrnoError(60);
547
+ let bytesRead = 0;
548
+ for (let i = 0; i < length; i++) {
549
+ var result;
550
+ try {
551
+ result = stream.tty.ops.get_char(stream.tty);
552
+ } catch (e) {
553
+ throw new FS.ErrnoError(29);
554
+ }
555
+ if (result === void 0 && bytesRead === 0) throw new FS.ErrnoError(6);
556
+ if (result === null || result === void 0) break;
557
+ bytesRead++;
558
+ buffer[offset + i] = result;
559
+ }
560
+ if (bytesRead) stream.node.atime = Date.now();
561
+ return bytesRead;
562
+ },
563
+ write(stream, buffer, offset, length, pos) {
564
+ if (!stream.tty || !stream.tty.ops.put_char) throw new FS.ErrnoError(60);
565
+ try {
566
+ for (var i = 0; i < length; i++) stream.tty.ops.put_char(stream.tty, buffer[offset + i]);
567
+ } catch (e) {
568
+ throw new FS.ErrnoError(29);
569
+ }
570
+ if (length) stream.node.mtime = stream.node.ctime = Date.now();
571
+ return i;
572
+ }
573
+ },
574
+ default_tty_ops: {
575
+ get_char(tty) {
576
+ return FS_stdin_getChar();
577
+ },
578
+ put_char(tty, val) {
579
+ if (val === null || val === 10) {
580
+ out(UTF8ArrayToString(tty.output));
581
+ tty.output = [];
582
+ } else if (val != 0) tty.output.push(val);
583
+ },
584
+ fsync(tty) {
585
+ if (tty.output?.length > 0) {
586
+ out(UTF8ArrayToString(tty.output));
587
+ tty.output = [];
588
+ }
589
+ },
590
+ ioctl_tcgets(tty) {
591
+ return {
592
+ c_iflag: 25856,
593
+ c_oflag: 5,
594
+ c_cflag: 191,
595
+ c_lflag: 35387,
596
+ c_cc: [
597
+ 3,
598
+ 28,
599
+ 127,
600
+ 21,
601
+ 4,
602
+ 0,
603
+ 1,
604
+ 0,
605
+ 17,
606
+ 19,
607
+ 26,
608
+ 0,
609
+ 18,
610
+ 15,
611
+ 23,
612
+ 22,
613
+ 0,
614
+ 0,
615
+ 0,
616
+ 0,
617
+ 0,
618
+ 0,
619
+ 0,
620
+ 0,
621
+ 0,
622
+ 0,
623
+ 0,
624
+ 0,
625
+ 0,
626
+ 0,
627
+ 0,
628
+ 0
629
+ ]
630
+ };
631
+ },
632
+ ioctl_tcsets(tty, optional_actions, data) {
633
+ return 0;
634
+ },
635
+ ioctl_tiocgwinsz(tty) {
636
+ return [24, 80];
637
+ }
638
+ },
639
+ default_tty1_ops: {
640
+ put_char(tty, val) {
641
+ if (val === null || val === 10) {
642
+ err(UTF8ArrayToString(tty.output));
643
+ tty.output = [];
644
+ } else if (val != 0) tty.output.push(val);
645
+ },
646
+ fsync(tty) {
647
+ if (tty.output?.length > 0) {
648
+ err(UTF8ArrayToString(tty.output));
649
+ tty.output = [];
650
+ }
651
+ }
652
+ }
653
+ };
654
+ const zeroMemory = (ptr, size) => HEAPU8.fill(0, ptr, ptr + size);
655
+ const alignMemory = (size, alignment) => Math.ceil(size / alignment) * alignment;
656
+ const mmapAlloc = (size) => {
657
+ size = alignMemory(size, 65536);
658
+ const ptr = _emscripten_builtin_memalign(65536, size);
659
+ if (ptr) zeroMemory(ptr, size);
660
+ return ptr;
661
+ };
662
+ var MEMFS = {
663
+ ops_table: null,
664
+ mount(mount) {
665
+ return MEMFS.createNode(null, "/", 16895, 0);
666
+ },
667
+ createNode(parent, name, mode, dev) {
668
+ if (FS.isBlkdev(mode) || FS.isFIFO(mode)) throw new FS.ErrnoError(63);
669
+ MEMFS.ops_table ||= {
670
+ dir: {
671
+ node: {
672
+ getattr: MEMFS.node_ops.getattr,
673
+ setattr: MEMFS.node_ops.setattr,
674
+ lookup: MEMFS.node_ops.lookup,
675
+ mknod: MEMFS.node_ops.mknod,
676
+ rename: MEMFS.node_ops.rename,
677
+ unlink: MEMFS.node_ops.unlink,
678
+ rmdir: MEMFS.node_ops.rmdir,
679
+ readdir: MEMFS.node_ops.readdir,
680
+ symlink: MEMFS.node_ops.symlink
681
+ },
682
+ stream: { llseek: MEMFS.stream_ops.llseek }
683
+ },
684
+ file: {
685
+ node: {
686
+ getattr: MEMFS.node_ops.getattr,
687
+ setattr: MEMFS.node_ops.setattr
688
+ },
689
+ stream: {
690
+ llseek: MEMFS.stream_ops.llseek,
691
+ read: MEMFS.stream_ops.read,
692
+ write: MEMFS.stream_ops.write,
693
+ mmap: MEMFS.stream_ops.mmap,
694
+ msync: MEMFS.stream_ops.msync
695
+ }
696
+ },
697
+ link: {
698
+ node: {
699
+ getattr: MEMFS.node_ops.getattr,
700
+ setattr: MEMFS.node_ops.setattr,
701
+ readlink: MEMFS.node_ops.readlink
702
+ },
703
+ stream: {}
704
+ },
705
+ chrdev: {
706
+ node: {
707
+ getattr: MEMFS.node_ops.getattr,
708
+ setattr: MEMFS.node_ops.setattr
709
+ },
710
+ stream: FS.chrdev_stream_ops
711
+ }
712
+ };
713
+ const node = FS.createNode(parent, name, mode, dev);
714
+ if (FS.isDir(node.mode)) {
715
+ node.node_ops = MEMFS.ops_table.dir.node;
716
+ node.stream_ops = MEMFS.ops_table.dir.stream;
717
+ node.contents = {};
718
+ } else if (FS.isFile(node.mode)) {
719
+ node.node_ops = MEMFS.ops_table.file.node;
720
+ node.stream_ops = MEMFS.ops_table.file.stream;
721
+ node.usedBytes = 0;
722
+ node.contents = null;
723
+ } else if (FS.isLink(node.mode)) {
724
+ node.node_ops = MEMFS.ops_table.link.node;
725
+ node.stream_ops = MEMFS.ops_table.link.stream;
726
+ } else if (FS.isChrdev(node.mode)) {
727
+ node.node_ops = MEMFS.ops_table.chrdev.node;
728
+ node.stream_ops = MEMFS.ops_table.chrdev.stream;
729
+ }
730
+ node.atime = node.mtime = node.ctime = Date.now();
731
+ if (parent) {
732
+ parent.contents[name] = node;
733
+ parent.atime = parent.mtime = parent.ctime = node.atime;
734
+ }
735
+ return node;
736
+ },
737
+ getFileDataAsTypedArray(node) {
738
+ if (!node.contents) return new Uint8Array(0);
739
+ if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes);
740
+ return new Uint8Array(node.contents);
741
+ },
742
+ expandFileStorage(node, newCapacity) {
743
+ const prevCapacity = node.contents ? node.contents.length : 0;
744
+ if (prevCapacity >= newCapacity) return;
745
+ const CAPACITY_DOUBLING_MAX = 1024 * 1024;
746
+ newCapacity = Math.max(newCapacity, prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125) >>> 0);
747
+ if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256);
748
+ const oldContents = node.contents;
749
+ node.contents = new Uint8Array(newCapacity);
750
+ if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0);
751
+ },
752
+ resizeFileStorage(node, newSize) {
753
+ if (node.usedBytes == newSize) return;
754
+ if (newSize == 0) {
755
+ node.contents = null;
756
+ node.usedBytes = 0;
757
+ } else {
758
+ const oldContents = node.contents;
759
+ node.contents = new Uint8Array(newSize);
760
+ if (oldContents) node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes)));
761
+ node.usedBytes = newSize;
762
+ }
763
+ },
764
+ node_ops: {
765
+ getattr(node) {
766
+ const attr = {};
767
+ attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
768
+ attr.ino = node.id;
769
+ attr.mode = node.mode;
770
+ attr.nlink = 1;
771
+ attr.uid = 0;
772
+ attr.gid = 0;
773
+ attr.rdev = node.rdev;
774
+ if (FS.isDir(node.mode)) attr.size = 4096;
775
+ else if (FS.isFile(node.mode)) attr.size = node.usedBytes;
776
+ else if (FS.isLink(node.mode)) attr.size = node.link.length;
777
+ else attr.size = 0;
778
+ attr.atime = new Date(node.atime);
779
+ attr.mtime = new Date(node.mtime);
780
+ attr.ctime = new Date(node.ctime);
781
+ attr.blksize = 4096;
782
+ attr.blocks = Math.ceil(attr.size / attr.blksize);
783
+ return attr;
784
+ },
785
+ setattr(node, attr) {
786
+ for (const key of [
787
+ "mode",
788
+ "atime",
789
+ "mtime",
790
+ "ctime"
791
+ ]) if (attr[key] != null) node[key] = attr[key];
792
+ if (attr.size !== void 0) MEMFS.resizeFileStorage(node, attr.size);
793
+ },
794
+ lookup(parent, name) {
795
+ if (!MEMFS.doesNotExistError) {
796
+ MEMFS.doesNotExistError = new FS.ErrnoError(44);
797
+ MEMFS.doesNotExistError.stack = "<generic error, no stack>";
798
+ }
799
+ throw MEMFS.doesNotExistError;
800
+ },
801
+ mknod(parent, name, mode, dev) {
802
+ return MEMFS.createNode(parent, name, mode, dev);
803
+ },
804
+ rename(old_node, new_dir, new_name) {
805
+ let new_node;
806
+ try {
807
+ new_node = FS.lookupNode(new_dir, new_name);
808
+ } catch (e) {}
809
+ if (new_node) {
810
+ if (FS.isDir(old_node.mode)) for (const i in new_node.contents) throw new FS.ErrnoError(55);
811
+ FS.hashRemoveNode(new_node);
812
+ }
813
+ delete old_node.parent.contents[old_node.name];
814
+ new_dir.contents[new_name] = old_node;
815
+ old_node.name = new_name;
816
+ new_dir.ctime = new_dir.mtime = old_node.parent.ctime = old_node.parent.mtime = Date.now();
817
+ },
818
+ unlink(parent, name) {
819
+ delete parent.contents[name];
820
+ parent.ctime = parent.mtime = Date.now();
821
+ },
822
+ rmdir(parent, name) {
823
+ const node = FS.lookupNode(parent, name);
824
+ for (const i in node.contents) throw new FS.ErrnoError(55);
825
+ delete parent.contents[name];
826
+ parent.ctime = parent.mtime = Date.now();
827
+ },
828
+ readdir(node) {
829
+ return [
830
+ ".",
831
+ "..",
832
+ ...Object.keys(node.contents)
833
+ ];
834
+ },
835
+ symlink(parent, newname, oldpath) {
836
+ const node = MEMFS.createNode(parent, newname, 41471, 0);
837
+ node.link = oldpath;
838
+ return node;
839
+ },
840
+ readlink(node) {
841
+ if (!FS.isLink(node.mode)) throw new FS.ErrnoError(28);
842
+ return node.link;
843
+ }
844
+ },
845
+ stream_ops: {
846
+ read(stream, buffer, offset, length, position) {
847
+ const contents = stream.node.contents;
848
+ if (position >= stream.node.usedBytes) return 0;
849
+ const size = Math.min(stream.node.usedBytes - position, length);
850
+ if (size > 8 && contents.subarray) buffer.set(contents.subarray(position, position + size), offset);
851
+ else for (let i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
852
+ return size;
853
+ },
854
+ write(stream, buffer, offset, length, position, canOwn) {
855
+ if (buffer.buffer === HEAP8.buffer) canOwn = false;
856
+ if (!length) return 0;
857
+ const node = stream.node;
858
+ node.mtime = node.ctime = Date.now();
859
+ if (buffer.subarray && (!node.contents || node.contents.subarray)) {
860
+ if (canOwn) {
861
+ node.contents = buffer.subarray(offset, offset + length);
862
+ node.usedBytes = length;
863
+ return length;
864
+ } else if (node.usedBytes === 0 && position === 0) {
865
+ node.contents = buffer.slice(offset, offset + length);
866
+ node.usedBytes = length;
867
+ return length;
868
+ } else if (position + length <= node.usedBytes) {
869
+ node.contents.set(buffer.subarray(offset, offset + length), position);
870
+ return length;
871
+ }
872
+ }
873
+ MEMFS.expandFileStorage(node, position + length);
874
+ if (node.contents.subarray && buffer.subarray) node.contents.set(buffer.subarray(offset, offset + length), position);
875
+ else for (let i = 0; i < length; i++) node.contents[position + i] = buffer[offset + i];
876
+ node.usedBytes = Math.max(node.usedBytes, position + length);
877
+ return length;
878
+ },
879
+ llseek(stream, offset, whence) {
880
+ let position = offset;
881
+ if (whence === 1) position += stream.position;
882
+ else if (whence === 2) {
883
+ if (FS.isFile(stream.node.mode)) position += stream.node.usedBytes;
884
+ }
885
+ if (position < 0) throw new FS.ErrnoError(28);
886
+ return position;
887
+ },
888
+ mmap(stream, length, position, prot, flags) {
889
+ if (!FS.isFile(stream.node.mode)) throw new FS.ErrnoError(43);
890
+ let ptr;
891
+ let allocated;
892
+ let contents = stream.node.contents;
893
+ if (!(flags & 2) && contents && contents.buffer === HEAP8.buffer) {
894
+ allocated = false;
895
+ ptr = contents.byteOffset;
896
+ } else {
897
+ allocated = true;
898
+ ptr = mmapAlloc(length);
899
+ if (!ptr) throw new FS.ErrnoError(48);
900
+ if (contents) {
901
+ if (position > 0 || position + length < contents.length) if (contents.subarray) contents = contents.subarray(position, position + length);
902
+ else contents = Array.prototype.slice.call(contents, position, position + length);
903
+ HEAP8.set(contents, ptr >>> 0);
904
+ }
905
+ }
906
+ return {
907
+ ptr,
908
+ allocated
909
+ };
910
+ },
911
+ msync(stream, buffer, offset, length, mmapFlags) {
912
+ MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
913
+ return 0;
914
+ }
915
+ }
916
+ };
917
+ const FS_modeStringToFlags = (str) => {
918
+ const flagModes = {
919
+ "r": 0,
920
+ "r+": 2,
921
+ "w": 577,
922
+ "w+": 578,
923
+ "a": 1089,
924
+ "a+": 1090
925
+ };
926
+ const flags = flagModes[str];
927
+ if (typeof flags == "undefined") throw new TypeError(`Unknown file open mode: ${str}`);
928
+ return flags;
929
+ };
930
+ const FS_getMode = (canRead, canWrite) => {
931
+ let mode = 0;
932
+ if (canRead) mode |= 365;
933
+ if (canWrite) mode |= 146;
934
+ return mode;
935
+ };
936
+ var IDBFS = {
937
+ dbs: {},
938
+ indexedDB: () => indexedDB,
939
+ DB_VERSION: 21,
940
+ DB_STORE_NAME: "FILE_DATA",
941
+ queuePersist: (mount) => {
942
+ function onPersistComplete() {
943
+ if (mount.idbPersistState === "again") startPersist();
944
+ else mount.idbPersistState = 0;
945
+ }
946
+ function startPersist() {
947
+ mount.idbPersistState = "idb";
948
+ IDBFS.syncfs(mount, false, onPersistComplete);
949
+ }
950
+ if (!mount.idbPersistState) mount.idbPersistState = setTimeout(startPersist, 0);
951
+ else if (mount.idbPersistState === "idb") mount.idbPersistState = "again";
952
+ },
953
+ mount: (mount) => {
954
+ const mnt = MEMFS.mount(mount);
955
+ if (mount?.opts?.autoPersist) {
956
+ mount.idbPersistState = 0;
957
+ const memfs_node_ops = mnt.node_ops;
958
+ mnt.node_ops = { ...mnt.node_ops };
959
+ mnt.node_ops.mknod = (parent, name, mode, dev) => {
960
+ const node = memfs_node_ops.mknod(parent, name, mode, dev);
961
+ node.node_ops = mnt.node_ops;
962
+ node.idbfs_mount = mnt.mount;
963
+ node.memfs_stream_ops = node.stream_ops;
964
+ node.stream_ops = { ...node.stream_ops };
965
+ node.stream_ops.write = (stream, buffer, offset, length, position, canOwn) => {
966
+ stream.node.isModified = true;
967
+ return node.memfs_stream_ops.write(stream, buffer, offset, length, position, canOwn);
968
+ };
969
+ node.stream_ops.close = (stream) => {
970
+ const n = stream.node;
971
+ if (n.isModified) {
972
+ IDBFS.queuePersist(n.idbfs_mount);
973
+ n.isModified = false;
974
+ }
975
+ if (n.memfs_stream_ops.close) return n.memfs_stream_ops.close(stream);
976
+ };
977
+ IDBFS.queuePersist(mnt.mount);
978
+ return node;
979
+ };
980
+ mnt.node_ops.rmdir = (...args) => (IDBFS.queuePersist(mnt.mount), memfs_node_ops.rmdir(...args));
981
+ mnt.node_ops.symlink = (...args) => (IDBFS.queuePersist(mnt.mount), memfs_node_ops.symlink(...args));
982
+ mnt.node_ops.unlink = (...args) => (IDBFS.queuePersist(mnt.mount), memfs_node_ops.unlink(...args));
983
+ mnt.node_ops.rename = (...args) => (IDBFS.queuePersist(mnt.mount), memfs_node_ops.rename(...args));
984
+ }
985
+ return mnt;
986
+ },
987
+ syncfs: (mount, populate, callback) => {
988
+ IDBFS.getLocalSet(mount, (err$1, local) => {
989
+ if (err$1) return callback(err$1);
990
+ IDBFS.getRemoteSet(mount, (err$2, remote) => {
991
+ if (err$2) return callback(err$2);
992
+ const src = populate ? remote : local;
993
+ const dst = populate ? local : remote;
994
+ IDBFS.reconcile(src, dst, callback);
995
+ });
996
+ });
997
+ },
998
+ quit: () => {
999
+ for (const value of Object.values(IDBFS.dbs)) value.close();
1000
+ IDBFS.dbs = {};
1001
+ },
1002
+ getDB: (name, callback) => {
1003
+ let db = IDBFS.dbs[name];
1004
+ if (db) return callback(null, db);
1005
+ let req;
1006
+ try {
1007
+ req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION);
1008
+ } catch (e) {
1009
+ return callback(e);
1010
+ }
1011
+ if (!req) return callback("Unable to connect to IndexedDB");
1012
+ req.onupgradeneeded = (e) => {
1013
+ const db$1 = e.target.result;
1014
+ const transaction = e.target.transaction;
1015
+ let fileStore;
1016
+ if (db$1.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME);
1017
+ else fileStore = db$1.createObjectStore(IDBFS.DB_STORE_NAME);
1018
+ if (!fileStore.indexNames.contains("timestamp")) fileStore.createIndex("timestamp", "timestamp", { unique: false });
1019
+ };
1020
+ req.onsuccess = () => {
1021
+ db = req.result;
1022
+ IDBFS.dbs[name] = db;
1023
+ callback(null, db);
1024
+ };
1025
+ req.onerror = (e) => {
1026
+ callback(e.target.error);
1027
+ e.preventDefault();
1028
+ };
1029
+ },
1030
+ getLocalSet: (mount, callback) => {
1031
+ const entries = {};
1032
+ function isRealDir(p) {
1033
+ return p !== "." && p !== "..";
1034
+ }
1035
+ function toAbsolute(root) {
1036
+ return (p) => PATH.join2(root, p);
1037
+ }
1038
+ const check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint));
1039
+ while (check.length) {
1040
+ const path = check.pop();
1041
+ var stat;
1042
+ try {
1043
+ stat = FS.stat(path);
1044
+ } catch (e) {
1045
+ return callback(e);
1046
+ }
1047
+ if (FS.isDir(stat.mode)) check.push(...FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
1048
+ entries[path] = { timestamp: stat.mtime };
1049
+ }
1050
+ return callback(null, {
1051
+ type: "local",
1052
+ entries
1053
+ });
1054
+ },
1055
+ getRemoteSet: (mount, callback) => {
1056
+ const entries = {};
1057
+ IDBFS.getDB(mount.mountpoint, (err$1, db) => {
1058
+ if (err$1) return callback(err$1);
1059
+ try {
1060
+ const transaction = db.transaction([IDBFS.DB_STORE_NAME], "readonly");
1061
+ transaction.onerror = (e) => {
1062
+ callback(e.target.error);
1063
+ e.preventDefault();
1064
+ };
1065
+ const store = transaction.objectStore(IDBFS.DB_STORE_NAME);
1066
+ const index = store.index("timestamp");
1067
+ index.openKeyCursor().onsuccess = (event) => {
1068
+ const cursor = event.target.result;
1069
+ if (!cursor) return callback(null, {
1070
+ type: "remote",
1071
+ db,
1072
+ entries
1073
+ });
1074
+ entries[cursor.primaryKey] = { timestamp: cursor.key };
1075
+ cursor.continue();
1076
+ };
1077
+ } catch (e) {
1078
+ return callback(e);
1079
+ }
1080
+ });
1081
+ },
1082
+ loadLocalEntry: (path, callback) => {
1083
+ let stat, node;
1084
+ try {
1085
+ const lookup = FS.lookupPath(path);
1086
+ node = lookup.node;
1087
+ stat = FS.stat(path);
1088
+ } catch (e) {
1089
+ return callback(e);
1090
+ }
1091
+ if (FS.isDir(stat.mode)) return callback(null, {
1092
+ timestamp: stat.mtime,
1093
+ mode: stat.mode
1094
+ });
1095
+ else if (FS.isFile(stat.mode)) {
1096
+ node.contents = MEMFS.getFileDataAsTypedArray(node);
1097
+ return callback(null, {
1098
+ timestamp: stat.mtime,
1099
+ mode: stat.mode,
1100
+ contents: node.contents
1101
+ });
1102
+ } else return callback(new Error("node type not supported"));
1103
+ },
1104
+ storeLocalEntry: (path, entry, callback) => {
1105
+ try {
1106
+ if (FS.isDir(entry.mode)) FS.mkdirTree(path, entry.mode);
1107
+ else if (FS.isFile(entry.mode)) FS.writeFile(path, entry.contents, { canOwn: true });
1108
+ else return callback(new Error("node type not supported"));
1109
+ FS.chmod(path, entry.mode);
1110
+ FS.utime(path, entry.timestamp, entry.timestamp);
1111
+ } catch (e) {
1112
+ return callback(e);
1113
+ }
1114
+ callback(null);
1115
+ },
1116
+ removeLocalEntry: (path, callback) => {
1117
+ try {
1118
+ const stat = FS.stat(path);
1119
+ if (FS.isDir(stat.mode)) FS.rmdir(path);
1120
+ else if (FS.isFile(stat.mode)) FS.unlink(path);
1121
+ } catch (e) {
1122
+ return callback(e);
1123
+ }
1124
+ callback(null);
1125
+ },
1126
+ loadRemoteEntry: (store, path, callback) => {
1127
+ const req = store.get(path);
1128
+ req.onsuccess = (event) => callback(null, event.target.result);
1129
+ req.onerror = (e) => {
1130
+ callback(e.target.error);
1131
+ e.preventDefault();
1132
+ };
1133
+ },
1134
+ storeRemoteEntry: (store, path, entry, callback) => {
1135
+ try {
1136
+ var req = store.put(entry, path);
1137
+ } catch (e) {
1138
+ callback(e);
1139
+ return;
1140
+ }
1141
+ req.onsuccess = (event) => callback();
1142
+ req.onerror = (e) => {
1143
+ callback(e.target.error);
1144
+ e.preventDefault();
1145
+ };
1146
+ },
1147
+ removeRemoteEntry: (store, path, callback) => {
1148
+ const req = store.delete(path);
1149
+ req.onsuccess = (event) => callback();
1150
+ req.onerror = (e) => {
1151
+ callback(e.target.error);
1152
+ e.preventDefault();
1153
+ };
1154
+ },
1155
+ reconcile: (src, dst, callback) => {
1156
+ let total = 0;
1157
+ const create = [];
1158
+ for (var [key, e] of Object.entries(src.entries)) {
1159
+ const e2 = dst.entries[key];
1160
+ if (!e2 || e.timestamp.getTime() != e2.timestamp.getTime()) {
1161
+ create.push(key);
1162
+ total++;
1163
+ }
1164
+ }
1165
+ const remove = [];
1166
+ for (var key of Object.keys(dst.entries)) if (!src.entries[key]) {
1167
+ remove.push(key);
1168
+ total++;
1169
+ }
1170
+ if (!total) return callback(null);
1171
+ let errored = false;
1172
+ const db = src.type === "remote" ? src.db : dst.db;
1173
+ const transaction = db.transaction([IDBFS.DB_STORE_NAME], "readwrite");
1174
+ const store = transaction.objectStore(IDBFS.DB_STORE_NAME);
1175
+ function done(err$1) {
1176
+ if (err$1 && !errored) {
1177
+ errored = true;
1178
+ return callback(err$1);
1179
+ }
1180
+ }
1181
+ transaction.onerror = transaction.onabort = (e$1) => {
1182
+ done(e$1.target.error);
1183
+ e$1.preventDefault();
1184
+ };
1185
+ transaction.oncomplete = (e$1) => {
1186
+ if (!errored) callback(null);
1187
+ };
1188
+ for (const path of create.sort()) if (dst.type === "local") IDBFS.loadRemoteEntry(store, path, (err$1, entry) => {
1189
+ if (err$1) return done(err$1);
1190
+ IDBFS.storeLocalEntry(path, entry, done);
1191
+ });
1192
+ else IDBFS.loadLocalEntry(path, (err$1, entry) => {
1193
+ if (err$1) return done(err$1);
1194
+ IDBFS.storeRemoteEntry(store, path, entry, done);
1195
+ });
1196
+ for (const path of remove.sort().reverse()) if (dst.type === "local") IDBFS.removeLocalEntry(path, done);
1197
+ else IDBFS.removeRemoteEntry(store, path, done);
1198
+ }
1199
+ };
1200
+ const asyncLoad = async (url) => {
1201
+ const arrayBuffer = await readAsync(url);
1202
+ return new Uint8Array(arrayBuffer);
1203
+ };
1204
+ const FS_createDataFile = (...args) => FS.createDataFile(...args);
1205
+ const getUniqueRunDependency = (id) => id;
1206
+ let runDependencies = 0;
1207
+ let dependenciesFulfilled = null;
1208
+ const removeRunDependency = (id) => {
1209
+ runDependencies--;
1210
+ Module.monitorRunDependencies?.(runDependencies);
1211
+ if (runDependencies == 0) {
1212
+ if (dependenciesFulfilled) {
1213
+ const callback = dependenciesFulfilled;
1214
+ dependenciesFulfilled = null;
1215
+ callback();
1216
+ }
1217
+ }
1218
+ };
1219
+ const addRunDependency = (id) => {
1220
+ runDependencies++;
1221
+ Module.monitorRunDependencies?.(runDependencies);
1222
+ };
1223
+ let preloadPlugins = [];
1224
+ const FS_handledByPreloadPlugin = async (byteArray, fullname) => {
1225
+ if (typeof Browser != "undefined") Browser.init();
1226
+ for (const plugin of preloadPlugins) if (plugin.canHandle(fullname)) return plugin.handle(byteArray, fullname);
1227
+ return byteArray;
1228
+ };
1229
+ const FS_preloadFile = async (parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish) => {
1230
+ const fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
1231
+ const dep = getUniqueRunDependency(`cp ${fullname}`);
1232
+ addRunDependency(dep);
1233
+ try {
1234
+ let byteArray = url;
1235
+ if (typeof url == "string") byteArray = await asyncLoad(url);
1236
+ byteArray = await FS_handledByPreloadPlugin(byteArray, fullname);
1237
+ preFinish?.();
1238
+ if (!dontCreateFile) FS_createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
1239
+ } finally {
1240
+ removeRunDependency(dep);
1241
+ }
1242
+ };
1243
+ const FS_createPreloadedFile = (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => {
1244
+ FS_preloadFile(parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish).then(onload).catch(onerror);
1245
+ };
1246
+ var FS = {
1247
+ root: null,
1248
+ mounts: [],
1249
+ devices: {},
1250
+ streams: [],
1251
+ nextInode: 1,
1252
+ nameTable: null,
1253
+ currentPath: "/",
1254
+ initialized: false,
1255
+ ignorePermissions: true,
1256
+ filesystems: null,
1257
+ syncFSRequests: 0,
1258
+ ErrnoError: class {
1259
+ name = "ErrnoError";
1260
+ constructor(errno) {
1261
+ this.errno = errno;
1262
+ }
1263
+ },
1264
+ FSStream: class {
1265
+ shared = {};
1266
+ get object() {
1267
+ return this.node;
1268
+ }
1269
+ set object(val) {
1270
+ this.node = val;
1271
+ }
1272
+ get isRead() {
1273
+ return (this.flags & 2097155) !== 1;
1274
+ }
1275
+ get isWrite() {
1276
+ return (this.flags & 2097155) !== 0;
1277
+ }
1278
+ get isAppend() {
1279
+ return this.flags & 1024;
1280
+ }
1281
+ get flags() {
1282
+ return this.shared.flags;
1283
+ }
1284
+ set flags(val) {
1285
+ this.shared.flags = val;
1286
+ }
1287
+ get position() {
1288
+ return this.shared.position;
1289
+ }
1290
+ set position(val) {
1291
+ this.shared.position = val;
1292
+ }
1293
+ },
1294
+ FSNode: class {
1295
+ node_ops = {};
1296
+ stream_ops = {};
1297
+ readMode = 365;
1298
+ writeMode = 146;
1299
+ mounted = null;
1300
+ constructor(parent, name, mode, rdev) {
1301
+ if (!parent) parent = this;
1302
+ this.parent = parent;
1303
+ this.mount = parent.mount;
1304
+ this.id = FS.nextInode++;
1305
+ this.name = name;
1306
+ this.mode = mode;
1307
+ this.rdev = rdev;
1308
+ this.atime = this.mtime = this.ctime = Date.now();
1309
+ }
1310
+ get read() {
1311
+ return (this.mode & this.readMode) === this.readMode;
1312
+ }
1313
+ set read(val) {
1314
+ val ? this.mode |= this.readMode : this.mode &= ~this.readMode;
1315
+ }
1316
+ get write() {
1317
+ return (this.mode & this.writeMode) === this.writeMode;
1318
+ }
1319
+ set write(val) {
1320
+ val ? this.mode |= this.writeMode : this.mode &= ~this.writeMode;
1321
+ }
1322
+ get isFolder() {
1323
+ return FS.isDir(this.mode);
1324
+ }
1325
+ get isDevice() {
1326
+ return FS.isChrdev(this.mode);
1327
+ }
1328
+ },
1329
+ lookupPath(path, opts = {}) {
1330
+ if (!path) throw new FS.ErrnoError(44);
1331
+ opts.follow_mount ??= true;
1332
+ if (!PATH.isAbs(path)) path = `${FS.cwd()}/${path}`;
1333
+ linkloop: for (let nlinks = 0; nlinks < 40; nlinks++) {
1334
+ const parts = path.split("/").filter((p) => !!p);
1335
+ let current = FS.root;
1336
+ let current_path = "/";
1337
+ for (let i = 0; i < parts.length; i++) {
1338
+ const islast = i === parts.length - 1;
1339
+ if (islast && opts.parent) break;
1340
+ if (parts[i] === ".") continue;
1341
+ if (parts[i] === "..") {
1342
+ current_path = PATH.dirname(current_path);
1343
+ if (FS.isRoot(current)) {
1344
+ path = `${current_path}/${parts.slice(i + 1).join("/")}`;
1345
+ nlinks--;
1346
+ continue linkloop;
1347
+ } else current = current.parent;
1348
+ continue;
1349
+ }
1350
+ current_path = PATH.join2(current_path, parts[i]);
1351
+ try {
1352
+ current = FS.lookupNode(current, parts[i]);
1353
+ } catch (e) {
1354
+ if (e?.errno === 44 && islast && opts.noent_okay) return { path: current_path };
1355
+ throw e;
1356
+ }
1357
+ if (FS.isMountpoint(current) && (!islast || opts.follow_mount)) current = current.mounted.root;
1358
+ if (FS.isLink(current.mode) && (!islast || opts.follow)) {
1359
+ if (!current.node_ops.readlink) throw new FS.ErrnoError(52);
1360
+ let link = current.node_ops.readlink(current);
1361
+ if (!PATH.isAbs(link)) link = `${PATH.dirname(current_path)}/${link}`;
1362
+ path = `${link}/${parts.slice(i + 1).join("/")}`;
1363
+ continue linkloop;
1364
+ }
1365
+ }
1366
+ return {
1367
+ path: current_path,
1368
+ node: current
1369
+ };
1370
+ }
1371
+ throw new FS.ErrnoError(32);
1372
+ },
1373
+ getPath(node) {
1374
+ let path;
1375
+ while (true) {
1376
+ if (FS.isRoot(node)) {
1377
+ const mount = node.mount.mountpoint;
1378
+ if (!path) return mount;
1379
+ return mount[mount.length - 1] !== "/" ? `${mount}/${path}` : mount + path;
1380
+ }
1381
+ path = path ? `${node.name}/${path}` : node.name;
1382
+ node = node.parent;
1383
+ }
1384
+ },
1385
+ hashName(parentid, name) {
1386
+ let hash = 0;
1387
+ for (let i = 0; i < name.length; i++) hash = (hash << 5) - hash + name.charCodeAt(i) | 0;
1388
+ return (parentid + hash >>> 0) % FS.nameTable.length;
1389
+ },
1390
+ hashAddNode(node) {
1391
+ const hash = FS.hashName(node.parent.id, node.name);
1392
+ node.name_next = FS.nameTable[hash];
1393
+ FS.nameTable[hash] = node;
1394
+ },
1395
+ hashRemoveNode(node) {
1396
+ const hash = FS.hashName(node.parent.id, node.name);
1397
+ if (FS.nameTable[hash] === node) FS.nameTable[hash] = node.name_next;
1398
+ else {
1399
+ let current = FS.nameTable[hash];
1400
+ while (current) {
1401
+ if (current.name_next === node) {
1402
+ current.name_next = node.name_next;
1403
+ break;
1404
+ }
1405
+ current = current.name_next;
1406
+ }
1407
+ }
1408
+ },
1409
+ lookupNode(parent, name) {
1410
+ const errCode = FS.mayLookup(parent);
1411
+ if (errCode) throw new FS.ErrnoError(errCode);
1412
+ const hash = FS.hashName(parent.id, name);
1413
+ for (let node = FS.nameTable[hash]; node; node = node.name_next) {
1414
+ const nodeName = node.name;
1415
+ if (node.parent.id === parent.id && nodeName === name) return node;
1416
+ }
1417
+ return FS.lookup(parent, name);
1418
+ },
1419
+ createNode(parent, name, mode, rdev) {
1420
+ const node = new FS.FSNode(parent, name, mode, rdev);
1421
+ FS.hashAddNode(node);
1422
+ return node;
1423
+ },
1424
+ destroyNode(node) {
1425
+ FS.hashRemoveNode(node);
1426
+ },
1427
+ isRoot(node) {
1428
+ return node === node.parent;
1429
+ },
1430
+ isMountpoint(node) {
1431
+ return !!node.mounted;
1432
+ },
1433
+ isFile(mode) {
1434
+ return (mode & 61440) === 32768;
1435
+ },
1436
+ isDir(mode) {
1437
+ return (mode & 61440) === 16384;
1438
+ },
1439
+ isLink(mode) {
1440
+ return (mode & 61440) === 40960;
1441
+ },
1442
+ isChrdev(mode) {
1443
+ return (mode & 61440) === 8192;
1444
+ },
1445
+ isBlkdev(mode) {
1446
+ return (mode & 61440) === 24576;
1447
+ },
1448
+ isFIFO(mode) {
1449
+ return (mode & 61440) === 4096;
1450
+ },
1451
+ isSocket(mode) {
1452
+ return (mode & 49152) === 49152;
1453
+ },
1454
+ flagsToPermissionString(flag) {
1455
+ let perms = [
1456
+ "r",
1457
+ "w",
1458
+ "rw"
1459
+ ][flag & 3];
1460
+ if (flag & 512) perms += "w";
1461
+ return perms;
1462
+ },
1463
+ nodePermissions(node, perms) {
1464
+ if (FS.ignorePermissions) return 0;
1465
+ if (perms.includes("r") && !(node.mode & 292)) return 2;
1466
+ if (perms.includes("w") && !(node.mode & 146)) return 2;
1467
+ if (perms.includes("x") && !(node.mode & 73)) return 2;
1468
+ return 0;
1469
+ },
1470
+ mayLookup(dir) {
1471
+ if (!FS.isDir(dir.mode)) return 54;
1472
+ const errCode = FS.nodePermissions(dir, "x");
1473
+ if (errCode) return errCode;
1474
+ if (!dir.node_ops.lookup) return 2;
1475
+ return 0;
1476
+ },
1477
+ mayCreate(dir, name) {
1478
+ if (!FS.isDir(dir.mode)) return 54;
1479
+ try {
1480
+ const node = FS.lookupNode(dir, name);
1481
+ return 20;
1482
+ } catch (e) {}
1483
+ return FS.nodePermissions(dir, "wx");
1484
+ },
1485
+ mayDelete(dir, name, isdir) {
1486
+ let node;
1487
+ try {
1488
+ node = FS.lookupNode(dir, name);
1489
+ } catch (e) {
1490
+ return e.errno;
1491
+ }
1492
+ const errCode = FS.nodePermissions(dir, "wx");
1493
+ if (errCode) return errCode;
1494
+ if (isdir) {
1495
+ if (!FS.isDir(node.mode)) return 54;
1496
+ if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) return 10;
1497
+ } else if (FS.isDir(node.mode)) return 31;
1498
+ return 0;
1499
+ },
1500
+ mayOpen(node, flags) {
1501
+ if (!node) return 44;
1502
+ if (FS.isLink(node.mode)) return 32;
1503
+ const mode = FS.flagsToPermissionString(flags);
1504
+ if (FS.isDir(node.mode)) {
1505
+ if (mode !== "r" || flags & 576) return 31;
1506
+ }
1507
+ return FS.nodePermissions(node, mode);
1508
+ },
1509
+ checkOpExists(op, err$1) {
1510
+ if (!op) throw new FS.ErrnoError(err$1);
1511
+ return op;
1512
+ },
1513
+ MAX_OPEN_FDS: 4096,
1514
+ nextfd() {
1515
+ for (let fd = 0; fd <= FS.MAX_OPEN_FDS; fd++) if (!FS.streams[fd]) return fd;
1516
+ throw new FS.ErrnoError(33);
1517
+ },
1518
+ getStreamChecked(fd) {
1519
+ const stream = FS.getStream(fd);
1520
+ if (!stream) throw new FS.ErrnoError(8);
1521
+ return stream;
1522
+ },
1523
+ getStream: (fd) => FS.streams[fd],
1524
+ createStream(stream, fd = -1) {
1525
+ stream = Object.assign(new FS.FSStream(), stream);
1526
+ if (fd == -1) fd = FS.nextfd();
1527
+ stream.fd = fd;
1528
+ FS.streams[fd] = stream;
1529
+ return stream;
1530
+ },
1531
+ closeStream(fd) {
1532
+ FS.streams[fd] = null;
1533
+ },
1534
+ dupStream(origStream, fd = -1) {
1535
+ const stream = FS.createStream(origStream, fd);
1536
+ stream.stream_ops?.dup?.(stream);
1537
+ return stream;
1538
+ },
1539
+ doSetAttr(stream, node, attr) {
1540
+ let setattr = stream?.stream_ops.setattr;
1541
+ const arg = setattr ? stream : node;
1542
+ setattr ??= node.node_ops.setattr;
1543
+ FS.checkOpExists(setattr, 63);
1544
+ setattr(arg, attr);
1545
+ },
1546
+ chrdev_stream_ops: {
1547
+ open(stream) {
1548
+ const device = FS.getDevice(stream.node.rdev);
1549
+ stream.stream_ops = device.stream_ops;
1550
+ stream.stream_ops.open?.(stream);
1551
+ },
1552
+ llseek() {
1553
+ throw new FS.ErrnoError(70);
1554
+ }
1555
+ },
1556
+ major: (dev) => dev >> 8,
1557
+ minor: (dev) => dev & 255,
1558
+ makedev: (ma, mi) => ma << 8 | mi,
1559
+ registerDevice(dev, ops) {
1560
+ FS.devices[dev] = { stream_ops: ops };
1561
+ },
1562
+ getDevice: (dev) => FS.devices[dev],
1563
+ getMounts(mount) {
1564
+ const mounts = [];
1565
+ const check = [mount];
1566
+ while (check.length) {
1567
+ const m = check.pop();
1568
+ mounts.push(m);
1569
+ check.push(...m.mounts);
1570
+ }
1571
+ return mounts;
1572
+ },
1573
+ syncfs(populate, callback) {
1574
+ if (typeof populate == "function") {
1575
+ callback = populate;
1576
+ populate = false;
1577
+ }
1578
+ FS.syncFSRequests++;
1579
+ if (FS.syncFSRequests > 1) err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`);
1580
+ const mounts = FS.getMounts(FS.root.mount);
1581
+ let completed = 0;
1582
+ function doCallback(errCode) {
1583
+ FS.syncFSRequests--;
1584
+ return callback(errCode);
1585
+ }
1586
+ function done(errCode) {
1587
+ if (errCode) {
1588
+ if (!done.errored) {
1589
+ done.errored = true;
1590
+ return doCallback(errCode);
1591
+ }
1592
+ return;
1593
+ }
1594
+ if (++completed >= mounts.length) doCallback(null);
1595
+ }
1596
+ for (const mount of mounts) if (mount.type.syncfs) mount.type.syncfs(mount, populate, done);
1597
+ else done(null);
1598
+ },
1599
+ mount(type, opts, mountpoint) {
1600
+ const root = mountpoint === "/";
1601
+ const pseudo = !mountpoint;
1602
+ let node;
1603
+ if (root && FS.root) throw new FS.ErrnoError(10);
1604
+ else if (!root && !pseudo) {
1605
+ const lookup = FS.lookupPath(mountpoint, { follow_mount: false });
1606
+ mountpoint = lookup.path;
1607
+ node = lookup.node;
1608
+ if (FS.isMountpoint(node)) throw new FS.ErrnoError(10);
1609
+ if (!FS.isDir(node.mode)) throw new FS.ErrnoError(54);
1610
+ }
1611
+ const mount = {
1612
+ type,
1613
+ opts,
1614
+ mountpoint,
1615
+ mounts: []
1616
+ };
1617
+ const mountRoot = type.mount(mount);
1618
+ mountRoot.mount = mount;
1619
+ mount.root = mountRoot;
1620
+ if (root) FS.root = mountRoot;
1621
+ else if (node) {
1622
+ node.mounted = mount;
1623
+ if (node.mount) node.mount.mounts.push(mount);
1624
+ }
1625
+ return mountRoot;
1626
+ },
1627
+ unmount(mountpoint) {
1628
+ const lookup = FS.lookupPath(mountpoint, { follow_mount: false });
1629
+ if (!FS.isMountpoint(lookup.node)) throw new FS.ErrnoError(28);
1630
+ const node = lookup.node;
1631
+ const mount = node.mounted;
1632
+ const mounts = FS.getMounts(mount);
1633
+ for (let [hash, current] of Object.entries(FS.nameTable)) while (current) {
1634
+ const next = current.name_next;
1635
+ if (mounts.includes(current.mount)) FS.destroyNode(current);
1636
+ current = next;
1637
+ }
1638
+ node.mounted = null;
1639
+ const idx = node.mount.mounts.indexOf(mount);
1640
+ node.mount.mounts.splice(idx, 1);
1641
+ },
1642
+ lookup(parent, name) {
1643
+ return parent.node_ops.lookup(parent, name);
1644
+ },
1645
+ mknod(path, mode, dev) {
1646
+ const lookup = FS.lookupPath(path, { parent: true });
1647
+ const parent = lookup.node;
1648
+ const name = PATH.basename(path);
1649
+ if (!name) throw new FS.ErrnoError(28);
1650
+ if (name === "." || name === "..") throw new FS.ErrnoError(20);
1651
+ const errCode = FS.mayCreate(parent, name);
1652
+ if (errCode) throw new FS.ErrnoError(errCode);
1653
+ if (!parent.node_ops.mknod) throw new FS.ErrnoError(63);
1654
+ return parent.node_ops.mknod(parent, name, mode, dev);
1655
+ },
1656
+ statfs(path) {
1657
+ return FS.statfsNode(FS.lookupPath(path, { follow: true }).node);
1658
+ },
1659
+ statfsStream(stream) {
1660
+ return FS.statfsNode(stream.node);
1661
+ },
1662
+ statfsNode(node) {
1663
+ const rtn = {
1664
+ bsize: 4096,
1665
+ frsize: 4096,
1666
+ blocks: 1e6,
1667
+ bfree: 5e5,
1668
+ bavail: 5e5,
1669
+ files: FS.nextInode,
1670
+ ffree: FS.nextInode - 1,
1671
+ fsid: 42,
1672
+ flags: 2,
1673
+ namelen: 255
1674
+ };
1675
+ if (node.node_ops.statfs) Object.assign(rtn, node.node_ops.statfs(node.mount.opts.root));
1676
+ return rtn;
1677
+ },
1678
+ create(path, mode = 438) {
1679
+ mode &= 4095;
1680
+ mode |= 32768;
1681
+ return FS.mknod(path, mode, 0);
1682
+ },
1683
+ mkdir(path, mode = 511) {
1684
+ mode &= 1023;
1685
+ mode |= 16384;
1686
+ return FS.mknod(path, mode, 0);
1687
+ },
1688
+ mkdirTree(path, mode) {
1689
+ const dirs = path.split("/");
1690
+ let d = "";
1691
+ for (const dir of dirs) {
1692
+ if (!dir) continue;
1693
+ if (d || PATH.isAbs(path)) d += "/";
1694
+ d += dir;
1695
+ try {
1696
+ FS.mkdir(d, mode);
1697
+ } catch (e) {
1698
+ if (e.errno != 20) throw e;
1699
+ }
1700
+ }
1701
+ },
1702
+ mkdev(path, mode, dev) {
1703
+ if (typeof dev == "undefined") {
1704
+ dev = mode;
1705
+ mode = 438;
1706
+ }
1707
+ mode |= 8192;
1708
+ return FS.mknod(path, mode, dev);
1709
+ },
1710
+ symlink(oldpath, newpath) {
1711
+ if (!PATH_FS.resolve(oldpath)) throw new FS.ErrnoError(44);
1712
+ const lookup = FS.lookupPath(newpath, { parent: true });
1713
+ const parent = lookup.node;
1714
+ if (!parent) throw new FS.ErrnoError(44);
1715
+ const newname = PATH.basename(newpath);
1716
+ const errCode = FS.mayCreate(parent, newname);
1717
+ if (errCode) throw new FS.ErrnoError(errCode);
1718
+ if (!parent.node_ops.symlink) throw new FS.ErrnoError(63);
1719
+ return parent.node_ops.symlink(parent, newname, oldpath);
1720
+ },
1721
+ rename(old_path, new_path) {
1722
+ const old_dirname = PATH.dirname(old_path);
1723
+ const new_dirname = PATH.dirname(new_path);
1724
+ const old_name = PATH.basename(old_path);
1725
+ const new_name = PATH.basename(new_path);
1726
+ let lookup, old_dir, new_dir;
1727
+ lookup = FS.lookupPath(old_path, { parent: true });
1728
+ old_dir = lookup.node;
1729
+ lookup = FS.lookupPath(new_path, { parent: true });
1730
+ new_dir = lookup.node;
1731
+ if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
1732
+ if (old_dir.mount !== new_dir.mount) throw new FS.ErrnoError(75);
1733
+ const old_node = FS.lookupNode(old_dir, old_name);
1734
+ let relative = PATH_FS.relative(old_path, new_dirname);
1735
+ if (relative.charAt(0) !== ".") throw new FS.ErrnoError(28);
1736
+ relative = PATH_FS.relative(new_path, old_dirname);
1737
+ if (relative.charAt(0) !== ".") throw new FS.ErrnoError(55);
1738
+ let new_node;
1739
+ try {
1740
+ new_node = FS.lookupNode(new_dir, new_name);
1741
+ } catch (e) {}
1742
+ if (old_node === new_node) return;
1743
+ const isdir = FS.isDir(old_node.mode);
1744
+ let errCode = FS.mayDelete(old_dir, old_name, isdir);
1745
+ if (errCode) throw new FS.ErrnoError(errCode);
1746
+ errCode = new_node ? FS.mayDelete(new_dir, new_name, isdir) : FS.mayCreate(new_dir, new_name);
1747
+ if (errCode) throw new FS.ErrnoError(errCode);
1748
+ if (!old_dir.node_ops.rename) throw new FS.ErrnoError(63);
1749
+ if (FS.isMountpoint(old_node) || new_node && FS.isMountpoint(new_node)) throw new FS.ErrnoError(10);
1750
+ if (new_dir !== old_dir) {
1751
+ errCode = FS.nodePermissions(old_dir, "w");
1752
+ if (errCode) throw new FS.ErrnoError(errCode);
1753
+ }
1754
+ FS.hashRemoveNode(old_node);
1755
+ try {
1756
+ old_dir.node_ops.rename(old_node, new_dir, new_name);
1757
+ old_node.parent = new_dir;
1758
+ } catch (e) {
1759
+ throw e;
1760
+ } finally {
1761
+ FS.hashAddNode(old_node);
1762
+ }
1763
+ },
1764
+ rmdir(path) {
1765
+ const lookup = FS.lookupPath(path, { parent: true });
1766
+ const parent = lookup.node;
1767
+ const name = PATH.basename(path);
1768
+ const node = FS.lookupNode(parent, name);
1769
+ const errCode = FS.mayDelete(parent, name, true);
1770
+ if (errCode) throw new FS.ErrnoError(errCode);
1771
+ if (!parent.node_ops.rmdir) throw new FS.ErrnoError(63);
1772
+ if (FS.isMountpoint(node)) throw new FS.ErrnoError(10);
1773
+ parent.node_ops.rmdir(parent, name);
1774
+ FS.destroyNode(node);
1775
+ },
1776
+ readdir(path) {
1777
+ const lookup = FS.lookupPath(path, { follow: true });
1778
+ const node = lookup.node;
1779
+ const readdir = FS.checkOpExists(node.node_ops.readdir, 54);
1780
+ return readdir(node);
1781
+ },
1782
+ unlink(path) {
1783
+ const lookup = FS.lookupPath(path, { parent: true });
1784
+ const parent = lookup.node;
1785
+ if (!parent) throw new FS.ErrnoError(44);
1786
+ const name = PATH.basename(path);
1787
+ const node = FS.lookupNode(parent, name);
1788
+ const errCode = FS.mayDelete(parent, name, false);
1789
+ if (errCode) throw new FS.ErrnoError(errCode);
1790
+ if (!parent.node_ops.unlink) throw new FS.ErrnoError(63);
1791
+ if (FS.isMountpoint(node)) throw new FS.ErrnoError(10);
1792
+ parent.node_ops.unlink(parent, name);
1793
+ FS.destroyNode(node);
1794
+ },
1795
+ readlink(path) {
1796
+ const lookup = FS.lookupPath(path);
1797
+ const link = lookup.node;
1798
+ if (!link) throw new FS.ErrnoError(44);
1799
+ if (!link.node_ops.readlink) throw new FS.ErrnoError(28);
1800
+ return link.node_ops.readlink(link);
1801
+ },
1802
+ stat(path, dontFollow) {
1803
+ const lookup = FS.lookupPath(path, { follow: !dontFollow });
1804
+ const node = lookup.node;
1805
+ const getattr = FS.checkOpExists(node.node_ops.getattr, 63);
1806
+ return getattr(node);
1807
+ },
1808
+ fstat(fd) {
1809
+ const stream = FS.getStreamChecked(fd);
1810
+ const node = stream.node;
1811
+ let getattr = stream.stream_ops.getattr;
1812
+ const arg = getattr ? stream : node;
1813
+ getattr ??= node.node_ops.getattr;
1814
+ FS.checkOpExists(getattr, 63);
1815
+ return getattr(arg);
1816
+ },
1817
+ lstat(path) {
1818
+ return FS.stat(path, true);
1819
+ },
1820
+ doChmod(stream, node, mode, dontFollow) {
1821
+ FS.doSetAttr(stream, node, {
1822
+ mode: mode & 4095 | node.mode & -4096,
1823
+ ctime: Date.now(),
1824
+ dontFollow
1825
+ });
1826
+ },
1827
+ chmod(path, mode, dontFollow) {
1828
+ let node;
1829
+ if (typeof path == "string") {
1830
+ const lookup = FS.lookupPath(path, { follow: !dontFollow });
1831
+ node = lookup.node;
1832
+ } else node = path;
1833
+ FS.doChmod(null, node, mode, dontFollow);
1834
+ },
1835
+ lchmod(path, mode) {
1836
+ FS.chmod(path, mode, true);
1837
+ },
1838
+ fchmod(fd, mode) {
1839
+ const stream = FS.getStreamChecked(fd);
1840
+ FS.doChmod(stream, stream.node, mode, false);
1841
+ },
1842
+ doChown(stream, node, dontFollow) {
1843
+ FS.doSetAttr(stream, node, {
1844
+ timestamp: Date.now(),
1845
+ dontFollow
1846
+ });
1847
+ },
1848
+ chown(path, uid, gid, dontFollow) {
1849
+ let node;
1850
+ if (typeof path == "string") {
1851
+ const lookup = FS.lookupPath(path, { follow: !dontFollow });
1852
+ node = lookup.node;
1853
+ } else node = path;
1854
+ FS.doChown(null, node, dontFollow);
1855
+ },
1856
+ lchown(path, uid, gid) {
1857
+ FS.chown(path, uid, gid, true);
1858
+ },
1859
+ fchown(fd, uid, gid) {
1860
+ const stream = FS.getStreamChecked(fd);
1861
+ FS.doChown(stream, stream.node, false);
1862
+ },
1863
+ doTruncate(stream, node, len) {
1864
+ if (FS.isDir(node.mode)) throw new FS.ErrnoError(31);
1865
+ if (!FS.isFile(node.mode)) throw new FS.ErrnoError(28);
1866
+ const errCode = FS.nodePermissions(node, "w");
1867
+ if (errCode) throw new FS.ErrnoError(errCode);
1868
+ FS.doSetAttr(stream, node, {
1869
+ size: len,
1870
+ timestamp: Date.now()
1871
+ });
1872
+ },
1873
+ truncate(path, len) {
1874
+ if (len < 0) throw new FS.ErrnoError(28);
1875
+ let node;
1876
+ if (typeof path == "string") {
1877
+ const lookup = FS.lookupPath(path, { follow: true });
1878
+ node = lookup.node;
1879
+ } else node = path;
1880
+ FS.doTruncate(null, node, len);
1881
+ },
1882
+ ftruncate(fd, len) {
1883
+ const stream = FS.getStreamChecked(fd);
1884
+ if (len < 0 || (stream.flags & 2097155) === 0) throw new FS.ErrnoError(28);
1885
+ FS.doTruncate(stream, stream.node, len);
1886
+ },
1887
+ utime(path, atime, mtime) {
1888
+ const lookup = FS.lookupPath(path, { follow: true });
1889
+ const node = lookup.node;
1890
+ const setattr = FS.checkOpExists(node.node_ops.setattr, 63);
1891
+ setattr(node, {
1892
+ atime,
1893
+ mtime
1894
+ });
1895
+ },
1896
+ open(path, flags, mode = 438) {
1897
+ if (path === "") throw new FS.ErrnoError(44);
1898
+ flags = typeof flags == "string" ? FS_modeStringToFlags(flags) : flags;
1899
+ if (flags & 64) mode = mode & 4095 | 32768;
1900
+ else mode = 0;
1901
+ let node;
1902
+ let isDirPath;
1903
+ if (typeof path == "object") node = path;
1904
+ else {
1905
+ isDirPath = path.endsWith("/");
1906
+ const lookup = FS.lookupPath(path, {
1907
+ follow: !(flags & 131072),
1908
+ noent_okay: true
1909
+ });
1910
+ node = lookup.node;
1911
+ path = lookup.path;
1912
+ }
1913
+ let created = false;
1914
+ if (flags & 64) if (node) {
1915
+ if (flags & 128) throw new FS.ErrnoError(20);
1916
+ } else if (isDirPath) throw new FS.ErrnoError(31);
1917
+ else {
1918
+ node = FS.mknod(path, mode | 511, 0);
1919
+ created = true;
1920
+ }
1921
+ if (!node) throw new FS.ErrnoError(44);
1922
+ if (FS.isChrdev(node.mode)) flags &= -513;
1923
+ if (flags & 65536 && !FS.isDir(node.mode)) throw new FS.ErrnoError(54);
1924
+ if (!created) {
1925
+ const errCode = FS.mayOpen(node, flags);
1926
+ if (errCode) throw new FS.ErrnoError(errCode);
1927
+ }
1928
+ if (flags & 512 && !created) FS.truncate(node, 0);
1929
+ flags &= -131713;
1930
+ const stream = FS.createStream({
1931
+ node,
1932
+ path: FS.getPath(node),
1933
+ flags,
1934
+ seekable: true,
1935
+ position: 0,
1936
+ stream_ops: node.stream_ops,
1937
+ ungotten: [],
1938
+ error: false
1939
+ });
1940
+ if (stream.stream_ops.open) stream.stream_ops.open(stream);
1941
+ if (created) FS.chmod(node, mode & 511);
1942
+ return stream;
1943
+ },
1944
+ close(stream) {
1945
+ if (FS.isClosed(stream)) throw new FS.ErrnoError(8);
1946
+ if (stream.getdents) stream.getdents = null;
1947
+ try {
1948
+ if (stream.stream_ops.close) stream.stream_ops.close(stream);
1949
+ } catch (e) {
1950
+ throw e;
1951
+ } finally {
1952
+ FS.closeStream(stream.fd);
1953
+ }
1954
+ stream.fd = null;
1955
+ },
1956
+ isClosed(stream) {
1957
+ return stream.fd === null;
1958
+ },
1959
+ llseek(stream, offset, whence) {
1960
+ if (FS.isClosed(stream)) throw new FS.ErrnoError(8);
1961
+ if (!stream.seekable || !stream.stream_ops.llseek) throw new FS.ErrnoError(70);
1962
+ if (whence != 0 && whence != 1 && whence != 2) throw new FS.ErrnoError(28);
1963
+ stream.position = stream.stream_ops.llseek(stream, offset, whence);
1964
+ stream.ungotten = [];
1965
+ return stream.position;
1966
+ },
1967
+ read(stream, buffer, offset, length, position) {
1968
+ if (length < 0 || position < 0) throw new FS.ErrnoError(28);
1969
+ if (FS.isClosed(stream)) throw new FS.ErrnoError(8);
1970
+ if ((stream.flags & 2097155) === 1) throw new FS.ErrnoError(8);
1971
+ if (FS.isDir(stream.node.mode)) throw new FS.ErrnoError(31);
1972
+ if (!stream.stream_ops.read) throw new FS.ErrnoError(28);
1973
+ const seeking = typeof position != "undefined";
1974
+ if (!seeking) position = stream.position;
1975
+ else if (!stream.seekable) throw new FS.ErrnoError(70);
1976
+ const bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
1977
+ if (!seeking) stream.position += bytesRead;
1978
+ return bytesRead;
1979
+ },
1980
+ write(stream, buffer, offset, length, position, canOwn) {
1981
+ if (length < 0 || position < 0) throw new FS.ErrnoError(28);
1982
+ if (FS.isClosed(stream)) throw new FS.ErrnoError(8);
1983
+ if ((stream.flags & 2097155) === 0) throw new FS.ErrnoError(8);
1984
+ if (FS.isDir(stream.node.mode)) throw new FS.ErrnoError(31);
1985
+ if (!stream.stream_ops.write) throw new FS.ErrnoError(28);
1986
+ if (stream.seekable && stream.flags & 1024) FS.llseek(stream, 0, 2);
1987
+ const seeking = typeof position != "undefined";
1988
+ if (!seeking) position = stream.position;
1989
+ else if (!stream.seekable) throw new FS.ErrnoError(70);
1990
+ const bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
1991
+ if (!seeking) stream.position += bytesWritten;
1992
+ return bytesWritten;
1993
+ },
1994
+ mmap(stream, length, position, prot, flags) {
1995
+ if ((prot & 2) !== 0 && (flags & 2) === 0 && (stream.flags & 2097155) !== 2) throw new FS.ErrnoError(2);
1996
+ if ((stream.flags & 2097155) === 1) throw new FS.ErrnoError(2);
1997
+ if (!stream.stream_ops.mmap) throw new FS.ErrnoError(43);
1998
+ if (!length) throw new FS.ErrnoError(28);
1999
+ return stream.stream_ops.mmap(stream, length, position, prot, flags);
2000
+ },
2001
+ msync(stream, buffer, offset, length, mmapFlags) {
2002
+ if (!stream.stream_ops.msync) return 0;
2003
+ return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags);
2004
+ },
2005
+ ioctl(stream, cmd, arg) {
2006
+ if (!stream.stream_ops.ioctl) throw new FS.ErrnoError(59);
2007
+ return stream.stream_ops.ioctl(stream, cmd, arg);
2008
+ },
2009
+ readFile(path, opts = {}) {
2010
+ opts.flags = opts.flags || 0;
2011
+ opts.encoding = opts.encoding || "binary";
2012
+ if (opts.encoding !== "utf8" && opts.encoding !== "binary") abort(`Invalid encoding type "${opts.encoding}"`);
2013
+ const stream = FS.open(path, opts.flags);
2014
+ const stat = FS.stat(path);
2015
+ const length = stat.size;
2016
+ let buf = new Uint8Array(length);
2017
+ FS.read(stream, buf, 0, length, 0);
2018
+ if (opts.encoding === "utf8") buf = UTF8ArrayToString(buf);
2019
+ FS.close(stream);
2020
+ return buf;
2021
+ },
2022
+ writeFile(path, data, opts = {}) {
2023
+ opts.flags = opts.flags || 577;
2024
+ const stream = FS.open(path, opts.flags, opts.mode);
2025
+ if (typeof data == "string") data = new Uint8Array(intArrayFromString(data, true));
2026
+ if (ArrayBuffer.isView(data)) FS.write(stream, data, 0, data.byteLength, void 0, opts.canOwn);
2027
+ else abort("Unsupported data type");
2028
+ FS.close(stream);
2029
+ },
2030
+ cwd: () => FS.currentPath,
2031
+ chdir(path) {
2032
+ const lookup = FS.lookupPath(path, { follow: true });
2033
+ if (lookup.node === null) throw new FS.ErrnoError(44);
2034
+ if (!FS.isDir(lookup.node.mode)) throw new FS.ErrnoError(54);
2035
+ const errCode = FS.nodePermissions(lookup.node, "x");
2036
+ if (errCode) throw new FS.ErrnoError(errCode);
2037
+ FS.currentPath = lookup.path;
2038
+ },
2039
+ createDefaultDirectories() {
2040
+ FS.mkdir("/tmp");
2041
+ FS.mkdir("/home");
2042
+ FS.mkdir("/home/web_user");
2043
+ },
2044
+ createDefaultDevices() {
2045
+ FS.mkdir("/dev");
2046
+ FS.registerDevice(FS.makedev(1, 3), {
2047
+ read: () => 0,
2048
+ write: (stream, buffer, offset, length, pos) => length,
2049
+ llseek: () => 0
2050
+ });
2051
+ FS.mkdev("/dev/null", FS.makedev(1, 3));
2052
+ TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
2053
+ TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
2054
+ FS.mkdev("/dev/tty", FS.makedev(5, 0));
2055
+ FS.mkdev("/dev/tty1", FS.makedev(6, 0));
2056
+ const randomBuffer = new Uint8Array(1024);
2057
+ let randomLeft = 0;
2058
+ const randomByte = () => {
2059
+ if (randomLeft === 0) {
2060
+ randomFill(randomBuffer);
2061
+ randomLeft = randomBuffer.byteLength;
2062
+ }
2063
+ return randomBuffer[--randomLeft];
2064
+ };
2065
+ FS.createDevice("/dev", "random", randomByte);
2066
+ FS.createDevice("/dev", "urandom", randomByte);
2067
+ FS.mkdir("/dev/shm");
2068
+ FS.mkdir("/dev/shm/tmp");
2069
+ },
2070
+ createSpecialDirectories() {
2071
+ FS.mkdir("/proc");
2072
+ const proc_self = FS.mkdir("/proc/self");
2073
+ FS.mkdir("/proc/self/fd");
2074
+ FS.mount({ mount() {
2075
+ const node = FS.createNode(proc_self, "fd", 16895, 73);
2076
+ node.stream_ops = { llseek: MEMFS.stream_ops.llseek };
2077
+ node.node_ops = {
2078
+ lookup(parent, name) {
2079
+ const fd = +name;
2080
+ const stream = FS.getStreamChecked(fd);
2081
+ const ret = {
2082
+ parent: null,
2083
+ mount: { mountpoint: "fake" },
2084
+ node_ops: { readlink: () => stream.path },
2085
+ id: fd + 1
2086
+ };
2087
+ ret.parent = ret;
2088
+ return ret;
2089
+ },
2090
+ readdir() {
2091
+ return Array.from(FS.streams.entries()).filter(([k, v]) => v).map(([k, v]) => k.toString());
2092
+ }
2093
+ };
2094
+ return node;
2095
+ } }, {}, "/proc/self/fd");
2096
+ },
2097
+ createStandardStreams(input, output, error) {
2098
+ if (input) FS.createDevice("/dev", "stdin", input);
2099
+ else FS.symlink("/dev/tty", "/dev/stdin");
2100
+ if (output) FS.createDevice("/dev", "stdout", null, output);
2101
+ else FS.symlink("/dev/tty", "/dev/stdout");
2102
+ if (error) FS.createDevice("/dev", "stderr", null, error);
2103
+ else FS.symlink("/dev/tty1", "/dev/stderr");
2104
+ const stdin = FS.open("/dev/stdin", 0);
2105
+ const stdout = FS.open("/dev/stdout", 1);
2106
+ const stderr = FS.open("/dev/stderr", 1);
2107
+ },
2108
+ staticInit() {
2109
+ FS.nameTable = Array.from({ length: 4096 });
2110
+ FS.mount(MEMFS, {}, "/");
2111
+ FS.createDefaultDirectories();
2112
+ FS.createDefaultDevices();
2113
+ FS.createSpecialDirectories();
2114
+ FS.filesystems = {
2115
+ MEMFS,
2116
+ IDBFS
2117
+ };
2118
+ },
2119
+ init(input, output, error) {
2120
+ FS.initialized = true;
2121
+ input ??= Module.stdin;
2122
+ output ??= Module.stdout;
2123
+ error ??= Module.stderr;
2124
+ FS.createStandardStreams(input, output, error);
2125
+ },
2126
+ quit() {
2127
+ FS.initialized = false;
2128
+ for (const stream of FS.streams) if (stream) FS.close(stream);
2129
+ },
2130
+ findObject(path, dontResolveLastLink) {
2131
+ const ret = FS.analyzePath(path, dontResolveLastLink);
2132
+ if (!ret.exists) return null;
2133
+ return ret.object;
2134
+ },
2135
+ analyzePath(path, dontResolveLastLink) {
2136
+ try {
2137
+ var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
2138
+ path = lookup.path;
2139
+ } catch (e) {}
2140
+ const ret = {
2141
+ isRoot: false,
2142
+ exists: false,
2143
+ error: 0,
2144
+ name: null,
2145
+ path: null,
2146
+ object: null,
2147
+ parentExists: false,
2148
+ parentPath: null,
2149
+ parentObject: null
2150
+ };
2151
+ try {
2152
+ var lookup = FS.lookupPath(path, { parent: true });
2153
+ ret.parentExists = true;
2154
+ ret.parentPath = lookup.path;
2155
+ ret.parentObject = lookup.node;
2156
+ ret.name = PATH.basename(path);
2157
+ lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
2158
+ ret.exists = true;
2159
+ ret.path = lookup.path;
2160
+ ret.object = lookup.node;
2161
+ ret.name = lookup.node.name;
2162
+ ret.isRoot = lookup.path === "/";
2163
+ } catch (e) {
2164
+ ret.error = e.errno;
2165
+ }
2166
+ return ret;
2167
+ },
2168
+ createPath(parent, path, canRead, canWrite) {
2169
+ parent = typeof parent == "string" ? parent : FS.getPath(parent);
2170
+ const parts = path.split("/").reverse();
2171
+ while (parts.length) {
2172
+ const part = parts.pop();
2173
+ if (!part) continue;
2174
+ var current = PATH.join2(parent, part);
2175
+ try {
2176
+ FS.mkdir(current);
2177
+ } catch (e) {
2178
+ if (e.errno != 20) throw e;
2179
+ }
2180
+ parent = current;
2181
+ }
2182
+ return current;
2183
+ },
2184
+ createFile(parent, name, properties, canRead, canWrite) {
2185
+ const path = PATH.join2(typeof parent == "string" ? parent : FS.getPath(parent), name);
2186
+ const mode = FS_getMode(canRead, canWrite);
2187
+ return FS.create(path, mode);
2188
+ },
2189
+ createDataFile(parent, name, data, canRead, canWrite, canOwn) {
2190
+ let path = name;
2191
+ if (parent) {
2192
+ parent = typeof parent == "string" ? parent : FS.getPath(parent);
2193
+ path = name ? PATH.join2(parent, name) : parent;
2194
+ }
2195
+ const mode = FS_getMode(canRead, canWrite);
2196
+ const node = FS.create(path, mode);
2197
+ if (data) {
2198
+ if (typeof data == "string") {
2199
+ const arr = Array.from({ length: data.length });
2200
+ for (let i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
2201
+ data = arr;
2202
+ }
2203
+ FS.chmod(node, mode | 146);
2204
+ const stream = FS.open(node, 577);
2205
+ FS.write(stream, data, 0, data.length, 0, canOwn);
2206
+ FS.close(stream);
2207
+ FS.chmod(node, mode);
2208
+ }
2209
+ },
2210
+ createDevice(parent, name, input, output) {
2211
+ const path = PATH.join2(typeof parent == "string" ? parent : FS.getPath(parent), name);
2212
+ const mode = FS_getMode(!!input, !!output);
2213
+ FS.createDevice.major ??= 64;
2214
+ const dev = FS.makedev(FS.createDevice.major++, 0);
2215
+ FS.registerDevice(dev, {
2216
+ open(stream) {
2217
+ stream.seekable = false;
2218
+ },
2219
+ close(stream) {
2220
+ if (output?.buffer?.length) output(10);
2221
+ },
2222
+ read(stream, buffer, offset, length, pos) {
2223
+ let bytesRead = 0;
2224
+ for (let i = 0; i < length; i++) {
2225
+ var result;
2226
+ try {
2227
+ result = input();
2228
+ } catch (e) {
2229
+ throw new FS.ErrnoError(29);
2230
+ }
2231
+ if (result === void 0 && bytesRead === 0) throw new FS.ErrnoError(6);
2232
+ if (result === null || result === void 0) break;
2233
+ bytesRead++;
2234
+ buffer[offset + i] = result;
2235
+ }
2236
+ if (bytesRead) stream.node.atime = Date.now();
2237
+ return bytesRead;
2238
+ },
2239
+ write(stream, buffer, offset, length, pos) {
2240
+ for (var i = 0; i < length; i++) try {
2241
+ output(buffer[offset + i]);
2242
+ } catch (e) {
2243
+ throw new FS.ErrnoError(29);
2244
+ }
2245
+ if (length) stream.node.mtime = stream.node.ctime = Date.now();
2246
+ return i;
2247
+ }
2248
+ });
2249
+ return FS.mkdev(path, mode, dev);
2250
+ },
2251
+ forceLoadFile(obj) {
2252
+ if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
2253
+ if (globalThis.XMLHttpRequest) abort("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
2254
+ else try {
2255
+ obj.contents = readBinary(obj.url);
2256
+ } catch (e) {
2257
+ throw new FS.ErrnoError(29);
2258
+ }
2259
+ },
2260
+ createLazyFile(parent, name, url, canRead, canWrite) {
2261
+ class LazyUint8Array {
2262
+ lengthKnown = false;
2263
+ chunks = [];
2264
+ get(idx) {
2265
+ if (idx > this.length - 1 || idx < 0) return void 0;
2266
+ const chunkOffset = idx % this.chunkSize;
2267
+ const chunkNum = idx / this.chunkSize | 0;
2268
+ return this.getter(chunkNum)[chunkOffset];
2269
+ }
2270
+ setDataGetter(getter) {
2271
+ this.getter = getter;
2272
+ }
2273
+ cacheLength() {
2274
+ const xhr = new XMLHttpRequest();
2275
+ xhr.open("HEAD", url, false);
2276
+ xhr.send(null);
2277
+ if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort(`Couldn't load ${url}. Status: ${xhr.status}`);
2278
+ let datalength = Number(xhr.getResponseHeader("Content-length"));
2279
+ let header;
2280
+ const hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
2281
+ const usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";
2282
+ let chunkSize = 1024 * 1024;
2283
+ if (!hasByteServing) chunkSize = datalength;
2284
+ const doXHR = (from, to) => {
2285
+ if (from > to) abort(`invalid range (${from}, ${to}) or no bytes requested!`);
2286
+ if (to > datalength - 1) abort(`only ${datalength} bytes available! programmer error!`);
2287
+ const xhr$1 = new XMLHttpRequest();
2288
+ xhr$1.open("GET", url, false);
2289
+ if (datalength !== chunkSize) xhr$1.setRequestHeader("Range", `bytes=${from}-${to}`);
2290
+ xhr$1.responseType = "arraybuffer";
2291
+ if (xhr$1.overrideMimeType) xhr$1.overrideMimeType("text/plain; charset=x-user-defined");
2292
+ xhr$1.send(null);
2293
+ if (!(xhr$1.status >= 200 && xhr$1.status < 300 || xhr$1.status === 304)) abort(`Couldn't load ${url}. Status: ${xhr$1.status}`);
2294
+ if (xhr$1.response !== void 0) return new Uint8Array(xhr$1.response || []);
2295
+ return intArrayFromString(xhr$1.responseText || "", true);
2296
+ };
2297
+ const lazyArray = this;
2298
+ lazyArray.setDataGetter((chunkNum) => {
2299
+ const start = chunkNum * chunkSize;
2300
+ let end = (chunkNum + 1) * chunkSize - 1;
2301
+ end = Math.min(end, datalength - 1);
2302
+ if (typeof lazyArray.chunks[chunkNum] == "undefined") lazyArray.chunks[chunkNum] = doXHR(start, end);
2303
+ if (typeof lazyArray.chunks[chunkNum] == "undefined") abort("doXHR failed!");
2304
+ return lazyArray.chunks[chunkNum];
2305
+ });
2306
+ if (usesGzip || !datalength) {
2307
+ chunkSize = datalength = 1;
2308
+ datalength = this.getter(0).length;
2309
+ chunkSize = datalength;
2310
+ out("LazyFiles on gzip forces download of the whole file when length is accessed");
2311
+ }
2312
+ this._length = datalength;
2313
+ this._chunkSize = chunkSize;
2314
+ this.lengthKnown = true;
2315
+ }
2316
+ get length() {
2317
+ if (!this.lengthKnown) this.cacheLength();
2318
+ return this._length;
2319
+ }
2320
+ get chunkSize() {
2321
+ if (!this.lengthKnown) this.cacheLength();
2322
+ return this._chunkSize;
2323
+ }
2324
+ }
2325
+ if (globalThis.XMLHttpRequest) {
2326
+ if (!ENVIRONMENT_IS_WORKER) abort("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc");
2327
+ const lazyArray = new LazyUint8Array();
2328
+ var properties = {
2329
+ isDevice: false,
2330
+ contents: lazyArray
2331
+ };
2332
+ } else var properties = {
2333
+ isDevice: false,
2334
+ url
2335
+ };
2336
+ const node = FS.createFile(parent, name, properties, canRead, canWrite);
2337
+ if (properties.contents) node.contents = properties.contents;
2338
+ else if (properties.url) {
2339
+ node.contents = null;
2340
+ node.url = properties.url;
2341
+ }
2342
+ Object.defineProperties(node, { usedBytes: { get() {
2343
+ return this.contents.length;
2344
+ } } });
2345
+ const stream_ops = {};
2346
+ for (const [key, fn] of Object.entries(node.stream_ops)) stream_ops[key] = (...args) => {
2347
+ FS.forceLoadFile(node);
2348
+ return fn(...args);
2349
+ };
2350
+ function writeChunks(stream, buffer, offset, length, position) {
2351
+ const contents = stream.node.contents;
2352
+ if (position >= contents.length) return 0;
2353
+ const size = Math.min(contents.length - position, length);
2354
+ if (contents.slice) for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
2355
+ else for (var i = 0; i < size; i++) buffer[offset + i] = contents.get(position + i);
2356
+ return size;
2357
+ }
2358
+ stream_ops.read = (stream, buffer, offset, length, position) => {
2359
+ FS.forceLoadFile(node);
2360
+ return writeChunks(stream, buffer, offset, length, position);
2361
+ };
2362
+ stream_ops.mmap = (stream, length, position, prot, flags) => {
2363
+ FS.forceLoadFile(node);
2364
+ const ptr = mmapAlloc(length);
2365
+ if (!ptr) throw new FS.ErrnoError(48);
2366
+ writeChunks(stream, HEAP8, ptr, length, position);
2367
+ return {
2368
+ ptr,
2369
+ allocated: true
2370
+ };
2371
+ };
2372
+ node.stream_ops = stream_ops;
2373
+ return node;
2374
+ }
2375
+ };
2376
+ const UTF8ToString = (ptr, maxBytesToRead, ignoreNul) => {
2377
+ ptr >>>= 0;
2378
+ if (!ptr) return "";
2379
+ const end = findStringEnd(HEAPU8, ptr, maxBytesToRead, ignoreNul);
2380
+ return UTF8Decoder.decode(HEAPU8.subarray(ptr >>> 0, end >>> 0));
2381
+ };
2382
+ var SYSCALLS = {
2383
+ calculateAt(dirfd, path, allowEmpty) {
2384
+ if (PATH.isAbs(path)) return path;
2385
+ let dir;
2386
+ if (dirfd === -100) dir = FS.cwd();
2387
+ else {
2388
+ const dirstream = SYSCALLS.getStreamFromFD(dirfd);
2389
+ dir = dirstream.path;
2390
+ }
2391
+ if (path.length == 0) {
2392
+ if (!allowEmpty) throw new FS.ErrnoError(44);
2393
+ return dir;
2394
+ }
2395
+ return `${dir}/${path}`;
2396
+ },
2397
+ writeStat(buf, stat) {
2398
+ HEAPU32[buf >>> 2 >>> 0] = stat.dev;
2399
+ HEAPU32[buf + 4 >>> 2 >>> 0] = stat.mode;
2400
+ HEAPU32[buf + 8 >>> 2 >>> 0] = stat.nlink;
2401
+ HEAPU32[buf + 12 >>> 2 >>> 0] = stat.uid;
2402
+ HEAPU32[buf + 16 >>> 2 >>> 0] = stat.gid;
2403
+ HEAPU32[buf + 20 >>> 2 >>> 0] = stat.rdev;
2404
+ HEAP64[buf + 24 >>> 3 >>> 0] = BigInt(stat.size);
2405
+ HEAP32[buf + 32 >>> 2 >>> 0] = 4096;
2406
+ HEAP32[buf + 36 >>> 2 >>> 0] = stat.blocks;
2407
+ const atime = stat.atime.getTime();
2408
+ const mtime = stat.mtime.getTime();
2409
+ const ctime = stat.ctime.getTime();
2410
+ HEAP64[buf + 40 >>> 3 >>> 0] = BigInt(Math.floor(atime / 1e3));
2411
+ HEAPU32[buf + 48 >>> 2 >>> 0] = atime % 1e3 * 1e3 * 1e3;
2412
+ HEAP64[buf + 56 >>> 3 >>> 0] = BigInt(Math.floor(mtime / 1e3));
2413
+ HEAPU32[buf + 64 >>> 2 >>> 0] = mtime % 1e3 * 1e3 * 1e3;
2414
+ HEAP64[buf + 72 >>> 3 >>> 0] = BigInt(Math.floor(ctime / 1e3));
2415
+ HEAPU32[buf + 80 >>> 2 >>> 0] = ctime % 1e3 * 1e3 * 1e3;
2416
+ HEAP64[buf + 88 >>> 3 >>> 0] = BigInt(stat.ino);
2417
+ return 0;
2418
+ },
2419
+ writeStatFs(buf, stats) {
2420
+ HEAPU32[buf + 4 >>> 2 >>> 0] = stats.bsize;
2421
+ HEAPU32[buf + 60 >>> 2 >>> 0] = stats.bsize;
2422
+ HEAP64[buf + 8 >>> 3 >>> 0] = BigInt(stats.blocks);
2423
+ HEAP64[buf + 16 >>> 3 >>> 0] = BigInt(stats.bfree);
2424
+ HEAP64[buf + 24 >>> 3 >>> 0] = BigInt(stats.bavail);
2425
+ HEAP64[buf + 32 >>> 3 >>> 0] = BigInt(stats.files);
2426
+ HEAP64[buf + 40 >>> 3 >>> 0] = BigInt(stats.ffree);
2427
+ HEAPU32[buf + 48 >>> 2 >>> 0] = stats.fsid;
2428
+ HEAPU32[buf + 64 >>> 2 >>> 0] = stats.flags;
2429
+ HEAPU32[buf + 56 >>> 2 >>> 0] = stats.namelen;
2430
+ },
2431
+ doMsync(addr, stream, len, flags, offset) {
2432
+ if (!FS.isFile(stream.node.mode)) throw new FS.ErrnoError(43);
2433
+ if (flags & 2) return 0;
2434
+ const buffer = HEAPU8.slice(addr, addr + len);
2435
+ FS.msync(stream, buffer, offset, len, flags);
2436
+ },
2437
+ getStreamFromFD(fd) {
2438
+ const stream = FS.getStreamChecked(fd);
2439
+ return stream;
2440
+ },
2441
+ varargs: void 0,
2442
+ getStr(ptr) {
2443
+ const ret = UTF8ToString(ptr);
2444
+ return ret;
2445
+ }
2446
+ };
2447
+ const INT53_MAX = 9007199254740992;
2448
+ const INT53_MIN = -9007199254740992;
2449
+ const bigintToI53Checked = (num) => num < INT53_MIN || num > INT53_MAX ? Number.NaN : Number(num);
2450
+ function ___syscall_chmod(path, mode) {
2451
+ path >>>= 0;
2452
+ try {
2453
+ path = SYSCALLS.getStr(path);
2454
+ FS.chmod(path, mode);
2455
+ return 0;
2456
+ } catch (e) {
2457
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2458
+ return -e.errno;
2459
+ }
2460
+ }
2461
+ function ___syscall_faccessat(dirfd, path, amode, flags) {
2462
+ path >>>= 0;
2463
+ try {
2464
+ path = SYSCALLS.getStr(path);
2465
+ path = SYSCALLS.calculateAt(dirfd, path);
2466
+ if (amode & -8) return -28;
2467
+ const lookup = FS.lookupPath(path, { follow: true });
2468
+ const node = lookup.node;
2469
+ if (!node) return -44;
2470
+ let perms = "";
2471
+ if (amode & 4) perms += "r";
2472
+ if (amode & 2) perms += "w";
2473
+ if (amode & 1) perms += "x";
2474
+ if (perms && FS.nodePermissions(node, perms)) return -2;
2475
+ return 0;
2476
+ } catch (e) {
2477
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2478
+ return -e.errno;
2479
+ }
2480
+ }
2481
+ function ___syscall_fchmod(fd, mode) {
2482
+ try {
2483
+ FS.fchmod(fd, mode);
2484
+ return 0;
2485
+ } catch (e) {
2486
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2487
+ return -e.errno;
2488
+ }
2489
+ }
2490
+ const syscallGetVarargI = () => {
2491
+ const ret = HEAP32[+SYSCALLS.varargs >>> 2 >>> 0];
2492
+ SYSCALLS.varargs += 4;
2493
+ return ret;
2494
+ };
2495
+ const syscallGetVarargP = syscallGetVarargI;
2496
+ function ___syscall_fcntl64(fd, cmd, varargs) {
2497
+ varargs >>>= 0;
2498
+ SYSCALLS.varargs = varargs;
2499
+ try {
2500
+ const stream = SYSCALLS.getStreamFromFD(fd);
2501
+ switch (cmd) {
2502
+ case 0: {
2503
+ var arg = syscallGetVarargI();
2504
+ if (arg < 0) return -28;
2505
+ while (FS.streams[arg]) arg++;
2506
+ let newStream;
2507
+ newStream = FS.dupStream(stream, arg);
2508
+ return newStream.fd;
2509
+ }
2510
+ case 1:
2511
+ case 2: return 0;
2512
+ case 3: return stream.flags;
2513
+ case 4: {
2514
+ var arg = syscallGetVarargI();
2515
+ stream.flags |= arg;
2516
+ return 0;
2517
+ }
2518
+ case 12: {
2519
+ var arg = syscallGetVarargP();
2520
+ const offset = 0;
2521
+ HEAP16[arg + offset >>> 1 >>> 0] = 2;
2522
+ return 0;
2523
+ }
2524
+ case 13:
2525
+ case 14: return 0;
2526
+ }
2527
+ return -28;
2528
+ } catch (e) {
2529
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2530
+ return -e.errno;
2531
+ }
2532
+ }
2533
+ function ___syscall_fdatasync(fd) {
2534
+ try {
2535
+ const stream = SYSCALLS.getStreamFromFD(fd);
2536
+ return 0;
2537
+ } catch (e) {
2538
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2539
+ return -e.errno;
2540
+ }
2541
+ }
2542
+ function ___syscall_fstat64(fd, buf) {
2543
+ buf >>>= 0;
2544
+ try {
2545
+ return SYSCALLS.writeStat(buf, FS.fstat(fd));
2546
+ } catch (e) {
2547
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2548
+ return -e.errno;
2549
+ }
2550
+ }
2551
+ function ___syscall_ftruncate64(fd, length) {
2552
+ length = bigintToI53Checked(length);
2553
+ try {
2554
+ if (isNaN(length)) return -61;
2555
+ FS.ftruncate(fd, length);
2556
+ return 0;
2557
+ } catch (e) {
2558
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2559
+ return -e.errno;
2560
+ }
2561
+ }
2562
+ const stringToUTF8 = (str, outPtr, maxBytesToWrite) => stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
2563
+ function ___syscall_getcwd(buf, size) {
2564
+ buf >>>= 0;
2565
+ size >>>= 0;
2566
+ try {
2567
+ if (size === 0) return -28;
2568
+ const cwd = FS.cwd();
2569
+ const cwdLengthInBytes = lengthBytesUTF8(cwd) + 1;
2570
+ if (size < cwdLengthInBytes) return -68;
2571
+ stringToUTF8(cwd, buf, size);
2572
+ return cwdLengthInBytes;
2573
+ } catch (e) {
2574
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2575
+ return -e.errno;
2576
+ }
2577
+ }
2578
+ function ___syscall_getdents64(fd, dirp, count) {
2579
+ dirp >>>= 0;
2580
+ count >>>= 0;
2581
+ try {
2582
+ const stream = SYSCALLS.getStreamFromFD(fd);
2583
+ stream.getdents ||= FS.readdir(stream.path);
2584
+ const struct_size = 280;
2585
+ let pos = 0;
2586
+ const off = FS.llseek(stream, 0, 1);
2587
+ const startIdx = Math.floor(off / struct_size);
2588
+ const endIdx = Math.min(stream.getdents.length, startIdx + Math.floor(count / struct_size));
2589
+ for (var idx = startIdx; idx < endIdx; idx++) {
2590
+ var id;
2591
+ var type;
2592
+ const name = stream.getdents[idx];
2593
+ if (name === ".") {
2594
+ id = stream.node.id;
2595
+ type = 4;
2596
+ } else if (name === "..") {
2597
+ const lookup = FS.lookupPath(stream.path, { parent: true });
2598
+ id = lookup.node.id;
2599
+ type = 4;
2600
+ } else {
2601
+ var child;
2602
+ try {
2603
+ child = FS.lookupNode(stream.node, name);
2604
+ } catch (e) {
2605
+ if (e?.errno === 28) continue;
2606
+ throw e;
2607
+ }
2608
+ id = child.id;
2609
+ type = FS.isChrdev(child.mode) ? 2 : FS.isDir(child.mode) ? 4 : FS.isLink(child.mode) ? 10 : 8;
2610
+ }
2611
+ HEAP64[dirp + pos >>> 3 >>> 0] = BigInt(id);
2612
+ HEAP64[dirp + pos + 8 >>> 3 >>> 0] = BigInt((idx + 1) * struct_size);
2613
+ HEAP16[dirp + pos + 16 >>> 1 >>> 0] = 280;
2614
+ HEAP8[dirp + pos + 18 >>> 0] = type;
2615
+ stringToUTF8(name, dirp + pos + 19, 256);
2616
+ pos += struct_size;
2617
+ }
2618
+ FS.llseek(stream, idx * struct_size, 0);
2619
+ return pos;
2620
+ } catch (e) {
2621
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2622
+ return -e.errno;
2623
+ }
2624
+ }
2625
+ function ___syscall_ioctl(fd, op, varargs) {
2626
+ varargs >>>= 0;
2627
+ SYSCALLS.varargs = varargs;
2628
+ try {
2629
+ const stream = SYSCALLS.getStreamFromFD(fd);
2630
+ switch (op) {
2631
+ case 21509: {
2632
+ if (!stream.tty) return -59;
2633
+ return 0;
2634
+ }
2635
+ case 21505: {
2636
+ if (!stream.tty) return -59;
2637
+ if (stream.tty.ops.ioctl_tcgets) {
2638
+ const termios = stream.tty.ops.ioctl_tcgets(stream);
2639
+ var argp = syscallGetVarargP();
2640
+ HEAP32[argp >>> 2 >>> 0] = termios.c_iflag || 0;
2641
+ HEAP32[argp + 4 >>> 2 >>> 0] = termios.c_oflag || 0;
2642
+ HEAP32[argp + 8 >>> 2 >>> 0] = termios.c_cflag || 0;
2643
+ HEAP32[argp + 12 >>> 2 >>> 0] = termios.c_lflag || 0;
2644
+ for (var i = 0; i < 32; i++) HEAP8[argp + i + 17 >>> 0] = termios.c_cc[i] || 0;
2645
+ return 0;
2646
+ }
2647
+ return 0;
2648
+ }
2649
+ case 21510:
2650
+ case 21511:
2651
+ case 21512: {
2652
+ if (!stream.tty) return -59;
2653
+ return 0;
2654
+ }
2655
+ case 21506:
2656
+ case 21507:
2657
+ case 21508: {
2658
+ if (!stream.tty) return -59;
2659
+ if (stream.tty.ops.ioctl_tcsets) {
2660
+ var argp = syscallGetVarargP();
2661
+ const c_iflag = HEAP32[argp >>> 2 >>> 0];
2662
+ const c_oflag = HEAP32[argp + 4 >>> 2 >>> 0];
2663
+ const c_cflag = HEAP32[argp + 8 >>> 2 >>> 0];
2664
+ const c_lflag = HEAP32[argp + 12 >>> 2 >>> 0];
2665
+ const c_cc = [];
2666
+ for (var i = 0; i < 32; i++) c_cc.push(HEAP8[argp + i + 17 >>> 0]);
2667
+ return stream.tty.ops.ioctl_tcsets(stream.tty, op, {
2668
+ c_iflag,
2669
+ c_oflag,
2670
+ c_cflag,
2671
+ c_lflag,
2672
+ c_cc
2673
+ });
2674
+ }
2675
+ return 0;
2676
+ }
2677
+ case 21519: {
2678
+ if (!stream.tty) return -59;
2679
+ var argp = syscallGetVarargP();
2680
+ HEAP32[argp >>> 2 >>> 0] = 0;
2681
+ return 0;
2682
+ }
2683
+ case 21520: {
2684
+ if (!stream.tty) return -59;
2685
+ return -28;
2686
+ }
2687
+ case 21537:
2688
+ case 21531: {
2689
+ var argp = syscallGetVarargP();
2690
+ return FS.ioctl(stream, op, argp);
2691
+ }
2692
+ case 21523: {
2693
+ if (!stream.tty) return -59;
2694
+ if (stream.tty.ops.ioctl_tiocgwinsz) {
2695
+ const winsize = stream.tty.ops.ioctl_tiocgwinsz(stream.tty);
2696
+ var argp = syscallGetVarargP();
2697
+ HEAP16[argp >>> 1 >>> 0] = winsize[0];
2698
+ HEAP16[argp + 2 >>> 1 >>> 0] = winsize[1];
2699
+ }
2700
+ return 0;
2701
+ }
2702
+ case 21524: {
2703
+ if (!stream.tty) return -59;
2704
+ return 0;
2705
+ }
2706
+ case 21515: {
2707
+ if (!stream.tty) return -59;
2708
+ return 0;
2709
+ }
2710
+ default: return -28;
2711
+ }
2712
+ } catch (e) {
2713
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2714
+ return -e.errno;
2715
+ }
2716
+ }
2717
+ function ___syscall_lstat64(path, buf) {
2718
+ path >>>= 0;
2719
+ buf >>>= 0;
2720
+ try {
2721
+ path = SYSCALLS.getStr(path);
2722
+ return SYSCALLS.writeStat(buf, FS.lstat(path));
2723
+ } catch (e) {
2724
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2725
+ return -e.errno;
2726
+ }
2727
+ }
2728
+ function ___syscall_mkdirat(dirfd, path, mode) {
2729
+ path >>>= 0;
2730
+ try {
2731
+ path = SYSCALLS.getStr(path);
2732
+ path = SYSCALLS.calculateAt(dirfd, path);
2733
+ FS.mkdir(path, mode, 0);
2734
+ return 0;
2735
+ } catch (e) {
2736
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2737
+ return -e.errno;
2738
+ }
2739
+ }
2740
+ function ___syscall_newfstatat(dirfd, path, buf, flags) {
2741
+ path >>>= 0;
2742
+ buf >>>= 0;
2743
+ try {
2744
+ path = SYSCALLS.getStr(path);
2745
+ const nofollow = flags & 256;
2746
+ const allowEmpty = flags & 4096;
2747
+ flags = flags & -6401;
2748
+ path = SYSCALLS.calculateAt(dirfd, path, allowEmpty);
2749
+ return SYSCALLS.writeStat(buf, nofollow ? FS.lstat(path) : FS.stat(path));
2750
+ } catch (e) {
2751
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2752
+ return -e.errno;
2753
+ }
2754
+ }
2755
+ function ___syscall_openat(dirfd, path, flags, varargs) {
2756
+ path >>>= 0;
2757
+ varargs >>>= 0;
2758
+ SYSCALLS.varargs = varargs;
2759
+ try {
2760
+ path = SYSCALLS.getStr(path);
2761
+ path = SYSCALLS.calculateAt(dirfd, path);
2762
+ const mode = varargs ? syscallGetVarargI() : 0;
2763
+ return FS.open(path, flags, mode).fd;
2764
+ } catch (e) {
2765
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2766
+ return -e.errno;
2767
+ }
2768
+ }
2769
+ function ___syscall_readlinkat(dirfd, path, buf, bufsize) {
2770
+ path >>>= 0;
2771
+ buf >>>= 0;
2772
+ bufsize >>>= 0;
2773
+ try {
2774
+ path = SYSCALLS.getStr(path);
2775
+ path = SYSCALLS.calculateAt(dirfd, path);
2776
+ if (bufsize <= 0) return -28;
2777
+ const ret = FS.readlink(path);
2778
+ const len = Math.min(bufsize, lengthBytesUTF8(ret));
2779
+ const endChar = HEAP8[buf + len >>> 0];
2780
+ stringToUTF8(ret, buf, bufsize + 1);
2781
+ HEAP8[buf + len >>> 0] = endChar;
2782
+ return len;
2783
+ } catch (e) {
2784
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2785
+ return -e.errno;
2786
+ }
2787
+ }
2788
+ function ___syscall_renameat(olddirfd, oldpath, newdirfd, newpath) {
2789
+ oldpath >>>= 0;
2790
+ newpath >>>= 0;
2791
+ try {
2792
+ oldpath = SYSCALLS.getStr(oldpath);
2793
+ newpath = SYSCALLS.getStr(newpath);
2794
+ oldpath = SYSCALLS.calculateAt(olddirfd, oldpath);
2795
+ newpath = SYSCALLS.calculateAt(newdirfd, newpath);
2796
+ FS.rename(oldpath, newpath);
2797
+ return 0;
2798
+ } catch (e) {
2799
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2800
+ return -e.errno;
2801
+ }
2802
+ }
2803
+ function ___syscall_rmdir(path) {
2804
+ path >>>= 0;
2805
+ try {
2806
+ path = SYSCALLS.getStr(path);
2807
+ FS.rmdir(path);
2808
+ return 0;
2809
+ } catch (e) {
2810
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2811
+ return -e.errno;
2812
+ }
2813
+ }
2814
+ function ___syscall_stat64(path, buf) {
2815
+ path >>>= 0;
2816
+ buf >>>= 0;
2817
+ try {
2818
+ path = SYSCALLS.getStr(path);
2819
+ return SYSCALLS.writeStat(buf, FS.stat(path));
2820
+ } catch (e) {
2821
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2822
+ return -e.errno;
2823
+ }
2824
+ }
2825
+ function ___syscall_truncate64(path, length) {
2826
+ path >>>= 0;
2827
+ length = bigintToI53Checked(length);
2828
+ try {
2829
+ if (isNaN(length)) return -61;
2830
+ path = SYSCALLS.getStr(path);
2831
+ FS.truncate(path, length);
2832
+ return 0;
2833
+ } catch (e) {
2834
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2835
+ return -e.errno;
2836
+ }
2837
+ }
2838
+ function ___syscall_unlinkat(dirfd, path, flags) {
2839
+ path >>>= 0;
2840
+ try {
2841
+ path = SYSCALLS.getStr(path);
2842
+ path = SYSCALLS.calculateAt(dirfd, path);
2843
+ if (!flags) FS.unlink(path);
2844
+ else if (flags === 512) FS.rmdir(path);
2845
+ else return -28;
2846
+ return 0;
2847
+ } catch (e) {
2848
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2849
+ return -e.errno;
2850
+ }
2851
+ }
2852
+ const __abort_js = () => abort("");
2853
+ let runtimeKeepaliveCounter = 0;
2854
+ const __emscripten_runtime_keepalive_clear = () => {
2855
+ noExitRuntime = false;
2856
+ runtimeKeepaliveCounter = 0;
2857
+ };
2858
+ const isLeapYear = (year) => year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
2859
+ const MONTH_DAYS_LEAP_CUMULATIVE = [
2860
+ 0,
2861
+ 31,
2862
+ 60,
2863
+ 91,
2864
+ 121,
2865
+ 152,
2866
+ 182,
2867
+ 213,
2868
+ 244,
2869
+ 274,
2870
+ 305,
2871
+ 335
2872
+ ];
2873
+ const MONTH_DAYS_REGULAR_CUMULATIVE = [
2874
+ 0,
2875
+ 31,
2876
+ 59,
2877
+ 90,
2878
+ 120,
2879
+ 151,
2880
+ 181,
2881
+ 212,
2882
+ 243,
2883
+ 273,
2884
+ 304,
2885
+ 334
2886
+ ];
2887
+ const ydayFromDate = (date) => {
2888
+ const leap = isLeapYear(date.getFullYear());
2889
+ const monthDaysCumulative = leap ? MONTH_DAYS_LEAP_CUMULATIVE : MONTH_DAYS_REGULAR_CUMULATIVE;
2890
+ const yday = monthDaysCumulative[date.getMonth()] + date.getDate() - 1;
2891
+ return yday;
2892
+ };
2893
+ function __localtime_js(time, tmPtr) {
2894
+ time = bigintToI53Checked(time);
2895
+ tmPtr >>>= 0;
2896
+ const date = new Date(time * 1e3);
2897
+ HEAP32[tmPtr >>> 2 >>> 0] = date.getSeconds();
2898
+ HEAP32[tmPtr + 4 >>> 2 >>> 0] = date.getMinutes();
2899
+ HEAP32[tmPtr + 8 >>> 2 >>> 0] = date.getHours();
2900
+ HEAP32[tmPtr + 12 >>> 2 >>> 0] = date.getDate();
2901
+ HEAP32[tmPtr + 16 >>> 2 >>> 0] = date.getMonth();
2902
+ HEAP32[tmPtr + 20 >>> 2 >>> 0] = date.getFullYear() - 1900;
2903
+ HEAP32[tmPtr + 24 >>> 2 >>> 0] = date.getDay();
2904
+ const yday = ydayFromDate(date) | 0;
2905
+ HEAP32[tmPtr + 28 >>> 2 >>> 0] = yday;
2906
+ HEAP32[tmPtr + 36 >>> 2 >>> 0] = -(date.getTimezoneOffset() * 60);
2907
+ const start = new Date(date.getFullYear(), 0, 1);
2908
+ const summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset();
2909
+ const winterOffset = start.getTimezoneOffset();
2910
+ const dst = (summerOffset != winterOffset && date.getTimezoneOffset() == Math.min(winterOffset, summerOffset)) | 0;
2911
+ HEAP32[tmPtr + 32 >>> 2 >>> 0] = dst;
2912
+ }
2913
+ function __mmap_js(len, prot, flags, fd, offset, allocated, addr) {
2914
+ len >>>= 0;
2915
+ offset = bigintToI53Checked(offset);
2916
+ allocated >>>= 0;
2917
+ addr >>>= 0;
2918
+ try {
2919
+ const stream = SYSCALLS.getStreamFromFD(fd);
2920
+ const res = FS.mmap(stream, len, offset, prot, flags);
2921
+ const ptr = res.ptr;
2922
+ HEAP32[allocated >>> 2 >>> 0] = res.allocated;
2923
+ HEAPU32[addr >>> 2 >>> 0] = ptr;
2924
+ return 0;
2925
+ } catch (e) {
2926
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2927
+ return -e.errno;
2928
+ }
2929
+ }
2930
+ function __munmap_js(addr, len, prot, flags, fd, offset) {
2931
+ addr >>>= 0;
2932
+ len >>>= 0;
2933
+ offset = bigintToI53Checked(offset);
2934
+ try {
2935
+ const stream = SYSCALLS.getStreamFromFD(fd);
2936
+ if (prot & 2) SYSCALLS.doMsync(addr, stream, len, flags, offset);
2937
+ } catch (e) {
2938
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
2939
+ return -e.errno;
2940
+ }
2941
+ }
2942
+ const timers = {};
2943
+ const handleException = (e) => {
2944
+ if (e instanceof ExitStatus || e == "unwind") return EXITSTATUS;
2945
+ quit_(1, e);
2946
+ };
2947
+ const keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0;
2948
+ const _proc_exit = (code) => {
2949
+ EXITSTATUS = code;
2950
+ if (!keepRuntimeAlive()) {
2951
+ Module.onExit?.(code);
2952
+ ABORT = true;
2953
+ }
2954
+ quit_(code, new ExitStatus(code));
2955
+ };
2956
+ const exitJS = (status, implicit) => {
2957
+ EXITSTATUS = status;
2958
+ _proc_exit(status);
2959
+ };
2960
+ const _exit = exitJS;
2961
+ const maybeExit = () => {
2962
+ if (!keepRuntimeAlive()) try {
2963
+ _exit(EXITSTATUS);
2964
+ } catch (e) {
2965
+ handleException(e);
2966
+ }
2967
+ };
2968
+ const callUserCallback = (func) => {
2969
+ if (ABORT) return;
2970
+ try {
2971
+ return func();
2972
+ } catch (e) {
2973
+ handleException(e);
2974
+ } finally {
2975
+ maybeExit();
2976
+ }
2977
+ };
2978
+ const _emscripten_get_now = () => performance.now();
2979
+ const __setitimer_js = (which, timeout_ms) => {
2980
+ if (timers[which]) {
2981
+ clearTimeout(timers[which].id);
2982
+ delete timers[which];
2983
+ }
2984
+ if (!timeout_ms) return 0;
2985
+ const id = setTimeout(() => {
2986
+ delete timers[which];
2987
+ callUserCallback(() => __emscripten_timeout(which, _emscripten_get_now()));
2988
+ }, timeout_ms);
2989
+ timers[which] = {
2990
+ id,
2991
+ timeout_ms
2992
+ };
2993
+ return 0;
2994
+ };
2995
+ const __tzset_js = function(timezone, daylight, std_name, dst_name) {
2996
+ timezone >>>= 0;
2997
+ daylight >>>= 0;
2998
+ std_name >>>= 0;
2999
+ dst_name >>>= 0;
3000
+ const currentYear = new Date().getFullYear();
3001
+ const winter = new Date(currentYear, 0, 1);
3002
+ const summer = new Date(currentYear, 6, 1);
3003
+ const winterOffset = winter.getTimezoneOffset();
3004
+ const summerOffset = summer.getTimezoneOffset();
3005
+ const stdTimezoneOffset = Math.max(winterOffset, summerOffset);
3006
+ HEAPU32[timezone >>> 2 >>> 0] = stdTimezoneOffset * 60;
3007
+ HEAP32[daylight >>> 2 >>> 0] = Number(winterOffset != summerOffset);
3008
+ const extractZone = (timezoneOffset) => {
3009
+ const sign = timezoneOffset >= 0 ? "-" : "+";
3010
+ const absOffset = Math.abs(timezoneOffset);
3011
+ const hours = String(Math.floor(absOffset / 60)).padStart(2, "0");
3012
+ const minutes = String(absOffset % 60).padStart(2, "0");
3013
+ return `UTC${sign}${hours}${minutes}`;
3014
+ };
3015
+ const winterName = extractZone(winterOffset);
3016
+ const summerName = extractZone(summerOffset);
3017
+ if (summerOffset < winterOffset) {
3018
+ stringToUTF8(winterName, std_name, 17);
3019
+ stringToUTF8(summerName, dst_name, 17);
3020
+ } else {
3021
+ stringToUTF8(winterName, dst_name, 17);
3022
+ stringToUTF8(summerName, std_name, 17);
3023
+ }
3024
+ };
3025
+ const _emscripten_date_now = () => Date.now();
3026
+ const nowIsMonotonic = 1;
3027
+ const checkWasiClock = (clock_id) => clock_id >= 0 && clock_id <= 3;
3028
+ function _clock_time_get(clk_id, ignored_precision, ptime) {
3029
+ ignored_precision = bigintToI53Checked(ignored_precision);
3030
+ ptime >>>= 0;
3031
+ if (!checkWasiClock(clk_id)) return 28;
3032
+ let now;
3033
+ if (clk_id === 0) now = _emscripten_date_now();
3034
+ else if (nowIsMonotonic) now = _emscripten_get_now();
3035
+ else return 52;
3036
+ const nsec = Math.round(now * 1e3 * 1e3);
3037
+ HEAP64[ptime >>> 3 >>> 0] = BigInt(nsec);
3038
+ return 0;
3039
+ }
3040
+ const getHeapMax = () => 4294901760;
3041
+ const growMemory = (size) => {
3042
+ const oldHeapSize = wasmMemory.buffer.byteLength;
3043
+ const pages = (size - oldHeapSize + 65535) / 65536 | 0;
3044
+ try {
3045
+ wasmMemory.grow(pages);
3046
+ updateMemoryViews();
3047
+ return 1;
3048
+ } catch (e) {}
3049
+ };
3050
+ function _emscripten_resize_heap(requestedSize) {
3051
+ requestedSize >>>= 0;
3052
+ const oldSize = HEAPU8.length;
3053
+ const maxHeapSize = getHeapMax();
3054
+ if (requestedSize > maxHeapSize) return false;
3055
+ for (let cutDown = 1; cutDown <= 4; cutDown *= 2) {
3056
+ let overGrownHeapSize = oldSize * (1 + .2 / cutDown);
3057
+ overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296);
3058
+ const newSize = Math.min(maxHeapSize, alignMemory(Math.max(requestedSize, overGrownHeapSize), 65536));
3059
+ const replacement = growMemory(newSize);
3060
+ if (replacement) return true;
3061
+ }
3062
+ return false;
3063
+ }
3064
+ const ENV = {};
3065
+ const getExecutableName = () => thisProgram || "./this.program";
3066
+ const getEnvStrings = () => {
3067
+ if (!getEnvStrings.strings) {
3068
+ const lang = `${(globalThis.navigator?.language ?? "C").replace("-", "_")}.UTF-8`;
3069
+ const env = {
3070
+ USER: "web_user",
3071
+ LOGNAME: "web_user",
3072
+ PATH: "/",
3073
+ PWD: "/",
3074
+ HOME: "/home/web_user",
3075
+ LANG: lang,
3076
+ _: getExecutableName()
3077
+ };
3078
+ for (var x in ENV) if (ENV[x] === void 0) delete env[x];
3079
+ else env[x] = ENV[x];
3080
+ const strings = [];
3081
+ for (var x in env) strings.push(`${x}=${env[x]}`);
3082
+ getEnvStrings.strings = strings;
3083
+ }
3084
+ return getEnvStrings.strings;
3085
+ };
3086
+ function _environ_get(__environ, environ_buf) {
3087
+ __environ >>>= 0;
3088
+ environ_buf >>>= 0;
3089
+ let bufSize = 0;
3090
+ let envp = 0;
3091
+ for (const string of getEnvStrings()) {
3092
+ const ptr = environ_buf + bufSize;
3093
+ HEAPU32[__environ + envp >>> 2 >>> 0] = ptr;
3094
+ bufSize += stringToUTF8(string, ptr, Infinity) + 1;
3095
+ envp += 4;
3096
+ }
3097
+ return 0;
3098
+ }
3099
+ function _environ_sizes_get(penviron_count, penviron_buf_size) {
3100
+ penviron_count >>>= 0;
3101
+ penviron_buf_size >>>= 0;
3102
+ const strings = getEnvStrings();
3103
+ HEAPU32[penviron_count >>> 2 >>> 0] = strings.length;
3104
+ let bufSize = 0;
3105
+ for (const string of strings) bufSize += lengthBytesUTF8(string) + 1;
3106
+ HEAPU32[penviron_buf_size >>> 2 >>> 0] = bufSize;
3107
+ return 0;
3108
+ }
3109
+ function _fd_close(fd) {
3110
+ try {
3111
+ const stream = SYSCALLS.getStreamFromFD(fd);
3112
+ FS.close(stream);
3113
+ return 0;
3114
+ } catch (e) {
3115
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
3116
+ return e.errno;
3117
+ }
3118
+ }
3119
+ function _fd_fdstat_get(fd, pbuf) {
3120
+ pbuf >>>= 0;
3121
+ try {
3122
+ const rightsBase = 0;
3123
+ const rightsInheriting = 0;
3124
+ const flags = 0;
3125
+ {
3126
+ const stream = SYSCALLS.getStreamFromFD(fd);
3127
+ var type = stream.tty ? 2 : FS.isDir(stream.mode) ? 3 : FS.isLink(stream.mode) ? 7 : 4;
3128
+ }
3129
+ HEAP8[pbuf >>> 0] = type;
3130
+ HEAP16[pbuf + 2 >>> 1 >>> 0] = flags;
3131
+ HEAP64[pbuf + 8 >>> 3 >>> 0] = BigInt(rightsBase);
3132
+ HEAP64[pbuf + 16 >>> 3 >>> 0] = BigInt(rightsInheriting);
3133
+ return 0;
3134
+ } catch (e) {
3135
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
3136
+ return e.errno;
3137
+ }
3138
+ }
3139
+ const doReadv = (stream, iov, iovcnt, offset) => {
3140
+ let ret = 0;
3141
+ for (let i = 0; i < iovcnt; i++) {
3142
+ const ptr = HEAPU32[iov >>> 2 >>> 0];
3143
+ const len = HEAPU32[iov + 4 >>> 2 >>> 0];
3144
+ iov += 8;
3145
+ const curr = FS.read(stream, HEAP8, ptr, len, offset);
3146
+ if (curr < 0) return -1;
3147
+ ret += curr;
3148
+ if (curr < len) break;
3149
+ if (typeof offset != "undefined") offset += curr;
3150
+ }
3151
+ return ret;
3152
+ };
3153
+ function _fd_pread(fd, iov, iovcnt, offset, pnum) {
3154
+ iov >>>= 0;
3155
+ iovcnt >>>= 0;
3156
+ offset = bigintToI53Checked(offset);
3157
+ pnum >>>= 0;
3158
+ try {
3159
+ if (isNaN(offset)) return 61;
3160
+ const stream = SYSCALLS.getStreamFromFD(fd);
3161
+ const num = doReadv(stream, iov, iovcnt, offset);
3162
+ HEAPU32[pnum >>> 2 >>> 0] = num;
3163
+ return 0;
3164
+ } catch (e) {
3165
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
3166
+ return e.errno;
3167
+ }
3168
+ }
3169
+ function _fd_read(fd, iov, iovcnt, pnum) {
3170
+ iov >>>= 0;
3171
+ iovcnt >>>= 0;
3172
+ pnum >>>= 0;
3173
+ try {
3174
+ const stream = SYSCALLS.getStreamFromFD(fd);
3175
+ const num = doReadv(stream, iov, iovcnt);
3176
+ HEAPU32[pnum >>> 2 >>> 0] = num;
3177
+ return 0;
3178
+ } catch (e) {
3179
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
3180
+ return e.errno;
3181
+ }
3182
+ }
3183
+ function _fd_seek(fd, offset, whence, newOffset) {
3184
+ offset = bigintToI53Checked(offset);
3185
+ newOffset >>>= 0;
3186
+ try {
3187
+ if (isNaN(offset)) return 61;
3188
+ const stream = SYSCALLS.getStreamFromFD(fd);
3189
+ FS.llseek(stream, offset, whence);
3190
+ HEAP64[newOffset >>> 3 >>> 0] = BigInt(stream.position);
3191
+ if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null;
3192
+ return 0;
3193
+ } catch (e) {
3194
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
3195
+ return e.errno;
3196
+ }
3197
+ }
3198
+ const doWritev = (stream, iov, iovcnt, offset) => {
3199
+ let ret = 0;
3200
+ for (let i = 0; i < iovcnt; i++) {
3201
+ const ptr = HEAPU32[iov >>> 2 >>> 0];
3202
+ const len = HEAPU32[iov + 4 >>> 2 >>> 0];
3203
+ iov += 8;
3204
+ const curr = FS.write(stream, HEAP8, ptr, len, offset);
3205
+ if (curr < 0) return -1;
3206
+ ret += curr;
3207
+ if (curr < len) break;
3208
+ if (typeof offset != "undefined") offset += curr;
3209
+ }
3210
+ return ret;
3211
+ };
3212
+ function _fd_write(fd, iov, iovcnt, pnum) {
3213
+ iov >>>= 0;
3214
+ iovcnt >>>= 0;
3215
+ pnum >>>= 0;
3216
+ try {
3217
+ const stream = SYSCALLS.getStreamFromFD(fd);
3218
+ const num = doWritev(stream, iov, iovcnt);
3219
+ HEAPU32[pnum >>> 2 >>> 0] = num;
3220
+ return 0;
3221
+ } catch (e) {
3222
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
3223
+ return e.errno;
3224
+ }
3225
+ }
3226
+ function _random_get(buffer, size) {
3227
+ buffer >>>= 0;
3228
+ size >>>= 0;
3229
+ try {
3230
+ randomFill(HEAPU8.subarray(buffer >>> 0, buffer + size >>> 0));
3231
+ return 0;
3232
+ } catch (e) {
3233
+ if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e;
3234
+ return e.errno;
3235
+ }
3236
+ }
3237
+ const getCFunc = (ident) => {
3238
+ const func = Module[`_${ident}`];
3239
+ return func;
3240
+ };
3241
+ const writeArrayToMemory = (array, buffer) => {
3242
+ HEAP8.set(array, buffer >>> 0);
3243
+ };
3244
+ const stackAlloc = (sz) => __emscripten_stack_alloc(sz);
3245
+ const stringToUTF8OnStack = (str) => {
3246
+ const size = lengthBytesUTF8(str) + 1;
3247
+ const ret = stackAlloc(size);
3248
+ stringToUTF8(str, ret, size);
3249
+ return ret;
3250
+ };
3251
+ const stackSave = () => _emscripten_stack_get_current();
3252
+ const stackRestore = (val) => __emscripten_stack_restore(val);
3253
+ const ccall = (ident, returnType, argTypes, args, opts) => {
3254
+ const toC = {
3255
+ string: (str) => {
3256
+ let ret$1 = 0;
3257
+ if (str !== null && str !== void 0 && str !== 0) ret$1 = stringToUTF8OnStack(str);
3258
+ return ret$1;
3259
+ },
3260
+ array: (arr) => {
3261
+ const ret$1 = stackAlloc(arr.length);
3262
+ writeArrayToMemory(arr, ret$1);
3263
+ return ret$1;
3264
+ }
3265
+ };
3266
+ function convertReturnValue(ret$1) {
3267
+ if (returnType === "string") return UTF8ToString(ret$1);
3268
+ if (returnType === "pointer") return ret$1 >>> 0;
3269
+ if (returnType === "boolean") return Boolean(ret$1);
3270
+ return ret$1;
3271
+ }
3272
+ const func = getCFunc(ident);
3273
+ const cArgs = [];
3274
+ let stack = 0;
3275
+ if (args) for (let i = 0; i < args.length; i++) {
3276
+ const converter = toC[argTypes[i]];
3277
+ if (converter) {
3278
+ if (stack === 0) stack = stackSave();
3279
+ cArgs[i] = converter(args[i]);
3280
+ } else cArgs[i] = args[i];
3281
+ }
3282
+ let ret = func(...cArgs);
3283
+ function onDone(ret$1) {
3284
+ if (stack !== 0) stackRestore(stack);
3285
+ return convertReturnValue(ret$1);
3286
+ }
3287
+ ret = onDone(ret);
3288
+ return ret;
3289
+ };
3290
+ const FS_createPath = (...args) => FS.createPath(...args);
3291
+ const FS_unlink = (...args) => FS.unlink(...args);
3292
+ const FS_createLazyFile = (...args) => FS.createLazyFile(...args);
3293
+ const FS_createDevice = (...args) => FS.createDevice(...args);
3294
+ FS.createPreloadedFile = FS_createPreloadedFile;
3295
+ FS.preloadFile = FS_preloadFile;
3296
+ FS.staticInit();
3297
+ {
3298
+ if (Module.noExitRuntime) noExitRuntime = Module.noExitRuntime;
3299
+ if (Module.preloadPlugins) preloadPlugins = Module.preloadPlugins;
3300
+ if (Module.print) out = Module.print;
3301
+ if (Module.printErr) err = Module.printErr;
3302
+ if (Module.wasmBinary) wasmBinary = Module.wasmBinary;
3303
+ if (Module.arguments) arguments_ = Module.arguments;
3304
+ if (Module.thisProgram) thisProgram = Module.thisProgram;
3305
+ if (Module.preInit) {
3306
+ if (typeof Module.preInit == "function") Module.preInit = [Module.preInit];
3307
+ while (Module.preInit.length > 0) Module.preInit.shift()();
3308
+ }
3309
+ }
3310
+ Module.addRunDependency = addRunDependency;
3311
+ Module.removeRunDependency = removeRunDependency;
3312
+ Module.ccall = ccall;
3313
+ Module.FS_preloadFile = FS_preloadFile;
3314
+ Module.FS_unlink = FS_unlink;
3315
+ Module.FS_createPath = FS_createPath;
3316
+ Module.FS_createDevice = FS_createDevice;
3317
+ Module.FS = FS;
3318
+ Module.FS_createDataFile = FS_createDataFile;
3319
+ Module.FS_createLazyFile = FS_createLazyFile;
3320
+ let _free, _malloc, _rime_wasm_init, _rime_wasm_process_input, _rime_wasm_pick_candidate, _rime_wasm_flip_page, _rime_wasm_clear_input, _rime_wasm_set_option, _rime_wasm_get_version, _rime_wasm_destroy, _emscripten_builtin_memalign, __emscripten_timeout, ___trap, __emscripten_stack_restore, __emscripten_stack_alloc, _emscripten_stack_get_current, memory, __indirect_function_table, wasmMemory;
3321
+ function assignWasmExports(wasmExports$1) {
3322
+ _free = Module._free = wasmExports$1.R;
3323
+ _malloc = Module._malloc = wasmExports$1.S;
3324
+ _rime_wasm_init = Module._rime_wasm_init = wasmExports$1.T;
3325
+ _rime_wasm_process_input = Module._rime_wasm_process_input = wasmExports$1.U;
3326
+ _rime_wasm_pick_candidate = Module._rime_wasm_pick_candidate = wasmExports$1.V;
3327
+ _rime_wasm_flip_page = Module._rime_wasm_flip_page = wasmExports$1.W;
3328
+ _rime_wasm_clear_input = Module._rime_wasm_clear_input = wasmExports$1.X;
3329
+ _rime_wasm_set_option = Module._rime_wasm_set_option = wasmExports$1.Y;
3330
+ _rime_wasm_get_version = Module._rime_wasm_get_version = wasmExports$1.Z;
3331
+ _rime_wasm_destroy = Module._rime_wasm_destroy = wasmExports$1._;
3332
+ _emscripten_builtin_memalign = wasmExports$1.$;
3333
+ __emscripten_timeout = wasmExports$1.aa;
3334
+ ___trap = wasmExports$1.ba;
3335
+ __emscripten_stack_restore = wasmExports$1.ca;
3336
+ __emscripten_stack_alloc = wasmExports$1.da;
3337
+ _emscripten_stack_get_current = wasmExports$1.ea;
3338
+ memory = wasmMemory = wasmExports$1.P;
3339
+ __indirect_function_table = wasmExports$1.__indirect_function_table;
3340
+ }
3341
+ var wasmImports = {
3342
+ r: ___syscall_chmod,
3343
+ k: ___syscall_faccessat,
3344
+ s: ___syscall_fchmod,
3345
+ c: ___syscall_fcntl64,
3346
+ j: ___syscall_fdatasync,
3347
+ N: ___syscall_fstat64,
3348
+ q: ___syscall_ftruncate64,
3349
+ u: ___syscall_getcwd,
3350
+ A: ___syscall_getdents64,
3351
+ O: ___syscall_ioctl,
3352
+ L: ___syscall_lstat64,
3353
+ G: ___syscall_mkdirat,
3354
+ K: ___syscall_newfstatat,
3355
+ d: ___syscall_openat,
3356
+ v: ___syscall_readlinkat,
3357
+ z: ___syscall_renameat,
3358
+ i: ___syscall_rmdir,
3359
+ M: ___syscall_stat64,
3360
+ t: ___syscall_truncate64,
3361
+ h: ___syscall_unlinkat,
3362
+ l: __abort_js,
3363
+ n: __emscripten_runtime_keepalive_clear,
3364
+ E: __localtime_js,
3365
+ C: __mmap_js,
3366
+ D: __munmap_js,
3367
+ o: __setitimer_js,
3368
+ F: __tzset_js,
3369
+ w: _clock_time_get,
3370
+ e: _emscripten_date_now,
3371
+ b: _emscripten_get_now,
3372
+ x: _emscripten_resize_heap,
3373
+ I: _environ_get,
3374
+ J: _environ_sizes_get,
3375
+ a: _fd_close,
3376
+ y: _fd_fdstat_get,
3377
+ B: _fd_pread,
3378
+ g: _fd_read,
3379
+ H: _fd_seek,
3380
+ f: _fd_write,
3381
+ m: _proc_exit,
3382
+ p: _random_get
3383
+ };
3384
+ function applySignatureConversions(wasmExports$1) {
3385
+ wasmExports$1 = Object.assign({}, wasmExports$1);
3386
+ const makeWrapper_pp = (f) => (a0) => f(a0) >>> 0;
3387
+ const makeWrapper_ppp = (f) => (a0, a1) => f(a0, a1) >>> 0;
3388
+ const makeWrapper_p = (f) => () => f() >>> 0;
3389
+ wasmExports$1.S = makeWrapper_pp(wasmExports$1.S);
3390
+ wasmExports$1.$ = makeWrapper_ppp(wasmExports$1.$);
3391
+ wasmExports$1.da = makeWrapper_pp(wasmExports$1.da);
3392
+ wasmExports$1.ea = makeWrapper_p(wasmExports$1.ea);
3393
+ return wasmExports$1;
3394
+ }
3395
+ function run() {
3396
+ if (runDependencies > 0) {
3397
+ dependenciesFulfilled = run;
3398
+ return;
3399
+ }
3400
+ preRun();
3401
+ if (runDependencies > 0) {
3402
+ dependenciesFulfilled = run;
3403
+ return;
3404
+ }
3405
+ function doRun() {
3406
+ Module.calledRun = true;
3407
+ if (ABORT) return;
3408
+ initRuntime();
3409
+ readyPromiseResolve?.(Module);
3410
+ Module.onRuntimeInitialized?.();
3411
+ postRun();
3412
+ }
3413
+ if (Module.setStatus) {
3414
+ Module.setStatus("Running...");
3415
+ setTimeout(() => {
3416
+ setTimeout(() => Module.setStatus(""), 1);
3417
+ doRun();
3418
+ }, 1);
3419
+ } else doRun();
3420
+ }
3421
+ let wasmExports;
3422
+ wasmExports = await createWasm();
3423
+ run();
3424
+ if (runtimeInitialized) moduleRtn = Module;
3425
+ else moduleRtn = new Promise((resolve, reject) => {
3426
+ readyPromiseResolve = resolve;
3427
+ readyPromiseReject = reject;
3428
+ });
3429
+ return moduleRtn;
3430
+ }
3431
+ var rime_api_default = createRimeModule;
3432
+
3433
+ //#endregion
3434
+ //#region src/rime.ts
3435
+ function syncfs(module, populate) {
3436
+ return new Promise((resolve, reject) => {
3437
+ module.FS.syncfs(populate, (err) => {
3438
+ if (err) reject(err);
3439
+ else resolve();
3440
+ });
3441
+ });
3442
+ }
3443
+ async function createRimeEngine(options = {}) {
3444
+ const wasmDir = options.wasmDir ?? ".";
3445
+ const Module = await rime_api_default({ locateFile(file) {
3446
+ return `${wasmDir}/${file}`;
3447
+ } });
3448
+ try {
3449
+ Module.FS.mkdir("/rime_user");
3450
+ } catch {}
3451
+ Module.FS.mount(Module.FS.filesystems.IDBFS, {}, "/rime_user");
3452
+ await syncfs(Module, true);
3453
+ try {
3454
+ Module.FS.mkdir("/rime");
3455
+ } catch {}
3456
+ try {
3457
+ Module.FS.mkdir("/rime/build");
3458
+ } catch {}
3459
+ const allDataFiles = options.dataFiles ?? [
3460
+ "default.yaml",
3461
+ "luna_pinyin.schema.yaml",
3462
+ "luna_pinyin.table.bin",
3463
+ "luna_pinyin.prism.bin",
3464
+ "luna_pinyin.reverse.bin"
3465
+ ];
3466
+ await Promise.all(allDataFiles.map(async (file) => {
3467
+ const url = `${wasmDir}/${file}`;
3468
+ const resp = await fetch(url);
3469
+ if (!resp.ok) throw new Error(`Failed to fetch ${url}: ${resp.status}`);
3470
+ const data = new Uint8Array(await resp.arrayBuffer());
3471
+ Module.FS.writeFile(`/rime/build/${file}`, data);
3472
+ }));
3473
+ const rc = Module.ccall("rime_wasm_init", "number", [], []);
3474
+ if (rc !== 0) throw new Error(`rime_wasm_init failed with code ${rc}`);
3475
+ await syncfs(Module, false);
3476
+ let destroyed = false;
3477
+ function callJson(fn, argTypes, args) {
3478
+ if (destroyed) throw new Error("Engine is destroyed");
3479
+ const json = Module.ccall(fn, "string", argTypes, args);
3480
+ return JSON.parse(json);
3481
+ }
3482
+ const engine = {
3483
+ processInput(keys) {
3484
+ return callJson("rime_wasm_process_input", ["string"], [keys]);
3485
+ },
3486
+ pickCandidate(index) {
3487
+ const state = callJson("rime_wasm_pick_candidate", ["number"], [index]);
3488
+ syncfs(Module, false).catch(() => {});
3489
+ return state;
3490
+ },
3491
+ flipPage(forward) {
3492
+ return callJson("rime_wasm_flip_page", ["number"], [forward ? 0 : 1]);
3493
+ },
3494
+ clearInput() {
3495
+ if (destroyed) return;
3496
+ Module.ccall("rime_wasm_clear_input", null, [], []);
3497
+ },
3498
+ setOption(name, value) {
3499
+ if (destroyed) return;
3500
+ Module.ccall("rime_wasm_set_option", null, ["string", "number"], [name, value ? 1 : 0]);
3501
+ },
3502
+ getVersion() {
3503
+ if (destroyed) return "unknown";
3504
+ return Module.ccall("rime_wasm_get_version", "string", [], []);
3505
+ },
3506
+ destroy() {
3507
+ if (destroyed) return;
3508
+ destroyed = true;
3509
+ Module.ccall("rime_wasm_destroy", null, [], []);
3510
+ syncfs(Module, false).catch(() => {});
3511
+ }
3512
+ };
3513
+ return engine;
3514
+ }
3515
+
3516
+ //#endregion
3517
+ //#region src/index.ts
3518
+ /**
3519
+ * 创建基于 RIME WASM 的拼音引擎,实现 PinyinEngine 通用接口。
3520
+ * 内部处理分页逻辑,processInput 返回所有页的候选词集合。
3521
+ */
3522
+ var RimePinyinEngine = class {
3523
+ engine = null;
3524
+ prevRimeInput = "";
3525
+ initPromise = null;
3526
+ constructor(options = {}) {
3527
+ this.options = options;
3528
+ this.initialize();
3529
+ }
3530
+ async getEngine() {
3531
+ await this.initialize();
3532
+ return this.engine;
3533
+ }
3534
+ async initialize() {
3535
+ if (this.initPromise) return this.initPromise;
3536
+ this.initPromise = (async () => {
3537
+ this.engine = await createRimeEngine(this.options);
3538
+ this.engine.setOption("zh_simp", this.options.simplified ?? true);
3539
+ })();
3540
+ return this.initPromise;
3541
+ }
3542
+ async processInput(fullPinyin) {
3543
+ const engine = await this.getEngine();
3544
+ if (!fullPinyin) {
3545
+ engine.clearInput();
3546
+ this.prevRimeInput = "";
3547
+ return null;
3548
+ }
3549
+ let state;
3550
+ if (fullPinyin.startsWith(this.prevRimeInput)) {
3551
+ const delta = fullPinyin.slice(this.prevRimeInput.length);
3552
+ state = engine.processInput(delta);
3553
+ } else {
3554
+ engine.clearInput();
3555
+ state = engine.processInput(fullPinyin);
3556
+ }
3557
+ this.prevRimeInput = fullPinyin;
3558
+ return state;
3559
+ }
3560
+ async pickCandidate(index) {
3561
+ const engine = await this.getEngine();
3562
+ return engine.pickCandidate(index);
3563
+ }
3564
+ async clearInput() {
3565
+ const engine = await this.getEngine();
3566
+ return engine.clearInput();
3567
+ }
3568
+ async setSimplified(simplified) {
3569
+ const engine = await this.getEngine();
3570
+ return engine.setOption("zh_simp", simplified);
3571
+ }
3572
+ async destroy() {
3573
+ const engine = await this.getEngine();
3574
+ return engine.destroy();
3575
+ }
3576
+ };
3577
+
3578
+ //#endregion
3579
+ export { RimePinyinEngine };
3580
+ //# sourceMappingURL=index.mjs.map