├── .gitignore
├── example
├── assets
│ ├── example.sqlite3
│ └── index.html
└── index.ts
├── external.d.ts
├── package-lock.json
├── package.json
├── readme.md
├── src
├── db.worker.ts
├── index.ts
├── ipfs.worker.ts
├── mutex.ts
└── sql.js
│ ├── .gitignore
│ ├── .npmignore
│ ├── sql-wasm-debug.js
│ ├── sql-wasm-debug.wasm
│ ├── sql-wasm.js
│ └── sql-wasm.wasm
├── tsconfig.json
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
--------------------------------------------------------------------------------
/example/assets/example.sqlite3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcliff/sqlite-ipfs/b5c9b397b0396181f3867a7eeaaf790e6a4f16b1/example/assets/example.sqlite3
--------------------------------------------------------------------------------
/example/assets/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Minimal sql.js-ipfs demo
4 |
5 | Hello World!
--------------------------------------------------------------------------------
/example/index.ts:
--------------------------------------------------------------------------------
1 | import { SqliteComlinkMod } from "../src/db.worker";
2 | import * as Comlink from "comlink";
3 | import {query} from "../src/index";
4 |
5 | // @ts-ignore we're in a module, and have access to import.meta.url
6 | const sqlJsURL = new URL("../src/sql.js/sql-wasm.wasm", import.meta.url).toString();
7 |
8 | // note: there's no good story around webpack/typescript/webworkers
9 | // so directly target the compiled file
10 | // TODO: fix this when possible.
11 | // const dbWorkerURL = new URL("db.worker", import.meta.url);
12 | const dbWorkerURL = "db.worker.js";
13 |
14 | // const ipfsWorkerURL = new URL("ipfs.worker", import.meta.url);
15 | const ipfsWorkerURL = "ipfs.worker.js";
16 |
17 | async function load() {
18 | // example.sqlite3
19 | // let path = "QmQRt5BRHAeBaspyEf4KG4cY9GdSmpisRfdJTi7SvPhBeY";
20 | // sample.sqlite3 @ 4kb page size
21 | // let path = "QmbcqJRH1rvFZtR1NBp5xqHTKz9brvdCRRMtiw6TVetwxa";
22 | // sample.sqlite3 @ 64kb page size
23 | // let ipfsPath = "QmZwoJuBtrvSNh6n5XmKoBCVf9Ny7mEGpuWh17JbnQedrw";
24 | // wdi.sqlite3 @ 64kb page size
25 | let ipfsPath = "Qme2jr3JG2CyZK2NJBzse7DjgZzktgbL1jxiJ73AxhuLNA";
26 |
27 | const dbManagerWorker: Worker = new Worker(dbWorkerURL);
28 | const dbManager = Comlink.wrap(dbManagerWorker);
29 |
30 | await dbManager.dummy();
31 |
32 | console.log("begin db worker spawn");
33 | const { db } = await dbManager.createDbWorker(
34 | sqlJsURL,
35 | ipfsWorkerURL,
36 | ipfsPath,
37 | );
38 | console.log("db worker created", db);
39 |
40 | const queryString1 = `select * from sqlite_master;`
41 | console.log(await query(db, queryString1));
42 |
43 | // exec(db, `select * from data where "Country Name" LIKE "%Africa%"`);
44 |
45 | // exec(db, `select count(id) from data`);
46 | }
47 |
48 | load();
--------------------------------------------------------------------------------
/external.d.ts:
--------------------------------------------------------------------------------
1 | declare module './sql.js/sql-wasm';
2 |
3 | declare module "json!*" {
4 | const value: any;
5 | export default value;
6 | }
7 |
8 | declare module '*.sqlite3' {
9 | const content: any;
10 | export default content;
11 | }
12 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sqlite-ipfs",
3 | "version": "1.0.0",
4 | "description": "sqlite on ipfs",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "rm -rf dist && ./node_modules/.bin/webpack --mode=production --config webpack.config",
8 | "dev": "./node_modules/.bin/webpack serve --mode=development --config webpack.config"
9 | },
10 | "author": "Henry Clifford",
11 | "license": "ISC",
12 | "dependencies": {
13 | "@babel/preset-typescript": "^7.16.7",
14 | "ipfs": "^0.62.0",
15 | "level-mem": "^6.0.1",
16 | "sql.js": "^1.6.2",
17 | "sql.js-httpvfs": "^0.8.11"
18 | },
19 | "devDependencies": {
20 | "@types/sql.js": "^1.4.3",
21 | "file-loader": "^6.2.0",
22 | "ts-loader": "^9.2.6",
23 | "typescript": "^4.5.4",
24 | "webpack": "^5.66.0",
25 | "webpack-cli": "^4.9.1",
26 | "webpack-dev-server": "^4.7.3",
27 | "node-polyfill-webpack-plugin": "^1.1.4"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # sql.js-ipfs
2 | ## [Demo](https://k51qzi5uqu5diy09qbtg7b3ma8n0cj4l05st37rza1bdoyrm3hw0wvzypt8n0l.ipns.dweb.link/)
3 |
4 | ## Inspiration / Deps
5 | Heavily inspired and uses code from [https://github.com/phiresky/sql.js-httpvfs](sql.js-httpvfs)
6 | Impossible without [sql.js](https://sql.js.org/#/)
7 |
8 | ## Usage
9 | ### Basic
10 | 1) `npm install`
11 | 2) `npm run dev`
12 | 3) **Using https** open your browser and navigate to the url given by webpack
13 | 4) Check the console
14 |
15 | ### With your own database
16 | 1) [Install IPFS](https://flyingzumwalt.gitbooks.io/decentralized-web-primer/content/install-ipfs/lessons/download-and-install.html)
17 | 2) Add your sqlite file ```ipfs add db.sqlite3```
18 | 3) Take the CID from the output and change ipfsPath in examples/index.ts
19 | 4) `npm run dev`
20 | 5) `Check the console`
21 |
22 | ## FAQ
23 | * **How does this work?** Your browser runs a wasm binary that contains the sqlite server & client. It reads blocks of data from a .sqlite file on ipfs and performs queries in your browser.
24 | * **Performance?** Table scans are very bad. The cross-worker communcation of [Atomics](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics) introduces heavy performance penalties too.
25 | * **Writes?** Certainly possible, but not implemented currently.
26 | * **What was the hardest part of the project?** Configuring webpack
27 | * **Is this blockchain? 🚀🚀🚀** It's not, but it is technically a distributed ledger, be sure anyone you give money too can explain the difference.
--------------------------------------------------------------------------------
/src/db.worker.ts:
--------------------------------------------------------------------------------
1 |
2 | import { Database } from "sql.js";
3 | import { ReaderComlinkMod } from "./ipfs.worker";
4 | import { lock, waitForLock } from "./mutex";
5 | import * as Comlink from "comlink";
6 | // @ts-ignore
7 | import initSqlJs from "./sql.js/sql-wasm";
8 |
9 | // exported for testing
10 | export async function createLazyFile(
11 | ipfsWorkerURL: string,
12 | fs: FileSystem,
13 | ipfsPath: string,
14 | ): Promise {
15 | console.log("createLazyFile called");
16 |
17 | console.time("ipfsWorker instantiation");
18 | const ipfsWorker: Worker = new Worker(ipfsWorkerURL);
19 | const ipfs = Comlink.wrap(ipfsWorker);
20 | // ipfs.dummy();
21 | await ipfs.boot();
22 | console.timeEnd("ipfsWorker instantiation");
23 |
24 | // @ts-ignore createFile does actually exist
25 | var node: FS.FSNode = fs.createFile("/", ipfsPath, {}, true, true);
26 |
27 | // consider making this lazy to avoid the network request at insantiation time
28 | // this is often a very long process for files recently uploaded to ipfs
29 | console.log("beginning stat");
30 | const statResult = await ipfs.stat(ipfsPath, {
31 | // speed things up by only pulling the size
32 | size: true
33 | });
34 | console.log(`${ipfsPath} statresult`, statResult);
35 |
36 | Object.defineProperties(node, {
37 | usedBytes: {
38 | get: function () { return statResult.size }
39 | }
40 | });
41 |
42 | // https://emscripten.org/docs/api_reference/Filesystem-API.html#FS.read
43 | // @ts-ignore strem_ops is a property of node
44 | node.stream_ops.read = function (
45 | _: { node: { path: string } },
46 | buffer: Uint8Array,
47 | // The offset within buffer to store the data.
48 | offset: number,
49 | // The length of data to write in buffer.
50 | length: number,
51 | // The offset within the stream to read. By default this is the stream’s current offset.
52 | position: number
53 | ) {
54 | // console.time("stream_ops.read");
55 |
56 | // our worker thread will write into this shared buffer
57 | const workerBuffer = new SharedArrayBuffer(length);
58 |
59 | // create a buffer large enough to hold one 32 bit integer
60 | const mu = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT);
61 | lock(mu);
62 |
63 | const readTimeout = 10000;
64 | // note: this is behind comlink and does not happen syncronously
65 | // we cannot await on it as `stream_ops.read` is a emscripten callback
66 | // that does not support async/await
67 | //
68 | // offset here is set to 0 as we instantiate a new buffer and pass it in
69 | ipfs.read(ipfsPath, workerBuffer, 0, length, position, mu, readTimeout);
70 |
71 | // this lock cannot be aquired until the previous lock is released
72 | // by `read` completing in a worker thread
73 | // if the read takes longer than readTimeout it will have failed
74 | const wait = waitForLock(mu, readTimeout);
75 | if (wait !== "ok") {
76 | throw new Error(`read timed out after ${readTimeout/1000}s`)
77 | }
78 |
79 | const uint8 = new Uint8Array(workerBuffer);
80 | buffer.set(uint8, offset);
81 |
82 | // console.timeEnd("stream_ops.read");
83 |
84 | return length;
85 | };
86 |
87 | return node;
88 | }
89 |
90 | export async function createDbWorker(
91 | sqlJsURL: string,
92 | asyncReaderURL: string,
93 | path: string,
94 | ): Promise<{ db: Database }> {
95 | console.info('beginning initSqlJs');
96 | const SQL = await initSqlJs({
97 | locateFile: (file: string) => {
98 | // sql.js.org is the original sql.js which is missing some extenions
99 | // return `https://sql.js.org/dist/${file}`;
100 |
101 | // phiresky.github.io is the fork we need
102 | // return 'https://phiresky.github.io/blog/sql-wasm.wasm';
103 |
104 | return sqlJsURL;
105 | }
106 | });
107 |
108 | // SQL.FS only exists in the sql.js fork we use, and not the official typings
109 | // createLazyFile spawns a long lived worker
110 | const ipfsFile = await createLazyFile(asyncReaderURL, SQL.FS, path);
111 | console.info("lazy ipfs file", ipfsFile);
112 |
113 | // use the same filename as
114 | const db: Database = new SQL.CustomDatabase(path);
115 |
116 | // verify page size and disable cache (since we hold everything in memory anyways)
117 | const pageSizeResp = await db.exec("pragma page_size; pragma cache_size=0");
118 | const pageSize = pageSizeResp[0].values[0][0];
119 | console.info(`page size ${pageSize}`);
120 |
121 | return Comlink.proxy({ db });
122 | }
123 |
124 |
125 | const mod = {
126 | createLazyFile: createLazyFile,
127 | createDbWorker: createDbWorker,
128 | dummy: function () {
129 | console.log("[dbworker]", "comlink works", Math.random());
130 | }
131 | }
132 | export type SqliteComlinkMod = typeof mod;
133 | Comlink.expose(mod);
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export type { Database, BindParams } from "sql.js";
2 | import { Database, BindParams, QueryExecResult } from "sql.js";
3 |
4 | export function toObjects(res: QueryExecResult[]): T[] {
5 | return res.flatMap(r => r.values.map((v) => {
6 | const o: any = {};
7 | for (let i = 0; i < r.columns.length; i++) {
8 | o[r.columns[i]] = v[i];
9 | }
10 | return o as T;
11 | }));
12 | }
13 |
14 | export async function query(db: Database, query: string, params?: BindParams): Promise {
15 | console.time(query);
16 | const result = await db.exec(query, params);
17 | console.timeEnd(query);
18 | return toObjects(result);
19 | }
--------------------------------------------------------------------------------
/src/ipfs.worker.ts:
--------------------------------------------------------------------------------
1 | import * as Comlink from "comlink";
2 | import { StatResult, StatOptions } from 'ipfs-core-types/src/files';
3 | import { create, IPFS } from "ipfs-core";
4 | import { Mutex, unlock } from "./mutex";
5 | import { createRepo } from "ipfs-repo";
6 | import { LevelDatastore } from "datastore-level";
7 | import { BlockstoreDatastoreAdapter } from "blockstore-datastore-adapter";
8 | // @ts-ignore
9 | import * as memstore from "level-mem";
10 |
11 | let ipfsConnection: IPFS;
12 |
13 | // https://github.com/ipfs-examples/js-ipfs-examples/blob/master/examples/custom-ipfs-repo/index.js
14 | const codecs = [
15 | require('@ipld/dag-pb'),
16 | require('@ipld/dag-cbor'),
17 | require('multiformats/codecs/raw')
18 | ].reduce((acc, curr) => {
19 | acc[curr.name] = curr
20 | acc[curr.code] = curr
21 |
22 | return acc
23 | }, {})
24 |
25 | // Support dag-pb and dag-cbor at a minimum
26 | const loadCodec = (nameOrCode: any) => {
27 | if (codecs[nameOrCode]) {
28 | return codecs[nameOrCode]
29 | }
30 |
31 | throw new Error(`Could not load codec for ${nameOrCode}`)
32 | }
33 |
34 | const boot = async function () {
35 | const repoPath = String(Math.random() + Date.now())
36 |
37 | const repo = createRepo(repoPath, loadCodec, {
38 | root: new LevelDatastore(repoPath, {
39 | prefix: '',
40 | version: 2,
41 | // note: the default repo uses LevelDatastore which is _incredibly_ slow
42 | // 30ms per read slow. Use an in-memory datastore instead.
43 | db: memstore
44 | }),
45 | blocks: new BlockstoreDatastoreAdapter(new LevelDatastore(`${repoPath}/blocks`, {
46 | prefix: '',
47 | version: 2,
48 | db: memstore
49 | })),
50 | datastore: new LevelDatastore(`${repoPath}/datastore`, {
51 | prefix: '',
52 | version: 2,
53 | db: memstore
54 | }),
55 | keys: new LevelDatastore(`${repoPath}/keys`, {
56 | prefix: '',
57 | version: 2,
58 | db: memstore
59 | }),
60 | pins: new LevelDatastore(`${repoPath}/pins`, {
61 | prefix: '',
62 | version: 2,
63 | db: memstore
64 | })
65 | });
66 |
67 | ipfsConnection = await create({
68 | repo: repo,
69 | init: { algorithm: 'Ed25519' },
70 | });
71 | }
72 |
73 | // reads the required bytes from ipfs into a buffer and unlocks the passed in mutex
74 | const read = async function (
75 | ipfsPath: string,
76 | buffer: SharedArrayBuffer,
77 | offset: number,
78 | length: number,
79 | position: number,
80 | // the mutex to unlock upon the operation completing
81 | mu: Mutex,
82 | timeout: number,
83 | ) {
84 | // console.log("read ipfs", ipfsPath, offset, length, position);
85 |
86 | const uint8 = new Uint8Array(buffer);
87 |
88 | // const timeLabel = `ipfs reading ${length} bytes`
89 | // console.time(timeLabel);
90 | let i = 0;
91 | for await (const chunk of ipfsConnection.files.read("/ipfs/" + ipfsPath, {
92 | offset: position,
93 | length: length,
94 | timeout: timeout
95 | })) {
96 | uint8.set(chunk, offset + i);
97 | i += chunk.length;
98 | }
99 | // console.timeEnd(timeLabel);
100 |
101 | unlock(mu);
102 | }
103 |
104 | const mod = {
105 | read: read,
106 | boot: boot,
107 | dummy: function () {
108 | console.log("[asyncreader]", "comlink works", Math.random());
109 | },
110 | stat: async function (path: string, options?: StatOptions): Promise {
111 | // note, stat doesn't support `withLocal` currently
112 | // there's no way to understand how much local storage is used
113 | // https://github.com/ipfs/js-ipfs/issues/2806
114 | return ipfsConnection.files.stat("/ipfs/" + path, options)
115 | }
116 | }
117 | export type ReaderComlinkMod = typeof mod;
118 | Comlink.expose(mod);
--------------------------------------------------------------------------------
/src/mutex.ts:
--------------------------------------------------------------------------------
1 | export type Mutex = SharedArrayBuffer
2 |
3 | const unlocked = 0
4 | const locked = 1
5 |
6 | export function unlock(m: Mutex) {
7 | const int32 = new Int32Array(m);
8 | const oldValue = Atomics.compareExchange(int32, 0, locked, unlocked);
9 | // if the mutex was locked then notify subscribers
10 | if(oldValue !== locked){
11 | throw new Error("already unlocked")
12 | }
13 | Atomics.notify(int32, 0);
14 | }
15 |
16 | // TODO: timeout doesn't account for retries
17 | export function lock(m: Mutex, timeout?: number): "ok" | "not-equal" | "timed-out" {
18 | const int32 = new Int32Array(m);
19 | for(;;){
20 | // sleep until the index is _not_ locked
21 | const wait = Atomics.wait(int32, 0, locked, timeout);
22 | const oldValue = Atomics.compareExchange(int32, 0, unlocked, locked);
23 | // if someone else aquired the lock, retry the operation
24 | if(oldValue === locked){
25 | continue;
26 | }
27 | return wait;
28 | }
29 | }
30 |
31 | export function waitForLock(m: Mutex, timeout?: number): "ok" | "not-equal" | "timed-out" {
32 | const int32 = new Int32Array(m);
33 | // sleep until the index is _not_ locked
34 | return Atomics.wait(int32, 0, locked, timeout);
35 | }
--------------------------------------------------------------------------------
/src/sql.js/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file
4 | !.gitignore
5 | !.npmignore
6 | !sql-wasm*
--------------------------------------------------------------------------------
/src/sql.js/.npmignore:
--------------------------------------------------------------------------------
1 | .gitignore
--------------------------------------------------------------------------------
/src/sql.js/sql-wasm-debug.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcliff/sqlite-ipfs/b5c9b397b0396181f3867a7eeaaf790e6a4f16b1/src/sql.js/sql-wasm-debug.wasm
--------------------------------------------------------------------------------
/src/sql.js/sql-wasm.js:
--------------------------------------------------------------------------------
1 |
2 | // We are modularizing this manually because the current modularize setting in Emscripten has some issues:
3 | // https://github.com/kripken/emscripten/issues/5820
4 | // In addition, When you use emcc's modularization, it still expects to export a global object called `Module`,
5 | // which is able to be used/called before the WASM is loaded.
6 | // The modularization below exports a promise that loads and resolves to the actual sql.js module.
7 | // That way, this module can't be used before the WASM is finished loading.
8 |
9 | // We are going to define a function that a user will call to start loading initializing our Sql.js library
10 | // However, that function might be called multiple times, and on subsequent calls, we don't actually want it to instantiate a new instance of the Module
11 | // Instead, we want to return the previously loaded module
12 |
13 | // TODO: Make this not declare a global if used in the browser
14 | var initSqlJsPromise = undefined;
15 |
16 | var initSqlJs = function (moduleConfig) {
17 |
18 | if (initSqlJsPromise){
19 | return initSqlJsPromise;
20 | }
21 | // If we're here, we've never called this function before
22 | initSqlJsPromise = new Promise(function (resolveModule, reject) {
23 |
24 | // We are modularizing this manually because the current modularize setting in Emscripten has some issues:
25 | // https://github.com/kripken/emscripten/issues/5820
26 |
27 | // The way to affect the loading of emcc compiled modules is to create a variable called `Module` and add
28 | // properties to it, like `preRun`, `postRun`, etc
29 | // We are using that to get notified when the WASM has finished loading.
30 | // Only then will we return our promise
31 |
32 | // If they passed in a moduleConfig object, use that
33 | // Otherwise, initialize Module to the empty object
34 | var Module = typeof moduleConfig !== 'undefined' ? moduleConfig : {};
35 |
36 | // EMCC only allows for a single onAbort function (not an array of functions)
37 | // So if the user defined their own onAbort function, we remember it and call it
38 | var originalOnAbortFunction = Module['onAbort'];
39 | Module['onAbort'] = function (errorThatCausedAbort) {
40 | reject(new Error(errorThatCausedAbort));
41 | if (originalOnAbortFunction){
42 | originalOnAbortFunction(errorThatCausedAbort);
43 | }
44 | };
45 |
46 | Module['postRun'] = Module['postRun'] || [];
47 | Module['postRun'].push(function () {
48 | // When Emscripted calls postRun, this promise resolves with the built Module
49 | resolveModule(Module);
50 | });
51 |
52 | // There is a section of code in the emcc-generated code below that looks like this:
53 | // (Note that this is lowercase `module`)
54 | // if (typeof module !== 'undefined') {
55 | // module['exports'] = Module;
56 | // }
57 | // When that runs, it's going to overwrite our own modularization export efforts in shell-post.js!
58 | // The only way to tell emcc not to emit it is to pass the MODULARIZE=1 or MODULARIZE_INSTANCE=1 flags,
59 | // but that carries with it additional unnecessary baggage/bugs we don't want either.
60 | // So, we have three options:
61 | // 1) We undefine `module`
62 | // 2) We remember what `module['exports']` was at the beginning of this function and we restore it later
63 | // 3) We write a script to remove those lines of code as part of the Make process.
64 | //
65 | // Since those are the only lines of code that care about module, we will undefine it. It's the most straightforward
66 | // of the options, and has the side effect of reducing emcc's efforts to modify the module if its output were to change in the future.
67 | // That's a nice side effect since we're handling the modularization efforts ourselves
68 | module = undefined;
69 |
70 | // The emcc-generated code and shell-post.js code goes below,
71 | // meaning that all of it runs inside of this promise. If anything throws an exception, our promise will abort
72 | var Module=typeof Module!=="undefined"?Module:{};var objAssign=Object.assign;null;Module["onRuntimeInitialized"]=function onRuntimeInitialized(){var apiTemp=stackAlloc(4);var cwrap=Module["cwrap"];var NULL=0;var SQLITE_OK=0;var SQLITE_ROW=100;var SQLITE_DONE=101;var SQLITE_INTEGER=1;var SQLITE_FLOAT=2;var SQLITE_TEXT=3;var SQLITE_BLOB=4;var SQLITE_UTF8=1;var sqlite3_open=cwrap("sqlite3_open","number",["string","number"]);var sqlite3_open_v2=cwrap("sqlite3_open_v2","number",["string","number","number","string"]);var sqlite3_close_v2=cwrap("sqlite3_close_v2","number",["number"]);var sqlite3_exec=cwrap("sqlite3_exec","number",["number","string","number","number","number"]);var sqlite3_changes=cwrap("sqlite3_changes","number",["number"]);var sqlite3_prepare_v2=cwrap("sqlite3_prepare_v2","number",["number","string","number","number","number"]);var sqlite3_sql=cwrap("sqlite3_sql","string",["number"]);var sqlite3_normalized_sql=cwrap("sqlite3_normalized_sql","string",["number"]);var sqlite3_prepare_v2_sqlptr=cwrap("sqlite3_prepare_v2","number",["number","number","number","number","number"]);var sqlite3_bind_text=cwrap("sqlite3_bind_text","number",["number","number","number","number","number"]);var sqlite3_bind_blob=cwrap("sqlite3_bind_blob","number",["number","number","number","number","number"]);var sqlite3_bind_double=cwrap("sqlite3_bind_double","number",["number","number","number"]);var sqlite3_bind_int=cwrap("sqlite3_bind_int","number",["number","number","number"]);var sqlite3_bind_parameter_index=cwrap("sqlite3_bind_parameter_index","number",["number","string"]);var sqlite3_step=cwrap("sqlite3_step","number",["number"]);var sqlite3_errmsg=cwrap("sqlite3_errmsg","string",["number"]);var sqlite3_column_count=cwrap("sqlite3_column_count","number",["number"]);var sqlite3_data_count=cwrap("sqlite3_data_count","number",["number"]);var sqlite3_column_double=cwrap("sqlite3_column_double","number",["number","number"]);var sqlite3_column_text=cwrap("sqlite3_column_text","string",["number","number"]);var sqlite3_column_blob=cwrap("sqlite3_column_blob","number",["number","number"]);var sqlite3_column_bytes=cwrap("sqlite3_column_bytes","number",["number","number"]);var sqlite3_column_type=cwrap("sqlite3_column_type","number",["number","number"]);var sqlite3_column_name=cwrap("sqlite3_column_name","string",["number","number"]);var sqlite3_reset=cwrap("sqlite3_reset","number",["number"]);var sqlite3_clear_bindings=cwrap("sqlite3_clear_bindings","number",["number"]);var sqlite3_finalize=cwrap("sqlite3_finalize","number",["number"]);var sqlite3_create_module_v2=cwrap("sqlite3_create_module_v2","number",["number","string","number","number","number"]);var sqlite3_create_function_v2=cwrap("sqlite3_create_function_v2","number",["number","string","number","number","number","number","number","number","number"]);var sqlite3_value_type=cwrap("sqlite3_value_type","number",["number"]);var sqlite3_value_bytes=cwrap("sqlite3_value_bytes","number",["number"]);var sqlite3_value_text=cwrap("sqlite3_value_text","string",["number"]);var sqlite3_value_blob=cwrap("sqlite3_value_blob","number",["number"]);var sqlite3_value_double=cwrap("sqlite3_value_double","number",["number"]);var sqlite3_result_double=cwrap("sqlite3_result_double","",["number","number"]);var sqlite3_result_null=cwrap("sqlite3_result_null","",["number"]);var sqlite3_result_text=cwrap("sqlite3_result_text","",["number","string","number","number"]);var sqlite3_result_blob=cwrap("sqlite3_result_blob","",["number","number","number","number"]);var sqlite3_result_int=cwrap("sqlite3_result_int","",["number","number"]);var sqlite3_result_error=cwrap("sqlite3_result_error","",["number","string","number"]);var sqlite3_malloc=cwrap("sqlite3_malloc","number",["number"]);Module["sqlite3_malloc"]=sqlite3_malloc;var registerExtensionFunctions=cwrap("RegisterExtensionFunctions","number",["number"]);function Statement(stmt1,db){this.stmt=stmt1;this.db=db;this.pos=1;this.allocatedmem=[]}Statement.prototype["bind"]=function bind(values){if(!this.stmt){throw"Statement closed"}this["reset"]();if(Array.isArray(values))return this.bindFromArray(values);if(values!=null&&typeof values==="object"){return this.bindFromObject(values)}return true};Statement.prototype["bind_"]=Statement.prototype.bind;Statement.prototype["step"]=function step(){if(!this.stmt){throw"Statement closed"}this.pos=1;var ret=sqlite3_step(this.stmt);switch(ret){case SQLITE_ROW:return true;case SQLITE_DONE:return false;default:throw this.db.handleError(ret)}};Statement.prototype.getNumber=function getNumber(pos){if(pos==null){pos=this.pos;this.pos+=1}return sqlite3_column_double(this.stmt,pos)};Statement.prototype.getString=function getString(pos){if(pos==null){pos=this.pos;this.pos+=1}return sqlite3_column_text(this.stmt,pos)};Statement.prototype.getBlob=function getBlob(pos){if(pos==null){pos=this.pos;this.pos+=1}var size=sqlite3_column_bytes(this.stmt,pos);var ptr=sqlite3_column_blob(this.stmt,pos);var result=new Uint8Array(size);for(var i=0;i>>0);if(data!=null){FS.createDataFile("/",this.filename,data,true,true)}const ret=sqlite3_open(this.filename,apiTemp);this.db=getValue(apiTemp,"i32");this.handleError(ret);registerExtensionFunctions(this.db);this.statements={};this.functions={}}function CustomDatabase(filename){this.filename=filename;const ret=sqlite3_open(this.filename,apiTemp);this.db=getValue(apiTemp,"i32");this.handleError(ret);registerExtensionFunctions(this.db);this.statements={};this.functions={}}Database.prototype["run"]=function run(sql,params){if(!this.db){throw"Database closed"}if(params){var stmt=this["prepare"](sql,params);try{stmt["step"]()}finally{stmt["free"]()}}else{this.handleError(sqlite3_exec(this.db,sql,0,0,apiTemp))}return this};Database.prototype["exec"]=function exec(sql,params){if(!this.db){throw"Database closed"}var stack=stackSave();var stmt=null;try{var nextSqlPtr=allocateUTF8OnStack(sql);var pzTail=stackAlloc(4);var results=[];while(getValue(nextSqlPtr,"i8")!==NULL){setValue(apiTemp,0,"i32");setValue(pzTail,0,"i32");this.handleError(sqlite3_prepare_v2_sqlptr(this.db,nextSqlPtr,-1,apiTemp,pzTail));var pStmt=getValue(apiTemp,"i32");nextSqlPtr=getValue(pzTail,"i32");if(pStmt!==NULL){var curresult=null;stmt=new Statement(pStmt,this);if(params!=null){stmt.bind(params)}while(stmt["step"]()){if(curresult===null){curresult={columns:stmt["getColumnNames"](),values:[]};results.push(curresult)}curresult["values"].push(stmt["get"]())}stmt["free"]()}}return results}catch(errCaught){if(stmt)stmt["free"]();throw errCaught}finally{stackRestore(stack)}};Database.prototype["each"]=function each(sql,params,callback,done){var stmt;if(typeof params==="function"){done=callback;callback=params;params=undefined}stmt=this["prepare"](sql,params);try{while(stmt["step"]()){callback(stmt["getAsObject"]())}}finally{stmt["free"]()}if(typeof done==="function"){return done()}return undefined};Database.prototype["prepare"]=function prepare(sql,params){setValue(apiTemp,0,"i32");this.handleError(sqlite3_prepare_v2(this.db,sql,-1,apiTemp,NULL));var pStmt=getValue(apiTemp,"i32");if(pStmt===NULL){throw"Nothing to prepare"}var stmt=new Statement(pStmt,this);if(params!=null){stmt.bind(params)}this.statements[pStmt]=stmt;return stmt};Database.prototype["iterateStatements"]=function iterateStatements(sql){return new StatementIterator(sql,this)};Database.prototype["export"]=function exportDatabase(){Object.values(this.statements).forEach(function each(stmt){stmt["free"]()});Object.values(this.functions).forEach(removeFunction);this.functions={};this.handleError(sqlite3_close_v2(this.db));var binaryDb=FS.readFile(this.filename,{encoding:"binary"});this.handleError(sqlite3_open(this.filename,apiTemp));this.db=getValue(apiTemp,"i32");return binaryDb};Database.prototype["close"]=function close(){if(this.db===null){return}Object.values(this.statements).forEach(function each(stmt){stmt["free"]()});Object.values(this.functions).forEach(removeFunction);this.functions={};this.handleError(sqlite3_close_v2(this.db));FS.unlink("/"+this.filename);this.db=null};Database.prototype["handleError"]=function handleError(returnCode){var errmsg;if(returnCode===SQLITE_OK){return null}errmsg=sqlite3_errmsg(this.db);throw new Error("SQLite: "+(errmsg||"Code "+returnCode))};Database.prototype["getRowsModified"]=function getRowsModified(){return sqlite3_changes(this.db)};Database.prototype["create_function"]=function create_function(name,func){function wrapped_func(cx,argc,argv){var result;var args=[];for(var i=0;i{throw toThrow};var ENVIRONMENT_IS_WEB=typeof window==="object";var ENVIRONMENT_IS_WORKER=typeof importScripts==="function";var ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;function logExceptionOnExit(e){if(e instanceof ExitStatus)return;let toLog=e;err("exiting due to exception: "+toLog)}var fs;var nodePath;var requireNodeFS;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}requireNodeFS=function(){if(!nodePath){fs=require("fs");nodePath=require("path")}};read_=function shell_read(filename,binary){requireNodeFS();filename=nodePath["normalize"](filename);return fs.readFileSync(filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}return ret};readAsync=function readAsync(filename,onload,onerror){requireNodeFS();filename=nodePath["normalize"](filename);fs.readFile(filename,function(err,data){if(err)onerror(err);else onload(data.buffer)})};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}quit_=((status,toThrow)=>{if(keepRuntimeAlive()){process["exitCode"]=status;throw toThrow}logExceptionOnExit(toThrow);process["exit"](status)});Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=(title=>document.title=title)}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);objAssign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];function convertJsFunctionToWasm(func,sig){if(typeof WebAssembly.Function==="function"){var typeNames={"i":"i32","j":"i64","f":"f32","d":"f64"};var type={parameters:[],results:sig[0]=="v"?[]:[typeNames[sig[0]]]};for(var i=1;i>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}function getValue(ptr,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return Number(HEAPF64[ptr>>3]);default:abort("invalid type for getValue: "+type)}return null}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort(text)}}function getCFunc(ident){var func=Module["_"+ident];return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string")return UTF8ToString(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}function allocateUTF8(str){var size=lengthBytesUTF8(str)+1;var ret=_malloc(size);if(ret)stringToUTF8Array(str,HEAP8,ret,size);return ret}function allocateUTF8OnStack(str){var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8Array(str,HEAP8,ret,size);return ret}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeKeepaliveCounter=0;function keepRuntimeAlive(){return noExitRuntime||runtimeKeepaliveCounter>0}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();FS.ignorePermissions=false;TTY.init();callRuntimeCallbacks(__ATINIT__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){{if(Module["onAbort"]){Module["onAbort"](what)}}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}function isFileURI(filename){return filename.startsWith("file://")}var wasmBinaryFile;wasmBinaryFile="sql-wasm.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(wasmBinaryFile)})}else{if(readAsync){return new Promise(function(resolve,reject){readAsync(wasmBinaryFile,function(response){resolve(new Uint8Array(response))},reject)})}}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["L"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["Fa"];addOnInit(Module["asm"]["M"]);removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(function(instance){return instance}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiationResult,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiationResult)})})}else{return instantiateArrayBuffer(receiveInstantiationResult)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync();return{}}var tempDouble;var tempI64;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){getWasmTableEntry(func)()}else{getWasmTableEntry(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function demangle(func){return func}function demangleAll(text){var regex=/\b_Z[\w\d_]+/g;return text.replace(regex,function(x){var y=demangle(x);return x===y?x:y+" ["+x+"]"})}var wasmTableMirror=[];function getWasmTableEntry(funcPtr){var func=wasmTableMirror[funcPtr];if(!func){if(funcPtr>=wasmTableMirror.length)wasmTableMirror.length=funcPtr+1;wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func}function jsStackTrace(){var error=new Error;if(!error.stack){try{throw new Error}catch(e){error=e}if(!error.stack){return"(no stack trace available)"}}return error.stack.toString()}function setWasmTableEntry(idx,func){wasmTable.set(idx,func);wasmTableMirror[idx]=func}function stackTrace(){var js=jsStackTrace();if(Module["extraStackTrace"])js+="\n"+Module["extraStackTrace"]();return demangleAll(js)}function ___assert_fail(condition,filename,line,func){abort("Assertion failed: "+UTF8ToString(condition)+", at: "+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"])}function _tzset_impl(){var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAP32[__get_timezone()>>2]=stdTimezoneOffset*60;HEAP32[__get_daylight()>>2]=Number(winterOffset!=summerOffset);function extractZone(date){var match=date.toTimeString().match(/\(([A-Za-z ]+)\)$/);return match?match[1]:"GMT"}var winterName=extractZone(winter);var summerName=extractZone(summer);var winterNamePtr=allocateUTF8(winterName);var summerNamePtr=allocateUTF8(summerName);if(summerOffset>2]=winterNamePtr;HEAP32[__get_tzname()+4>>2]=summerNamePtr}else{HEAP32[__get_tzname()>>2]=summerNamePtr;HEAP32[__get_tzname()+4>>2]=winterNamePtr}}function _tzset(){if(_tzset.called)return;_tzset.called=true;_tzset_impl()}function _localtime_r(time,tmPtr){_tzset();var date=new Date(HEAP32[time>>2]*1e3);HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getDay();var start=new Date(date.getFullYear(),0,1);var yday=(date.getTime()-start.getTime())/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr+36>>2]=-(date.getTimezoneOffset()*60);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dst=(summerOffset!=winterOffset&&date.getTimezoneOffset()==Math.min(winterOffset,summerOffset))|0;HEAP32[tmPtr+32>>2]=dst;var zonePtr=HEAP32[__get_tzname()+(dst?4:0)>>2];HEAP32[tmPtr+40>>2]=zonePtr;return tmPtr}function ___localtime_r(a0,a1){return _localtime_r(a0,a1)}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};function getRandomDevice(){if(typeof crypto==="object"&&typeof crypto["getRandomValues"]==="function"){var randomBuffer=new Uint8Array(1);return function(){crypto.getRandomValues(randomBuffer);return randomBuffer[0]}}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");return function(){return crypto_module["randomBytes"](1)[0]}}catch(e){}}return function(){abort("randomDevice")}}var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:function(from,to){from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()},put_char:function(tty,val){if(val===null||val===10){out(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};function zeroMemory(address,size){HEAPU8.fill(0,address,address+size)}function alignMemory(size,alignment){return Math.ceil(size/alignment)*alignment}function mmapAlloc(size){size=alignMemory(size,65536);var ptr=_memalign(65536,size);if(!ptr)return 0;zeroMemory(ptr,size);return ptr}var MEMFS={ops_table:null,mount:function(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode:function(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node;parent.timestamp=node.timestamp}return node},getFileDataAsTypedArray:function(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage:function(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr:function(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr:function(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup:function(parent,name){throw FS.genericErrors[44]},mknod:function(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename:function(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.parent.timestamp=Date.now();old_node.name=new_name;new_dir.contents[new_name]=old_node;new_dir.timestamp=old_node.parent.timestamp;old_node.parent=new_dir},unlink:function(parent,name){delete parent.contents[name];parent.timestamp=Date.now()},rmdir:function(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.timestamp=Date.now()},readdir:function(node){var entries=[".",".."];for(var key in node.contents){if(!node.contents.hasOwnProperty(key)){continue}entries.push(key)}return entries},symlink:function(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink:function(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read:function(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),false);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:function(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:function(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:function(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:function(node){FS.hashRemoveNode(node)},isRoot:function(node){return node===node.parent},isMountpoint:function(node){return!!node.mounted},isFile:function(mode){return(mode&61440)===32768},isDir:function(mode){return(mode&61440)===16384},isLink:function(mode){return(mode&61440)===40960},isChrdev:function(mode){return(mode&61440)===8192},isBlkdev:function(mode){return(mode&61440)===24576},isFIFO:function(mode){return(mode&61440)===4096},isSocket:function(mode){return(mode&49152)===49152},flagModes:{"r":0,"r+":2,"w":577,"w+":578,"a":1089,"a+":1090},modeStringToFlags:function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:function(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:function(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup:function(dir){var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:function(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:function(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:function(fd){return FS.streams[fd]},createStream:function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=function(){};FS.FSStream.prototype={object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}}}}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:function(fd){FS.streams[fd]=null},chrdev_stream_ops:{open:function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:function(){throw new FS.ErrnoError(70)}},major:function(dev){return dev>>8},minor:function(dev){return dev&255},makedev:function(ma,mi){return ma<<8|mi},registerDevice:function(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:function(dev){return FS.devices[dev]},getMounts:function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:function(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup:function(parent,name){return parent.node_ops.lookup(parent,name)},mknod:function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:function(path,mode){var dirs=path.split("/");var d="";for(var i=0;i"})},staticInit:function(){FS.ensureErrnoError();FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={"MEMFS":MEMFS}},init:function(input,output,error){FS.init.initialized=true;FS.ensureErrnoError();Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()},quit:function(){FS.init.initialized=false;for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}});stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){FS.forceLoadFile(node);var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags,offset){var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},doMkdir:function(path,mode){path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0},doMknod:function(path,mode,dev){switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}FS.mknod(path,mode,dev);return 0},doReadlink:function(path,buf,bufsize){if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len},doAccess:function(path,amode){if(amode&~7){return-28}var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0},doDup:function(path,flags,suggestFD){var suggest=FS.getStream(suggestFD);if(suggest)FS.close(suggest);return FS.open(path,flags,0,suggestFD,suggestFD).fd},doReadv:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream},get64:function(low,high){return low}};function ___syscall_access(path,amode){try{path=SYSCALLS.getStr(path);return SYSCALLS.doAccess(path,amode)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_chmod(path,mode){try{path=SYSCALLS.getStr(path);FS.chmod(path,mode);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_chown32(path,owner,group){try{path=SYSCALLS.getStr(path);FS.chown(path,owner,group);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_fchmod(fd,mode){try{FS.fchmod(fd,mode);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_fchown32(fd,owner,group){try{FS.fchown(fd,owner,group);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function setErrNo(value){HEAP32[___errno_location()>>2]=value;return value}function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.open(stream.path,stream.flags,0,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 5:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 6:case 7:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_fstat64(fd,buf){try{var stream=SYSCALLS.getStreamFromFD(fd);return SYSCALLS.doStat(FS.stat,stream.path,buf)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_fstatat64(dirfd,path,buf,flags){try{path=SYSCALLS.getStr(path);var nofollow=flags&256;var allowEmpty=flags&4096;flags=flags&~4352;path=SYSCALLS.calculateAt(dirfd,path,allowEmpty);return SYSCALLS.doStat(nofollow?FS.lstat:FS.stat,path,buf)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_ftruncate64(fd,low,high){try{var length=SYSCALLS.get64(low,high);FS.ftruncate(fd,length);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_getcwd(buf,size){try{if(size===0)return-28;var cwd=FS.cwd();var cwdLengthInBytes=lengthBytesUTF8(cwd);if(size{var t=process["hrtime"]();return t[0]*1e3+t[1]/1e6})}else _emscripten_get_now=(()=>performance.now());function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){var oldSize=HEAPU8.length;requestedSize=requestedSize>>>0;var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var ENV={};function getExecutableName(){return thisProgram||"./this.program"}function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof navigator==="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(x+"="+env[x])}getEnvStrings.strings=strings}return getEnvStrings.strings}function _environ_get(__environ,environ_buf){var bufSize=0;getEnvStrings().forEach(function(string,i){var ptr=environ_buf+bufSize;HEAP32[__environ+i*4>>2]=ptr;writeAsciiToMemory(string,ptr);bufSize+=string.length+1});return 0}function _environ_sizes_get(penviron_count,penviron_buf_size){var strings=getEnvStrings();HEAP32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(function(string){bufSize+=string.length+1});HEAP32[penviron_buf_size>>2]=bufSize;return 0}function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function _fd_fdstat_get(fd,pbuf){try{var stream=SYSCALLS.getStreamFromFD(fd);var type=stream.tty?2:FS.isDir(stream.mode)?3:FS.isLink(stream.mode)?7:4;HEAP8[pbuf>>0]=type;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function _fd_read(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doReadv(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var stream=SYSCALLS.getStreamFromFD(fd);var HIGH_OFFSET=4294967296;var offset=offset_high*HIGH_OFFSET+(offset_low>>>0);var DOUBLE_LIMIT=9007199254740992;if(offset<=-DOUBLE_LIMIT||offset>=DOUBLE_LIMIT){return-61}FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function _fd_sync(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);if(stream.stream_ops&&stream.stream_ops.fsync){return-stream.stream_ops.fsync(stream)}return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doWritev(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function _gettimeofday(ptr){var now=Date.now();HEAP32[ptr>>2]=now/1e3|0;HEAP32[ptr+4>>2]=now%1e3*1e3|0;return 0}function _time(ptr){var ret=Date.now()/1e3|0;if(ptr){HEAP32[ptr>>2]=ret}return ret}function setFileTime(path,time){path=UTF8ToString(path);try{FS.utime(path,time,time);return 0}catch(e){if(!(e instanceof FS.ErrnoError))throw e+" : "+stackTrace();setErrNo(e.errno);return-1}}function _utimes(path,times){var time;if(times){var mtime=times+8;time=HEAP32[mtime>>2]*1e3;time+=HEAP32[mtime+4>>2]/1e3}else{time=Date.now()}return setFileTime(path,time)}var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.staticInit();function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var asmLibraryArg={"a":___assert_fail,"y":___localtime_r,"k":___syscall_access,"i":___syscall_chmod,"g":___syscall_chown32,"j":___syscall_fchmod,"h":___syscall_fchown32,"b":___syscall_fcntl64,"J":___syscall_fstat64,"G":___syscall_fstatat64,"E":___syscall_ftruncate64,"D":___syscall_getcwd,"z":___syscall_geteuid32,"H":___syscall_lstat64,"x":___syscall_mkdir,"w":___syscall_mmap2,"v":___syscall_munmap,"u":___syscall_open,"s":___syscall_readlink,"r":___syscall_rmdir,"I":___syscall_stat64,"p":___syscall_unlink,"q":_emscripten_get_heap_max,"e":_emscripten_get_now,"m":_emscripten_memcpy_big,"c":_emscripten_resize_heap,"B":_environ_get,"C":_environ_sizes_get,"d":_fd_close,"o":_fd_fdstat_get,"t":_fd_read,"l":_fd_seek,"F":_fd_sync,"n":_fd_write,"f":_gettimeofday,"K":_time,"A":_utimes};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["M"]).apply(null,arguments)};var _sqlite3_malloc=Module["_sqlite3_malloc"]=function(){return(_sqlite3_malloc=Module["_sqlite3_malloc"]=Module["asm"]["N"]).apply(null,arguments)};var _sqlite3_free=Module["_sqlite3_free"]=function(){return(_sqlite3_free=Module["_sqlite3_free"]=Module["asm"]["O"]).apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return(___errno_location=Module["___errno_location"]=Module["asm"]["P"]).apply(null,arguments)};var _sqlite3_finalize=Module["_sqlite3_finalize"]=function(){return(_sqlite3_finalize=Module["_sqlite3_finalize"]=Module["asm"]["Q"]).apply(null,arguments)};var _sqlite3_reset=Module["_sqlite3_reset"]=function(){return(_sqlite3_reset=Module["_sqlite3_reset"]=Module["asm"]["R"]).apply(null,arguments)};var _sqlite3_clear_bindings=Module["_sqlite3_clear_bindings"]=function(){return(_sqlite3_clear_bindings=Module["_sqlite3_clear_bindings"]=Module["asm"]["S"]).apply(null,arguments)};var _sqlite3_value_blob=Module["_sqlite3_value_blob"]=function(){return(_sqlite3_value_blob=Module["_sqlite3_value_blob"]=Module["asm"]["T"]).apply(null,arguments)};var _sqlite3_value_text=Module["_sqlite3_value_text"]=function(){return(_sqlite3_value_text=Module["_sqlite3_value_text"]=Module["asm"]["U"]).apply(null,arguments)};var _sqlite3_value_bytes=Module["_sqlite3_value_bytes"]=function(){return(_sqlite3_value_bytes=Module["_sqlite3_value_bytes"]=Module["asm"]["V"]).apply(null,arguments)};var _sqlite3_value_double=Module["_sqlite3_value_double"]=function(){return(_sqlite3_value_double=Module["_sqlite3_value_double"]=Module["asm"]["W"]).apply(null,arguments)};var _sqlite3_value_int=Module["_sqlite3_value_int"]=function(){return(_sqlite3_value_int=Module["_sqlite3_value_int"]=Module["asm"]["X"]).apply(null,arguments)};var _sqlite3_value_type=Module["_sqlite3_value_type"]=function(){return(_sqlite3_value_type=Module["_sqlite3_value_type"]=Module["asm"]["Y"]).apply(null,arguments)};var _sqlite3_result_blob=Module["_sqlite3_result_blob"]=function(){return(_sqlite3_result_blob=Module["_sqlite3_result_blob"]=Module["asm"]["Z"]).apply(null,arguments)};var _sqlite3_result_double=Module["_sqlite3_result_double"]=function(){return(_sqlite3_result_double=Module["_sqlite3_result_double"]=Module["asm"]["_"]).apply(null,arguments)};var _sqlite3_result_error=Module["_sqlite3_result_error"]=function(){return(_sqlite3_result_error=Module["_sqlite3_result_error"]=Module["asm"]["$"]).apply(null,arguments)};var _sqlite3_result_int=Module["_sqlite3_result_int"]=function(){return(_sqlite3_result_int=Module["_sqlite3_result_int"]=Module["asm"]["aa"]).apply(null,arguments)};var _sqlite3_result_int64=Module["_sqlite3_result_int64"]=function(){return(_sqlite3_result_int64=Module["_sqlite3_result_int64"]=Module["asm"]["ba"]).apply(null,arguments)};var _sqlite3_result_null=Module["_sqlite3_result_null"]=function(){return(_sqlite3_result_null=Module["_sqlite3_result_null"]=Module["asm"]["ca"]).apply(null,arguments)};var _sqlite3_result_text=Module["_sqlite3_result_text"]=function(){return(_sqlite3_result_text=Module["_sqlite3_result_text"]=Module["asm"]["da"]).apply(null,arguments)};var _sqlite3_step=Module["_sqlite3_step"]=function(){return(_sqlite3_step=Module["_sqlite3_step"]=Module["asm"]["ea"]).apply(null,arguments)};var _sqlite3_column_count=Module["_sqlite3_column_count"]=function(){return(_sqlite3_column_count=Module["_sqlite3_column_count"]=Module["asm"]["fa"]).apply(null,arguments)};var _sqlite3_data_count=Module["_sqlite3_data_count"]=function(){return(_sqlite3_data_count=Module["_sqlite3_data_count"]=Module["asm"]["ga"]).apply(null,arguments)};var _sqlite3_column_blob=Module["_sqlite3_column_blob"]=function(){return(_sqlite3_column_blob=Module["_sqlite3_column_blob"]=Module["asm"]["ha"]).apply(null,arguments)};var _sqlite3_column_bytes=Module["_sqlite3_column_bytes"]=function(){return(_sqlite3_column_bytes=Module["_sqlite3_column_bytes"]=Module["asm"]["ia"]).apply(null,arguments)};var _sqlite3_column_double=Module["_sqlite3_column_double"]=function(){return(_sqlite3_column_double=Module["_sqlite3_column_double"]=Module["asm"]["ja"]).apply(null,arguments)};var _sqlite3_column_text=Module["_sqlite3_column_text"]=function(){return(_sqlite3_column_text=Module["_sqlite3_column_text"]=Module["asm"]["ka"]).apply(null,arguments)};var _sqlite3_column_type=Module["_sqlite3_column_type"]=function(){return(_sqlite3_column_type=Module["_sqlite3_column_type"]=Module["asm"]["la"]).apply(null,arguments)};var _sqlite3_column_name=Module["_sqlite3_column_name"]=function(){return(_sqlite3_column_name=Module["_sqlite3_column_name"]=Module["asm"]["ma"]).apply(null,arguments)};var _sqlite3_bind_blob=Module["_sqlite3_bind_blob"]=function(){return(_sqlite3_bind_blob=Module["_sqlite3_bind_blob"]=Module["asm"]["na"]).apply(null,arguments)};var _sqlite3_bind_double=Module["_sqlite3_bind_double"]=function(){return(_sqlite3_bind_double=Module["_sqlite3_bind_double"]=Module["asm"]["oa"]).apply(null,arguments)};var _sqlite3_bind_int=Module["_sqlite3_bind_int"]=function(){return(_sqlite3_bind_int=Module["_sqlite3_bind_int"]=Module["asm"]["pa"]).apply(null,arguments)};var _sqlite3_bind_text=Module["_sqlite3_bind_text"]=function(){return(_sqlite3_bind_text=Module["_sqlite3_bind_text"]=Module["asm"]["qa"]).apply(null,arguments)};var _sqlite3_bind_parameter_index=Module["_sqlite3_bind_parameter_index"]=function(){return(_sqlite3_bind_parameter_index=Module["_sqlite3_bind_parameter_index"]=Module["asm"]["ra"]).apply(null,arguments)};var _sqlite3_sql=Module["_sqlite3_sql"]=function(){return(_sqlite3_sql=Module["_sqlite3_sql"]=Module["asm"]["sa"]).apply(null,arguments)};var _sqlite3_normalized_sql=Module["_sqlite3_normalized_sql"]=function(){return(_sqlite3_normalized_sql=Module["_sqlite3_normalized_sql"]=Module["asm"]["ta"]).apply(null,arguments)};var _sqlite3_errmsg=Module["_sqlite3_errmsg"]=function(){return(_sqlite3_errmsg=Module["_sqlite3_errmsg"]=Module["asm"]["ua"]).apply(null,arguments)};var _sqlite3_exec=Module["_sqlite3_exec"]=function(){return(_sqlite3_exec=Module["_sqlite3_exec"]=Module["asm"]["va"]).apply(null,arguments)};var _sqlite3_prepare_v2=Module["_sqlite3_prepare_v2"]=function(){return(_sqlite3_prepare_v2=Module["_sqlite3_prepare_v2"]=Module["asm"]["wa"]).apply(null,arguments)};var _sqlite3_create_module_v2=Module["_sqlite3_create_module_v2"]=function(){return(_sqlite3_create_module_v2=Module["_sqlite3_create_module_v2"]=Module["asm"]["xa"]).apply(null,arguments)};var _sqlite3_declare_vtab=Module["_sqlite3_declare_vtab"]=function(){return(_sqlite3_declare_vtab=Module["_sqlite3_declare_vtab"]=Module["asm"]["ya"]).apply(null,arguments)};var _sqlite3_changes=Module["_sqlite3_changes"]=function(){return(_sqlite3_changes=Module["_sqlite3_changes"]=Module["asm"]["za"]).apply(null,arguments)};var _sqlite3_close_v2=Module["_sqlite3_close_v2"]=function(){return(_sqlite3_close_v2=Module["_sqlite3_close_v2"]=Module["asm"]["Aa"]).apply(null,arguments)};var _sqlite3_create_function_v2=Module["_sqlite3_create_function_v2"]=function(){return(_sqlite3_create_function_v2=Module["_sqlite3_create_function_v2"]=Module["asm"]["Ba"]).apply(null,arguments)};var _sqlite3_open=Module["_sqlite3_open"]=function(){return(_sqlite3_open=Module["_sqlite3_open"]=Module["asm"]["Ca"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["Da"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["Ea"]).apply(null,arguments)};var _RegisterExtensionFunctions=Module["_RegisterExtensionFunctions"]=function(){return(_RegisterExtensionFunctions=Module["_RegisterExtensionFunctions"]=Module["asm"]["Ga"]).apply(null,arguments)};var __get_tzname=Module["__get_tzname"]=function(){return(__get_tzname=Module["__get_tzname"]=Module["asm"]["Ha"]).apply(null,arguments)};var __get_daylight=Module["__get_daylight"]=function(){return(__get_daylight=Module["__get_daylight"]=Module["asm"]["Ia"]).apply(null,arguments)};var __get_timezone=Module["__get_timezone"]=function(){return(__get_timezone=Module["__get_timezone"]=Module["asm"]["Ja"]).apply(null,arguments)};var stackSave=Module["stackSave"]=function(){return(stackSave=Module["stackSave"]=Module["asm"]["Ka"]).apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){return(stackRestore=Module["stackRestore"]=Module["asm"]["La"]).apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){return(stackAlloc=Module["stackAlloc"]=Module["asm"]["Ma"]).apply(null,arguments)};var _memalign=Module["_memalign"]=function(){return(_memalign=Module["_memalign"]=Module["asm"]["Na"]).apply(null,arguments)};Module["ccall"]=ccall;Module["cwrap"]=cwrap;Module["setValue"]=setValue;Module["getValue"]=getValue;Module["UTF8ToString"]=UTF8ToString;Module["stringToUTF8"]=stringToUTF8;Module["lengthBytesUTF8"]=lengthBytesUTF8;Module["addFunction"]=addFunction;Module["stackSave"]=stackSave;Module["stackRestore"]=stackRestore;Module["stackAlloc"]=stackAlloc;var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run();
73 |
74 |
75 | // The shell-pre.js and emcc-generated code goes above
76 | return Module;
77 | }); // The end of the promise being returned
78 |
79 | return initSqlJsPromise;
80 | } // The end of our initSqlJs function
81 |
82 | // This bit below is copied almost exactly from what you get when you use the MODULARIZE=1 flag with emcc
83 | // However, we don't want to use the emcc modularization. See shell-pre.js
84 | if (typeof exports === 'object' && typeof module === 'object'){
85 | module.exports = initSqlJs;
86 | // This will allow the module to be used in ES6 or CommonJS
87 | module.exports.default = initSqlJs;
88 | }
89 | else if (typeof define === 'function' && define['amd']) {
90 | define([], function() { return initSqlJs; });
91 | }
92 | else if (typeof exports === 'object'){
93 | exports["Module"] = initSqlJs;
94 | }
95 |
--------------------------------------------------------------------------------
/src/sql.js/sql-wasm.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hcliff/sqlite-ipfs/b5c9b397b0396181f3867a7eeaaf790e6a4f16b1/src/sql.js/sql-wasm.wasm
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [ "src", "external.d.ts"],
3 | "compilerOptions": {
4 | /* Visit https://aka.ms/tsconfig.json to read more about this file */
5 |
6 | /* Projects */
7 | // "incremental": true, /* Enable incremental compilation */
8 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
9 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
10 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
11 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
12 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
13 |
14 | /* Language and Environment */
15 | "target": "es2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
16 | "lib": ["es2020", "dom"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
17 | // "jsx": "preserve", /* Specify what JSX code is generated. */
18 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
19 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
20 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
21 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
22 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
23 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
24 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
25 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
26 |
27 | /* Modules */
28 | "module": "es2020", /* Specify what module code is generated. */
29 | // "rootDir": "./", /* Specify the root folder within your source files. */
30 | "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
34 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
35 | "types": [], /* Specify type package names to be included without being referenced in a source file. */
36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
37 | // "resolveJsonModule": true, /* Enable importing .json files */
38 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */
39 |
40 | /* JavaScript Support */
41 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
42 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
43 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
44 |
45 | /* Emit */
46 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
47 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */
48 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
49 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
50 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
51 | // "outDir": "./", /* Specify an output folder for all emitted files. */
52 | // "removeComments": true, /* Disable emitting comments. */
53 | // "noEmit": true, /* Disable emitting files from a compilation. */
54 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
55 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
56 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
57 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
58 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
59 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
60 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
61 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
62 | // "newLine": "crlf", /* Set the newline character for emitting files. */
63 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
64 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
65 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
66 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
67 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
68 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
69 |
70 | /* Interop Constraints */
71 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
72 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
73 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
74 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
75 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
76 |
77 | /* Type Checking */
78 | "strict": true, /* Enable all strict type-checking options. */
79 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
80 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
81 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
82 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
83 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
84 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
85 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
86 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
87 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
88 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
89 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
90 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
91 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
92 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
93 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
94 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
95 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
96 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
97 |
98 | /* Completeness */
99 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
100 | "skipLibCheck": true /* Skip type checking all .d.ts files. */
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
2 | const path = require('path');
3 |
4 | const example = {
5 | target: 'web',
6 | watch: false,
7 | devServer: {
8 | magicHtml: false,
9 | watchFiles: [],
10 |
11 | static: ["example/assets"],
12 | https: true,
13 | // interferes with targeting webworkers
14 | hot: false,
15 | liveReload: false,
16 | // headers required for SharedArrayBuffer to be available
17 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/Planned_changes
18 | headers: {
19 | 'Cross-Origin-Embedder-Policy': 'require-corp',
20 | 'Cross-Origin-Opener-Policy': 'same-origin',
21 | },
22 | devMiddleware: {
23 | // webpack attempts to serve compiled ts files as a video (???)
24 | // overide that behaviour
25 | mimeTypes: { 'ts': 'application/javascript' },
26 | }
27 | },
28 |
29 | devtool: 'inline-source-map',
30 | entry: {
31 | index: "./example/index.ts"
32 | },
33 | plugins: [
34 | new NodePolyfillPlugin(),
35 | ],
36 | module: {
37 | rules: [
38 | {
39 | test: /\.tsx?$/,
40 | use: "ts-loader",
41 | exclude: /node_modules/,
42 | },
43 | {
44 | test: [/\.wasm$/],
45 | type: 'asset/resource',
46 | },
47 | {
48 | test: [/\.sqlite3$/],
49 | loader: 'raw-loader',
50 | }
51 | ],
52 | },
53 | resolve: {
54 | extensions: [".tsx", ".ts", ".js"],
55 | fallback: {
56 | fs: false,
57 | crypto: false,
58 | path: false,
59 | },
60 | }
61 | }
62 |
63 | const web = {
64 | target: 'web',
65 | devtool: 'inline-source-map',
66 | entry: {
67 | index: "./src/index.ts"
68 | },
69 | plugins: [
70 | new NodePolyfillPlugin(),
71 | ],
72 | module: {
73 | rules: [
74 | {
75 | test: /\.tsx?$/,
76 | use: "ts-loader",
77 | exclude: /node_modules/,
78 | }
79 | ],
80 | },
81 | resolve: {
82 | extensions: [".tsx", ".ts", ".js"],
83 | fallback: {
84 | fs: false,
85 | crypto: false,
86 | path: false,
87 | },
88 | },
89 | output: {
90 | filename: "[name].js",
91 | },
92 | };
93 |
94 | const workers = {
95 | watch: false,
96 | target: 'webworker',
97 | devtool: 'inline-source-map',
98 | entry: {
99 | "db.worker": "./src/db.worker.ts",
100 | "ipfs.worker": "./src/ipfs.worker.ts"
101 | },
102 | plugins: [
103 | new NodePolyfillPlugin(),
104 | ],
105 | module: {
106 | rules: [
107 | {
108 | test: /\.tsx?$/,
109 | use: "ts-loader",
110 | exclude: /node_modules/,
111 | }
112 | ],
113 | },
114 | resolve: {
115 | extensions: [".tsx", ".ts", ".js"],
116 | fallback: {
117 | fs: false,
118 | crypto: false,
119 | path: false,
120 | },
121 | },
122 | output: {
123 | filename: "[name].js",
124 | },
125 | };
126 |
127 | module.exports = [example, web, workers];
--------------------------------------------------------------------------------