aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-05-07 01:26:26 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-05-07 01:26:26 -0700
commitfad34bb4abfe1715d4febec6e7de2809bfffb4e2 (patch)
tree6616f92155a3473c228e46f3c5693c47548761e9 /src
parentdd9e7de689dafb29ed3e79e2b7af54ea097f75e9 (diff)
downloadbun-fad34bb4abfe1715d4febec6e7de2809bfffb4e2.tar.gz
bun-fad34bb4abfe1715d4febec6e7de2809bfffb4e2.tar.zst
bun-fad34bb4abfe1715d4febec6e7de2809bfffb4e2.zip
cool
Former-commit-id: 96ff169e46fcb43d5afbc9a6e2fde039e27e9d5f
Diffstat (limited to 'src')
-rw-r--r--src/alloc.zig4
-rw-r--r--src/api/demo/.gitignore34
-rw-r--r--src/api/demo/README.md34
-rw-r--r--src/api/demo/lib/api.ts77
-rw-r--r--src/api/demo/package.json16
-rw-r--r--src/api/demo/pages/_app.js7
-rw-r--r--src/api/demo/pages/api/hello.js5
-rw-r--r--src/api/demo/pages/index.js69
-rw-r--r--src/api/demo/pnpm-lock.yaml1915
-rw-r--r--src/api/demo/public/favicon.icobin0 -> 15086 bytes
-rw-r--r--src/api/demo/public/vercel.svg4
-rw-r--r--src/api/demo/styles/Home.module.css121
-rw-r--r--src/api/demo/styles/globals.css16
-rw-r--r--src/api/schema.d.ts188
-rw-r--r--src/api/schema.js631
-rw-r--r--src/api/schema.peechy107
-rw-r--r--src/api/schema.ts166
-rw-r--r--src/api/schema.zig739
-rw-r--r--src/ast/base.zig4
-rw-r--r--src/defines-table.zig2
-rw-r--r--src/defines.zig4
-rw-r--r--src/exports.zig44
-rw-r--r--src/fs.zig2
-rw-r--r--src/global.zig39
-rw-r--r--src/js_ast.zig6
-rw-r--r--src/js_lexer.zig18
-rw-r--r--src/js_parser/imports.zig2
-rw-r--r--src/js_parser/js_parser.zig22
-rw-r--r--src/js_parser/js_parser_test.zig2
-rw-r--r--src/js_printer.zig34
-rw-r--r--src/json_parser.zig4
-rw-r--r--src/logger.zig8
-rw-r--r--src/main.zig13
-rw-r--r--src/main_wasi.zig108
-rw-r--r--src/main_wasm.zig254
-rw-r--r--src/options.zig2
-rw-r--r--src/output_native.zig5
-rw-r--r--src/output_wasi.zig5
-rw-r--r--src/output_wasm.zig5
-rw-r--r--src/renamer.zig4
-rw-r--r--src/string_immutable.zig7
-rw-r--r--src/string_mutable.zig2
-rw-r--r--src/test/fixtures/noop.js1
-rw-r--r--src/test/fixtures/simple-150x.jsx443
-rw-r--r--src/zee_alloc.zig663
45 files changed, 5691 insertions, 145 deletions
diff --git a/src/alloc.zig b/src/alloc.zig
index ec6a678e8..ed790d096 100644
--- a/src/alloc.zig
+++ b/src/alloc.zig
@@ -9,8 +9,8 @@ pub var dynamic: *std.mem.Allocator = undefined;
pub fn setup(root: *std.mem.Allocator) !void {
needs_setup = false;
- static = std.heap.c_allocator;
- dynamic = std.heap.c_allocator;
+ static = root;
+ dynamic = root;
// static = @ptrCast(*std.mem.Allocator, &stat.allocator);
}
diff --git a/src/api/demo/.gitignore b/src/api/demo/.gitignore
new file mode 100644
index 000000000..1437c53f7
--- /dev/null
+++ b/src/api/demo/.gitignore
@@ -0,0 +1,34 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+# vercel
+.vercel
diff --git a/src/api/demo/README.md b/src/api/demo/README.md
new file mode 100644
index 000000000..b12f3e33e
--- /dev/null
+++ b/src/api/demo/README.md
@@ -0,0 +1,34 @@
+This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
+
+## Getting Started
+
+First, run the development server:
+
+```bash
+npm run dev
+# or
+yarn dev
+```
+
+Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
+
+You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
+
+[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
+
+The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
+
+## Learn More
+
+To learn more about Next.js, take a look at the following resources:
+
+- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
+- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
+
+You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
+
+## Deploy on Vercel
+
+The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
+
+Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
diff --git a/src/api/demo/lib/api.ts b/src/api/demo/lib/api.ts
new file mode 100644
index 000000000..e09eec51b
--- /dev/null
+++ b/src/api/demo/lib/api.ts
@@ -0,0 +1,77 @@
+import * as Schema from "../../schema";
+import { ByteBuffer } from "peechy";
+
+export interface WebAssemblyModule {
+ init(): number;
+ transform(a: number): number;
+ malloc(a: number): number;
+ calloc(a: number): number;
+ realloc(a: number): number;
+ free(a: number): number;
+}
+
+export class ESDev {
+ static has_initialized = false;
+ static wasm_source: WebAssembly.WebAssemblyInstantiatedSource = null;
+ static wasm_exports: WebAssemblyModule;
+ static memory: WebAssembly.Memory;
+ static memory_array: Uint8Array;
+ static async init(url) {
+ if (typeof SharedArrayBuffer !== "undefined") {
+ ESDev.memory = new WebAssembly.Memory({
+ initial: 1500,
+ maximum: 3000,
+ shared: true,
+ });
+ } else {
+ ESDev.memory = new WebAssembly.Memory({
+ initial: 1500,
+ maximum: 3000,
+ });
+ }
+ ESDev.memory_array = new Uint8Array(ESDev.memory.buffer);
+ ESDev.wasm_source = await globalThis.WebAssembly.instantiateStreaming(
+ fetch(url),
+ {
+ js: {
+ mem: ESDev.memory,
+ },
+ }
+ );
+
+ ESDev.wasm_exports = ESDev.wasm_source.instance.exports as any;
+ ESDev.wasm_exports.init();
+ console.log("WASM loaded.");
+ ESDev.has_initialized = true;
+ }
+
+ static transform(content: string, file_name: string) {
+ if (!ESDev.has_initialized) {
+ throw "Please run await ESDev.init(wasm_url) before using this.";
+ }
+
+ const bb = new ByteBuffer(
+ new Uint8Array(content.length + file_name.length)
+ );
+ bb.length = 0;
+
+ Schema.encodeTransform(
+ {
+ contents: content,
+ path: file_name,
+ },
+ bb
+ );
+ const data = bb.toUint8Array();
+ const ptr = ESDev.wasm_exports.malloc(data.byteLength);
+ ESDev.memory_array.set(data, ptr);
+ debugger;
+ const resp_ptr = ESDev.wasm_exports.transform(ptr);
+ var _bb = new ByteBuffer(ESDev.memory_array.subarray(resp_ptr));
+ const response = Schema.decodeTransformResponse(_bb);
+ ESDev.wasm_exports.free(resp_ptr);
+ return response;
+ }
+}
+
+globalThis.ESDev = ESDev;
diff --git a/src/api/demo/package.json b/src/api/demo/package.json
new file mode 100644
index 000000000..27c8c943e
--- /dev/null
+++ b/src/api/demo/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "demo",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start"
+ },
+ "dependencies": {
+ "next": "10.2.0",
+ "peechy": "0.3.6",
+ "react": "17.0.2",
+ "react-dom": "17.0.2"
+ }
+}
diff --git a/src/api/demo/pages/_app.js b/src/api/demo/pages/_app.js
new file mode 100644
index 000000000..1e1cec924
--- /dev/null
+++ b/src/api/demo/pages/_app.js
@@ -0,0 +1,7 @@
+import '../styles/globals.css'
+
+function MyApp({ Component, pageProps }) {
+ return <Component {...pageProps} />
+}
+
+export default MyApp
diff --git a/src/api/demo/pages/api/hello.js b/src/api/demo/pages/api/hello.js
new file mode 100644
index 000000000..9987aff4c
--- /dev/null
+++ b/src/api/demo/pages/api/hello.js
@@ -0,0 +1,5 @@
+// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
+
+export default (req, res) => {
+ res.status(200).json({ name: 'John Doe' })
+}
diff --git a/src/api/demo/pages/index.js b/src/api/demo/pages/index.js
new file mode 100644
index 000000000..2f5fcc6d6
--- /dev/null
+++ b/src/api/demo/pages/index.js
@@ -0,0 +1,69 @@
+import Head from "next/head";
+import Image from "next/image";
+import styles from "../styles/Home.module.css";
+import "../lib/api.ts";
+export default function Home() {
+ return (
+ <div className={styles.container}>
+ <Head>
+ <title>Create Next App</title>
+ <meta name="description" content="Generated by create next app" />
+ <link rel="icon" href="/favicon.ico" />
+ </Head>
+
+ <main className={styles.main}>
+ <h1 className={styles.title}>
+ Welcome to <a href="https://nextjs.org">Next.js!</a>
+ </h1>
+
+ <p className={styles.description}>
+ Get started by editing{" "}
+ <code className={styles.code}>pages/index.js</code>
+ </p>
+
+ <div className={styles.grid}>
+ <a href="https://nextjs.org/docs" className={styles.card}>
+ <h2>Documentation &rarr;</h2>
+ <p>Find in-depth information about Next.js features and API.</p>
+ </a>
+
+ <a href="https://nextjs.org/learn" className={styles.card}>
+ <h2>Learn &rarr;</h2>
+ <p>Learn about Next.js in an interactive course with quizzes!</p>
+ </a>
+
+ <a
+ href="https://github.com/vercel/next.js/tree/master/examples"
+ className={styles.card}
+ >
+ <h2>Examples &rarr;</h2>
+ <p>Discover and deploy boilerplate example Next.js projects.</p>
+ </a>
+
+ <a
+ href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
+ className={styles.card}
+ >
+ <h2>Deploy &rarr;</h2>
+ <p>
+ Instantly deploy your Next.js site to a public URL with Vercel.
+ </p>
+ </a>
+ </div>
+ </main>
+
+ <footer className={styles.footer}>
+ <a
+ href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
+ target="_blank"
+ rel="noopener noreferrer"
+ >
+ Powered by{" "}
+ <span className={styles.logo}>
+ <Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
+ </span>
+ </a>
+ </footer>
+ </div>
+ );
+}
diff --git a/src/api/demo/pnpm-lock.yaml b/src/api/demo/pnpm-lock.yaml
new file mode 100644
index 000000000..cd3dfa28b
--- /dev/null
+++ b/src/api/demo/pnpm-lock.yaml
@@ -0,0 +1,1915 @@
+lockfileVersion: 5.3
+
+specifiers:
+ next: 10.2.0
+ peechy: 0.3.6
+ react: 17.0.2
+ react-dom: 17.0.2
+
+dependencies:
+ next: 10.2.0_react-dom@17.0.2+react@17.0.2
+ peechy: 0.3.6
+ react: 17.0.2
+ react-dom: 17.0.2_react@17.0.2
+
+packages:
+
+ /@babel/code-frame/7.12.11:
+ resolution: {integrity: sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==}
+ dependencies:
+ '@babel/highlight': 7.14.0
+ dev: false
+
+ /@babel/helper-validator-identifier/7.14.0:
+ resolution: {integrity: sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==}
+ dev: false
+
+ /@babel/highlight/7.14.0:
+ resolution: {integrity: sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==}
+ dependencies:
+ '@babel/helper-validator-identifier': 7.14.0
+ chalk: 2.4.2
+ js-tokens: 4.0.0
+ dev: false
+
+ /@babel/runtime/7.12.5:
+ resolution: {integrity: sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==}
+ dependencies:
+ regenerator-runtime: 0.13.7
+ dev: false
+
+ /@babel/types/7.8.3:
+ resolution: {integrity: sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==}
+ dependencies:
+ esutils: 2.0.3
+ lodash: 4.17.21
+ to-fast-properties: 2.0.0
+ dev: false
+
+ /@hapi/accept/5.0.1:
+ resolution: {integrity: sha512-fMr4d7zLzsAXo28PRRQPXR1o2Wmu+6z+VY1UzDp0iFo13Twj8WePakwXBiqn3E1aAlTpSNzCXdnnQXFhst8h8Q==}
+ dependencies:
+ '@hapi/boom': 9.1.2
+ '@hapi/hoek': 9.2.0
+ dev: false
+
+ /@hapi/boom/9.1.2:
+ resolution: {integrity: sha512-uJEJtiNHzKw80JpngDGBCGAmWjBtzxDCz17A9NO2zCi8LLBlb5Frpq4pXwyN+2JQMod4pKz5BALwyneCgDg89Q==}
+ dependencies:
+ '@hapi/hoek': 9.2.0
+ dev: false
+
+ /@hapi/hoek/9.2.0:
+ resolution: {integrity: sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==}
+ dev: false
+
+ /@next/env/10.2.0:
+ resolution: {integrity: sha512-tsWBsn1Rb6hXRaHc/pWMCpZ4Ipkf3OCbZ54ef5ukgIyEvzzGdGFXQshPP2AF7yb+8yMpunWs7vOMZW3e8oPF6A==}
+ dev: false
+
+ /@next/polyfill-module/10.2.0:
+ resolution: {integrity: sha512-Nl3GexIUXsmuggkUqrRFyE/2k7UI44JaVzSywtXEyHzxpZm2a5bdMaWuC89pgLiFDDOqmbqyLAbtwm5lNxa7Eg==}
+ dev: false
+
+ /@next/react-dev-overlay/10.2.0_react-dom@17.0.2+react@17.0.2:
+ resolution: {integrity: sha512-PRIAoWog41hLN4iJ8dChKp4ysOX0Q8yiNQ/cwzyqEd3EjugkDV5OiKl3mumGKaApJaIra1MX6j1wgQRuLhuWMA==}
+ peerDependencies:
+ react: ^16.9.0 || ^17
+ react-dom: ^16.9.0 || ^17
+ dependencies:
+ '@babel/code-frame': 7.12.11
+ anser: 1.4.9
+ chalk: 4.0.0
+ classnames: 2.2.6
+ css.escape: 1.5.1
+ data-uri-to-buffer: 3.0.1
+ platform: 1.3.6
+ react: 17.0.2
+ react-dom: 17.0.2_react@17.0.2
+ shell-quote: 1.7.2
+ source-map: 0.8.0-beta.0
+ stacktrace-parser: 0.1.10
+ strip-ansi: 6.0.0
+ dev: false
+
+ /@next/react-refresh-utils/10.2.0_react-refresh@0.8.3:
+ resolution: {integrity: sha512-3I31K9B4hEQRl7yQ44Umyz+szHtuMJrNdwsgJGhoEnUCXSBRHp5wv5Zv8eDa2NewSbe53b2C0oOpivrzmdBakw==}
+ peerDependencies:
+ react-refresh: 0.8.3
+ webpack: ^4 || ^5
+ peerDependenciesMeta:
+ webpack:
+ optional: true
+ dependencies:
+ react-refresh: 0.8.3
+ dev: false
+
+ /@opentelemetry/api/0.14.0:
+ resolution: {integrity: sha512-L7RMuZr5LzMmZiQSQDy9O1jo0q+DaLy6XpYJfIGfYSfoJA5qzYwUP3sP1uMIQ549DvxAgM3ng85EaPTM/hUHwQ==}
+ engines: {node: '>=8.0.0'}
+ dependencies:
+ '@opentelemetry/context-base': 0.14.0
+ dev: false
+
+ /@opentelemetry/context-base/0.14.0:
+ resolution: {integrity: sha512-sDOAZcYwynHFTbLo6n8kIbLiVF3a3BLkrmehJUyEbT9F+Smbi47kLGS2gG2g0fjBLR/Lr1InPD7kXL7FaTqEkw==}
+ engines: {node: '>=8.0.0'}
+ dev: false
+
+ /@types/node/15.0.2:
+ resolution: {integrity: sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA==}
+ dev: false
+
+ /anser/1.4.9:
+ resolution: {integrity: sha512-AI+BjTeGt2+WFk4eWcqbQ7snZpDBt8SaLlj0RT2h5xfdWaiy51OjYvqwMrNzJLGy8iOAL6nKDITWO+rd4MkYEA==}
+ dev: false
+
+ /ansi-regex/5.0.0:
+ resolution: {integrity: sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==}
+ engines: {node: '>=8'}
+ dev: false
+
+ /ansi-styles/3.2.1:
+ resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
+ engines: {node: '>=4'}
+ dependencies:
+ color-convert: 1.9.3
+ dev: false
+
+ /ansi-styles/4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+ dependencies:
+ color-convert: 2.0.1
+ dev: false
+
+ /anymatch/3.1.2:
+ resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==}
+ engines: {node: '>= 8'}
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.2.3
+ dev: false
+
+ /array-filter/1.0.0:
+ resolution: {integrity: sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=}
+ dev: false
+
+ /asn1.js/5.4.1:
+ resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==}
+ dependencies:
+ bn.js: 4.12.0
+ inherits: 2.0.4
+ minimalistic-assert: 1.0.1
+ safer-buffer: 2.1.2
+ dev: false
+
+ /assert/1.5.0:
+ resolution: {integrity: sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==}
+ dependencies:
+ object-assign: 4.1.1
+ util: 0.10.3
+ dev: false
+
+ /assert/2.0.0:
+ resolution: {integrity: sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==}
+ dependencies:
+ es6-object-assign: 1.1.0
+ is-nan: 1.3.2
+ object-is: 1.1.5
+ util: 0.12.3
+ dev: false
+
+ /ast-types/0.13.2:
+ resolution: {integrity: sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA==}
+ engines: {node: '>=4'}
+ dev: false
+
+ /available-typed-arrays/1.0.2:
+ resolution: {integrity: sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ array-filter: 1.0.0
+ dev: false
+
+ /babel-plugin-syntax-jsx/6.18.0:
+ resolution: {integrity: sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=}
+ dev: false
+
+ /base64-js/1.5.1:
+ resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
+ dev: false
+
+ /big.js/5.2.2:
+ resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==}
+ dev: false
+
+ /binary-extensions/2.2.0:
+ resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
+ engines: {node: '>=8'}
+ dev: false
+
+ /bn.js/4.12.0:
+ resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==}
+ dev: false
+
+ /bn.js/5.2.0:
+ resolution: {integrity: sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==}
+ dev: false
+
+ /braces/3.0.2:
+ resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
+ engines: {node: '>=8'}
+ dependencies:
+ fill-range: 7.0.1
+ dev: false
+
+ /brorand/1.1.0:
+ resolution: {integrity: sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=}
+ dev: false
+
+ /browserify-aes/1.2.0:
+ resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==}
+ dependencies:
+ buffer-xor: 1.0.3
+ cipher-base: 1.0.4
+ create-hash: 1.2.0
+ evp_bytestokey: 1.0.3
+ inherits: 2.0.4
+ safe-buffer: 5.2.1
+ dev: false
+
+ /browserify-cipher/1.0.1:
+ resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==}
+ dependencies:
+ browserify-aes: 1.2.0
+ browserify-des: 1.0.2
+ evp_bytestokey: 1.0.3
+ dev: false
+
+ /browserify-des/1.0.2:
+ resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==}
+ dependencies:
+ cipher-base: 1.0.4
+ des.js: 1.0.1
+ inherits: 2.0.4
+ safe-buffer: 5.2.1
+ dev: false
+
+ /browserify-rsa/4.1.0:
+ resolution: {integrity: sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==}
+ dependencies:
+ bn.js: 5.2.0
+ randombytes: 2.1.0
+ dev: false
+
+ /browserify-sign/4.2.1:
+ resolution: {integrity: sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==}
+ dependencies:
+ bn.js: 5.2.0
+ browserify-rsa: 4.1.0
+ create-hash: 1.2.0
+ create-hmac: 1.1.7
+ elliptic: 6.5.4
+ inherits: 2.0.4
+ parse-asn1: 5.1.6
+ readable-stream: 3.6.0
+ safe-buffer: 5.2.1
+ dev: false
+
+ /browserify-zlib/0.2.0:
+ resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==}
+ dependencies:
+ pako: 1.0.11
+ dev: false
+
+ /browserslist/4.16.1:
+ resolution: {integrity: sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+ dependencies:
+ caniuse-lite: 1.0.30001223
+ colorette: 1.2.2
+ electron-to-chromium: 1.3.727
+ escalade: 3.1.1
+ node-releases: 1.1.71
+ dev: false
+
+ /buffer-xor/1.0.3:
+ resolution: {integrity: sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=}
+ dev: false
+
+ /buffer/4.9.2:
+ resolution: {integrity: sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==}
+ dependencies:
+ base64-js: 1.5.1
+ ieee754: 1.2.1
+ isarray: 1.0.0
+ dev: false
+
+ /buffer/5.6.0:
+ resolution: {integrity: sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==}
+ dependencies:
+ base64-js: 1.5.1
+ ieee754: 1.2.1
+ dev: false
+
+ /builtin-status-codes/3.0.0:
+ resolution: {integrity: sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=}
+ dev: false
+
+ /bytes/3.1.0:
+ resolution: {integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==}
+ engines: {node: '>= 0.8'}
+ dev: false
+
+ /call-bind/1.0.2:
+ resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
+ dependencies:
+ function-bind: 1.1.1
+ get-intrinsic: 1.1.1
+ dev: false
+
+ /camel-case/4.1.2:
+ resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
+ dependencies:
+ pascal-case: 3.1.2
+ tslib: 2.2.0
+ dev: false
+
+ /caniuse-lite/1.0.30001223:
+ resolution: {integrity: sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA==}
+ dev: false
+
+ /capital-case/1.0.4:
+ resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==}
+ dependencies:
+ no-case: 3.0.4
+ tslib: 2.2.0
+ upper-case-first: 2.0.2
+ dev: false
+
+ /chalk/2.4.2:
+ resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
+ engines: {node: '>=4'}
+ dependencies:
+ ansi-styles: 3.2.1
+ escape-string-regexp: 1.0.5
+ supports-color: 5.5.0
+ dev: false
+
+ /chalk/4.0.0:
+ resolution: {integrity: sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==}
+ engines: {node: '>=10'}
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+ dev: false
+
+ /change-case/4.1.2:
+ resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==}
+ dependencies:
+ camel-case: 4.1.2
+ capital-case: 1.0.4
+ constant-case: 3.0.4
+ dot-case: 3.0.4
+ header-case: 2.0.4
+ no-case: 3.0.4
+ param-case: 3.0.4
+ pascal-case: 3.1.2
+ path-case: 3.0.4
+ sentence-case: 3.0.4
+ snake-case: 3.0.4
+ tslib: 2.2.0
+ dev: false
+
+ /chokidar/3.5.1:
+ resolution: {integrity: sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==}
+ engines: {node: '>= 8.10.0'}
+ dependencies:
+ anymatch: 3.1.2
+ braces: 3.0.2
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.1
+ normalize-path: 3.0.0
+ readdirp: 3.5.0
+ optionalDependencies:
+ fsevents: 2.3.2
+ dev: false
+
+ /cipher-base/1.0.4:
+ resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==}
+ dependencies:
+ inherits: 2.0.4
+ safe-buffer: 5.2.1
+ dev: false
+
+ /classnames/2.2.6:
+ resolution: {integrity: sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==}
+ dev: false
+
+ /color-convert/1.9.3:
+ resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
+ dependencies:
+ color-name: 1.1.3
+ dev: false
+
+ /color-convert/2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+ dependencies:
+ color-name: 1.1.4
+ dev: false
+
+ /color-name/1.1.3:
+ resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=}
+ dev: false
+
+ /color-name/1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+ dev: false
+
+ /colorette/1.2.2:
+ resolution: {integrity: sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==}
+ dev: false
+
+ /commondir/1.0.1:
+ resolution: {integrity: sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=}
+ dev: false
+
+ /console-browserify/1.2.0:
+ resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==}
+ dev: false
+
+ /constant-case/3.0.4:
+ resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==}
+ dependencies:
+ no-case: 3.0.4
+ tslib: 2.2.0
+ upper-case: 2.0.2
+ dev: false
+
+ /constants-browserify/1.0.0:
+ resolution: {integrity: sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=}
+ dev: false
+
+ /convert-source-map/1.7.0:
+ resolution: {integrity: sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==}
+ dependencies:
+ safe-buffer: 5.1.2
+ dev: false
+
+ /core-util-is/1.0.2:
+ resolution: {integrity: sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=}
+ dev: false
+
+ /create-ecdh/4.0.4:
+ resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==}
+ dependencies:
+ bn.js: 4.12.0
+ elliptic: 6.5.4
+ dev: false
+
+ /create-hash/1.2.0:
+ resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==}
+ dependencies:
+ cipher-base: 1.0.4
+ inherits: 2.0.4
+ md5.js: 1.3.5
+ ripemd160: 2.0.2
+ sha.js: 2.4.11
+ dev: false
+
+ /create-hmac/1.1.7:
+ resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==}
+ dependencies:
+ cipher-base: 1.0.4
+ create-hash: 1.2.0
+ inherits: 2.0.4
+ ripemd160: 2.0.2
+ safe-buffer: 5.2.1
+ sha.js: 2.4.11
+ dev: false
+
+ /crypto-browserify/3.12.0:
+ resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==}
+ dependencies:
+ browserify-cipher: 1.0.1
+ browserify-sign: 4.2.1
+ create-ecdh: 4.0.4
+ create-hash: 1.2.0
+ create-hmac: 1.1.7
+ diffie-hellman: 5.0.3
+ inherits: 2.0.4
+ pbkdf2: 3.1.2
+ public-encrypt: 4.0.3
+ randombytes: 2.1.0
+ randomfill: 1.0.4
+ dev: false
+
+ /css.escape/1.5.1:
+ resolution: {integrity: sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=}
+ dev: false
+
+ /cssnano-preset-simple/2.0.0_postcss@8.2.13:
+ resolution: {integrity: sha512-HkufSLkaBJbKBFx/7aj5HmCK9Ni/JedRQm0mT2qBzMG/dEuJOLnMt2lK6K1rwOOyV4j9aSY+knbW9WoS7BYpzg==}
+ peerDependencies:
+ postcss: ^8.2.1
+ dependencies:
+ caniuse-lite: 1.0.30001223
+ postcss: 8.2.13
+ dev: false
+
+ /cssnano-simple/2.0.0_postcss@8.2.13:
+ resolution: {integrity: sha512-0G3TXaFxlh/szPEG/o3VcmCwl0N3E60XNb9YZZijew5eIs6fLjJuOPxQd9yEBaX2p/YfJtt49i4vYi38iH6/6w==}
+ peerDependencies:
+ postcss: ^8.2.2
+ dependencies:
+ cssnano-preset-simple: 2.0.0_postcss@8.2.13
+ postcss: 8.2.13
+ dev: false
+
+ /data-uri-to-buffer/3.0.1:
+ resolution: {integrity: sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==}
+ engines: {node: '>= 6'}
+ dev: false
+
+ /debug/2.6.9:
+ resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
+ dependencies:
+ ms: 2.0.0
+ dev: false
+
+ /define-properties/1.1.3:
+ resolution: {integrity: sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ object-keys: 1.1.1
+ dev: false
+
+ /depd/1.1.2:
+ resolution: {integrity: sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /des.js/1.0.1:
+ resolution: {integrity: sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==}
+ dependencies:
+ inherits: 2.0.4
+ minimalistic-assert: 1.0.1
+ dev: false
+
+ /diffie-hellman/5.0.3:
+ resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==}
+ dependencies:
+ bn.js: 4.12.0
+ miller-rabin: 4.0.1
+ randombytes: 2.1.0
+ dev: false
+
+ /domain-browser/1.2.0:
+ resolution: {integrity: sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==}
+ engines: {node: '>=0.4', npm: '>=1.2'}
+ dev: false
+
+ /domain-browser/4.19.0:
+ resolution: {integrity: sha512-fRA+BaAWOR/yr/t7T9E9GJztHPeFjj8U35ajyAjCDtAAnTn1Rc1f6W6VGPJrO1tkQv9zWu+JRof7z6oQtiYVFQ==}
+ engines: {node: '>=10'}
+ dev: false
+
+ /dot-case/3.0.4:
+ resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
+ dependencies:
+ no-case: 3.0.4
+ tslib: 2.2.0
+ dev: false
+
+ /electron-to-chromium/1.3.727:
+ resolution: {integrity: sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg==}
+ dev: false
+
+ /elliptic/6.5.4:
+ resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==}
+ dependencies:
+ bn.js: 4.12.0
+ brorand: 1.1.0
+ hash.js: 1.1.7
+ hmac-drbg: 1.0.1
+ inherits: 2.0.4
+ minimalistic-assert: 1.0.1
+ minimalistic-crypto-utils: 1.0.1
+ dev: false
+
+ /emojis-list/2.1.0:
+ resolution: {integrity: sha1-TapNnbAPmBmIDHn6RXrlsJof04k=}
+ engines: {node: '>= 0.10'}
+ dev: false
+
+ /encoding/0.1.13:
+ resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==}
+ dependencies:
+ iconv-lite: 0.6.2
+ dev: false
+
+ /es-abstract/1.18.0:
+ resolution: {integrity: sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ es-to-primitive: 1.2.1
+ function-bind: 1.1.1
+ get-intrinsic: 1.1.1
+ has: 1.0.3
+ has-symbols: 1.0.2
+ is-callable: 1.2.3
+ is-negative-zero: 2.0.1
+ is-regex: 1.1.2
+ is-string: 1.0.5
+ object-inspect: 1.10.2
+ object-keys: 1.1.1
+ object.assign: 4.1.2
+ string.prototype.trimend: 1.0.4
+ string.prototype.trimstart: 1.0.4
+ unbox-primitive: 1.0.1
+ dev: false
+
+ /es-to-primitive/1.2.1:
+ resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ is-callable: 1.2.3
+ is-date-object: 1.0.3
+ is-symbol: 1.0.3
+ dev: false
+
+ /es6-object-assign/1.1.0:
+ resolution: {integrity: sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=}
+ dev: false
+
+ /escalade/3.1.1:
+ resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
+ engines: {node: '>=6'}
+ dev: false
+
+ /escape-string-regexp/1.0.5:
+ resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=}
+ engines: {node: '>=0.8.0'}
+ dev: false
+
+ /esutils/2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
+ /etag/1.8.1:
+ resolution: {integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /events/3.3.0:
+ resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
+ engines: {node: '>=0.8.x'}
+ dev: false
+
+ /evp_bytestokey/1.0.3:
+ resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==}
+ dependencies:
+ md5.js: 1.3.5
+ safe-buffer: 5.2.1
+ dev: false
+
+ /fill-range/7.0.1:
+ resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ to-regex-range: 5.0.1
+ dev: false
+
+ /find-cache-dir/3.3.1:
+ resolution: {integrity: sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ commondir: 1.0.1
+ make-dir: 3.1.0
+ pkg-dir: 4.2.0
+ dev: false
+
+ /find-up/4.1.0:
+ resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
+ engines: {node: '>=8'}
+ dependencies:
+ locate-path: 5.0.0
+ path-exists: 4.0.0
+ dev: false
+
+ /foreach/2.0.5:
+ resolution: {integrity: sha1-C+4AUBiusmDQo6865ljdATbsG5k=}
+ dev: false
+
+ /fsevents/2.3.2:
+ resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+ dev: false
+ optional: true
+
+ /function-bind/1.1.1:
+ resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
+ dev: false
+
+ /get-intrinsic/1.1.1:
+ resolution: {integrity: sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==}
+ dependencies:
+ function-bind: 1.1.1
+ has: 1.0.3
+ has-symbols: 1.0.2
+ dev: false
+
+ /get-orientation/1.1.2:
+ resolution: {integrity: sha512-/pViTfifW+gBbh/RnlFYHINvELT9Znt+SYyDKAUL6uV6By019AK/s+i9XP4jSwq7lwP38Fd8HVeTxym3+hkwmQ==}
+ dependencies:
+ stream-parser: 0.3.1
+ dev: false
+
+ /glob-parent/5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+ dependencies:
+ is-glob: 4.0.1
+ dev: false
+
+ /glob-to-regexp/0.4.1:
+ resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
+ dev: false
+
+ /graceful-fs/4.2.6:
+ resolution: {integrity: sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==}
+ dev: false
+
+ /has-bigints/1.0.1:
+ resolution: {integrity: sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==}
+ dev: false
+
+ /has-flag/3.0.0:
+ resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=}
+ engines: {node: '>=4'}
+ dev: false
+
+ /has-flag/4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+ dev: false
+
+ /has-symbols/1.0.2:
+ resolution: {integrity: sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /has/1.0.3:
+ resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
+ engines: {node: '>= 0.4.0'}
+ dependencies:
+ function-bind: 1.1.1
+ dev: false
+
+ /hash-base/3.1.0:
+ resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==}
+ engines: {node: '>=4'}
+ dependencies:
+ inherits: 2.0.4
+ readable-stream: 3.6.0
+ safe-buffer: 5.2.1
+ dev: false
+
+ /hash.js/1.1.7:
+ resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==}
+ dependencies:
+ inherits: 2.0.4
+ minimalistic-assert: 1.0.1
+ dev: false
+
+ /he/1.2.0:
+ resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
+ hasBin: true
+ dev: false
+
+ /header-case/2.0.4:
+ resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==}
+ dependencies:
+ capital-case: 1.0.4
+ tslib: 2.2.0
+ dev: false
+
+ /hmac-drbg/1.0.1:
+ resolution: {integrity: sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=}
+ dependencies:
+ hash.js: 1.1.7
+ minimalistic-assert: 1.0.1
+ minimalistic-crypto-utils: 1.0.1
+ dev: false
+
+ /http-errors/1.7.3:
+ resolution: {integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==}
+ engines: {node: '>= 0.6'}
+ dependencies:
+ depd: 1.1.2
+ inherits: 2.0.4
+ setprototypeof: 1.1.1
+ statuses: 1.5.0
+ toidentifier: 1.0.0
+ dev: false
+
+ /https-browserify/1.0.0:
+ resolution: {integrity: sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=}
+ dev: false
+
+ /iconv-lite/0.4.24:
+ resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ safer-buffer: 2.1.2
+ dev: false
+
+ /iconv-lite/0.6.2:
+ resolution: {integrity: sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ safer-buffer: 2.1.2
+ dev: false
+
+ /ieee754/1.2.1:
+ resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
+ dev: false
+
+ /inherits/2.0.1:
+ resolution: {integrity: sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=}
+ dev: false
+
+ /inherits/2.0.3:
+ resolution: {integrity: sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=}
+ dev: false
+
+ /inherits/2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+ dev: false
+
+ /is-arguments/1.1.0:
+ resolution: {integrity: sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ dev: false
+
+ /is-bigint/1.0.2:
+ resolution: {integrity: sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==}
+ dev: false
+
+ /is-binary-path/2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+ dependencies:
+ binary-extensions: 2.2.0
+ dev: false
+
+ /is-boolean-object/1.1.0:
+ resolution: {integrity: sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ dev: false
+
+ /is-callable/1.2.3:
+ resolution: {integrity: sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /is-date-object/1.0.3:
+ resolution: {integrity: sha512-tDpEUInNcy2Yw3lNSepK3Wdw1RnXLcIVienz6Ou631Acl15cJyRWK4dgA1vCmOEgIbtOV0W7MHg+AR2Gdg1NXQ==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /is-extglob/2.1.1:
+ resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
+ /is-generator-function/1.0.9:
+ resolution: {integrity: sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /is-glob/4.0.1:
+ resolution: {integrity: sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ is-extglob: 2.1.1
+ dev: false
+
+ /is-nan/1.3.2:
+ resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.3
+ dev: false
+
+ /is-negative-zero/2.0.1:
+ resolution: {integrity: sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /is-number-object/1.0.4:
+ resolution: {integrity: sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /is-number/7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+ dev: false
+
+ /is-regex/1.1.2:
+ resolution: {integrity: sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ has-symbols: 1.0.2
+ dev: false
+
+ /is-string/1.0.5:
+ resolution: {integrity: sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /is-symbol/1.0.3:
+ resolution: {integrity: sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-symbols: 1.0.2
+ dev: false
+
+ /is-typed-array/1.1.5:
+ resolution: {integrity: sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ available-typed-arrays: 1.0.2
+ call-bind: 1.0.2
+ es-abstract: 1.18.0
+ foreach: 2.0.5
+ has-symbols: 1.0.2
+ dev: false
+
+ /isarray/1.0.0:
+ resolution: {integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=}
+ dev: false
+
+ /jest-worker/27.0.0-next.5:
+ resolution: {integrity: sha512-mk0umAQ5lT+CaOJ+Qp01N6kz48sJG2kr2n1rX0koqKf6FIygQV0qLOdN9SCYID4IVeSigDOcPeGLozdMLYfb5g==}
+ engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+ dependencies:
+ '@types/node': 15.0.2
+ merge-stream: 2.0.0
+ supports-color: 8.1.1
+ dev: false
+
+ /js-tokens/4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+ dev: false
+
+ /json5/1.0.1:
+ resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==}
+ hasBin: true
+ dependencies:
+ minimist: 1.2.5
+ dev: false
+
+ /loader-utils/1.2.3:
+ resolution: {integrity: sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==}
+ engines: {node: '>=4.0.0'}
+ dependencies:
+ big.js: 5.2.2
+ emojis-list: 2.1.0
+ json5: 1.0.1
+ dev: false
+
+ /locate-path/5.0.0:
+ resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
+ engines: {node: '>=8'}
+ dependencies:
+ p-locate: 4.1.0
+ dev: false
+
+ /lodash.sortby/4.7.0:
+ resolution: {integrity: sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=}
+ dev: false
+
+ /lodash/4.17.21:
+ resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+ dev: false
+
+ /loose-envify/1.4.0:
+ resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
+ hasBin: true
+ dependencies:
+ js-tokens: 4.0.0
+ dev: false
+
+ /lower-case/2.0.2:
+ resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
+ dependencies:
+ tslib: 2.2.0
+ dev: false
+
+ /make-dir/3.1.0:
+ resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
+ engines: {node: '>=8'}
+ dependencies:
+ semver: 6.3.0
+ dev: false
+
+ /md5.js/1.3.5:
+ resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==}
+ dependencies:
+ hash-base: 3.1.0
+ inherits: 2.0.4
+ safe-buffer: 5.2.1
+ dev: false
+
+ /merge-stream/2.0.0:
+ resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
+ dev: false
+
+ /miller-rabin/4.0.1:
+ resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==}
+ hasBin: true
+ dependencies:
+ bn.js: 4.12.0
+ brorand: 1.1.0
+ dev: false
+
+ /minimalistic-assert/1.0.1:
+ resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==}
+ dev: false
+
+ /minimalistic-crypto-utils/1.0.1:
+ resolution: {integrity: sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=}
+ dev: false
+
+ /minimist/1.2.5:
+ resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==}
+ dev: false
+
+ /ms/2.0.0:
+ resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=}
+ dev: false
+
+ /nanoid/3.1.22:
+ resolution: {integrity: sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+ dev: false
+
+ /native-url/0.3.4:
+ resolution: {integrity: sha512-6iM8R99ze45ivyH8vybJ7X0yekIcPf5GgLV5K0ENCbmRcaRIDoj37BC8iLEmaaBfqqb8enuZ5p0uhY+lVAbAcA==}
+ dependencies:
+ querystring: 0.2.1
+ dev: false
+
+ /next/10.2.0_react-dom@17.0.2+react@17.0.2:
+ resolution: {integrity: sha512-PKDKCSF7s82xudu3kQhOEaokxggpbLEWouEUtzP6OqV0YqKYHF+Ff+BFLycEem8ixtTM2M6ElN0VRJcskJfxPQ==}
+ engines: {node: '>=10.13.0'}
+ hasBin: true
+ peerDependencies:
+ fibers: '>= 3.1.0'
+ node-sass: ^4.0.0 || ^5.0.0
+ react: ^16.6.0 || ^17
+ react-dom: ^16.6.0 || ^17
+ sass: ^1.3.0
+ peerDependenciesMeta:
+ fibers:
+ optional: true
+ node-sass:
+ optional: true
+ sass:
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.12.5
+ '@hapi/accept': 5.0.1
+ '@next/env': 10.2.0
+ '@next/polyfill-module': 10.2.0
+ '@next/react-dev-overlay': 10.2.0_react-dom@17.0.2+react@17.0.2
+ '@next/react-refresh-utils': 10.2.0_react-refresh@0.8.3
+ '@opentelemetry/api': 0.14.0
+ assert: 2.0.0
+ ast-types: 0.13.2
+ browserify-zlib: 0.2.0
+ browserslist: 4.16.1
+ buffer: 5.6.0
+ caniuse-lite: 1.0.30001223
+ chalk: 2.4.2
+ chokidar: 3.5.1
+ constants-browserify: 1.0.0
+ crypto-browserify: 3.12.0
+ cssnano-simple: 2.0.0_postcss@8.2.13
+ domain-browser: 4.19.0
+ encoding: 0.1.13
+ etag: 1.8.1
+ find-cache-dir: 3.3.1
+ get-orientation: 1.1.2
+ https-browserify: 1.0.0
+ jest-worker: 27.0.0-next.5
+ native-url: 0.3.4
+ node-fetch: 2.6.1
+ node-html-parser: 1.4.9
+ node-libs-browser: 2.2.1
+ os-browserify: 0.3.0
+ p-limit: 3.1.0
+ path-browserify: 1.0.1
+ pnp-webpack-plugin: 1.6.4
+ postcss: 8.2.13
+ process: 0.11.10
+ prop-types: 15.7.2
+ querystring-es3: 0.2.1
+ raw-body: 2.4.1
+ react: 17.0.2
+ react-dom: 17.0.2_react@17.0.2
+ react-is: 16.13.1
+ react-refresh: 0.8.3
+ stream-browserify: 3.0.0
+ stream-http: 3.1.1
+ string_decoder: 1.3.0
+ styled-jsx: 3.3.2_react@17.0.2
+ timers-browserify: 2.0.12
+ tty-browserify: 0.0.1
+ use-subscription: 1.5.1_react@17.0.2
+ util: 0.12.3
+ vm-browserify: 1.1.2
+ watchpack: 2.1.1
+ transitivePeerDependencies:
+ - typescript
+ - webpack
+ dev: false
+
+ /no-case/3.0.4:
+ resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
+ dependencies:
+ lower-case: 2.0.2
+ tslib: 2.2.0
+ dev: false
+
+ /node-fetch/2.6.1:
+ resolution: {integrity: sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==}
+ engines: {node: 4.x || >=6.0.0}
+ dev: false
+
+ /node-html-parser/1.4.9:
+ resolution: {integrity: sha512-UVcirFD1Bn0O+TSmloHeHqZZCxHjvtIeGdVdGMhyZ8/PWlEiZaZ5iJzR189yKZr8p0FXN58BUeC7RHRkf/KYGw==}
+ dependencies:
+ he: 1.2.0
+ dev: false
+
+ /node-libs-browser/2.2.1:
+ resolution: {integrity: sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==}
+ dependencies:
+ assert: 1.5.0
+ browserify-zlib: 0.2.0
+ buffer: 4.9.2
+ console-browserify: 1.2.0
+ constants-browserify: 1.0.0
+ crypto-browserify: 3.12.0
+ domain-browser: 1.2.0
+ events: 3.3.0
+ https-browserify: 1.0.0
+ os-browserify: 0.3.0
+ path-browserify: 0.0.1
+ process: 0.11.10
+ punycode: 1.4.1
+ querystring-es3: 0.2.1
+ readable-stream: 2.3.7
+ stream-browserify: 2.0.2
+ stream-http: 2.8.3
+ string_decoder: 1.3.0
+ timers-browserify: 2.0.12
+ tty-browserify: 0.0.0
+ url: 0.11.0
+ util: 0.11.1
+ vm-browserify: 1.1.2
+ dev: false
+
+ /node-releases/1.1.71:
+ resolution: {integrity: sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==}
+ dev: false
+
+ /normalize-path/3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
+ /object-assign/4.1.1:
+ resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
+ /object-inspect/1.10.2:
+ resolution: {integrity: sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==}
+ dev: false
+
+ /object-is/1.1.5:
+ resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.3
+ dev: false
+
+ /object-keys/1.1.1:
+ resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /object.assign/4.1.2:
+ resolution: {integrity: sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.3
+ has-symbols: 1.0.2
+ object-keys: 1.1.1
+ dev: false
+
+ /os-browserify/0.3.0:
+ resolution: {integrity: sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=}
+ dev: false
+
+ /p-limit/2.3.0:
+ resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
+ engines: {node: '>=6'}
+ dependencies:
+ p-try: 2.2.0
+ dev: false
+
+ /p-limit/3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+ dependencies:
+ yocto-queue: 0.1.0
+ dev: false
+
+ /p-locate/4.1.0:
+ resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
+ engines: {node: '>=8'}
+ dependencies:
+ p-limit: 2.3.0
+ dev: false
+
+ /p-try/2.2.0:
+ resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
+ engines: {node: '>=6'}
+ dev: false
+
+ /pako/1.0.11:
+ resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
+ dev: false
+
+ /param-case/3.0.4:
+ resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
+ dependencies:
+ dot-case: 3.0.4
+ tslib: 2.2.0
+ dev: false
+
+ /parse-asn1/5.1.6:
+ resolution: {integrity: sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==}
+ dependencies:
+ asn1.js: 5.4.1
+ browserify-aes: 1.2.0
+ evp_bytestokey: 1.0.3
+ pbkdf2: 3.1.2
+ safe-buffer: 5.2.1
+ dev: false
+
+ /pascal-case/3.1.2:
+ resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==}
+ dependencies:
+ no-case: 3.0.4
+ tslib: 2.2.0
+ dev: false
+
+ /path-browserify/0.0.1:
+ resolution: {integrity: sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==}
+ dev: false
+
+ /path-browserify/1.0.1:
+ resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
+ dev: false
+
+ /path-case/3.0.4:
+ resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==}
+ dependencies:
+ dot-case: 3.0.4
+ tslib: 2.2.0
+ dev: false
+
+ /path-exists/4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+ dev: false
+
+ /pbkdf2/3.1.2:
+ resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==}
+ engines: {node: '>=0.12'}
+ dependencies:
+ create-hash: 1.2.0
+ create-hmac: 1.1.7
+ ripemd160: 2.0.2
+ safe-buffer: 5.2.1
+ sha.js: 2.4.11
+ dev: false
+
+ /peechy/0.3.6:
+ resolution: {integrity: sha512-CUtPbzX8W4wlhHwZhPWhD9iK8q9BX09JfmKzXFUsMkbi49MGPH2X/tnRQJQaCwHiPqYUijzLLcRYmZQOLmo7Nw==}
+ hasBin: true
+ dependencies:
+ change-case: 4.1.2
+ dev: false
+
+ /picomatch/2.2.3:
+ resolution: {integrity: sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==}
+ engines: {node: '>=8.6'}
+ dev: false
+
+ /pkg-dir/4.2.0:
+ resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ find-up: 4.1.0
+ dev: false
+
+ /platform/1.3.6:
+ resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==}
+ dev: false
+
+ /pnp-webpack-plugin/1.6.4:
+ resolution: {integrity: sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==}
+ engines: {node: '>=6'}
+ dependencies:
+ ts-pnp: 1.2.0
+ transitivePeerDependencies:
+ - typescript
+ dev: false
+
+ /postcss/8.2.13:
+ resolution: {integrity: sha512-FCE5xLH+hjbzRdpbRb1IMCvPv9yZx2QnDarBEYSN0N0HYk+TcXsEhwdFcFb+SRWOKzKGErhIEbBK2ogyLdTtfQ==}
+ engines: {node: ^10 || ^12 || >=14}
+ dependencies:
+ colorette: 1.2.2
+ nanoid: 3.1.22
+ source-map: 0.6.1
+ dev: false
+
+ /process-nextick-args/2.0.1:
+ resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
+ dev: false
+
+ /process/0.11.10:
+ resolution: {integrity: sha1-czIwDoQBYb2j5podHZGn1LwW8YI=}
+ engines: {node: '>= 0.6.0'}
+ dev: false
+
+ /prop-types/15.7.2:
+ resolution: {integrity: sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==}
+ dependencies:
+ loose-envify: 1.4.0
+ object-assign: 4.1.1
+ react-is: 16.13.1
+ dev: false
+
+ /public-encrypt/4.0.3:
+ resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==}
+ dependencies:
+ bn.js: 4.12.0
+ browserify-rsa: 4.1.0
+ create-hash: 1.2.0
+ parse-asn1: 5.1.6
+ randombytes: 2.1.0
+ safe-buffer: 5.2.1
+ dev: false
+
+ /punycode/1.3.2:
+ resolution: {integrity: sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=}
+ dev: false
+
+ /punycode/1.4.1:
+ resolution: {integrity: sha1-wNWmOycYgArY4esPpSachN1BhF4=}
+ dev: false
+
+ /punycode/2.1.1:
+ resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
+ engines: {node: '>=6'}
+ dev: false
+
+ /querystring-es3/0.2.1:
+ resolution: {integrity: sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=}
+ engines: {node: '>=0.4.x'}
+ dev: false
+
+ /querystring/0.2.0:
+ resolution: {integrity: sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=}
+ engines: {node: '>=0.4.x'}
+ dev: false
+
+ /querystring/0.2.1:
+ resolution: {integrity: sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==}
+ engines: {node: '>=0.4.x'}
+ dev: false
+
+ /randombytes/2.1.0:
+ resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
+ dependencies:
+ safe-buffer: 5.2.1
+ dev: false
+
+ /randomfill/1.0.4:
+ resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==}
+ dependencies:
+ randombytes: 2.1.0
+ safe-buffer: 5.2.1
+ dev: false
+
+ /raw-body/2.4.1:
+ resolution: {integrity: sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==}
+ engines: {node: '>= 0.8'}
+ dependencies:
+ bytes: 3.1.0
+ http-errors: 1.7.3
+ iconv-lite: 0.4.24
+ unpipe: 1.0.0
+ dev: false
+
+ /react-dom/17.0.2_react@17.0.2:
+ resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==}
+ peerDependencies:
+ react: 17.0.2
+ dependencies:
+ loose-envify: 1.4.0
+ object-assign: 4.1.1
+ react: 17.0.2
+ scheduler: 0.20.2
+ dev: false
+
+ /react-is/16.13.1:
+ resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
+ dev: false
+
+ /react-refresh/0.8.3:
+ resolution: {integrity: sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
+ /react/17.0.2:
+ resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ loose-envify: 1.4.0
+ object-assign: 4.1.1
+ dev: false
+
+ /readable-stream/2.3.7:
+ resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==}
+ dependencies:
+ core-util-is: 1.0.2
+ inherits: 2.0.4
+ isarray: 1.0.0
+ process-nextick-args: 2.0.1
+ safe-buffer: 5.1.2
+ string_decoder: 1.1.1
+ util-deprecate: 1.0.2
+ dev: false
+
+ /readable-stream/3.6.0:
+ resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==}
+ engines: {node: '>= 6'}
+ dependencies:
+ inherits: 2.0.4
+ string_decoder: 1.3.0
+ util-deprecate: 1.0.2
+ dev: false
+
+ /readdirp/3.5.0:
+ resolution: {integrity: sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==}
+ engines: {node: '>=8.10.0'}
+ dependencies:
+ picomatch: 2.2.3
+ dev: false
+
+ /regenerator-runtime/0.13.7:
+ resolution: {integrity: sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==}
+ dev: false
+
+ /ripemd160/2.0.2:
+ resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==}
+ dependencies:
+ hash-base: 3.1.0
+ inherits: 2.0.4
+ dev: false
+
+ /safe-buffer/5.1.2:
+ resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
+ dev: false
+
+ /safe-buffer/5.2.1:
+ resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+ dev: false
+
+ /safer-buffer/2.1.2:
+ resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+ dev: false
+
+ /scheduler/0.20.2:
+ resolution: {integrity: sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==}
+ dependencies:
+ loose-envify: 1.4.0
+ object-assign: 4.1.1
+ dev: false
+
+ /semver/6.3.0:
+ resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==}
+ hasBin: true
+ dev: false
+
+ /sentence-case/3.0.4:
+ resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==}
+ dependencies:
+ no-case: 3.0.4
+ tslib: 2.2.0
+ upper-case-first: 2.0.2
+ dev: false
+
+ /setimmediate/1.0.5:
+ resolution: {integrity: sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=}
+ dev: false
+
+ /setprototypeof/1.1.1:
+ resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==}
+ dev: false
+
+ /sha.js/2.4.11:
+ resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==}
+ hasBin: true
+ dependencies:
+ inherits: 2.0.4
+ safe-buffer: 5.2.1
+ dev: false
+
+ /shell-quote/1.7.2:
+ resolution: {integrity: sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==}
+ dev: false
+
+ /snake-case/3.0.4:
+ resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
+ dependencies:
+ dot-case: 3.0.4
+ tslib: 2.2.0
+ dev: false
+
+ /source-map/0.6.1:
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
+ /source-map/0.7.3:
+ resolution: {integrity: sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==}
+ engines: {node: '>= 8'}
+ dev: false
+
+ /source-map/0.8.0-beta.0:
+ resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==}
+ engines: {node: '>= 8'}
+ dependencies:
+ whatwg-url: 7.1.0
+ dev: false
+
+ /stacktrace-parser/0.1.10:
+ resolution: {integrity: sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==}
+ engines: {node: '>=6'}
+ dependencies:
+ type-fest: 0.7.1
+ dev: false
+
+ /statuses/1.5.0:
+ resolution: {integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /stream-browserify/2.0.2:
+ resolution: {integrity: sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==}
+ dependencies:
+ inherits: 2.0.4
+ readable-stream: 2.3.7
+ dev: false
+
+ /stream-browserify/3.0.0:
+ resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==}
+ dependencies:
+ inherits: 2.0.4
+ readable-stream: 3.6.0
+ dev: false
+
+ /stream-http/2.8.3:
+ resolution: {integrity: sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==}
+ dependencies:
+ builtin-status-codes: 3.0.0
+ inherits: 2.0.4
+ readable-stream: 2.3.7
+ to-arraybuffer: 1.0.1
+ xtend: 4.0.2
+ dev: false
+
+ /stream-http/3.1.1:
+ resolution: {integrity: sha512-S7OqaYu0EkFpgeGFb/NPOoPLxFko7TPqtEeFg5DXPB4v/KETHG0Ln6fRFrNezoelpaDKmycEmmZ81cC9DAwgYg==}
+ dependencies:
+ builtin-status-codes: 3.0.0
+ inherits: 2.0.4
+ readable-stream: 3.6.0
+ xtend: 4.0.2
+ dev: false
+
+ /stream-parser/0.3.1:
+ resolution: {integrity: sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M=}
+ dependencies:
+ debug: 2.6.9
+ dev: false
+
+ /string-hash/1.1.3:
+ resolution: {integrity: sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=}
+ dev: false
+
+ /string.prototype.trimend/1.0.4:
+ resolution: {integrity: sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.3
+ dev: false
+
+ /string.prototype.trimstart/1.0.4:
+ resolution: {integrity: sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.3
+ dev: false
+
+ /string_decoder/1.1.1:
+ resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
+ dependencies:
+ safe-buffer: 5.1.2
+ dev: false
+
+ /string_decoder/1.3.0:
+ resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
+ dependencies:
+ safe-buffer: 5.2.1
+ dev: false
+
+ /strip-ansi/6.0.0:
+ resolution: {integrity: sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==}
+ engines: {node: '>=8'}
+ dependencies:
+ ansi-regex: 5.0.0
+ dev: false
+
+ /styled-jsx/3.3.2_react@17.0.2:
+ resolution: {integrity: sha512-daAkGd5mqhbBhLd6jYAjYBa9LpxYCzsgo/f6qzPdFxVB8yoGbhxvzQgkC0pfmCVvW3JuAEBn0UzFLBfkHVZG1g==}
+ peerDependencies:
+ react: 15.x.x || 16.x.x || 17.x.x
+ dependencies:
+ '@babel/types': 7.8.3
+ babel-plugin-syntax-jsx: 6.18.0
+ convert-source-map: 1.7.0
+ loader-utils: 1.2.3
+ react: 17.0.2
+ source-map: 0.7.3
+ string-hash: 1.1.3
+ stylis: 3.5.4
+ stylis-rule-sheet: 0.0.10_stylis@3.5.4
+ dev: false
+
+ /stylis-rule-sheet/0.0.10_stylis@3.5.4:
+ resolution: {integrity: sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==}
+ peerDependencies:
+ stylis: ^3.5.0
+ dependencies:
+ stylis: 3.5.4
+ dev: false
+
+ /stylis/3.5.4:
+ resolution: {integrity: sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==}
+ dev: false
+
+ /supports-color/5.5.0:
+ resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
+ engines: {node: '>=4'}
+ dependencies:
+ has-flag: 3.0.0
+ dev: false
+
+ /supports-color/7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+ dependencies:
+ has-flag: 4.0.0
+ dev: false
+
+ /supports-color/8.1.1:
+ resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
+ engines: {node: '>=10'}
+ dependencies:
+ has-flag: 4.0.0
+ dev: false
+
+ /timers-browserify/2.0.12:
+ resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==}
+ engines: {node: '>=0.6.0'}
+ dependencies:
+ setimmediate: 1.0.5
+ dev: false
+
+ /to-arraybuffer/1.0.1:
+ resolution: {integrity: sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=}
+ dev: false
+
+ /to-fast-properties/2.0.0:
+ resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=}
+ engines: {node: '>=4'}
+ dev: false
+
+ /to-regex-range/5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+ dependencies:
+ is-number: 7.0.0
+ dev: false
+
+ /toidentifier/1.0.0:
+ resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==}
+ engines: {node: '>=0.6'}
+ dev: false
+
+ /tr46/1.0.1:
+ resolution: {integrity: sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=}
+ dependencies:
+ punycode: 2.1.1
+ dev: false
+
+ /ts-pnp/1.2.0:
+ resolution: {integrity: sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==}
+ engines: {node: '>=6'}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dev: false
+
+ /tslib/2.2.0:
+ resolution: {integrity: sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==}
+ dev: false
+
+ /tty-browserify/0.0.0:
+ resolution: {integrity: sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=}
+ dev: false
+
+ /tty-browserify/0.0.1:
+ resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==}
+ dev: false
+
+ /type-fest/0.7.1:
+ resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==}
+ engines: {node: '>=8'}
+ dev: false
+
+ /unbox-primitive/1.0.1:
+ resolution: {integrity: sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==}
+ dependencies:
+ function-bind: 1.1.1
+ has-bigints: 1.0.1
+ has-symbols: 1.0.2
+ which-boxed-primitive: 1.0.2
+ dev: false
+
+ /unpipe/1.0.0:
+ resolution: {integrity: sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=}
+ engines: {node: '>= 0.8'}
+ dev: false
+
+ /upper-case-first/2.0.2:
+ resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==}
+ dependencies:
+ tslib: 2.2.0
+ dev: false
+
+ /upper-case/2.0.2:
+ resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==}
+ dependencies:
+ tslib: 2.2.0
+ dev: false
+
+ /url/0.11.0:
+ resolution: {integrity: sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=}
+ dependencies:
+ punycode: 1.3.2
+ querystring: 0.2.0
+ dev: false
+
+ /use-subscription/1.5.1_react@17.0.2:
+ resolution: {integrity: sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ dependencies:
+ object-assign: 4.1.1
+ react: 17.0.2
+ dev: false
+
+ /util-deprecate/1.0.2:
+ resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=}
+ dev: false
+
+ /util/0.10.3:
+ resolution: {integrity: sha1-evsa/lCAUkZInj23/g7TeTNqwPk=}
+ dependencies:
+ inherits: 2.0.1
+ dev: false
+
+ /util/0.11.1:
+ resolution: {integrity: sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==}
+ dependencies:
+ inherits: 2.0.3
+ dev: false
+
+ /util/0.12.3:
+ resolution: {integrity: sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==}
+ dependencies:
+ inherits: 2.0.4
+ is-arguments: 1.1.0
+ is-generator-function: 1.0.9
+ is-typed-array: 1.1.5
+ safe-buffer: 5.2.1
+ which-typed-array: 1.1.4
+ dev: false
+
+ /vm-browserify/1.1.2:
+ resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==}
+ dev: false
+
+ /watchpack/2.1.1:
+ resolution: {integrity: sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==}
+ engines: {node: '>=10.13.0'}
+ dependencies:
+ glob-to-regexp: 0.4.1
+ graceful-fs: 4.2.6
+ dev: false
+
+ /webidl-conversions/4.0.2:
+ resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
+ dev: false
+
+ /whatwg-url/7.1.0:
+ resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
+ dependencies:
+ lodash.sortby: 4.7.0
+ tr46: 1.0.1
+ webidl-conversions: 4.0.2
+ dev: false
+
+ /which-boxed-primitive/1.0.2:
+ resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
+ dependencies:
+ is-bigint: 1.0.2
+ is-boolean-object: 1.1.0
+ is-number-object: 1.0.4
+ is-string: 1.0.5
+ is-symbol: 1.0.3
+ dev: false
+
+ /which-typed-array/1.1.4:
+ resolution: {integrity: sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ available-typed-arrays: 1.0.2
+ call-bind: 1.0.2
+ es-abstract: 1.18.0
+ foreach: 2.0.5
+ function-bind: 1.1.1
+ has-symbols: 1.0.2
+ is-typed-array: 1.1.5
+ dev: false
+
+ /xtend/4.0.2:
+ resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
+ engines: {node: '>=0.4'}
+ dev: false
+
+ /yocto-queue/0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+ dev: false
diff --git a/src/api/demo/public/favicon.ico b/src/api/demo/public/favicon.ico
new file mode 100644
index 000000000..4965832f2
--- /dev/null
+++ b/src/api/demo/public/favicon.ico
Binary files differ
diff --git a/src/api/demo/public/vercel.svg b/src/api/demo/public/vercel.svg
new file mode 100644
index 000000000..fbf0e25a6
--- /dev/null
+++ b/src/api/demo/public/vercel.svg
@@ -0,0 +1,4 @@
+<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
+ xmlns="http://www.w3.org/2000/svg">
+ <path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
+</svg> \ No newline at end of file
diff --git a/src/api/demo/styles/Home.module.css b/src/api/demo/styles/Home.module.css
new file mode 100644
index 000000000..35454bb74
--- /dev/null
+++ b/src/api/demo/styles/Home.module.css
@@ -0,0 +1,121 @@
+.container {
+ min-height: 100vh;
+ padding: 0 0.5rem;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+}
+
+.main {
+ padding: 5rem 0;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.footer {
+ width: 100%;
+ height: 100px;
+ border-top: 1px solid #eaeaea;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.footer a {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-grow: 1;
+}
+
+.title a {
+ color: #0070f3;
+ text-decoration: none;
+}
+
+.title a:hover,
+.title a:focus,
+.title a:active {
+ text-decoration: underline;
+}
+
+.title {
+ margin: 0;
+ line-height: 1.15;
+ font-size: 4rem;
+}
+
+.title,
+.description {
+ text-align: center;
+}
+
+.description {
+ line-height: 1.5;
+ font-size: 1.5rem;
+}
+
+.code {
+ background: #fafafa;
+ border-radius: 5px;
+ padding: 0.75rem;
+ font-size: 1.1rem;
+ font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
+ Bitstream Vera Sans Mono, Courier New, monospace;
+}
+
+.grid {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-wrap: wrap;
+ max-width: 800px;
+ margin-top: 3rem;
+}
+
+.card {
+ margin: 1rem;
+ padding: 1.5rem;
+ text-align: left;
+ color: inherit;
+ text-decoration: none;
+ border: 1px solid #eaeaea;
+ border-radius: 10px;
+ transition: color 0.15s ease, border-color 0.15s ease;
+ width: 45%;
+}
+
+.card:hover,
+.card:focus,
+.card:active {
+ color: #0070f3;
+ border-color: #0070f3;
+}
+
+.card h2 {
+ margin: 0 0 1rem 0;
+ font-size: 1.5rem;
+}
+
+.card p {
+ margin: 0;
+ font-size: 1.25rem;
+ line-height: 1.5;
+}
+
+.logo {
+ height: 1em;
+ margin-left: 0.5rem;
+}
+
+@media (max-width: 600px) {
+ .grid {
+ width: 100%;
+ flex-direction: column;
+ }
+}
diff --git a/src/api/demo/styles/globals.css b/src/api/demo/styles/globals.css
new file mode 100644
index 000000000..e5e2dcc23
--- /dev/null
+++ b/src/api/demo/styles/globals.css
@@ -0,0 +1,16 @@
+html,
+body {
+ padding: 0;
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
+ Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+* {
+ box-sizing: border-box;
+}
diff --git a/src/api/schema.d.ts b/src/api/schema.d.ts
new file mode 100644
index 000000000..f89eb0e40
--- /dev/null
+++ b/src/api/schema.d.ts
@@ -0,0 +1,188 @@
+import type { ByteBuffer } from "peechy";
+
+type byte = number;
+type float = number;
+type int = number;
+type alphanumeric = string;
+type uint = number;
+type int8 = number;
+type lowp = number;
+type int16 = number;
+type int32 = number;
+type float32 = number;
+type uint16 = number;
+type uint32 = number;
+export enum Loader {
+ jsx = 1,
+ js = 2,
+ ts = 3,
+ tsx = 4,
+ css = 5,
+ file = 6,
+ json = 7,
+}
+export const LoaderKeys = {
+ 1: "jsx",
+ jsx: "jsx",
+ 2: "js",
+ js: "js",
+ 3: "ts",
+ ts: "ts",
+ 4: "tsx",
+ tsx: "tsx",
+ 5: "css",
+ css: "css",
+ 6: "file",
+ file: "file",
+ 7: "json",
+ json: "json",
+};
+export enum JSXRuntime {
+ automatic = 1,
+ classic = 2,
+}
+export const JSXRuntimeKeys = {
+ 1: "automatic",
+ automatic: "automatic",
+ 2: "classic",
+ classic: "classic",
+};
+export enum TransformResponseStatus {
+ success = 1,
+ fail = 2,
+}
+export const TransformResponseStatusKeys = {
+ 1: "success",
+ success: "success",
+ 2: "fail",
+ fail: "fail",
+};
+export enum MessageKind {
+ err = 1,
+ warn = 2,
+ note = 3,
+ debug = 4,
+}
+export const MessageKindKeys = {
+ 1: "err",
+ err: "err",
+ 2: "warn",
+ warn: "warn",
+ 3: "note",
+ note: "note",
+ 4: "debug",
+ debug: "debug",
+};
+export interface JSX {
+ factory: string;
+ runtime: JSXRuntime;
+ fragment: string;
+ production: boolean;
+ import_source: string;
+ react_fast_refresh: boolean;
+ loader_keys: string[];
+ loader_values: Loader[];
+}
+
+export interface TransformOptions {
+ jsx: JSX;
+ ts: boolean;
+ base_path: string;
+ define_keys: string[];
+ define_values: string[];
+}
+
+export interface FileHandle {
+ path: string;
+ size: uint;
+ fd: uint;
+}
+
+export interface Transform {
+ handle?: FileHandle;
+ path?: string;
+ contents?: string;
+ loader?: Loader;
+ options?: TransformOptions;
+}
+
+export interface OutputFile {
+ data: Uint8Array;
+ path: string;
+}
+
+export interface TransformResponse {
+ status: TransformResponseStatus;
+ files: OutputFile[];
+ errors: Message[];
+}
+
+export interface Location {
+ file: string;
+ namespace: string;
+ line: int32;
+ column: int32;
+ line_text: string;
+ suggestion: string;
+ offset: uint;
+}
+
+export interface MessageData {
+ text?: string;
+ location?: Location;
+}
+
+export interface Message {
+ kind: MessageKind;
+ data: MessageData;
+ notes: MessageData[];
+}
+
+export interface Log {
+ warnings: uint32;
+ errors: uint32;
+ msgs: Message[];
+}
+
+export declare function encodeJSX(message: JSX, bb: ByteBuffer): void;
+export declare function decodeJSX(buffer: ByteBuffer): JSX;
+export declare function encodeTransformOptions(
+ message: TransformOptions,
+ bb: ByteBuffer
+): void;
+export declare function decodeTransformOptions(
+ buffer: ByteBuffer
+): TransformOptions;
+export declare function encodeFileHandle(
+ message: FileHandle,
+ bb: ByteBuffer
+): void;
+export declare function decodeFileHandle(buffer: ByteBuffer): FileHandle;
+export declare function encodeTransform(
+ message: Transform,
+ bb: ByteBuffer
+): void;
+export declare function decodeTransform(buffer: ByteBuffer): Transform;
+export declare function encodeOutputFile(
+ message: OutputFile,
+ bb: ByteBuffer
+): void;
+export declare function decodeOutputFile(buffer: ByteBuffer): OutputFile;
+export declare function encodeTransformResponse(
+ message: TransformResponse,
+ bb: ByteBuffer
+): void;
+export declare function decodeTransformResponse(
+ buffer: ByteBuffer
+): TransformResponse;
+export declare function encodeLocation(message: Location, bb: ByteBuffer): void;
+export declare function decodeLocation(buffer: ByteBuffer): Location;
+export declare function encodeMessageData(
+ message: MessageData,
+ bb: ByteBuffer
+): void;
+export declare function decodeMessageData(buffer: ByteBuffer): MessageData;
+export declare function encodeMessage(message: Message, bb: ByteBuffer): void;
+export declare function decodeMessage(buffer: ByteBuffer): Message;
+export declare function encodeLog(message: Log, bb: ByteBuffer): void;
+export declare function decodeLog(buffer: ByteBuffer): Log;
diff --git a/src/api/schema.js b/src/api/schema.js
new file mode 100644
index 000000000..9f6947b33
--- /dev/null
+++ b/src/api/schema.js
@@ -0,0 +1,631 @@
+const Loader = {
+ "1": 1,
+ "2": 2,
+ "3": 3,
+ "4": 4,
+ "5": 5,
+ "6": 6,
+ "7": 7,
+ "jsx": 1,
+ "js": 2,
+ "ts": 3,
+ "tsx": 4,
+ "css": 5,
+ "file": 6,
+ "json": 7
+};
+const LoaderKeys = {
+ "1": "jsx",
+ "2": "js",
+ "3": "ts",
+ "4": "tsx",
+ "5": "css",
+ "6": "file",
+ "7": "json",
+ "jsx": "jsx",
+ "js": "js",
+ "ts": "ts",
+ "tsx": "tsx",
+ "css": "css",
+ "file": "file",
+ "json": "json"
+};
+const JSXRuntime = {
+ "1": 1,
+ "2": 2,
+ "automatic": 1,
+ "classic": 2
+};
+const JSXRuntimeKeys = {
+ "1": "automatic",
+ "2": "classic",
+ "automatic": "automatic",
+ "classic": "classic"
+};
+
+function decodeJSX(bb) {
+ var result = {};
+
+ result["factory"] = bb.readString();
+ result["runtime"] = JSXRuntime[bb.readByte()];
+ result["fragment"] = bb.readString();
+ result["production"] = !!bb.readByte();
+ result["import_source"] = bb.readString();
+ result["react_fast_refresh"] = !!bb.readByte();
+ var length = bb.readVarUint();
+ var values = result["loader_keys"] = Array(length);
+ for (var i = 0; i < length; i++) values[i] = bb.readString();
+ var length = bb.readVarUint();
+ var values = result["loader_values"] = Array(length);
+ for (var i = 0; i < length; i++) values[i] = Loader[bb.readByte()];
+ return result;
+}
+
+function encodeJSX(message, bb) {
+
+ var value = message["factory"];
+ if (value != null) {
+ bb.writeString(value);
+ } else {
+ throw new Error("Missing required field \"factory\"");
+ }
+
+ var value = message["runtime"];
+ if (value != null) {
+ var encoded = JSXRuntime[value];
+if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"JSXRuntime\"");
+bb.writeByte(encoded);
+ } else {
+ throw new Error("Missing required field \"runtime\"");
+ }
+
+ var value = message["fragment"];
+ if (value != null) {
+ bb.writeString(value);
+ } else {
+ throw new Error("Missing required field \"fragment\"");
+ }
+
+ var value = message["production"];
+ if (value != null) {
+ bb.writeByte(value);
+ } else {
+ throw new Error("Missing required field \"production\"");
+ }
+
+ var value = message["import_source"];
+ if (value != null) {
+ bb.writeString(value);
+ } else {
+ throw new Error("Missing required field \"import_source\"");
+ }
+
+ var value = message["react_fast_refresh"];
+ if (value != null) {
+ bb.writeByte(value);
+ } else {
+ throw new Error("Missing required field \"react_fast_refresh\"");
+ }
+
+ var value = message["loader_keys"];
+ if (value != null) {
+ var values = value, n = values.length;
+ bb.writeVarUint(n);
+ for (var i = 0; i < n; i++) {
+ value = values[i];
+ bb.writeString(value);
+ }
+ } else {
+ throw new Error("Missing required field \"loader_keys\"");
+ }
+
+ var value = message["loader_values"];
+ if (value != null) {
+ var values = value, n = values.length;
+ bb.writeVarUint(n);
+ for (var i = 0; i < n; i++) {
+ value = values[i];
+ var encoded = Loader[value];
+if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"Loader\"");
+bb.writeByte(encoded);
+ }
+ } else {
+ throw new Error("Missing required field \"loader_values\"");
+ }
+
+}
+
+function decodeTransformOptions(bb) {
+ var result = {};
+
+ result["jsx"] = decodeJSX(bb);
+ result["ts"] = !!bb.readByte();
+ result["base_path"] = bb.readString();
+ var length = bb.readVarUint();
+ var values = result["define_keys"] = Array(length);
+ for (var i = 0; i < length; i++) values[i] = bb.readString();
+ var length = bb.readVarUint();
+ var values = result["define_values"] = Array(length);
+ for (var i = 0; i < length; i++) values[i] = bb.readString();
+ return result;
+}
+
+function encodeTransformOptions(message, bb) {
+
+ var value = message["jsx"];
+ if (value != null) {
+ encodeJSX(value, bb);
+ } else {
+ throw new Error("Missing required field \"jsx\"");
+ }
+
+ var value = message["ts"];
+ if (value != null) {
+ bb.writeByte(value);
+ } else {
+ throw new Error("Missing required field \"ts\"");
+ }
+
+ var value = message["base_path"];
+ if (value != null) {
+ bb.writeString(value);
+ } else {
+ throw new Error("Missing required field \"base_path\"");
+ }
+
+ var value = message["define_keys"];
+ if (value != null) {
+ var values = value, n = values.length;
+ bb.writeVarUint(n);
+ for (var i = 0; i < n; i++) {
+ value = values[i];
+ bb.writeString(value);
+ }
+ } else {
+ throw new Error("Missing required field \"define_keys\"");
+ }
+
+ var value = message["define_values"];
+ if (value != null) {
+ var values = value, n = values.length;
+ bb.writeVarUint(n);
+ for (var i = 0; i < n; i++) {
+ value = values[i];
+ bb.writeString(value);
+ }
+ } else {
+ throw new Error("Missing required field \"define_values\"");
+ }
+
+}
+
+function decodeFileHandle(bb) {
+ var result = {};
+
+ result["path"] = bb.readString();
+ result["size"] = bb.readVarUint();
+ result["fd"] = bb.readVarUint();
+ return result;
+}
+
+function encodeFileHandle(message, bb) {
+
+ var value = message["path"];
+ if (value != null) {
+ bb.writeString(value);
+ } else {
+ throw new Error("Missing required field \"path\"");
+ }
+
+ var value = message["size"];
+ if (value != null) {
+ bb.writeVarUint(value);
+ } else {
+ throw new Error("Missing required field \"size\"");
+ }
+
+ var value = message["fd"];
+ if (value != null) {
+ bb.writeVarUint(value);
+ } else {
+ throw new Error("Missing required field \"fd\"");
+ }
+
+}
+
+function decodeTransform(bb) {
+ var result = {};
+
+ while (true) {
+ switch (bb.readVarUint()) {
+ case 0:
+ return result;
+
+ case 1:
+ result["handle"] = decodeFileHandle(bb);
+ break;
+
+ case 2:
+ result["path"] = bb.readString();
+ break;
+
+ case 3:
+ result["contents"] = bb.readString();
+ break;
+
+ case 4:
+ result["loader"] = Loader[bb.readByte()];
+ break;
+
+ case 5:
+ result["options"] = decodeTransformOptions(bb);
+ break;
+
+ default:
+ throw new Error("Attempted to parse invalid message");
+ }
+ }
+}
+
+function encodeTransform(message, bb) {
+
+ var value = message["handle"];
+ if (value != null) {
+ bb.writeVarUint(1);
+ encodeFileHandle(value, bb);
+ }
+
+ var value = message["path"];
+ if (value != null) {
+ bb.writeVarUint(2);
+ bb.writeString(value);
+ }
+
+ var value = message["contents"];
+ if (value != null) {
+ bb.writeVarUint(3);
+ bb.writeString(value);
+ }
+
+ var value = message["loader"];
+ if (value != null) {
+ bb.writeVarUint(4);
+ var encoded = Loader[value];
+if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"Loader\"");
+bb.writeByte(encoded);
+ }
+
+ var value = message["options"];
+ if (value != null) {
+ bb.writeVarUint(5);
+ encodeTransformOptions(value, bb);
+ }
+ bb.writeVarUint(0);
+
+}
+const TransformResponseStatus = {
+ "1": 1,
+ "2": 2,
+ "success": 1,
+ "fail": 2
+};
+const TransformResponseStatusKeys = {
+ "1": "success",
+ "2": "fail",
+ "success": "success",
+ "fail": "fail"
+};
+
+function decodeOutputFile(bb) {
+ var result = {};
+
+ result["data"] = bb.readByteArray();
+ result["path"] = bb.readString();
+ return result;
+}
+
+function encodeOutputFile(message, bb) {
+
+ var value = message["data"];
+ if (value != null) {
+ bb.writeByteArray(value);
+ } else {
+ throw new Error("Missing required field \"data\"");
+ }
+
+ var value = message["path"];
+ if (value != null) {
+ bb.writeString(value);
+ } else {
+ throw new Error("Missing required field \"path\"");
+ }
+
+}
+
+function decodeTransformResponse(bb) {
+ var result = {};
+
+ result["status"] = TransformResponseStatus[bb.readVarUint()];
+ var length = bb.readVarUint();
+ var values = result["files"] = Array(length);
+ for (var i = 0; i < length; i++) values[i] = decodeOutputFile(bb);
+ var length = bb.readVarUint();
+ var values = result["errors"] = Array(length);
+ for (var i = 0; i < length; i++) values[i] = decodeMessage(bb);
+ return result;
+}
+
+function encodeTransformResponse(message, bb) {
+
+ var value = message["status"];
+ if (value != null) {
+ var encoded = TransformResponseStatus[value];
+if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"TransformResponseStatus\"");
+bb.writeVarUint(encoded);
+ } else {
+ throw new Error("Missing required field \"status\"");
+ }
+
+ var value = message["files"];
+ if (value != null) {
+ var values = value, n = values.length;
+ bb.writeVarUint(n);
+ for (var i = 0; i < n; i++) {
+ value = values[i];
+ encodeOutputFile(value, bb);
+ }
+ } else {
+ throw new Error("Missing required field \"files\"");
+ }
+
+ var value = message["errors"];
+ if (value != null) {
+ var values = value, n = values.length;
+ bb.writeVarUint(n);
+ for (var i = 0; i < n; i++) {
+ value = values[i];
+ encodeMessage(value, bb);
+ }
+ } else {
+ throw new Error("Missing required field \"errors\"");
+ }
+
+}
+const MessageKind = {
+ "1": 1,
+ "2": 2,
+ "3": 3,
+ "4": 4,
+ "err": 1,
+ "warn": 2,
+ "note": 3,
+ "debug": 4
+};
+const MessageKindKeys = {
+ "1": "err",
+ "2": "warn",
+ "3": "note",
+ "4": "debug",
+ "err": "err",
+ "warn": "warn",
+ "note": "note",
+ "debug": "debug"
+};
+
+function decodeLocation(bb) {
+ var result = {};
+
+ result["file"] = bb.readString();
+ result["namespace"] = bb.readString();
+ result["line"] = bb.readInt32();
+ result["column"] = bb.readInt32();
+ result["line_text"] = bb.readString();
+ result["suggestion"] = bb.readString();
+ result["offset"] = bb.readVarUint();
+ return result;
+}
+
+function encodeLocation(message, bb) {
+
+ var value = message["file"];
+ if (value != null) {
+ bb.writeString(value);
+ } else {
+ throw new Error("Missing required field \"file\"");
+ }
+
+ var value = message["namespace"];
+ if (value != null) {
+ bb.writeString(value);
+ } else {
+ throw new Error("Missing required field \"namespace\"");
+ }
+
+ var value = message["line"];
+ if (value != null) {
+ bb.writeInt32(value);
+ } else {
+ throw new Error("Missing required field \"line\"");
+ }
+
+ var value = message["column"];
+ if (value != null) {
+ bb.writeInt32(value);
+ } else {
+ throw new Error("Missing required field \"column\"");
+ }
+
+ var value = message["line_text"];
+ if (value != null) {
+ bb.writeString(value);
+ } else {
+ throw new Error("Missing required field \"line_text\"");
+ }
+
+ var value = message["suggestion"];
+ if (value != null) {
+ bb.writeString(value);
+ } else {
+ throw new Error("Missing required field \"suggestion\"");
+ }
+
+ var value = message["offset"];
+ if (value != null) {
+ bb.writeVarUint(value);
+ } else {
+ throw new Error("Missing required field \"offset\"");
+ }
+
+}
+
+function decodeMessageData(bb) {
+ var result = {};
+
+ while (true) {
+ switch (bb.readVarUint()) {
+ case 0:
+ return result;
+
+ case 1:
+ result["text"] = bb.readString();
+ break;
+
+ case 2:
+ result["location"] = decodeLocation(bb);
+ break;
+
+ default:
+ throw new Error("Attempted to parse invalid message");
+ }
+ }
+}
+
+function encodeMessageData(message, bb) {
+
+ var value = message["text"];
+ if (value != null) {
+ bb.writeVarUint(1);
+ bb.writeString(value);
+ }
+
+ var value = message["location"];
+ if (value != null) {
+ bb.writeVarUint(2);
+ encodeLocation(value, bb);
+ }
+ bb.writeVarUint(0);
+
+}
+
+function decodeMessage(bb) {
+ var result = {};
+
+ result["kind"] = MessageKind[bb.readVarUint()];
+ result["data"] = decodeMessageData(bb);
+ var length = bb.readVarUint();
+ var values = result["notes"] = Array(length);
+ for (var i = 0; i < length; i++) values[i] = decodeMessageData(bb);
+ return result;
+}
+
+function encodeMessage(message, bb) {
+
+ var value = message["kind"];
+ if (value != null) {
+ var encoded = MessageKind[value];
+if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"MessageKind\"");
+bb.writeVarUint(encoded);
+ } else {
+ throw new Error("Missing required field \"kind\"");
+ }
+
+ var value = message["data"];
+ if (value != null) {
+ encodeMessageData(value, bb);
+ } else {
+ throw new Error("Missing required field \"data\"");
+ }
+
+ var value = message["notes"];
+ if (value != null) {
+ var values = value, n = values.length;
+ bb.writeVarUint(n);
+ for (var i = 0; i < n; i++) {
+ value = values[i];
+ encodeMessageData(value, bb);
+ }
+ } else {
+ throw new Error("Missing required field \"notes\"");
+ }
+
+}
+
+function decodeLog(bb) {
+ var result = {};
+
+ result["warnings"] = bb.readUint32();
+ result["errors"] = bb.readUint32();
+ var length = bb.readVarUint();
+ var values = result["msgs"] = Array(length);
+ for (var i = 0; i < length; i++) values[i] = decodeMessage(bb);
+ return result;
+}
+
+function encodeLog(message, bb) {
+
+ var value = message["warnings"];
+ if (value != null) {
+ bb.writeUint32(value);
+ } else {
+ throw new Error("Missing required field \"warnings\"");
+ }
+
+ var value = message["errors"];
+ if (value != null) {
+ bb.writeUint32(value);
+ } else {
+ throw new Error("Missing required field \"errors\"");
+ }
+
+ var value = message["msgs"];
+ if (value != null) {
+ var values = value, n = values.length;
+ bb.writeVarUint(n);
+ for (var i = 0; i < n; i++) {
+ value = values[i];
+ encodeMessage(value, bb);
+ }
+ } else {
+ throw new Error("Missing required field \"msgs\"");
+ }
+
+}
+
+export { Loader }
+export { LoaderKeys }
+export { JSXRuntime }
+export { JSXRuntimeKeys }
+export { decodeJSX }
+export { encodeJSX }
+export { decodeTransformOptions }
+export { encodeTransformOptions }
+export { decodeFileHandle }
+export { encodeFileHandle }
+export { decodeTransform }
+export { encodeTransform }
+export { TransformResponseStatus }
+export { TransformResponseStatusKeys }
+export { decodeOutputFile }
+export { encodeOutputFile }
+export { decodeTransformResponse }
+export { encodeTransformResponse }
+export { MessageKind }
+export { MessageKindKeys }
+export { decodeLocation }
+export { encodeLocation }
+export { decodeMessageData }
+export { encodeMessageData }
+export { decodeMessage }
+export { encodeMessage }
+export { decodeLog }
+export { encodeLog } \ No newline at end of file
diff --git a/src/api/schema.peechy b/src/api/schema.peechy
new file mode 100644
index 000000000..2f4579201
--- /dev/null
+++ b/src/api/schema.peechy
@@ -0,0 +1,107 @@
+package Api;
+
+smol Loader {
+ jsx = 1;
+ js = 2;
+ ts = 3;
+ tsx = 4;
+ css = 5;
+ file = 6;
+ json = 7;
+}
+
+
+smol JSXRuntime {
+ automatic = 1;
+ classic = 2;
+}
+
+struct JSX {
+ string factory;
+ JSXRuntime runtime;
+ string fragment;
+ bool production;
+
+ // Probably react
+ string import_source;
+
+ bool react_fast_refresh;
+
+ string[] loader_keys;
+ Loader[] loader_values;
+}
+
+
+struct TransformOptions {
+ JSX jsx;
+ bool ts;
+
+ string base_path;
+ string[] define_keys;
+ string[] define_values;
+}
+
+struct FileHandle {
+ string path;
+ uint size;
+ uint fd;
+}
+
+message Transform {
+ FileHandle handle = 1;
+ string path = 2;
+ string contents = 3;
+
+ Loader loader = 4;
+ TransformOptions options = 5;
+}
+
+enum TransformResponseStatus {
+ success = 1;
+ fail = 2;
+}
+
+struct OutputFile {
+ byte[] data;
+ string path;
+}
+
+struct TransformResponse {
+ TransformResponseStatus status;
+ OutputFile[] files;
+ Message[] errors;
+}
+
+enum MessageKind {
+ err = 1;
+ warn =2;
+ note = 3;
+ debug = 4;
+}
+
+struct Location {
+ string file;
+ string namespace;
+ int32 line;
+ int32 column;
+ string line_text;
+ string suggestion;
+ uint offset;
+}
+
+message MessageData {
+ string text = 1;
+ Location location = 2;
+}
+
+struct Message {
+ MessageKind kind;
+ MessageData data;
+ MessageData[] notes;
+}
+
+struct Log {
+ uint32 warnings;
+ uint32 errors;
+ Message[] msgs;
+} \ No newline at end of file
diff --git a/src/api/schema.ts b/src/api/schema.ts
new file mode 100644
index 000000000..a922b6a33
--- /dev/null
+++ b/src/api/schema.ts
@@ -0,0 +1,166 @@
+import type {ByteBuffer} from "peechy";
+
+type byte = number;
+type float = number;
+type int = number;
+type alphanumeric = string;
+type uint = number;
+type int8 = number;
+type lowp = number;
+type int16 = number;
+type int32 = number;
+type float32 = number;
+type uint16 = number;
+type uint32 = number;
+ export enum Loader {
+ jsx = 1,
+ js = 2,
+ ts = 3,
+ tsx = 4,
+ css = 5,
+ file = 6,
+ json = 7
+ }
+ export const LoaderKeys = {
+ 1: "jsx",
+ jsx: "jsx",
+ 2: "js",
+ js: "js",
+ 3: "ts",
+ ts: "ts",
+ 4: "tsx",
+ tsx: "tsx",
+ 5: "css",
+ css: "css",
+ 6: "file",
+ file: "file",
+ 7: "json",
+ json: "json"
+ }
+ export enum JSXRuntime {
+ automatic = 1,
+ classic = 2
+ }
+ export const JSXRuntimeKeys = {
+ 1: "automatic",
+ automatic: "automatic",
+ 2: "classic",
+ classic: "classic"
+ }
+ export enum TransformResponseStatus {
+ success = 1,
+ fail = 2
+ }
+ export const TransformResponseStatusKeys = {
+ 1: "success",
+ success: "success",
+ 2: "fail",
+ fail: "fail"
+ }
+ export enum MessageKind {
+ err = 1,
+ warn = 2,
+ note = 3,
+ debug = 4
+ }
+ export const MessageKindKeys = {
+ 1: "err",
+ err: "err",
+ 2: "warn",
+ warn: "warn",
+ 3: "note",
+ note: "note",
+ 4: "debug",
+ debug: "debug"
+ }
+ export interface JSX {
+ factory: string;
+ runtime: JSXRuntime;
+ fragment: string;
+ production: boolean;
+ import_source: string;
+ react_fast_refresh: boolean;
+ loader_keys: string[];
+ loader_values: Loader[];
+ }
+
+ export interface TransformOptions {
+ jsx: JSX;
+ ts: boolean;
+ base_path: string;
+ define_keys: string[];
+ define_values: string[];
+ }
+
+ export interface FileHandle {
+ path: string;
+ size: uint;
+ fd: uint;
+ }
+
+ export interface Transform {
+ handle?: FileHandle;
+ path?: string;
+ contents?: string;
+ loader?: Loader;
+ options?: TransformOptions;
+ }
+
+ export interface OutputFile {
+ data: Uint8Array;
+ path: string;
+ }
+
+ export interface TransformResponse {
+ status: TransformResponseStatus;
+ files: OutputFile[];
+ errors: Message[];
+ }
+
+ export interface Location {
+ file: string;
+ namespace: string;
+ line: int32;
+ column: int32;
+ line_text: string;
+ suggestion: string;
+ offset: uint;
+ }
+
+ export interface MessageData {
+ text?: string;
+ location?: Location;
+ }
+
+ export interface Message {
+ kind: MessageKind;
+ data: MessageData;
+ notes: MessageData[];
+ }
+
+ export interface Log {
+ warnings: uint32;
+ errors: uint32;
+ msgs: Message[];
+ }
+
+ export declare function encodeJSX(message: JSX, bb: ByteBuffer): void;
+ export declare function decodeJSX(buffer: ByteBuffer): JSX;
+ export declare function encodeTransformOptions(message: TransformOptions, bb: ByteBuffer): void;
+ export declare function decodeTransformOptions(buffer: ByteBuffer): TransformOptions;
+ export declare function encodeFileHandle(message: FileHandle, bb: ByteBuffer): void;
+ export declare function decodeFileHandle(buffer: ByteBuffer): FileHandle;
+ export declare function encodeTransform(message: Transform, bb: ByteBuffer): void;
+ export declare function decodeTransform(buffer: ByteBuffer): Transform;
+ export declare function encodeOutputFile(message: OutputFile, bb: ByteBuffer): void;
+ export declare function decodeOutputFile(buffer: ByteBuffer): OutputFile;
+ export declare function encodeTransformResponse(message: TransformResponse, bb: ByteBuffer): void;
+ export declare function decodeTransformResponse(buffer: ByteBuffer): TransformResponse;
+ export declare function encodeLocation(message: Location, bb: ByteBuffer): void;
+ export declare function decodeLocation(buffer: ByteBuffer): Location;
+ export declare function encodeMessageData(message: MessageData, bb: ByteBuffer): void;
+ export declare function decodeMessageData(buffer: ByteBuffer): MessageData;
+ export declare function encodeMessage(message: Message, bb: ByteBuffer): void;
+ export declare function decodeMessage(buffer: ByteBuffer): Message;
+ export declare function encodeLog(message: Log, bb: ByteBuffer): void;
+ export declare function decodeLog(buffer: ByteBuffer): Log;
diff --git a/src/api/schema.zig b/src/api/schema.zig
new file mode 100644
index 000000000..09da2f058
--- /dev/null
+++ b/src/api/schema.zig
@@ -0,0 +1,739 @@
+const std = @import("std");
+
+pub const Api = struct {
+ pub const Loader = enum(u8) {
+ _none,
+ /// jsx
+ jsx,
+
+ /// js
+ js,
+
+ /// ts
+ ts,
+
+ /// tsx
+ tsx,
+
+ /// css
+ css,
+
+ /// file
+ file,
+
+ /// json
+ json,
+
+ _,
+
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
+
+ pub const JsxRuntime = enum(u8) {
+ _none,
+ /// automatic
+ automatic,
+
+ /// classic
+ classic,
+
+ _,
+
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
+
+ pub const Jsx = struct {
+ /// factory
+ factory: []u8,
+
+ /// runtime
+ runtime: JsxRuntime,
+
+ /// fragment
+ fragment: []u8,
+
+ /// production
+ production: bool = false,
+
+ /// import_source
+ import_source: []u8,
+
+ /// react_fast_refresh
+ react_fast_refresh: bool = false,
+
+ /// loader_keys
+ loader_keys: [][]u8,
+
+ /// loader_values
+ loader_values: []Loader,
+
+ pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!Jsx {
+ var obj = std.mem.zeroes(Jsx);
+ try update(&obj, allocator, reader);
+ return obj;
+ }
+ pub fn update(result: *Jsx, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
+ var length: usize = 0;
+ length = try reader.readIntNative(u32);
+ if (result.factory.len != length) {
+ result.factory = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.factory);
+ result.runtime = try reader.readEnum(JsxRuntime, .Little);
+ length = try reader.readIntNative(u32);
+ if (result.fragment.len != length) {
+ result.fragment = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.fragment);
+ result.production = (try reader.readByte()) == @as(u8, 1);
+ length = try reader.readIntNative(u32);
+ if (result.import_source.len != length) {
+ result.import_source = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.import_source);
+ result.react_fast_refresh = (try reader.readByte()) == @as(u8, 1);
+ {
+ var array_count = try reader.readIntNative(u32);
+ if (array_count != result.loader_keys.len) {
+ result.loader_keys = try allocator.alloc([]u8, array_count);
+ }
+ length = try reader.readIntNative(u32);
+ for (result.loader_keys) |content, j| {
+ if (result.loader_keys[j].len != length) {
+ result.loader_keys[j] = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.loader_keys[j]);
+ }
+ }
+ length = try reader.readIntNative(u32);
+ result.loader_values = try allocator.alloc(Loader, length);
+ {
+ var j: usize = 0;
+ while (j < length) : (j += 1) {
+ result.loader_values[j] = try reader.readEnum(Loader, .Little);
+ }
+ }
+ return;
+ }
+
+ pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
+ var n: usize = 0;
+ try writer.writeIntNative(u32, @intCast(u32, result.factory.len));
+ try writer.writeAll(std.mem.sliceAsBytes(result.factory));
+
+ try writer.writeIntNative(@TypeOf(@enumToInt(result.runtime)), @enumToInt(result.runtime));
+
+ try writer.writeIntNative(u32, @intCast(u32, result.fragment.len));
+ try writer.writeAll(std.mem.sliceAsBytes(result.fragment));
+
+ try writer.writeByte(@boolToInt(result.production));
+
+ try writer.writeIntNative(u32, @intCast(u32, result.import_source.len));
+ try writer.writeAll(std.mem.sliceAsBytes(result.import_source));
+
+ try writer.writeByte(@boolToInt(result.react_fast_refresh));
+
+ n = result.loader_keys.len;
+ _ = try writer.writeIntNative(u32, @intCast(u32, n));
+ {
+ var j: usize = 0;
+ while (j < n) : (j += 1) {
+ _ = try writer.writeIntNative(u32, @intCast(u32, result.loader_keys[j].len));
+ try writer.writeAll(std.mem.sliceAsBytes(result.loader_keys[j]));
+ }
+ }
+
+ n = result.loader_values.len;
+ _ = try writer.writeIntNative(u32, @intCast(u32, n));
+ {
+ var j: usize = 0;
+ while (j < n) : (j += 1) {
+ try writer.writeByte(@enumToInt(result.loader_values[j]));
+ }
+ }
+ return;
+ }
+ };
+
+ pub const TransformOptions = struct {
+ /// jsx
+ jsx: Jsx,
+
+ /// ts
+ ts: bool = false,
+
+ /// base_path
+ base_path: []u8,
+
+ /// define_keys
+ define_keys: [][]u8,
+
+ /// define_values
+ define_values: [][]u8,
+
+ pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!TransformOptions {
+ var obj = std.mem.zeroes(TransformOptions);
+ try update(&obj, allocator, reader);
+ return obj;
+ }
+ pub fn update(result: *TransformOptions, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
+ var length: usize = 0;
+ result.jsx = try Jsx.decode(allocator, reader);
+ result.ts = (try reader.readByte()) == @as(u8, 1);
+ length = try reader.readIntNative(u32);
+ if (result.base_path.len != length) {
+ result.base_path = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.base_path);
+ {
+ var array_count = try reader.readIntNative(u32);
+ if (array_count != result.define_keys.len) {
+ result.define_keys = try allocator.alloc([]u8, array_count);
+ }
+ length = try reader.readIntNative(u32);
+ for (result.define_keys) |content, j| {
+ if (result.define_keys[j].len != length) {
+ result.define_keys[j] = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.define_keys[j]);
+ }
+ }
+ {
+ var array_count = try reader.readIntNative(u32);
+ if (array_count != result.define_values.len) {
+ result.define_values = try allocator.alloc([]u8, array_count);
+ }
+ length = try reader.readIntNative(u32);
+ for (result.define_values) |content, j| {
+ if (result.define_values[j].len != length) {
+ result.define_values[j] = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.define_values[j]);
+ }
+ }
+ return;
+ }
+
+ pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
+ var n: usize = 0;
+ try result.jsx.encode(writer);
+
+ try writer.writeByte(@boolToInt(result.ts));
+
+ try writer.writeIntNative(u32, @intCast(u32, result.base_path.len));
+ try writer.writeAll(std.mem.sliceAsBytes(result.base_path));
+
+ n = result.define_keys.len;
+ _ = try writer.writeIntNative(u32, @intCast(u32, n));
+ {
+ var j: usize = 0;
+ while (j < n) : (j += 1) {
+ _ = try writer.writeIntNative(u32, @intCast(u32, result.define_keys[j].len));
+ try writer.writeAll(std.mem.sliceAsBytes(result.define_keys[j]));
+ }
+ }
+
+ n = result.define_values.len;
+ _ = try writer.writeIntNative(u32, @intCast(u32, n));
+ {
+ var j: usize = 0;
+ while (j < n) : (j += 1) {
+ _ = try writer.writeIntNative(u32, @intCast(u32, result.define_values[j].len));
+ try writer.writeAll(std.mem.sliceAsBytes(result.define_values[j]));
+ }
+ }
+ return;
+ }
+ };
+
+ pub const FileHandle = struct {
+ /// path
+ path: []u8,
+
+ /// size
+ size: u32 = 0,
+
+ /// fd
+ fd: u32 = 0,
+
+ pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!FileHandle {
+ var obj = std.mem.zeroes(FileHandle);
+ try update(&obj, allocator, reader);
+ return obj;
+ }
+ pub fn update(result: *FileHandle, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
+ var length: usize = 0;
+ length = try reader.readIntNative(u32);
+ if (result.path.len != length) {
+ result.path = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.path);
+ _ = try reader.readAll(std.mem.asBytes(&result.size));
+ _ = try reader.readAll(std.mem.asBytes(&result.fd));
+ return;
+ }
+
+ pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeIntNative(u32, @intCast(u32, result.path.len));
+ try writer.writeAll(std.mem.sliceAsBytes(result.path));
+
+ try writer.writeIntNative(u32, result.size);
+
+ try writer.writeIntNative(u32, result.fd);
+ return;
+ }
+ };
+
+ pub const Transform = struct {
+ /// handle
+ handle: ?FileHandle = null,
+
+ /// path
+ path: ?[]u8 = null,
+
+ /// contents
+ contents: ?[]u8 = null,
+
+ /// loader
+ loader: ?Loader = null,
+
+ /// options
+ options: ?TransformOptions = null,
+
+ pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!Transform {
+ var obj = std.mem.zeroes(Transform);
+ try update(&obj, allocator, reader);
+ return obj;
+ }
+ pub fn update(result: *Transform, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
+ var length: usize = 0;
+ while (true) {
+ const field_type: u8 = try reader.readByte();
+ switch (field_type) {
+ 0 => {
+ return;
+ },
+
+ 1 => {
+ result.handle = try FileHandle.decode(allocator, reader);
+ },
+ 2 => {
+ length = try reader.readIntNative(u32);
+ if ((result.path orelse &([_]u8{})).len != length) {
+ result.path = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.path.?);
+ },
+ 3 => {
+ length = try reader.readIntNative(u32);
+ if ((result.contents orelse &([_]u8{})).len != length) {
+ result.contents = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.contents.?);
+ },
+ 4 => {
+ result.loader = try reader.readEnum(Loader, .Little);
+ },
+ 5 => {
+ result.options = try TransformOptions.decode(allocator, reader);
+ },
+ else => {
+ return error.InvalidMessage;
+ },
+ }
+ }
+ }
+
+ pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
+ if (result.handle) |handle| {
+ try writer.writeByte(1);
+ try handle.encode(writer);
+ }
+
+ if (result.path) |path| {
+ try writer.writeByte(2);
+ try writer.writeIntNative(u32, @intCast(u32, path.len));
+ try writer.writeAll(std.mem.sliceAsBytes(path));
+ }
+
+ if (result.contents) |contents| {
+ try writer.writeByte(3);
+ try writer.writeIntNative(u32, @intCast(u32, contents.len));
+ try writer.writeAll(std.mem.sliceAsBytes(contents));
+ }
+
+ if (result.loader) |loader| {
+ try writer.writeByte(4);
+ try writer.writeIntNative(@TypeOf(@enumToInt(result.loader orelse unreachable)), @enumToInt(result.loader orelse unreachable));
+ }
+
+ if (result.options) |options| {
+ try writer.writeByte(5);
+ try options.encode(writer);
+ }
+ try writer.writeByte(0);
+ return;
+ }
+ };
+
+ pub const TransformResponseStatus = enum(u32) {
+ _none,
+ /// success
+ success,
+
+ /// fail
+ fail,
+
+ _,
+
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
+
+ pub const OutputFile = struct {
+ /// data
+ data: []u8,
+
+ /// path
+ path: []u8,
+
+ pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!OutputFile {
+ var obj = std.mem.zeroes(OutputFile);
+ try update(&obj, allocator, reader);
+ return obj;
+ }
+ pub fn update(result: *OutputFile, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
+ var length: usize = 0;
+ _ = try reader.readAll(result.data);
+ length = try reader.readIntNative(u32);
+ if (result.path.len != length) {
+ result.path = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.path);
+ return;
+ }
+
+ pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeAll(result.data);
+
+ try writer.writeIntNative(u32, @intCast(u32, result.path.len));
+ try writer.writeAll(std.mem.sliceAsBytes(result.path));
+ return;
+ }
+ };
+
+ pub const TransformResponse = struct {
+ /// status
+ status: TransformResponseStatus,
+
+ /// files
+ files: []OutputFile,
+
+ /// errors
+ errors: []Message,
+
+ pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!TransformResponse {
+ var obj = std.mem.zeroes(TransformResponse);
+ try update(&obj, allocator, reader);
+ return obj;
+ }
+ pub fn update(result: *TransformResponse, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
+ var length: usize = 0;
+ result.status = try reader.readEnum(TransformResponseStatus, .Little);
+ length = try reader.readIntNative(u32);
+ result.files = try allocator.alloc(OutputFile, length);
+ {
+ var j: usize = 0;
+ while (j < length) : (j += 1) {
+ result.files[j] = try OutputFile.decode(allocator, reader);
+ }
+ }
+ length = try reader.readIntNative(u32);
+ result.errors = try allocator.alloc(Message, length);
+ {
+ var j: usize = 0;
+ while (j < length) : (j += 1) {
+ result.errors[j] = try Message.decode(allocator, reader);
+ }
+ }
+ return;
+ }
+
+ pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
+ var n: usize = 0;
+ try writer.writeIntNative(@TypeOf(@enumToInt(result.status)), @enumToInt(result.status));
+
+ n = result.files.len;
+ _ = try writer.writeIntNative(u32, @intCast(u32, n));
+ {
+ var j: usize = 0;
+ while (j < n) : (j += 1) {
+ try result.files[j].encode(writer);
+ }
+ }
+
+ n = result.errors.len;
+ _ = try writer.writeIntNative(u32, @intCast(u32, n));
+ {
+ var j: usize = 0;
+ while (j < n) : (j += 1) {
+ try result.errors[j].encode(writer);
+ }
+ }
+ return;
+ }
+ };
+
+ pub const MessageKind = enum(u32) {
+ _none,
+ /// err
+ err,
+
+ /// warn
+ warn,
+
+ /// note
+ note,
+
+ /// debug
+ debug,
+
+ _,
+
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
+
+ pub const Location = struct {
+ /// file
+ file: []u8,
+
+ /// namespace
+ namespace: []u8,
+
+ /// line
+ line: i32 = 0,
+
+ /// column
+ column: i32 = 0,
+
+ /// line_text
+ line_text: []u8,
+
+ /// suggestion
+ suggestion: []u8,
+
+ /// offset
+ offset: u32 = 0,
+
+ pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!Location {
+ var obj = std.mem.zeroes(Location);
+ try update(&obj, allocator, reader);
+ return obj;
+ }
+ pub fn update(result: *Location, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
+ var length: usize = 0;
+ length = try reader.readIntNative(u32);
+ if (result.file.len != length) {
+ result.file = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.file);
+ length = try reader.readIntNative(u32);
+ if (result.namespace.len != length) {
+ result.namespace = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.namespace);
+ _ = try reader.readAll(std.mem.asBytes(&result.line));
+ _ = try reader.readAll(std.mem.asBytes(&result.column));
+ length = try reader.readIntNative(u32);
+ if (result.line_text.len != length) {
+ result.line_text = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.line_text);
+ length = try reader.readIntNative(u32);
+ if (result.suggestion.len != length) {
+ result.suggestion = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.suggestion);
+ _ = try reader.readAll(std.mem.asBytes(&result.offset));
+ return;
+ }
+
+ pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeIntNative(u32, @intCast(u32, result.file.len));
+ try writer.writeAll(std.mem.sliceAsBytes(result.file));
+
+ try writer.writeIntNative(u32, @intCast(u32, result.namespace.len));
+ try writer.writeAll(std.mem.sliceAsBytes(result.namespace));
+
+ try writer.writeIntNative(i32, result.line);
+
+ try writer.writeIntNative(i32, result.column);
+
+ try writer.writeIntNative(u32, @intCast(u32, result.line_text.len));
+ try writer.writeAll(std.mem.sliceAsBytes(result.line_text));
+
+ try writer.writeIntNative(u32, @intCast(u32, result.suggestion.len));
+ try writer.writeAll(std.mem.sliceAsBytes(result.suggestion));
+
+ try writer.writeIntNative(u32, result.offset);
+ return;
+ }
+ };
+
+ pub const MessageData = struct {
+ /// text
+ text: ?[]u8 = null,
+
+ /// location
+ location: ?Location = null,
+
+ pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!MessageData {
+ var obj = std.mem.zeroes(MessageData);
+ try update(&obj, allocator, reader);
+ return obj;
+ }
+ pub fn update(result: *MessageData, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
+ var length: usize = 0;
+ while (true) {
+ const field_type: u8 = try reader.readByte();
+ switch (field_type) {
+ 0 => {
+ return;
+ },
+
+ 1 => {
+ length = try reader.readIntNative(u32);
+ if ((result.text orelse &([_]u8{})).len != length) {
+ result.text = try allocator.alloc(u8, length);
+ }
+ _ = try reader.readAll(result.text.?);
+ },
+ 2 => {
+ result.location = try Location.decode(allocator, reader);
+ },
+ else => {
+ return error.InvalidMessage;
+ },
+ }
+ }
+ }
+
+ pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
+ if (result.text) |text| {
+ try writer.writeByte(1);
+ try writer.writeIntNative(u32, @intCast(u32, text.len));
+ try writer.writeAll(std.mem.sliceAsBytes(text));
+ }
+
+ if (result.location) |location| {
+ try writer.writeByte(2);
+ try location.encode(writer);
+ }
+ try writer.writeByte(0);
+ return;
+ }
+ };
+
+ pub const Message = struct {
+ /// kind
+ kind: MessageKind,
+
+ /// data
+ data: MessageData,
+
+ /// notes
+ notes: []MessageData,
+
+ pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!Message {
+ var obj = std.mem.zeroes(Message);
+ try update(&obj, allocator, reader);
+ return obj;
+ }
+ pub fn update(result: *Message, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
+ var length: usize = 0;
+ result.kind = try reader.readEnum(MessageKind, .Little);
+ result.data = try MessageData.decode(allocator, reader);
+ length = try reader.readIntNative(u32);
+ result.notes = try allocator.alloc(MessageData, length);
+ {
+ var j: usize = 0;
+ while (j < length) : (j += 1) {
+ result.notes[j] = try MessageData.decode(allocator, reader);
+ }
+ }
+ return;
+ }
+
+ pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
+ var n: usize = 0;
+ try writer.writeIntNative(@TypeOf(@enumToInt(result.kind)), @enumToInt(result.kind));
+
+ try result.data.encode(writer);
+
+ n = result.notes.len;
+ _ = try writer.writeIntNative(u32, @intCast(u32, n));
+ {
+ var j: usize = 0;
+ while (j < n) : (j += 1) {
+ try result.notes[j].encode(writer);
+ }
+ }
+ return;
+ }
+ };
+
+ pub const Log = struct {
+ /// warnings
+ warnings: u32 = 0,
+
+ /// errors
+ errors: u32 = 0,
+
+ /// msgs
+ msgs: []Message,
+
+ pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!Log {
+ var obj = std.mem.zeroes(Log);
+ try update(&obj, allocator, reader);
+ return obj;
+ }
+ pub fn update(result: *Log, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
+ var length: usize = 0;
+ _ = try reader.readAll(std.mem.asBytes(&result.warnings));
+ _ = try reader.readAll(std.mem.asBytes(&result.errors));
+ length = try reader.readIntNative(u32);
+ result.msgs = try allocator.alloc(Message, length);
+ {
+ var j: usize = 0;
+ while (j < length) : (j += 1) {
+ result.msgs[j] = try Message.decode(allocator, reader);
+ }
+ }
+ return;
+ }
+
+ pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
+ var n: usize = 0;
+ try writer.writeIntNative(u32, result.warnings);
+
+ try writer.writeIntNative(u32, result.errors);
+
+ n = result.msgs.len;
+ _ = try writer.writeIntNative(u32, @intCast(u32, n));
+ {
+ var j: usize = 0;
+ while (j < n) : (j += 1) {
+ try result.msgs[j].encode(writer);
+ }
+ }
+ return;
+ }
+ };
+};
diff --git a/src/ast/base.zig b/src/ast/base.zig
index 1e2a414a0..9e42818de 100644
--- a/src/ast/base.zig
+++ b/src/ast/base.zig
@@ -64,10 +64,10 @@ pub const RequireOrImportMeta = struct {
is_wrapper_async: bool = false,
};
pub fn debug(comptime fmt: []const u8, args: anytype) callconv(.Inline) void {
- // std.debug.print(fmt, args);
+ // Output.print(fmt, args);
}
pub fn debugl(
comptime fmt: []const u8,
) callconv(.Inline) void {
- // std.debug.print("{s}\n", .{fmt});
+ // Output.print("{s}\n", .{fmt});
}
diff --git a/src/defines-table.zig b/src/defines-table.zig
index 3816f74c3..a09d304df 100644
--- a/src/defines-table.zig
+++ b/src/defines-table.zig
@@ -1,4 +1,4 @@
-usingnamespace @import("strings.zig");
+usingnamespace @import("global.zig");
// If something is in this list, then a direct identifier expression or property
// access chain matching this will be assumed to have no side effects and will
diff --git a/src/defines.zig b/src/defines.zig
index 1a9023354..020a0b8c9 100644
--- a/src/defines.zig
+++ b/src/defines.zig
@@ -5,7 +5,7 @@ const logger = @import("logger.zig");
const js_lexer = @import("js_lexer.zig");
const json_parser = @import("json_parser.zig");
const fs = @import("fs.zig");
-usingnamespace @import("strings.zig");
+usingnamespace @import("global.zig");
usingnamespace @import("ast/base.zig");
const GlobalDefinesKey = @import("./defines-table.zig").GlobalDefinesKey;
@@ -294,7 +294,7 @@ test "Defines" {
var log = logger.Log.init(alloc.dynamic);
var data = try DefineData.from_input(orig, &log, alloc.dynamic);
var defines = try Define.init(alloc.dynamic, data);
- std.debug.print("Time: {d}", .{std.time.nanoTimestamp() - start});
+ Output.print("Time: {d}", .{std.time.nanoTimestamp() - start});
const node_env_dots = defines.dots.get("NODE_ENV");
expect(node_env_dots != null);
expect(node_env_dots.?.len > 0);
diff --git a/src/exports.zig b/src/exports.zig
new file mode 100644
index 000000000..cf37e8a38
--- /dev/null
+++ b/src/exports.zig
@@ -0,0 +1,44 @@
+const std = @import("std");
+const alloc = @import("alloc.zig");
+usingnamespace @import("global.zig");
+
+const Root = @import("main_wasm.zig").Root;
+
+pub extern fn init() void {
+ alloc.dynamic = std.heap.c_allocator;
+ alloc.static = std.heap.c_allocator;
+}
+
+/// Convert a slice into known memory representation -- enables C ABI
+pub const U8Chunk = packed struct {
+ const Float = @Type(builtin.TypeInfo{ .Float = .{ .bits = 2 * @bitSizeOf(usize) } });
+ const Abi = if (builtin.arch.isWasm()) Float else U8Chunk;
+
+ ptr: [*]u8,
+ len: usize,
+
+ pub fn toSlice(raw: Abi) []u8 {
+ const self = @bitCast(U8Chunk, raw);
+ return self.ptr[0..self.len];
+ }
+
+ pub fn fromSlice(slice: []u8) Abi {
+ const self = U8Chunk{ .ptr = slice.ptr, .len = slice.len };
+ return @bitCast(Abi, self);
+ }
+
+ pub fn empty() Abi {
+ return U8Chunk.fromSlice(&[0]u8{});
+ }
+};
+
+export fn fd_create() ?*Root {
+ const fd = allocator.create(Root) catch return null;
+ fd.* = .{};
+ return fd;
+}
+
+export fn fd_destroy(fd: *Root) void {
+ fd.deinit(allocator);
+ allocator.destroy(fd);
+}
diff --git a/src/fs.zig b/src/fs.zig
index 133ac99aa..c765208e2 100644
--- a/src/fs.zig
+++ b/src/fs.zig
@@ -1,6 +1,6 @@
const std = @import("std");
-usingnamespace @import("strings.zig");
+usingnamespace @import("global.zig");
const alloc = @import("alloc.zig");
const expect = std.testing.expect;
diff --git a/src/global.zig b/src/global.zig
new file mode 100644
index 000000000..4ff43ed8e
--- /dev/null
+++ b/src/global.zig
@@ -0,0 +1,39 @@
+const std = @import("std");
+pub usingnamespace @import("strings.zig");
+
+pub const Output = struct {
+ pub const source = comptime {
+ if (std.builtin.os.tag == .wasi) {
+ return @import("./output_wasi.zig");
+ } else if (std.builtin.target.isWasm()) {
+ return @import("./output_wasm.zig");
+ } else {
+ return @import("./output_native.zig");
+ }
+ };
+
+ pub fn print(comptime fmt: string, args: anytype) void {
+ if (comptime std.builtin.target.isWasm()) {
+ std.fmt.format(source.writer, fmt, args) catch unreachable;
+ } else {
+ std.fmt.format(source.writer orelse unreachable, fmt, args) catch unreachable;
+ }
+ }
+ pub fn printError(comptime fmt: string, args: anytype) void {
+ if (comptime std.builtin.target.isWasm()) {
+ std.fmt.format(source.writer, fmt, args) catch unreachable;
+ } else {
+ std.fmt.format(source.writer orelse unreachable, fmt, args) catch unreachable;
+ }
+ }
+};
+
+pub const Global = struct {
+ pub fn panic(comptime fmt: string, args: anytype) noreturn {
+ if (comptime std.builtin.target.isWasm()) {
+ @panic(fmt);
+ } else {
+ std.debug.panic(fmt, args);
+ }
+ }
+};
diff --git a/src/js_ast.zig b/src/js_ast.zig
index d8b5d6f89..4162fab28 100644
--- a/src/js_ast.zig
+++ b/src/js_ast.zig
@@ -2,7 +2,7 @@ const std = @import("std");
const logger = @import("logger.zig");
const JSXRuntime = @import("options.zig").JSX.Runtime;
-usingnamespace @import("strings.zig");
+usingnamespace @import("global.zig");
usingnamespace @import("ast/base.zig");
const ImportRecord = @import("import_record.zig").ImportRecord;
@@ -170,7 +170,7 @@ pub const Binding = struct {
return Expr.alloc(wrapper.allocator, E.Object{ .properties = properties, .is_single_line = b.is_single_line }, loc);
},
else => {
- std.debug.panic("Interanl error", .{});
+ Global.panic("Interanl error", .{});
},
}
}
@@ -3213,7 +3213,7 @@ pub const Scope = struct {
};
pub fn printmem(comptime format: string, args: anytype) void {
- // std.debug.print(format, args);
+ // Output.print(format, args);
}
test "Binding.init" {
diff --git a/src/js_lexer.zig b/src/js_lexer.zig
index 4d6b16b31..0cae6b0b4 100644
--- a/src/js_lexer.zig
+++ b/src/js_lexer.zig
@@ -6,7 +6,7 @@ const build_options = @import("build_options");
const js_ast = @import("js_ast.zig");
usingnamespace @import("ast/base.zig");
-usingnamespace @import("strings.zig");
+usingnamespace @import("global.zig");
const unicode = std.unicode;
@@ -21,7 +21,7 @@ pub const TypescriptStmtKeyword = tables.TypescriptStmtKeyword;
pub const TypeScriptAccessibilityModifier = tables.TypeScriptAccessibilityModifier;
fn notimpl() noreturn {
- std.debug.panic("not implemented yet!", .{});
+ Global.panic("not implemented yet!", .{});
}
pub var emptyJavaScriptString = ([_]u16{0});
@@ -111,7 +111,7 @@ pub const Lexer = struct {
self.log.addErrorFmt(self.source, __loc, self.allocator, format, args) catch unreachable;
self.prev_error_loc = __loc;
var msg = self.log.msgs.items[self.log.msgs.items.len - 1];
- msg.formatNoWriter(std.debug.panic);
+ msg.formatNoWriter(Global.panic);
}
pub fn addRangeError(self: *LexerType, r: logger.Range, comptime format: []const u8, args: anytype, panic: bool) void {
@@ -129,7 +129,7 @@ pub const Lexer = struct {
const writer = stream.writer();
self.log.print(writer) catch unreachable;
- std.debug.panic("{s}", .{fixedBuffer[0..stream.pos]});
+ Global.panic("{s}", .{fixedBuffer[0..stream.pos]});
}
}
@@ -137,7 +137,7 @@ pub const Lexer = struct {
if (@import("builtin").is_test) {
self.did_panic = true;
} else {
- std.debug.panic("{s}", .{content});
+ Global.panic("{s}", .{content});
}
}
@@ -341,9 +341,9 @@ pub const Lexer = struct {
self.log.print(stderr) catch unreachable;
} else {
if (self.token == T.t_identifier or self.token == T.t_string_literal) {
- std.debug.print(" {s} ", .{self.raw()});
+ Output.print(" {s} ", .{self.raw()});
} else {
- std.debug.print(" <{s}> ", .{tokenToString.get(self.token)});
+ Output.print(" <{s}> ", .{tokenToString.get(self.token)});
}
}
}
@@ -2168,9 +2168,9 @@ fn test_lexer(contents: []const u8) Lexer {
fn expectStr(lexer: *Lexer, expected: string, actual: string) void {
if (lexer.log.errors > 0 or lexer.log.warnings > 0) {
- std.debug.panic("{s}", .{lexer.log.msgs.items});
+ Global.panic("{s}", .{lexer.log.msgs.items});
// const msg: logger.Msg = lexer.log.msgs.items[0];
- // msg.formatNoWriter(std.debug.panic);
+ // msg.formatNoWriter(Global.panic);
}
std.testing.expectEqual(lexer.log.errors, 0);
std.testing.expectEqual(lexer.log.warnings, 0);
diff --git a/src/js_parser/imports.zig b/src/js_parser/imports.zig
index d5197930d..9ac9f2a3e 100644
--- a/src/js_parser/imports.zig
+++ b/src/js_parser/imports.zig
@@ -9,7 +9,7 @@ pub const js_printer = @import("../js_printer.zig");
pub const renamer = @import("../renamer.zig");
pub const fs = @import("../fs.zig");
-pub usingnamespace @import("../strings.zig");
+pub usingnamespace @import("../global.zig");
pub usingnamespace @import("../ast/base.zig");
pub usingnamespace js_ast.G;
pub usingnamespace @import("../defines.zig");
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index 26dfc9bc2..59152f869 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -1010,15 +1010,15 @@ pub const StmtsKind = enum {
};
fn notimpl() noreturn {
- std.debug.panic("Not implemented yet!!", .{});
+ Global.panic("Not implemented yet!!", .{});
}
fn lexerpanic() noreturn {
- std.debug.panic("LexerPanic", .{});
+ Global.panic("LexerPanic", .{});
}
fn fail() noreturn {
- std.debug.panic("Something went wrong :cry;", .{});
+ Global.panic("Something went wrong :cry;", .{});
}
const ExprBindingTuple = struct { expr: ?ExprNodeIndex = null, binding: ?Binding = null, override_expr: ?ExprNodeIndex = null };
@@ -2254,7 +2254,7 @@ pub const P = struct {
// Sanity-check that the scopes generated by the first and second passes match
if (order.loc.start != loc.start or order.scope.kind != kind) {
- std.debug.print("Expected scope ({s}, {d}) in {s}, found scope ({s}, {d})", .{ kind, loc.start, p.source.path.pretty, order.scope.kind, order.loc.start });
+ Output.print("Expected scope ({s}, {d}) in {s}, found scope ({s}, {d})", .{ kind, loc.start, p.source.path.pretty, order.scope.kind, order.loc.start });
p.panic("", .{});
}
@@ -4046,7 +4046,7 @@ pub const P = struct {
}
}
}
- // std.debug.print("\n\nmVALUE {s}:{s}\n", .{ expr, name });
+ // Output.print("\n\nmVALUE {s}:{s}\n", .{ expr, name });
p.lexer.expectOrInsertSemicolon();
return p.s(S.SExpr{ .value = expr }, loc);
},
@@ -4204,7 +4204,7 @@ pub const P = struct {
var let_range = p.lexer.range();
var raw = p.lexer.raw();
if (p.lexer.token != .t_identifier or !strings.eql(raw, "let")) {
- // std.debug.print("HI", .{});
+ // Output.print("HI", .{});
return ExprOrLetStmt{ .stmt_or_expr = js_ast.StmtOrExpr{ .expr = p.parseExpr(.lowest) } };
}
@@ -6653,13 +6653,13 @@ pub const P = struct {
var stream = std.io.fixedBufferStream(&fixedBuffer);
p.log.print(stream.writer()) catch unreachable;
- std.debug.panic("{s}", .{fixedBuffer});
+ Global.panic("{s}", .{fixedBuffer});
}
pub fn _parsePrefix(p: *P, level: Level, errors: *DeferredErrors, flags: Expr.EFlags) Expr {
const loc = p.lexer.loc();
const l = @enumToInt(level);
- // std.debug.print("Parse Prefix {s}:{s} @{s} ", .{ p.lexer.token, p.lexer.raw(), @tagName(level) });
+ // Output.print("Parse Prefix {s}:{s} @{s} ", .{ p.lexer.token, p.lexer.raw(), @tagName(level) });
switch (p.lexer.token) {
.t_super => {
@@ -6812,7 +6812,7 @@ pub const P = struct {
_ = p.pushScopeForParsePass(.function_args, loc) catch unreachable;
defer p.popScope();
- // std.debug.print("HANDLE START ", .{});
+ // Output.print("HANDLE START ", .{});
return p.e(p.parseArrowBody(args, p.m(FnOrArrowDataParse{})) catch unreachable, loc);
}
@@ -7763,7 +7763,7 @@ pub const P = struct {
}
},
else => {
- std.debug.panic("Unexpected type in export default: {s}", .{s2});
+ Global.panic("Unexpected type in export default: {s}", .{s2});
},
}
},
@@ -8706,7 +8706,7 @@ pub const P = struct {
var property = e_.properties[i];
if (property.kind != .spread) {
- const key = p.visitExpr(property.key orelse std.debug.panic("Expected property key", .{}));
+ const key = p.visitExpr(property.key orelse Global.panic("Expected property key", .{}));
e_.properties[i].key = key;
// Forbid duplicate "__proto__" properties according to the specification
diff --git a/src/js_parser/js_parser_test.zig b/src/js_parser/js_parser_test.zig
index 05b9b1f8e..36252f715 100644
--- a/src/js_parser/js_parser_test.zig
+++ b/src/js_parser/js_parser_test.zig
@@ -203,7 +203,7 @@ fn expectPrinted(t: *Tester, contents: string, expected: string, src: anytype) !
var stream = std.io.fixedBufferStream(&fixedBuffer);
try log.print(stream.writer());
- std.debug.print("{s}", .{fixedBuffer});
+ Output.print("{s}", .{fixedBuffer});
}
var linker = Linker{};
debugl("START AST PRINT");
diff --git a/src/js_printer.zig b/src/js_printer.zig
index 40894f2c9..80304c982 100644
--- a/src/js_printer.zig
+++ b/src/js_printer.zig
@@ -8,7 +8,7 @@ const alloc = @import("alloc.zig");
const rename = @import("renamer.zig");
const fs = @import("fs.zig");
-usingnamespace @import("strings.zig");
+usingnamespace @import("global.zig");
usingnamespace @import("ast/base.zig");
usingnamespace js_ast.G;
@@ -43,7 +43,7 @@ const assert = std.debug.assert;
const Linker = @import("linker.zig").Linker;
fn notimpl() void {
- std.debug.panic("Not implemented yet!", .{});
+ Global.panic("Not implemented yet!", .{});
}
pub const SourceMapChunk = struct {
@@ -83,7 +83,7 @@ pub const Options = struct {
}
};
-pub const PrintResult = struct { js: string, source_map: ?SourceMapChunk = null };
+pub const PrintResult = struct { js: []u8, source_map: ?SourceMapChunk = null };
// Zig represents booleans in packed structs as 1 bit, with no padding
// This is effectively a bit field
@@ -677,7 +677,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
// First, we will assert to make detecting this case a little clearer for us in development.
if (std.builtin.mode == std.builtin.Mode.Debug) {
- std.debug.panic("Internal error: {s} is an external require, which should never happen.", .{record});
+ Global.panic("Internal error: {s} is an external require, which should never happen.", .{record});
}
p.printSpaceBeforeIdentifier();
@@ -1150,7 +1150,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
}
if (e.func.name) |sym| {
- p.printSymbol(sym.ref orelse std.debug.panic("internal error: expected E.Function's name symbol to have a ref\n{s}", .{e.func}));
+ p.printSymbol(sym.ref orelse Global.panic("internal error: expected E.Function's name symbol to have a ref\n{s}", .{e.func}));
}
p.printFunc(e.func);
@@ -1168,7 +1168,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
p.printSpaceBeforeIdentifier();
p.print("class");
if (e.class_name) |name| {
- p.printSymbol(name.ref orelse std.debug.panic("internal error: expected E.Class's name symbol to have a ref\n{s}", .{e}));
+ p.printSymbol(name.ref orelse Global.panic("internal error: expected E.Class's name symbol to have a ref\n{s}", .{e}));
p.maybePrintSpace();
}
p.printClass(e.*);
@@ -1596,7 +1596,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
}
},
else => {
- // std.debug.panic("Unexpected expression of type {s}", .{std.meta.activeTag(expr.data});
+ // Global.panic("Unexpected expression of type {s}", .{std.meta.activeTag(expr.data});
},
}
}
@@ -1946,7 +1946,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
p.print("}");
},
else => {
- std.debug.panic("Unexpected binding of type {s}", .{binding});
+ Global.panic("Unexpected binding of type {s}", .{binding});
},
}
}
@@ -1985,8 +1985,8 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
p.print("*");
p.printSpace();
}
- const name = s.func.name orelse std.debug.panic("Internal error: expected func to have a name ref\n{s}", .{s});
- const nameRef = name.ref orelse std.debug.panic("Internal error: expected func to have a name\n{s}", .{s});
+ const name = s.func.name orelse Global.panic("Internal error: expected func to have a name ref\n{s}", .{s});
+ const nameRef = name.ref orelse Global.panic("Internal error: expected func to have a name\n{s}", .{s});
p.printSpace();
p.printSymbol(nameRef);
p.printFunc(s.func);
@@ -2035,7 +2035,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
p.printSpace();
}
if (func.func.name) |name| {
- p.printSymbol(name.ref orelse std.debug.panic("Internal error: Expected func to have a name ref\n{s}", .{func}));
+ p.printSymbol(name.ref orelse Global.panic("Internal error: Expected func to have a name ref\n{s}", .{func}));
}
p.printFunc(func.func);
p.printNewline();
@@ -2044,7 +2044,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
p.printSpaceBeforeIdentifier();
if (class.class.class_name) |name| {
p.print("class ");
- p.printSymbol(name.ref orelse std.debug.panic("Internal error: Expected class to have a name ref\n{s}", .{class}));
+ p.printSymbol(name.ref orelse Global.panic("Internal error: Expected class to have a name ref\n{s}", .{class}));
} else {
p.print("class");
}
@@ -2052,7 +2052,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
p.printNewline();
},
else => {
- std.debug.panic("Internal error: unexpected export default stmt data {s}", .{s});
+ Global.panic("Internal error: unexpected export default stmt data {s}", .{s});
},
}
},
@@ -2268,7 +2268,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
},
.s_label => |s| {
p.printIndent();
- p.printSymbol(s.name.ref orelse std.debug.panic("Internal error: expected label to have a name {s}", .{s}));
+ p.printSymbol(s.name.ref orelse Global.panic("Internal error: expected label to have a name {s}", .{s}));
p.print(":");
p.printBody(s.stmt);
},
@@ -2526,7 +2526,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
p.printSemicolonAfterStatement();
},
else => {
- std.debug.panic("Unexpected statement of type {s}", .{@TypeOf(stmt)});
+ Global.panic("Unexpected statement of type {s}", .{@TypeOf(stmt)});
},
}
}
@@ -2554,7 +2554,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
}
},
else => {
- std.debug.panic("Internal error: Unexpected stmt in for loop {s}", .{initSt});
+ Global.panic("Internal error: Unexpected stmt in for loop {s}", .{initSt});
},
}
}
@@ -2705,7 +2705,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
temp = [_]u8{ '\\', 'u', hex_chars[c >> 12], hex_chars[(c >> 8) & 15], hex_chars[(c >> 4) & 15], hex_chars[c & 15] };
p.print(&temp);
} else {
- std.debug.panic("Not implemented yet: unicode escapes in ascii only", .{});
+ Global.panic("Not implemented yet: unicode escapes in ascii only", .{});
}
continue;
}
diff --git a/src/json_parser.zig b/src/json_parser.zig
index cf1a9382d..771207f0c 100644
--- a/src/json_parser.zig
+++ b/src/json_parser.zig
@@ -7,7 +7,7 @@ const options = @import("options.zig");
const alloc = @import("alloc.zig");
const fs = @import("fs.zig");
-usingnamespace @import("strings.zig");
+usingnamespace @import("global.zig");
usingnamespace @import("ast/base.zig");
usingnamespace js_ast.G;
@@ -249,7 +249,7 @@ fn expectPrintedJSON(_contents: string, expected: string) void {
var symbols: SymbolList = &([_][]Symbol{tree.symbols});
var symbol_map = js_ast.Symbol.Map.initList(symbols);
if (log.msgs.items.len > 0) {
- std.debug.panic("--FAIL--\nExpr {s}\nLog: {s}\n--FAIL--", .{ expr, log.msgs.items[0].data.text });
+ Global.panic("--FAIL--\nExpr {s}\nLog: {s}\n--FAIL--", .{ expr, log.msgs.items[0].data.text });
}
var linker = @import("linker.zig").Linker{};
diff --git a/src/logger.zig b/src/logger.zig
index 1731bc31b..c82f2d85d 100644
--- a/src/logger.zig
+++ b/src/logger.zig
@@ -1,6 +1,6 @@
const std = @import("std");
-usingnamespace @import("strings.zig");
+usingnamespace @import("global.zig");
const fs = @import("fs.zig");
const unicode = std.unicode;
@@ -122,7 +122,7 @@ pub const Msg = struct {
});
}
- pub fn formatNoWriter(msg: *const Msg, comptime formatterFunc: @TypeOf(std.debug.panic)) void {
+ pub fn formatNoWriter(msg: *const Msg, comptime formatterFunc: @TypeOf(Global.panic)) void {
formatterFunc("\n\n{s}: {s}\n{s}\n{s}:{}:{} ({d})", .{
msg.kind.string(),
msg.data.text,
@@ -486,10 +486,6 @@ test "ErrorPosition" {
var msgs = ArrayList(Msg).init(std.testing.allocator);
var log = Log{ .msgs = msgs };
defer log.msgs.deinit();
- var filename = "test.js".*;
- var syntax = "for (i".*;
- var err = "invalid syntax".*;
- var namespace = "file".*;
try log.addMsg(Msg{
.kind = .err,
diff --git a/src/main.zig b/src/main.zig
index 5f735412d..20a07e33b 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -10,6 +10,7 @@ const js_ast = @import("js_ast.zig");
const linker = @import("linker.zig");
usingnamespace @import("ast/base.zig");
usingnamespace @import("defines.zig");
+usingnamespace @import("global.zig");
const panicky = @import("panic_handler.zig");
const MainPanicHandler = panicky.NewPanicHandler(panicky.default_panic);
@@ -23,7 +24,15 @@ pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) nore
}
pub fn main() anyerror!void {
- try alloc.setup(std.heap.page_allocator);
+ // The memory allocator makes a massive difference.
+ // std.heap.raw_c_allocator and std.heap.c_allocator perform similarly.
+ // std.heap.GeneralPurposeAllocator makes this about 3x _slower_ than esbuild.
+ // var root_alloc = std.heap.ArenaAllocator.init(std.heap.raw_c_allocator);
+ // var root_alloc_ = &root_alloc.allocator;
+ try alloc.setup(std.heap.c_allocator);
+ Output.source.Stream = std.io.getStdOut();
+ Output.source.writer = Output.source.Stream.?.writer();
+ Output.source.errorWriter = std.io.getStdErr().writer();
var log = logger.Log.init(alloc.dynamic);
var panicker = MainPanicHandler.init(&log);
MainPanicHandler.Singleton = &panicker;
@@ -77,7 +86,7 @@ pub fn main() anyerror!void {
ast = res.ast;
},
else => {
- std.debug.panic("Unsupported loader: {s}", .{opts.loader});
+ Global.panic("Unsupported loader: {s}", .{opts.loader});
},
}
diff --git a/src/main_wasi.zig b/src/main_wasi.zig
new file mode 100644
index 000000000..5d24c2e69
--- /dev/null
+++ b/src/main_wasi.zig
@@ -0,0 +1,108 @@
+const std = @import("std");
+const lex = @import("js_lexer.zig");
+const logger = @import("logger.zig");
+const alloc = @import("alloc.zig");
+const options = @import("options.zig");
+const js_parser = @import("js_parser.zig");
+const json_parser = @import("json_parser.zig");
+const js_printer = @import("js_printer.zig");
+const js_ast = @import("js_ast.zig");
+const linker = @import("linker.zig");
+usingnamespace @import("ast/base.zig");
+usingnamespace @import("defines.zig");
+const panicky = @import("panic_handler.zig");
+const fs = @import("fs.zig");
+
+const MainPanicHandler = panicky.NewPanicHandler(panicky.default_panic);
+
+pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn {
+ if (MainPanicHandler.Singleton) |singleton| {
+ MainPanicHandler.handle_panic(msg, error_return_trace);
+ } else {
+ panicky.default_panic(msg, error_return_trace);
+ }
+}
+// const Alloc = zee.ZeeAllocDefaults.wasm_allocator
+pub fn main() anyerror!void {
+ var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
+ var allocator = &arena.allocator;
+ try alloc.setup(allocator);
+ var log = logger.Log.init(alloc.dynamic);
+ var panicker = MainPanicHandler.init(&log);
+ MainPanicHandler.Singleton = &panicker;
+
+ const args = try std.process.argsAlloc(alloc.dynamic);
+ const stdout = std.io.getStdOut();
+ const stderr = std.io.getStdErr();
+
+ if (args.len < 1) {
+ const len = stderr.write("Pass a file");
+ return;
+ }
+
+ const absolutePath = args[args.len - 1];
+ const pathname = fs.PathName.init(absolutePath);
+ const entryPointName = try alloc.dynamic.alloc(u8, pathname.base.len + pathname.ext.len);
+ std.mem.copy(u8, entryPointName, pathname.base);
+ std.mem.copy(u8, entryPointName[pathname.base.len..entryPointName.len], pathname.ext);
+ const code = try std.io.getStdIn().readToEndAlloc(alloc.dynamic, std.math.maxInt(usize));
+
+ const opts = try options.TransformOptions.initUncached(alloc.dynamic, entryPointName, code);
+ var source = logger.Source.initFile(opts.entry_point, alloc.dynamic);
+ var ast: js_ast.Ast = undefined;
+
+ var raw_defines = RawDefines.init(alloc.static);
+ try raw_defines.put("process.env.NODE_ENV", "\"development\"");
+
+ var user_defines = try DefineData.from_input(raw_defines, &log, alloc.static);
+
+ var define = try Define.init(
+ alloc.static,
+ user_defines,
+ );
+
+ switch (opts.loader) {
+ .json => {
+ var expr = try json_parser.ParseJSON(&source, &log, alloc.dynamic);
+ var stmt = js_ast.Stmt.alloc(alloc.dynamic, js_ast.S.ExportDefault{
+ .value = js_ast.StmtOrExpr{ .expr = expr },
+ .default_name = js_ast.LocRef{ .loc = logger.Loc{}, .ref = Ref{} },
+ }, logger.Loc{ .start = 0 });
+
+ var part = js_ast.Part{
+ .stmts = &([_]js_ast.Stmt{stmt}),
+ };
+
+ ast = js_ast.Ast.initTest(&([_]js_ast.Part{part}));
+ },
+ .jsx, .tsx, .ts, .js => {
+ var parser = try js_parser.Parser.init(opts, &log, &source, define, alloc.dynamic);
+ var res = try parser.parse();
+ ast = res.ast;
+ },
+ else => {
+ Global.panic("Unsupported loader: {s}", .{opts.loader});
+ },
+ }
+
+ var _linker = linker.Linker{};
+ var symbols: [][]js_ast.Symbol = &([_][]js_ast.Symbol{ast.symbols});
+ const printed = try js_printer.printAst(
+ alloc.dynamic,
+ ast,
+ js_ast.Symbol.Map.initList(symbols),
+ &source,
+ false,
+ js_printer.Options{ .to_module_ref = ast.module_ref orelse js_ast.Ref{ .inner_index = 0 } },
+ &_linker,
+ );
+
+ // if (std.builtin.mode == std.builtin.Mode.Debug) {
+ // var fixed_buffer = [_]u8{0} ** 512000;
+ // var buf_stream = std.io.fixedBufferStream(&fixed_buffer);
+
+ // try ast.toJSON(alloc.dynamic, stderr.writer());
+ // }
+
+ _ = try stdout.write(printed.js);
+}
diff --git a/src/main_wasm.zig b/src/main_wasm.zig
index 83a2498e6..a379b4eb0 100644
--- a/src/main_wasm.zig
+++ b/src/main_wasm.zig
@@ -11,8 +11,10 @@ const linker = @import("linker.zig");
usingnamespace @import("ast/base.zig");
usingnamespace @import("defines.zig");
const panicky = @import("panic_handler.zig");
+usingnamespace @import("global.zig");
const fs = @import("fs.zig");
-
+const Schema = @import("api/schema.zig").Api;
+const builtin = std.builtin;
const MainPanicHandler = panicky.NewPanicHandler(panicky.default_panic);
pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn {
@@ -23,84 +25,186 @@ pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) nore
}
}
-pub fn main() anyerror!void {
- try alloc.setup(std.heap.page_allocator);
- var log = logger.Log.init(alloc.dynamic);
- var panicker = MainPanicHandler.init(&log);
- MainPanicHandler.Singleton = &panicker;
+var default_options = std.mem.zeroes(Schema.TransformOptions);
+
+pub const Uint8Array = packed struct {
+ pub const Float = @Type(builtin.TypeInfo{ .Float = .{ .bits = 2 * @bitSizeOf(usize) } });
+ pub const Abi = if (builtin.target.isWasm()) Float else Uint8Array;
+
+ ptr: [*]u8,
+ len: usize,
+
+ pub fn toSlice(raw: Abi) []u8 {
+ const self = @bitCast(Uint8Array, raw);
+ return self.ptr[0..self.len];
+ }
+
+ pub fn fromSlice(slice: []u8) Abi {
+ const self = Uint8Array{ .ptr = slice.ptr, .len = slice.len };
+ return @bitCast(Abi, self);
+ }
+
+ pub fn empty() Abi {
+ return Uint8Array.fromSlice(&[0]u8{});
+ }
+
+ pub fn encode(comptime SchemaType: type, obj: SchemaType) !Abi {
+ var list = std.ArrayList(u8).init(alloc.dynamic);
+ var writer = list.writer();
+ try obj.encode(writer);
+ return Uint8Array.fromSlice(list.toOwnedSlice());
+ }
+
+ pub fn decode(self: Abi, comptime SchemaType: type) !SchemaType {
+ var buf = Uint8Array.toSlice(self);
+ var stream = std.io.fixedBufferStream(buf);
+ return try SchemaType.decode(alloc.dynamic, stream.reader());
+ }
+};
+
+pub fn constStrToU8(s: string) []u8 {
+ return @intToPtr([*]u8, @ptrToInt(s.ptr))[0..s.len];
+}
+
+pub const Api = struct {
+ options: *Schema.TransformOptions = &default_options,
+ files: std.ArrayList(string),
+ log: logger.Log,
+
+ pub fn transform(self: *Api, request: Schema.Transform) !Schema.TransformResponse {
+ const opts = try options.TransformOptions.initUncached(alloc.dynamic, request.path.?, request.contents.?);
+ var source = logger.Source.initFile(opts.entry_point, alloc.dynamic);
+
+ var ast: js_ast.Ast = undefined;
+ var raw_defines = RawDefines.init(alloc.static);
+ try raw_defines.put("process.env.NODE_ENV", "\"development\"");
+
+ var user_defines = try DefineData.from_input(raw_defines, &self.log, alloc.static);
+ var define = try Define.init(
+ alloc.static,
+ user_defines,
+ );
+
+ switch (opts.loader) {
+ .json => {
+ var expr = try json_parser.ParseJSON(&source, &self.log, alloc.dynamic);
+ var stmt = js_ast.Stmt.alloc(alloc.dynamic, js_ast.S.ExportDefault{
+ .value = js_ast.StmtOrExpr{ .expr = expr },
+ .default_name = js_ast.LocRef{ .loc = logger.Loc{}, .ref = Ref{} },
+ }, logger.Loc{ .start = 0 });
+
+ var part = js_ast.Part{
+ .stmts = &([_]js_ast.Stmt{stmt}),
+ };
+
+ ast = js_ast.Ast.initTest(&([_]js_ast.Part{part}));
+ },
+ .jsx, .tsx, .ts, .js => {
+ var parser = try js_parser.Parser.init(opts, &self.log, &source, define, alloc.dynamic);
+ var res = try parser.parse();
+ ast = res.ast;
+ },
+ else => {
+ Global.panic("Unsupported loader: {s}", .{opts.loader});
+ },
+ }
+
+ var _linker = linker.Linker{};
+ var symbols: [][]js_ast.Symbol = &([_][]js_ast.Symbol{ast.symbols});
+ const printed = try js_printer.printAst(
+ alloc.dynamic,
+ ast,
+ js_ast.Symbol.Map.initList(symbols),
+ &source,
+ false,
+ js_printer.Options{ .to_module_ref = ast.module_ref orelse js_ast.Ref{ .inner_index = 0 } },
+ &_linker,
+ );
+ var output_files = try alloc.dynamic.alloc(Schema.OutputFile, 1);
+ var _data = printed.js[0..printed.js.len];
+ var _path = constStrToU8(source.path.text);
+
+ output_files[0] = Schema.OutputFile{ .data = _data, .path = _path };
+
+ var resp = std.mem.zeroes(Schema.TransformResponse);
+ resp.status = .success;
+ resp.files = output_files;
+
+ return resp;
+ // var source = logger.Source.initFile(file: fs.File, allocator: *std.mem.Allocator)
+ }
+};
+
+pub const Exports = struct {
+ fn init() callconv(.C) u8 {
+ if (alloc.needs_setup) {
+ var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
+ var allocator = &arena.allocator;
+ alloc.setup(allocator) catch return 0;
+ }
- const args = try std.process.argsAlloc(alloc.dynamic);
- const stdout = std.io.getStdOut();
- const stderr = std.io.getStdErr();
+ var _api = alloc.static.create(Api) catch return 0;
- if (args.len < 1) {
- const len = stderr.write("Pass a file");
- return;
+ _api.* = Api{ .files = std.ArrayList(string).init(alloc.dynamic), .log = logger.Log.init(alloc.dynamic) };
+ api = _api;
+
+ return 1;
}
- const absolutePath = args[args.len - 2];
- const pathname = fs.PathName.init(absolutePath);
- const entryPointName = try alloc.dynamic.alloc(u8, pathname.base.len + pathname.ext.len);
- std.mem.copy(u8, entryPointName, pathname.base);
- std.mem.copy(u8, entryPointName[pathname.base.len..entryPointName.len], pathname.ext);
-
- const code = try std.io.getStdIn().readToEndAlloc(alloc.dynamic, 99999999);
-
- const opts = try options.TransformOptions.initUncached(alloc.dynamic, entryPointName, code);
- var source = logger.Source.initFile(opts.entry_point, alloc.dynamic);
- var ast: js_ast.Ast = undefined;
-
- var raw_defines = RawDefines.init(alloc.static);
- try raw_defines.put("process.env.NODE_ENV", "\"development\"");
-
- var user_defines = try DefineData.from_input(raw_defines, &log, alloc.static);
-
- var define = try Define.init(
- alloc.static,
- user_defines,
- );
-
- switch (opts.loader) {
- .json => {
- var expr = try json_parser.ParseJSON(&source, &log, alloc.dynamic);
- var stmt = js_ast.Stmt.alloc(alloc.dynamic, js_ast.S.ExportDefault{
- .value = js_ast.StmtOrExpr{ .expr = expr },
- .default_name = js_ast.LocRef{ .loc = logger.Loc{}, .ref = Ref{} },
- }, logger.Loc{ .start = 0 });
-
- var part = js_ast.Part{
- .stmts = &([_]js_ast.Stmt{stmt}),
- };
-
- ast = js_ast.Ast.initTest(&([_]js_ast.Part{part}));
- },
- .jsx, .tsx, .ts, .js => {
- var parser = try js_parser.Parser.init(opts, &log, &source, define, alloc.dynamic);
- var res = try parser.parse();
- ast = res.ast;
- },
- else => {
- std.debug.panic("Unsupported loader: {s}", .{opts.loader});
- },
+ fn transform(abi: Uint8Array.Abi) callconv(.C) Uint8Array.Abi {
+ const req: Schema.Transform = Uint8Array.decode(abi, Schema.Transform) catch return Uint8Array.empty();
+ alloc.dynamic.free(Uint8Array.toSlice(abi));
+ const resp = api.?.transform(req) catch return Uint8Array.empty();
+ return Uint8Array.encode(Schema.TransformResponse, resp) catch return Uint8Array.empty();
}
- var _linker = linker.Linker{};
- var symbols: [][]js_ast.Symbol = &([_][]js_ast.Symbol{ast.symbols});
- const printed = try js_printer.printAst(
- alloc.dynamic,
- ast,
- js_ast.Symbol.Map.initList(symbols),
- false,
- js_printer.Options{ .to_module_ref = ast.module_ref orelse js_ast.Ref{ .inner_index = 0 } },
- &_linker,
- );
-
- // if (std.builtin.mode == std.builtin.Mode.Debug) {
- // var fixed_buffer = [_]u8{0} ** 512000;
- // var buf_stream = std.io.fixedBufferStream(&fixed_buffer);
-
- // try ast.toJSON(alloc.dynamic, stderr.writer());
- // }
-
- _ = try stdout.write(printed.js);
+ fn malloc(size: usize) callconv(.C) ?*c_void {
+ if (size == 0) {
+ return null;
+ }
+ //const result = alloc.dynamic.alloc(u8, size) catch return null;
+ const result = alloc.dynamic.allocFn(alloc.dynamic, size, 1, 1, 0) catch return null;
+ return result.ptr;
+ }
+ fn calloc(num_elements: usize, element_size: usize) callconv(.C) ?*c_void {
+ const size = num_elements *% element_size;
+ const c_ptr = @call(.{ .modifier = .never_inline }, malloc, .{size});
+ if (c_ptr) |ptr| {
+ const p = @ptrCast([*]u8, ptr);
+ @memset(p, 0, size);
+ }
+ return c_ptr;
+ }
+ fn realloc(c_ptr: ?*c_void, new_size: usize) callconv(.C) ?*c_void {
+ if (new_size == 0) {
+ @call(.{ .modifier = .never_inline }, free, .{c_ptr});
+ return null;
+ } else if (c_ptr) |ptr| {
+ // Use a synthetic slice
+ const p = @ptrCast([*]u8, ptr);
+ const result = alloc.dynamic.realloc(p[0..1], new_size) catch return null;
+ return @ptrCast(*c_void, result.ptr);
+ } else {
+ return @call(.{ .modifier = .never_inline }, malloc, .{new_size});
+ }
+ }
+ fn free(c_ptr: ?*c_void) callconv(.C) void {
+ if (c_ptr) |ptr| {
+ // Use a synthetic slice. zee_alloc will free via corresponding metadata.
+ const p = @ptrCast([*]u8, ptr);
+ //alloc.dynamic.free(p[0..1]);
+ _ = alloc.dynamic.resizeFn(alloc.dynamic, p[0..1], 0, 0, 0, 0) catch unreachable;
+ }
+ }
+};
+
+comptime {
+ @export(Exports.init, .{ .name = "init", .linkage = .Strong });
+ @export(Exports.transform, .{ .name = "transform", .linkage = .Strong });
+ @export(Exports.malloc, .{ .name = "malloc", .linkage = .Strong });
+ @export(Exports.calloc, .{ .name = "calloc", .linkage = .Strong });
+ @export(Exports.realloc, .{ .name = "realloc", .linkage = .Strong });
+ @export(Exports.free, .{ .name = "free", .linkage = .Strong });
}
+
+var api: ?*Api = null;
diff --git a/src/options.zig b/src/options.zig
index 9106fbdf6..eaf57e6f8 100644
--- a/src/options.zig
+++ b/src/options.zig
@@ -3,7 +3,7 @@ const log = @import("logger.zig");
const fs = @import("fs.zig");
const alloc = @import("alloc.zig");
-usingnamespace @import("strings.zig");
+usingnamespace @import("global.zig");
const assert = std.debug.assert;
diff --git a/src/output_native.zig b/src/output_native.zig
new file mode 100644
index 000000000..f0570bf32
--- /dev/null
+++ b/src/output_native.zig
@@ -0,0 +1,5 @@
+const std = @import("std");
+
+pub var Stream: ?std.fs.File = null;
+pub var writer: ?std.fs.File.Writer = null;
+pub var errorWriter: ?std.fs.File.Writer = null;
diff --git a/src/output_wasi.zig b/src/output_wasi.zig
new file mode 100644
index 000000000..f0570bf32
--- /dev/null
+++ b/src/output_wasi.zig
@@ -0,0 +1,5 @@
+const std = @import("std");
+
+pub var Stream: ?std.fs.File = null;
+pub var writer: ?std.fs.File.Writer = null;
+pub var errorWriter: ?std.fs.File.Writer = null;
diff --git a/src/output_wasm.zig b/src/output_wasm.zig
new file mode 100644
index 000000000..8ad9fdebb
--- /dev/null
+++ b/src/output_wasm.zig
@@ -0,0 +1,5 @@
+const std = @import("std");
+
+pub var out_buffer = [_]u8{0} ** 1024;
+pub var Stream = std.io.fixedBufferStream(&out_buffer);
+pub var writer = Stream.writer();
diff --git a/src/renamer.zig b/src/renamer.zig
index eef40d111..7c950da51 100644
--- a/src/renamer.zig
+++ b/src/renamer.zig
@@ -1,5 +1,5 @@
const js_ast = @import("js_ast.zig");
-usingnamespace @import("strings.zig");
+usingnamespace @import("global.zig");
const std = @import("std");
const logger = @import("logger.zig");
@@ -20,7 +20,7 @@ pub const Renamer = struct {
if (renamer.symbols.get(resolved)) |symbol| {
return symbol.original_name;
} else {
- std.debug.panic("Invalid symbol {s}", .{ref});
+ Global.panic("Invalid symbol {s}", .{ref});
}
}
};
diff --git a/src/string_immutable.zig b/src/string_immutable.zig
index fcd0edb4a..bac82f9f2 100644
--- a/src/string_immutable.zig
+++ b/src/string_immutable.zig
@@ -80,6 +80,8 @@ pub fn eql(self: string, other: anytype) bool {
}
return true;
}
+// I have not actually verified that this makes it faster
+// It's probably like 0.0001ms faster
pub fn eqlComptime(self: string, comptime alt: string) bool {
comptime var matcher_size: usize = 0;
@@ -346,11 +348,6 @@ pub fn ExactSizeMatcher(comptime max_bytes: usize) type {
return std.mem.readIntNative(T, &tmp);
}
- fn hashNoCheck(str: anytype) T {
- var tmp = [_]u8{0} ** max_bytes;
- std.mem.copy(u8, &tmp, str[0..str.len]);
- return std.mem.readIntNative(T, &tmp);
- }
fn hashUnsafe(str: anytype) T {
var tmp = [_]u8{0} ** max_bytes;
std.mem.copy(u8, &tmp, str[0..str.len]);
diff --git a/src/string_mutable.zig b/src/string_mutable.zig
index b041de6e3..f142f5101 100644
--- a/src/string_mutable.zig
+++ b/src/string_mutable.zig
@@ -112,7 +112,7 @@ pub const MutableString = struct {
return self.list.toOwnedSlice(self.allocator);
}
- pub fn toOwnedSliceLeaky(self: *MutableString) string {
+ pub fn toOwnedSliceLeaky(self: *MutableString) []u8 {
return self.list.items;
}
diff --git a/src/test/fixtures/noop.js b/src/test/fixtures/noop.js
index b67880d83..e69de29bb 100644
--- a/src/test/fixtures/noop.js
+++ b/src/test/fixtures/noop.js
@@ -1 +0,0 @@
-function hi() {}
diff --git a/src/test/fixtures/simple-150x.jsx b/src/test/fixtures/simple-150x.jsx
new file mode 100644
index 000000000..920e84ea5
--- /dev/null
+++ b/src/test/fixtures/simple-150x.jsx
@@ -0,0 +1,443 @@
+import { Link } from "../routes";
+import Head from "../components/head";
+import Nav from "../components/nav";
+import withRedux from "next-redux-wrapper";
+import Header from "../components/Header";
+import Button from "../components/Button";
+import cookies from "next-cookies";
+import Text from "../components/Text";
+import _ from "lodash";
+import { updateEntities, setCurrentUser, initStore } from "../redux/store";
+import { getFeaturedProfiles, getCurrentUser } from "../api";
+import { bindActionCreators } from "redux";
+import { Router } from "../routes";
+import PageFooter from "../components/PageFooter";
+import withLogin from "../lib/withLogin";
+import qs from "qs";
+import LazyLoad from "react-lazyload";
+import { buildImgSrcSet } from "../lib/imgUri";
+import { buildProfileURL } from "../lib/routeHelpers";
+import LoginGate, { LOGIN_STATUSES } from "../components/LoginGate";
+import Divider from "../components/Divider";
+import { SPACING } from "../helpers/styles";
+
+(function () {
+ const FeaturedProfile = ({ profile }) => {
+ return (
+ <Link route={buildProfileURL(profile.id)}>
+ <a className="Profile">
+ <img
+ src={_.first(profile.photos)}
+ srcSet={buildImgSrcSet(_.first(profile.photos), 250)}
+ />
+ <div className="Text">
+ <div className="Title">
+ <Text
+ font="sans-serif"
+ lineHeight="20px"
+ weight="semiBold"
+ size="18px"
+ color="#000"
+ >
+ {profile.name}
+ </Text>
+ </div>
+
+ <div className="Tagline">
+ <Text size="14px">{(profile.tagline || "").substr(0, 100)}</Text>
+ </div>
+ </div>
+ <style jsx>{`
+ .Profile {
+ background-color: #ffffff;
+ cursor: pointer;
+ text-decoration: none;
+ text-align: left;
+ width: 100%;
+ height: 100%;
+ border-radius: 6px;
+ display: flex;
+ flex-shrink: 0;
+ flex-grow: 0;
+ flex-direction: column;
+ }
+
+ .Text {
+ flex: 1;
+ }
+
+ .Profile:hover img {
+ opacity: 0.85;
+ }
+
+ .Title {
+ margin-top: 1rem;
+ margin-bottom: 0.5rem;
+ }
+
+ .Tagline {
+ margin-bottom: 1.5rem;
+ }
+
+ img {
+ object-fit: cover;
+ flex: 0 0 250px;
+ flex-shrink: 0;
+ display: flex;
+ width: 250px;
+ height: 250px;
+ opacity: 1;
+ transition: opacity 0.1s linear;
+ }
+
+ @media (max-width: 500px) {
+ .Profile {
+ margin-bottom: 2em;
+ }
+ }
+ `}</style>
+ </a>
+ </Link>
+ );
+ };
+
+ class SignupForm extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ email: this.props.email || "",
+ };
+ }
+
+ setEmail = (evt) => this.setState({ email: evt.target.value });
+
+ componentDidMount() {
+ Router.prefetchRoute(`/sign-up/verify`);
+ }
+
+ handleSubmit = (evt) => {
+ evt.preventDefault();
+
+ Router.pushRoute(
+ `/sign-up/verify?${qs.stringify({ email: this.state.email })}`
+ );
+ };
+
+ render() {
+ return (
+ <form onSubmit={this.handleSubmit}>
+ <input
+ type="email"
+ name="email"
+ autoComplete="email"
+ onChange={this.setEmail}
+ placeholder="Your email"
+ value={this.state.email}
+ />
+ <Button componentType="button" inline>
+ CREATE MY PAGE
+ </Button>
+
+ <style jsx>{`
+ form {
+ display: flex;
+ }
+
+ input {
+ font-size: 14px;
+ padding: 14px 22px;
+ border-radius: 33px;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border: 1px solid #bababa;
+ border-right: 0px;
+ line-height: 18px;
+ color: #000;
+ outline: none;
+ width: auto;
+ display: flex;
+ flex: 1;
+ }
+
+ input::-webkit-input-placeholder {
+ color: #c5cbd4;
+ }
+
+ input:focus {
+ border-color: #b0b0b0;
+ }
+ `}</style>
+ </form>
+ );
+ }
+ }
+
+ class Homepage extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ isLoadingProfiles: true,
+ profiles: [],
+ };
+ }
+
+ static async getInitialProps(ctx) {
+ if (ctx.isServer && ctx.req.path === "/") {
+ const { currentUserId } = cookies(ctx);
+
+ if (currentUserId) {
+ ctx.res.writeHead(302, {
+ Location: `${process.env.DOMAIN}/welcome`,
+ });
+
+ ctx.res.end();
+ ctx.res.finished = true;
+ }
+ }
+ }
+
+ async componentDidMount() {
+ const profileResponse = await getFeaturedProfiles();
+ this.props.updateEntities(profileResponse.body);
+
+ this.setState({
+ isLoadingProfiles: false,
+ profiles: profileResponse.body.data,
+ });
+
+ Router.prefetchRoute(`/lucy`);
+ }
+
+ render() {
+ return (
+ <div>
+ <Head
+ title="Apply to Date – your own game of The Bachelor(ette)"
+ url={`${process.env.DOMAIN}/`}
+ disableGoogle={false}
+ />
+ <Header />
+ <article>
+ <main>
+ <div className="Copy">
+ <img
+ className="Logo Logo-Home"
+ src="/static/animatedlogo.gif"
+ />
+ <div className="Copy-title">
+ <Text
+ font="serif"
+ size="36px"
+ lineHeight="44px"
+ weight="bold"
+ >
+ Your own game of The Bachelor(ette)
+ </Text>
+ </div>
+ <div className="Copy-body">
+ <Text size="16px" lineHeight="24px" font="sans-serif">
+ Create a page where people apply to go on a date with you.
+ You pick the winners.
+ </Text>
+ </div>
+
+ {!this.props.currentUserId && <SignupForm />}
+
+ <div className="AppStoreContainer">
+ <Divider height={`${SPACING.normal}px`} color="transparent" />
+ <a
+ className="AppStore AppStore--ios"
+ target="_blank"
+ href="https://itunes.apple.com/us/app/apply-to-date/id1357419725?mt=8"
+ >
+ <img src="https://devimages-cdn.apple.com/app-store/marketing/guidelines/images/badge-download-on-the-app-store.svg" />
+ </a>
+
+ <a
+ target="_blank"
+ className="AppStore AppStore--android"
+ href="https://play.google.com/store/apps/details?id=com.shipfirstlabs.applytodate&utm_source=homepage&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1"
+ >
+ <img
+ alt="Get it on Google Play"
+ src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
+ />
+ </a>
+ </div>
+ </div>
+ </main>
+ </article>
+
+ <footer>
+ <div className="divider" />
+
+ <Text size="36px" font="sans-serif" color="#000">
+ Featured pages
+ </Text>
+
+ <div className="FeaturedProfiles-wrapper">
+ {this.state.isLoadingProfiles && <div className="Spinner" />}
+ <div className="FeaturedProfiles">
+ {!_.isEmpty(this.state.profiles) &&
+ this.state.profiles.map((profile) => (
+ <FeaturedProfile key={profile.id} profile={profile} />
+ ))}
+ </div>
+ </div>
+ </footer>
+
+ <article>
+ <PageFooter center />
+ </article>
+ <style jsx>{`
+ article {
+ max-width: 710px;
+ margin-left: auto;
+ margin-right: auto;
+ padding-left: 14px;
+ padding-right: 14px;
+ overflow-x: hidden;
+ }
+
+ main {
+ display: flex;
+ margin-top: 6rem;
+ margin-bottom: 6rem;
+
+ justify-content: center;
+ }
+
+ footer {
+ display: flex;
+ flex-direction: column;
+ text-align: center;
+ overflow-x: hidden;
+ }
+
+ .divider {
+ height: 2px;
+ width: 269px;
+ margin-bottom: 6rem;
+ margin-left: auto;
+ margin-right: auto;
+ background-color: #0aca9b;
+ }
+
+ .Logo-Home {
+ margin-left: auto;
+ margin-right: auto;
+ width: 97px;
+ height: 152.02px;
+ margin-bottom: 28px;
+ }
+
+ .Copy {
+ max-width: 710px;
+ margin: 0 auto;
+ text-align: center;
+ }
+
+ .Copy-body {
+ margin-top: 1rem;
+ margin-bottom: 2rem;
+ font-weight: 200;
+ }
+
+ .FeaturedProfiles-wrapper {
+ padding-top: 4rem;
+ padding-bottom: 6rem;
+ padding-left: 28px;
+ padding-right: 28px;
+
+ overflow-x: auto;
+ width: 100vw;
+ }
+
+ .Spinner {
+ display: flex;
+ content: "";
+ margin: 84px auto;
+ height: 28px;
+ width: 28px;
+ animation: rotate 0.8s infinite linear;
+ border: 4px solid #4be1ab;
+ border-right-color: transparent;
+ border-radius: 50%;
+ }
+
+ .AppStoreContainer {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+
+ .AppStore--ios img {
+ width: 180px;
+ }
+
+ .AppStore--android img {
+ width: 230px;
+ }
+
+ @keyframes rotate {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
+
+ .FeaturedProfiles {
+ display: grid;
+ grid-column-gap: 2rem;
+ grid-row-gap: 2rem;
+ text-align: center;
+ justify-content: center;
+ margin-left: auto;
+ margin-right: auto;
+ grid-template-columns: 250px 250px 250px 250px;
+ }
+
+ @media (max-width: 1100px) {
+ .FeaturedProfiles {
+ grid-template-columns: 250px 250px 250px;
+ }
+ }
+
+ @media (max-width: 900px) {
+ .FeaturedProfiles {
+ grid-template-columns: 250px 250px;
+ }
+ }
+
+ @media (max-width: 554px) {
+ .FeaturedProfiles-wrapper {
+ padding-left: 14px;
+ padding-right: 14px;
+ }
+
+ .AppStoreContainer {
+ flex-direction: column;
+ }
+
+ .FeaturedProfiles {
+ grid-auto-flow: row dense;
+ grid-auto-rows: auto;
+ grid-template-columns: 250px;
+ grid-template-rows: 1fr;
+ justify-content: center;
+ }
+ }
+ `}</style>
+ </div>
+ );
+ }
+ }
+
+ const HomepageWithStore = withRedux(initStore, null, (dispatch) =>
+ bindActionCreators({ updateEntities, setCurrentUser }, dispatch)
+ )(LoginGate(Homepage));
+})();
diff --git a/src/zee_alloc.zig b/src/zee_alloc.zig
new file mode 100644
index 000000000..ab98fe854
--- /dev/null
+++ b/src/zee_alloc.zig
@@ -0,0 +1,663 @@
+const std = @import("std");
+
+const Allocator = std.mem.Allocator;
+
+pub const Config = struct {
+ /// ZeeAlloc will request a multiple of `slab_size` from the backing allocator.
+ /// **Must** be a power of two.
+ slab_size: usize = std.math.max(std.mem.page_size, 65536), // 64K ought to be enough for everybody
+
+ /// **Must** be a power of two.
+ min_element_size: usize = 4,
+
+ fn maxElementSize(conf: Config) usize {
+ // Scientifically derived value
+ return conf.slab_size / 4;
+ }
+};
+
+pub const ZeeAllocDefaults = ZeeAlloc(Config{});
+
+pub fn ZeeAlloc(comptime conf: Config) type {
+ return struct {
+ const Self = @This();
+
+ const min_shift_size = unsafeLog2(usize, conf.min_element_size);
+ const max_shift_size = unsafeLog2(usize, conf.maxElementSize());
+ const total_slabs = max_shift_size - min_shift_size + 1;
+
+ /// The definitive™ way of using `ZeeAlloc`
+ pub const wasm_allocator = &_wasm.allocator;
+ var _wasm = init(&wasm_page_allocator);
+
+ jumbo: ?*Slab = null,
+ slabs: [total_slabs]?*Slab = [_]?*Slab{null} ** total_slabs,
+ backing_allocator: *std.mem.Allocator,
+
+ allocator: Allocator = Allocator{
+ .allocFn = alloc,
+ .resizeFn = resize,
+ },
+
+ const Slab = extern struct {
+ const header_size = 2 * @sizeOf(usize);
+ const payload_alignment = header_size;
+
+ next: ?*Slab align(conf.slab_size),
+ element_size: usize,
+ pad: [conf.slab_size - header_size]u8 align(payload_alignment),
+
+ fn init(element_size: usize) Slab {
+ var result: Slab = undefined;
+ result.reset(element_size);
+ return result;
+ }
+
+ fn reset(self: *Slab, element_size: usize) void {
+ self.next = null;
+ self.element_size = element_size;
+
+ const blocks = self.freeBlocks();
+ for (blocks) |*block| {
+ block.* = std.math.maxInt(u64);
+ }
+
+ const remaining_bits = @truncate(u6, (self.elementCount() - self.dataOffset()) % 64);
+ // TODO: detect overflow
+ blocks[blocks.len - 1] = (@as(u64, 1) << remaining_bits) - 1;
+ }
+
+ fn fromMemPtr(ptr: [*]u8) *Slab {
+ const addr = std.mem.alignBackward(@ptrToInt(ptr), conf.slab_size);
+ return @intToPtr(*Slab, addr);
+ }
+
+ const detached_signal = @intToPtr(*align(1) Slab, 0xaaaa);
+ fn markDetached(self: *Slab) void {
+ // Salt the earth
+ const raw_next = @ptrCast(*usize, &self.next);
+ raw_next.* = @ptrToInt(detached_signal);
+ }
+
+ fn isDetached(self: Slab) bool {
+ return self.next == detached_signal;
+ }
+
+ fn freeBlocks(self: *Slab) []u64 {
+ const count = divCeil(usize, self.elementCount(), 64);
+ const ptr = @ptrCast([*]u64, &self.pad);
+ return ptr[0..count];
+ }
+
+ fn totalFree(self: *Slab) usize {
+ var i: usize = 0;
+ for (self.freeBlocks()) |block| {
+ i += @popCount(u64, block);
+ }
+ return i;
+ }
+
+ const UsizeShift = std.meta.Int(.unsigned, @bitSizeOf(std.math.Log2Int(usize)) - 1);
+ fn elementSizeShift(self: Slab) UsizeShift {
+ return @truncate(UsizeShift, @ctz(usize, self.element_size));
+ }
+
+ fn elementCount(self: Slab) usize {
+ return conf.slab_size >> self.elementSizeShift();
+ }
+
+ fn dataOffset(self: Slab) usize {
+ const BITS_PER_BYTE = 8;
+ return 1 + ((conf.slab_size / BITS_PER_BYTE) >> self.elementSizeShift() >> self.elementSizeShift());
+ }
+
+ fn elementAt(self: *Slab, idx: usize) []u8 {
+ std.debug.assert(idx >= self.dataOffset());
+ std.debug.assert(idx < self.elementCount());
+
+ const bytes = std.mem.asBytes(self);
+ return bytes[idx << self.elementSizeShift() ..][0..self.element_size];
+ }
+
+ fn elementIdx(self: *Slab, element: []u8) usize {
+ std.debug.assert(element.len <= self.element_size);
+ const diff = @ptrToInt(element.ptr) - @ptrToInt(self);
+ std.debug.assert(diff % self.element_size == 0);
+
+ return diff >> self.elementSizeShift();
+ }
+
+ fn alloc(self: *Slab) ![]u8 {
+ for (self.freeBlocks()) |*block, i| {
+ const bit = @ctz(u64, block.*);
+ if (bit != 64) {
+ const index = 64 * i + bit;
+
+ const mask = @as(u64, 1) << @intCast(u6, bit);
+ block.* &= ~mask;
+
+ return self.elementAt(index + self.dataOffset());
+ }
+ }
+
+ return error.OutOfMemory;
+ }
+
+ fn free(self: *Slab, element: []u8) void {
+ const index = self.elementIdx(element) - self.dataOffset();
+
+ const block = &self.freeBlocks()[index / 64];
+ const mask = @as(u64, 1) << @truncate(u6, index);
+ std.debug.assert(mask & block.* == 0);
+ block.* |= mask;
+ }
+ };
+
+ pub fn init(allocator: *std.mem.Allocator) Self {
+ return .{ .backing_allocator = allocator };
+ }
+
+ pub fn deinit(self: *Self) void {
+ {
+ var iter = self.jumbo;
+ while (iter) |node| {
+ iter = node.next;
+ const bytes = @ptrCast([*]u8, node);
+ self.backing_allocator.free(bytes[0..node.element_size]);
+ }
+ }
+
+ for (self.slabs) |root| {
+ var iter = root;
+ while (iter) |node| {
+ iter = node.next;
+ self.backing_allocator.destroy(node);
+ }
+ }
+ self.* = undefined;
+ }
+
+ fn isJumbo(value: usize) bool {
+ return value > conf.slab_size / 4;
+ }
+
+ fn padToSize(memsize: usize) usize {
+ if (isJumbo(memsize)) {
+ return std.mem.alignForward(memsize + Slab.header_size, conf.slab_size);
+ } else {
+ return std.math.max(conf.min_element_size, ceilPowerOfTwo(usize, memsize));
+ }
+ }
+
+ fn unsafeLog2(comptime T: type, val: T) T {
+ std.debug.assert(ceilPowerOfTwo(T, val) == val);
+ return @ctz(T, val);
+ }
+
+ fn findSlabIndex(padded_size: usize) usize {
+ return unsafeLog2(usize, padded_size) - min_shift_size;
+ }
+
+ fn allocJumbo(self: *Self, padded_size: usize, ptr_align: usize) ![*]u8 {
+ if (ptr_align > Slab.payload_alignment) {
+ return error.OutOfMemory;
+ }
+
+ const slab: *Slab = blk: {
+ var prev = @ptrCast(*align(@alignOf(Self)) Slab, self);
+ while (prev.next) |curr| : (prev = curr) {
+ if (curr.element_size == padded_size) {
+ prev.next = curr.next;
+ break :blk curr;
+ }
+ }
+
+ const new_frame = try self.backing_allocator.allocAdvanced(u8, conf.slab_size, padded_size, .exact);
+ const synth_slab = @ptrCast(*Slab, new_frame.ptr);
+ synth_slab.element_size = padded_size;
+ break :blk synth_slab;
+ };
+ slab.markDetached();
+ return @ptrCast([*]u8, &slab.pad);
+ }
+
+ fn allocSlab(self: *Self, element_size: usize, ptr_align: usize) ![*]u8 {
+ if (ptr_align > element_size) {
+ return error.OutOfMemory;
+ }
+
+ const idx = findSlabIndex(element_size);
+ const slab = self.slabs[idx] orelse blk: {
+ const new_slab = try self.backing_allocator.create(Slab);
+ new_slab.reset(element_size);
+ self.slabs[idx] = new_slab;
+ break :blk new_slab;
+ };
+
+ const result = slab.alloc() catch unreachable;
+ if (slab.totalFree() == 0) {
+ self.slabs[idx] = slab.next;
+ slab.markDetached();
+ }
+
+ return result.ptr;
+ }
+
+ fn alloc(allocator: *Allocator, n: usize, ptr_align: u29, len_align: u29, ret_addr: usize) Allocator.Error![]u8 {
+ const self = @fieldParentPtr(Self, "allocator", allocator);
+
+ const padded_size = padToSize(n);
+ const ptr: [*]u8 = if (isJumbo(n))
+ try self.allocJumbo(padded_size, ptr_align)
+ else
+ try self.allocSlab(padded_size, ptr_align);
+
+ return ptr[0..std.mem.alignAllocLen(padded_size, n, len_align)];
+ }
+
+ fn resize(allocator: *Allocator, buf: []u8, buf_align: u29, new_size: usize, len_align: u29, ret_addr: usize) Allocator.Error!usize {
+ const self = @fieldParentPtr(Self, "allocator", allocator);
+
+ const slab = Slab.fromMemPtr(buf.ptr);
+ if (new_size == 0) {
+ if (isJumbo(slab.element_size)) {
+ std.debug.assert(slab.isDetached());
+ slab.next = self.jumbo;
+ self.jumbo = slab;
+ } else {
+ slab.free(buf);
+ if (slab.isDetached()) {
+ const idx = findSlabIndex(slab.element_size);
+ slab.next = self.slabs[idx];
+ self.slabs[idx] = slab;
+ }
+ }
+ return 0;
+ }
+
+ const padded_new_size = padToSize(new_size);
+ if (padded_new_size > slab.element_size) {
+ return error.OutOfMemory;
+ }
+
+ return std.mem.alignAllocLen(padded_new_size, new_size, len_align);
+ }
+ };
+}
+
+var wasm_page_allocator = init: {
+ if (!std.builtin.target.isWasm()) {
+ @compileError("wasm allocator is only available for wasm32 arch");
+ }
+
+ // std.heap.WasmPageAllocator is designed for reusing pages
+ // We never free, so this lets us stay super small
+ const WasmPageAllocator = struct {
+ fn alloc(allocator: *Allocator, n: usize, alignment: u29, len_align: u29, ret_addr: usize) Allocator.Error![]u8 {
+ const is_debug = std.builtin.mode == .Debug;
+ @setRuntimeSafety(is_debug);
+ std.debug.assert(n % std.mem.page_size == 0); // Should only be allocating page size chunks
+ std.debug.assert(alignment % std.mem.page_size == 0); // Should only align to page_size increments
+
+ const requested_page_count = @intCast(u32, n / std.mem.page_size);
+ const prev_page_count = @wasmMemoryGrow(0, requested_page_count);
+ if (prev_page_count < 0) {
+ return error.OutOfMemory;
+ }
+
+ const start_ptr = @intToPtr([*]u8, @intCast(usize, prev_page_count) * std.mem.page_size);
+ return start_ptr[0..n];
+ }
+ };
+
+ break :init Allocator{
+ .allocFn = WasmPageAllocator.alloc,
+ .resizeFn = undefined, // Shouldn't be shrinking / freeing
+ };
+};
+
+pub const ExportC = struct {
+ allocator: *std.mem.Allocator,
+ malloc: bool = true,
+ free: bool = true,
+ calloc: bool = false,
+ realloc: bool = false,
+
+ pub fn run(comptime conf: ExportC) void {
+ const Funcs = struct {
+ fn malloc(size: usize) callconv(.C) ?*c_void {
+ if (size == 0) {
+ return null;
+ }
+ //const result = conf.allocator.alloc(u8, size) catch return null;
+ const result = conf.allocator.allocFn(conf.allocator, size, 1, 1, 0) catch return null;
+ return result.ptr;
+ }
+ fn calloc(num_elements: usize, element_size: usize) callconv(.C) ?*c_void {
+ const size = num_elements *% element_size;
+ const c_ptr = @call(.{ .modifier = .never_inline }, malloc, .{size});
+ if (c_ptr) |ptr| {
+ const p = @ptrCast([*]u8, ptr);
+ @memset(p, 0, size);
+ }
+ return c_ptr;
+ }
+ fn realloc(c_ptr: ?*c_void, new_size: usize) callconv(.C) ?*c_void {
+ if (new_size == 0) {
+ @call(.{ .modifier = .never_inline }, free, .{c_ptr});
+ return null;
+ } else if (c_ptr) |ptr| {
+ // Use a synthetic slice
+ const p = @ptrCast([*]u8, ptr);
+ const result = conf.allocator.realloc(p[0..1], new_size) catch return null;
+ return @ptrCast(*c_void, result.ptr);
+ } else {
+ return @call(.{ .modifier = .never_inline }, malloc, .{new_size});
+ }
+ }
+ fn free(c_ptr: ?*c_void) callconv(.C) void {
+ if (c_ptr) |ptr| {
+ // Use a synthetic slice. zee_alloc will free via corresponding metadata.
+ const p = @ptrCast([*]u8, ptr);
+ //conf.allocator.free(p[0..1]);
+ _ = conf.allocator.resizeFn(conf.allocator, p[0..1], 0, 0, 0, 0) catch unreachable;
+ }
+ }
+ };
+
+ if (conf.malloc) {
+ @export(Funcs.malloc, .{ .name = "malloc" });
+ }
+ if (conf.calloc) {
+ @export(Funcs.calloc, .{ .name = "calloc" });
+ }
+ if (conf.realloc) {
+ @export(Funcs.realloc, .{ .name = "realloc" });
+ }
+ if (conf.free) {
+ @export(Funcs.free, .{ .name = "free" });
+ }
+ }
+};
+
+fn divCeil(comptime T: type, numerator: T, denominator: T) T {
+ return (numerator + denominator - 1) / denominator;
+}
+
+// https://github.com/ziglang/zig/issues/2426
+fn ceilPowerOfTwo(comptime T: type, value: T) T {
+ std.debug.assert(value != 0);
+ const Shift = comptime std.math.Log2Int(T);
+ return @as(T, 1) << @intCast(Shift, @bitSizeOf(T) - @clz(T, value - 1));
+}
+
+test "divCeil" {
+ std.testing.expectEqual(@as(u32, 0), divCeil(u32, 0, 64));
+ std.testing.expectEqual(@as(u32, 1), divCeil(u32, 1, 64));
+ std.testing.expectEqual(@as(u32, 1), divCeil(u32, 64, 64));
+ std.testing.expectEqual(@as(u32, 2), divCeil(u32, 65, 64));
+}
+
+test "Slab.init" {
+ {
+ const slab = ZeeAllocDefaults.Slab.init(16384);
+ std.testing.expectEqual(@as(usize, 16384), slab.element_size);
+ std.testing.expectEqual(@as(?*ZeeAllocDefaults.Slab, null), slab.next);
+
+ const raw_ptr = @ptrCast(*const u64, &slab.pad);
+ std.testing.expectEqual((@as(u64, 1) << 3) - 1, raw_ptr.*);
+ }
+
+ {
+ const slab = ZeeAllocDefaults.Slab.init(2048);
+ std.testing.expectEqual(@as(usize, 2048), slab.element_size);
+ std.testing.expectEqual(@as(?*ZeeAllocDefaults.Slab, null), slab.next);
+
+ const raw_ptr = @ptrCast(*const u64, &slab.pad);
+ std.testing.expectEqual((@as(u64, 1) << 31) - 1, raw_ptr.*);
+ }
+
+ const u64_max: u64 = std.math.maxInt(u64);
+
+ {
+ const slab = ZeeAllocDefaults.Slab.init(256);
+ std.testing.expectEqual(@as(usize, 256), slab.element_size);
+ std.testing.expectEqual(@as(?*ZeeAllocDefaults.Slab, null), slab.next);
+
+ const raw_ptr = @ptrCast([*]const u64, &slab.pad);
+ std.testing.expectEqual(u64_max, raw_ptr[0]);
+ std.testing.expectEqual(u64_max, raw_ptr[1]);
+ std.testing.expectEqual(u64_max, raw_ptr[2]);
+ std.testing.expectEqual((@as(u64, 1) << 63) - 1, raw_ptr[3]);
+ }
+}
+
+test "Slab.elementAt" {
+ {
+ var slab = ZeeAllocDefaults.Slab.init(16384);
+
+ var element = slab.elementAt(1);
+ std.testing.expectEqual(slab.element_size, element.len);
+ std.testing.expectEqual(1 * slab.element_size, @ptrToInt(element.ptr) - @ptrToInt(&slab));
+
+ element = slab.elementAt(2);
+ std.testing.expectEqual(slab.element_size, element.len);
+ std.testing.expectEqual(2 * slab.element_size, @ptrToInt(element.ptr) - @ptrToInt(&slab));
+
+ element = slab.elementAt(3);
+ std.testing.expectEqual(slab.element_size, element.len);
+ std.testing.expectEqual(3 * slab.element_size, @ptrToInt(element.ptr) - @ptrToInt(&slab));
+ }
+ {
+ var slab = ZeeAllocDefaults.Slab.init(128);
+
+ var element = slab.elementAt(1);
+ std.testing.expectEqual(slab.element_size, element.len);
+ std.testing.expectEqual(1 * slab.element_size, @ptrToInt(element.ptr) - @ptrToInt(&slab));
+
+ element = slab.elementAt(2);
+ std.testing.expectEqual(slab.element_size, element.len);
+ std.testing.expectEqual(2 * slab.element_size, @ptrToInt(element.ptr) - @ptrToInt(&slab));
+
+ element = slab.elementAt(3);
+ std.testing.expectEqual(slab.element_size, element.len);
+ std.testing.expectEqual(3 * slab.element_size, @ptrToInt(element.ptr) - @ptrToInt(&slab));
+ }
+ {
+ var slab = ZeeAllocDefaults.Slab.init(64);
+ std.testing.expectEqual(@as(usize, 3), slab.dataOffset());
+
+ var element = slab.elementAt(3);
+ std.testing.expectEqual(slab.element_size, element.len);
+ std.testing.expectEqual(3 * slab.element_size, @ptrToInt(element.ptr) - @ptrToInt(&slab));
+
+ element = slab.elementAt(5);
+ std.testing.expectEqual(slab.element_size, element.len);
+ std.testing.expectEqual(5 * slab.element_size, @ptrToInt(element.ptr) - @ptrToInt(&slab));
+ }
+ {
+ var slab = ZeeAllocDefaults.Slab.init(4);
+ std.testing.expectEqual(@as(usize, 513), slab.dataOffset());
+
+ var element = slab.elementAt(513);
+ std.testing.expectEqual(slab.element_size, element.len);
+ std.testing.expectEqual(513 * slab.element_size, @ptrToInt(element.ptr) - @ptrToInt(&slab));
+
+ element = slab.elementAt(1023);
+ std.testing.expectEqual(slab.element_size, element.len);
+ std.testing.expectEqual(1023 * slab.element_size, @ptrToInt(element.ptr) - @ptrToInt(&slab));
+ }
+}
+
+test "Slab.elementIdx" {
+ var slab = ZeeAllocDefaults.Slab.init(128);
+
+ var element = slab.elementAt(1);
+ std.testing.expectEqual(@as(usize, 1), slab.elementIdx(element));
+}
+
+test "Slab.freeBlocks" {
+ {
+ var slab = ZeeAllocDefaults.Slab.init(16384);
+
+ const blocks = slab.freeBlocks();
+ std.testing.expectEqual(@as(usize, 1), blocks.len);
+ std.testing.expectEqual(@ptrToInt(&slab.pad), @ptrToInt(blocks.ptr));
+ }
+ {
+ var slab = ZeeAllocDefaults.Slab.init(128);
+
+ const blocks = slab.freeBlocks();
+ std.testing.expectEqual(@as(usize, 8), blocks.len);
+ std.testing.expectEqual(@ptrToInt(&slab.pad), @ptrToInt(blocks.ptr));
+ }
+}
+
+test "Slab.alloc + free" {
+ var slab = ZeeAllocDefaults.Slab.init(16384);
+
+ std.testing.expectEqual(@as(usize, 3), slab.totalFree());
+
+ const data0 = try slab.alloc();
+ std.testing.expectEqual(@as(usize, 2), slab.totalFree());
+ std.testing.expectEqual(@as(usize, 16384), data0.len);
+
+ const data1 = try slab.alloc();
+ std.testing.expectEqual(@as(usize, 1), slab.totalFree());
+ std.testing.expectEqual(@as(usize, 16384), data1.len);
+ std.testing.expectEqual(@as(usize, 16384), @ptrToInt(data1.ptr) - @ptrToInt(data0.ptr));
+
+ const data2 = try slab.alloc();
+ std.testing.expectEqual(@as(usize, 0), slab.totalFree());
+ std.testing.expectEqual(@as(usize, 16384), data2.len);
+ std.testing.expectEqual(@as(usize, 16384), @ptrToInt(data2.ptr) - @ptrToInt(data1.ptr));
+
+ std.testing.expectError(error.OutOfMemory, slab.alloc());
+
+ {
+ slab.free(data2);
+ std.testing.expectEqual(@as(usize, 1), slab.totalFree());
+ slab.free(data1);
+ std.testing.expectEqual(@as(usize, 2), slab.totalFree());
+ slab.free(data0);
+ std.testing.expectEqual(@as(usize, 3), slab.totalFree());
+ }
+}
+
+test "padToSize" {
+ const page_size = 65536;
+ const header_size = 2 * @sizeOf(usize);
+
+ std.testing.expectEqual(@as(usize, 4), ZeeAllocDefaults.padToSize(1));
+ std.testing.expectEqual(@as(usize, 4), ZeeAllocDefaults.padToSize(4));
+ std.testing.expectEqual(@as(usize, 8), ZeeAllocDefaults.padToSize(8));
+ std.testing.expectEqual(@as(usize, 16), ZeeAllocDefaults.padToSize(9));
+ std.testing.expectEqual(@as(usize, 16384), ZeeAllocDefaults.padToSize(16384));
+}
+
+test "alloc slabs" {
+ var zee_alloc = ZeeAllocDefaults.init(std.testing.allocator);
+ defer zee_alloc.deinit();
+
+ for (zee_alloc.slabs) |root| {
+ std.testing.expect(root == null);
+ }
+
+ std.testing.expect(zee_alloc.slabs[0] == null);
+ const small = try zee_alloc.allocator.alloc(u8, 4);
+ std.testing.expect(zee_alloc.slabs[0] != null);
+ const smalls_before_free = zee_alloc.slabs[0].?.totalFree();
+ zee_alloc.allocator.free(small);
+ std.testing.expectEqual(smalls_before_free + 1, zee_alloc.slabs[0].?.totalFree());
+
+ std.testing.expect(zee_alloc.slabs[12] == null);
+ const large = try zee_alloc.allocator.alloc(u8, 16384);
+ std.testing.expect(zee_alloc.slabs[12] != null);
+ const larges_before_free = zee_alloc.slabs[12].?.totalFree();
+ zee_alloc.allocator.free(large);
+ std.testing.expectEqual(larges_before_free + 1, zee_alloc.slabs[12].?.totalFree());
+}
+
+test "alloc jumbo" {
+ var zee_alloc = ZeeAllocDefaults.init(std.testing.allocator);
+ defer zee_alloc.deinit();
+
+ std.testing.expect(zee_alloc.jumbo == null);
+ const first = try zee_alloc.allocator.alloc(u8, 32000);
+ std.testing.expect(zee_alloc.jumbo == null);
+ std.testing.expectEqual(@as(usize, ZeeAllocDefaults.Slab.header_size), @ptrToInt(first.ptr) % 65536);
+ zee_alloc.allocator.free(first);
+ std.testing.expect(zee_alloc.jumbo != null);
+
+ const reuse = try zee_alloc.allocator.alloc(u8, 32000);
+ std.testing.expect(zee_alloc.jumbo == null);
+ std.testing.expectEqual(first.ptr, reuse.ptr);
+ zee_alloc.allocator.free(first);
+ std.testing.expect(zee_alloc.jumbo != null);
+}
+
+test "functional tests" {
+ var zee_alloc = ZeeAllocDefaults.init(std.testing.allocator);
+ defer zee_alloc.deinit();
+
+ try std.heap.testAllocator(&zee_alloc.allocator);
+ try std.heap.testAllocatorAligned(&zee_alloc.allocator, 16);
+}
+
+fn expectIllegalBehavior(context: anytype, comptime func: anytype) !void {
+ if (!@hasDecl(std.os.system, "fork") or !std.debug.runtime_safety) return;
+
+ const child_pid = try std.os.fork();
+ if (child_pid == 0) {
+ const null_fd = std.os.openZ("/dev/null", std.os.O_RDWR, 0) catch {
+ std.debug.print("Cannot open /dev/null\n", .{});
+ std.os.exit(0);
+ };
+ std.os.dup2(null_fd, std.io.getStdErr().handle) catch {
+ std.debug.print("Cannot close child process stderr\n", .{});
+ std.os.exit(0);
+ };
+
+ func(context); // this should crash
+ std.os.exit(0);
+ } else {
+ const status = std.os.waitpid(child_pid, 0);
+ // Maybe we should use a fixed error code instead of checking status != 0
+ if (status == 0) @panic("Expected illegal behavior but succeeded instead");
+ }
+}
+
+const AllocContext = struct {
+ allocator: *Allocator,
+ mem: []u8,
+
+ fn init(allocator: *Allocator, mem: []u8) AllocContext {
+ return .{ .allocator = allocator, .mem = mem };
+ }
+
+ fn free(self: AllocContext) void {
+ self.allocator.free(self.mem);
+ }
+};
+
+test "double free" {
+ var zee_alloc = ZeeAllocDefaults.init(std.testing.allocator);
+ defer zee_alloc.deinit();
+
+ const mem = try zee_alloc.allocator.alloc(u8, 16);
+ zee_alloc.allocator.free(mem);
+
+ const context = AllocContext.init(&zee_alloc.allocator, mem);
+ try expectIllegalBehavior(context, AllocContext.free);
+}
+
+test "freeing non-owned memory" {
+ var zee_alloc = ZeeAllocDefaults.init(std.testing.allocator);
+ defer zee_alloc.deinit();
+
+ const mem = try std.testing.allocator.alloc(u8, 16);
+ defer std.testing.allocator.free(mem);
+
+ const context = AllocContext.init(&zee_alloc.allocator, mem);
+ try expectIllegalBehavior(context, AllocContext.free);
+}