diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 684ec3cf8..ceffde09e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,6 +12,7 @@ jobs: needs: - build-bench - build-dist + - build-examples - build-flatpak - build-freebsd - build-linux @@ -22,6 +23,7 @@ jobs: - build-snap - build-windows - test + - test-simd - test-gtk - test-sentry-linux - test-macos @@ -87,6 +89,42 @@ jobs: - name: Build Benchmarks run: nix develop -c zig build -Demit-bench + build-examples: + strategy: + fail-fast: false + matrix: + dir: [zig-vt] + name: Example ${{ matrix.dir }} + runs-on: namespace-profile-ghostty-sm + needs: test + env: + ZIG_LOCAL_CACHE_DIR: /zig/local-cache + ZIG_GLOBAL_CACHE_DIR: /zig/global-cache + steps: + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Setup Cache + uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17 + with: + path: | + /nix + /zig + + # Install Nix and use that to run our tests so our environment matches exactly. + - uses: cachix/install-nix-action@a809471b5c7c913aa67bec8f459a11a0decc3fce # v31.6.2 + with: + nix_path: nixpkgs=channel:nixos-unstable + - uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16 + with: + name: ghostty + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + + - name: Build Example + run: | + cd example/${{ matrix.dir }} + nix develop -c zig build + build-flatpak: strategy: fail-fast: false @@ -564,6 +602,41 @@ jobs: -Dgtk-x11=${{ matrix.x11 }} \ -Dgtk-wayland=${{ matrix.wayland }} + test-simd: + strategy: + fail-fast: false + matrix: + simd: ["true", "false"] + name: Build -Dsimd=${{ matrix.simd }} + runs-on: namespace-profile-ghostty-sm + needs: test + env: + ZIG_LOCAL_CACHE_DIR: /zig/local-cache + ZIG_GLOBAL_CACHE_DIR: /zig/global-cache + steps: + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Setup Cache + uses: namespacelabs/nscloud-cache-action@a289cf5d2fcd6874376aa92f0ef7f99dc923592a # v1.2.17 + with: + path: | + /nix + /zig + + # Install Nix and use that to run our tests so our environment matches exactly. + - uses: cachix/install-nix-action@a809471b5c7c913aa67bec8f459a11a0decc3fce # v31.6.2 + with: + nix_path: nixpkgs=channel:nixos-unstable + - uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16 + with: + name: ghostty + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + + - name: Test + run: | + nix develop -c zig build test -Dsimd=${{ matrix.simd }} + test-sentry-linux: strategy: fail-fast: false diff --git a/build.zig b/build.zig index 38cfd0e56..8838572b7 100644 --- a/build.zig +++ b/build.zig @@ -8,12 +8,25 @@ comptime { } pub fn build(b: *std.Build) !void { - // This defines all the available build options (e.g. `-D`). + // This defines all the available build options (e.g. `-D`). If you + // want to know what options are available, you can run `--help` or + // you can read `src/build/Config.zig`. const config = try buildpkg.Config.init(b); - const test_filter = b.option( - []const u8, + const test_filters = b.option( + [][]const u8, "test-filter", "Filter for test. Only applies to Zig tests.", + ) orelse &[0][]const u8{}; + + // Ghostty dependencies used by many artifacts. + const deps = try buildpkg.SharedDeps.init(b, &config); + + // The modules exported for Zig consumers of libghostty. If you're + // writing a Zig program that uses libghostty, read this file. + const mod = try buildpkg.GhosttyZig.init( + b, + &config, + &deps, ); // All our steps which we'll hook up later. The steps are shown @@ -24,6 +37,10 @@ pub fn build(b: *std.Build) !void { "Run the app under valgrind", ); const test_step = b.step("test", "Run tests"); + const test_lib_vt_step = b.step( + "test-lib-vt", + "Run libghostty-vt tests", + ); const test_valgrind_step = b.step( "test-valgrind", "Run tests under valgrind", @@ -37,10 +54,6 @@ pub fn build(b: *std.Build) !void { const resources = try buildpkg.GhosttyResources.init(b, &config); const i18n = if (config.i18n) try buildpkg.GhosttyI18n.init(b, &config) else null; - // Ghostty dependencies used by many artifacts. - const deps = try buildpkg.SharedDeps.init(b, &config); - if (config.emit_helpgen) deps.help_strings.install(); - // Ghostty executable, the actual runnable Ghostty program. const exe = try buildpkg.GhosttyExe.init(b, &config, &deps); @@ -83,6 +96,9 @@ pub fn build(b: *std.Build) !void { &deps, ); + // Helpgen + if (config.emit_helpgen) deps.help_strings.install(); + // Runtime "none" is libghostty, anything else is an executable. if (config.app_runtime != .none) { if (config.emit_exe) { @@ -185,7 +201,7 @@ pub fn build(b: *std.Build) !void { run_step.dependOn(&macos_app_native_only.open.step); // If we have no test filters, install the tests too - if (test_filter == null) { + if (test_filters.len == 0) { macos_app_native_only.addTestStepDependencies(test_step); } } @@ -216,11 +232,24 @@ pub fn build(b: *std.Build) !void { run_valgrind_step.dependOn(&run_cmd.step); } + // Zig module tests + { + const mod_vt_test = b.addTest(.{ + .root_module = mod.vt, + .target = config.target, + .optimize = config.optimize, + .filters = test_filters, + }); + const mod_vt_test_run = b.addRunArtifact(mod_vt_test); + test_lib_vt_step.dependOn(&mod_vt_test_run.step); + } + // Tests { + // Full unit tests const test_exe = b.addTest(.{ .name = "ghostty-test", - .filters = if (test_filter) |v| &.{v} else &.{}, + .filters = test_filters, .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = config.baselineTarget(), @@ -230,7 +259,6 @@ pub fn build(b: *std.Build) !void { .unwind_tables = .sync, }), }); - if (config.emit_test_exe) b.installArtifact(test_exe); _ = try deps.add(test_exe); @@ -238,6 +266,9 @@ pub fn build(b: *std.Build) !void { const test_run = b.addRunArtifact(test_exe); test_step.dependOn(&test_run.step); + // Normal tests always test our libghostty modules + test_step.dependOn(test_lib_vt_step); + // Valgrind test running const valgrind_run = b.addSystemCommand(&.{ "valgrind", diff --git a/example/app.ts b/example/app.ts deleted file mode 100644 index 5b426a333..000000000 --- a/example/app.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { ZigJS } from "zig-js"; - -const zjs = new ZigJS(); -const importObject = { - module: {}, - env: { - memory: new WebAssembly.Memory({ - initial: 25, - maximum: 65536, - shared: true, - }), - log: (ptr: number, len: number) => { - const arr = new Uint8ClampedArray(zjs.memory.buffer, ptr, len); - const data = arr.slice(); - const str = new TextDecoder("utf-8").decode(data); - console.log(str); - }, - }, - - ...zjs.importObject(), -}; - -const url = new URL("ghostty-wasm.wasm", import.meta.url); -fetch(url.href) - .then((response) => response.arrayBuffer()) - .then((bytes) => WebAssembly.instantiate(bytes, importObject)) - .then((results) => { - const memory = importObject.env.memory; - const { - malloc, - free, - config_new, - config_free, - config_load_string, - config_finalize, - face_new, - face_free, - face_render_glyph, - face_debug_canvas, - deferred_face_new, - deferred_face_free, - deferred_face_load, - deferred_face_face, - group_new, - group_free, - group_add_face, - group_init_sprite_face, - group_index_for_codepoint, - group_render_glyph, - group_cache_new, - group_cache_free, - group_cache_index_for_codepoint, - group_cache_render_glyph, - group_cache_atlas_grayscale, - group_cache_atlas_color, - atlas_new, - atlas_free, - atlas_debug_canvas, - shaper_new, - shaper_free, - shaper_test, - } = results.instance.exports; - // Give us access to the zjs value for debugging. - globalThis.zjs = zjs; - console.log(zjs); - - // Initialize our zig-js memory - zjs.memory = memory; - - // Helpers - const makeStr = (str) => { - const utf8 = new TextEncoder().encode(str); - const ptr = malloc(utf8.byteLength); - new Uint8Array(memory.buffer, ptr).set(utf8); - return { ptr: ptr, len: utf8.byteLength }; - }; - - // Create our config - const config = config_new(); - const config_str = makeStr("font-family = monospace"); - config_load_string(config, config_str.ptr, config_str.len); - config_finalize(config); - free(config_str.ptr); - - // Create our atlas - // const atlas = atlas_new(512, 0 /* grayscale */); - - // Create some memory for our string - const font_name = makeStr("monospace"); - - // Initialize our deferred face - // const df = deferred_face_new(font_ptr, font.byteLength, 0 /* text */); - //deferred_face_load(df, 72 /* size */); - //const face = deferred_face_face(df); - - // Initialize our font face - //const face = face_new(font_ptr, font.byteLength, 72 /* size in px */); - //free(font_ptr); - - // Create our group - const group = group_new(32 /* size */); - group_add_face( - group, - 0 /* regular */, - deferred_face_new(font_name.ptr, font_name.len, 0 /* text */), - ); - group_add_face( - group, - 0 /* regular */, - deferred_face_new(font_name.ptr, font_name.len, 1 /* emoji */), - ); - - // Initialize our sprite font, without this we just use the browser. - group_init_sprite_face(group); - - // Create our group cache - const group_cache = group_cache_new(group); - - // Render a glyph - // for (let i = 33; i <= 126; i++) { - // const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1); - // group_cache_render_glyph(group_cache, font_idx, i, 0); - // //face_render_glyph(face, atlas, i); - // } - // - // const emoji = ["🐏","🌞","🌚","🍱","πŸ’Ώ","🐈","πŸ“ƒ","πŸ“€","πŸ•‘","πŸ™ƒ"]; - // for (let i = 0; i < emoji.length; i++) { - // const cp = emoji[i].codePointAt(0); - // const font_idx = group_cache_index_for_codepoint(group_cache, cp, 0, -1 /* best choice */); - // group_cache_render_glyph(group_cache, font_idx, cp, 0); - // } - - for (let i = 0x2500; i <= 0x257f; i++) { - const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1); - group_cache_render_glyph(group_cache, font_idx, i, 0); - } - for (let i = 0x2580; i <= 0x259f; i++) { - const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1); - group_cache_render_glyph(group_cache, font_idx, i, 0); - } - for (let i = 0x2800; i <= 0x28ff; i++) { - const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1); - group_cache_render_glyph(group_cache, font_idx, i, 0); - } - for (let i = 0x1fb00; i <= 0x1fb3b; i++) { - const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1); - group_cache_render_glyph(group_cache, font_idx, i, 0); - } - for (let i = 0x1fb3c; i <= 0x1fb6b; i++) { - const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1); - group_cache_render_glyph(group_cache, font_idx, i, 0); - } - - //face_render_glyph(face, atlas, "ζ©‹".codePointAt(0)); - //face_render_glyph(face, atlas, "p".codePointAt(0)); - - // Debug our canvas - //face_debug_canvas(face); - - // Let's try shaping - const shaper = shaper_new(120); - //const input = makeStr("hello🐏"); - const input = makeStr("helloπŸπŸ‘πŸ½"); - shaper_test(shaper, group_cache, input.ptr, input.len); - - const cp = 1114112; - const font_idx = group_cache_index_for_codepoint( - group_cache, - cp, - 0, - -1 /* best choice */, - ); - group_cache_render_glyph(group_cache, font_idx, cp, -1); - - // Debug our atlas canvas - { - const atlas = group_cache_atlas_grayscale(group_cache); - const id = atlas_debug_canvas(atlas); - document.getElementById("atlas-canvas").append(zjs.deleteValue(id)); - } - - { - const atlas = group_cache_atlas_color(group_cache); - const id = atlas_debug_canvas(atlas); - document.getElementById("atlas-color-canvas").append(zjs.deleteValue(id)); - } - - //face_free(face); - }); diff --git a/example/index.html b/example/index.html deleted file mode 100644 index 2e66f92d1..000000000 --- a/example/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - Ghostty Example - - - -

Open your console, we are just debugging here.

-

The current grayscale font atlas is rendered below.

-
-

The current color font atlas is rendered below.

-
- - diff --git a/example/package-lock.json b/example/package-lock.json deleted file mode 100644 index 3cb4de6f0..000000000 --- a/example/package-lock.json +++ /dev/null @@ -1,4436 +0,0 @@ -{ - "name": "ghostty example", - "version": "0.1.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "ghostty example", - "version": "0.1.0", - "license": "MIT", - "dependencies": { - "zig-js": "file:../vendor/zig-js/js" - }, - "devDependencies": { - "@parcel/transformer-inline-string": "^2.8.0", - "parcel": "^2.8.0", - "typescript": "^4.9.3" - } - }, - "../js": { - "extraneous": true - }, - "../vendor/zig-js/js": { - "name": "zig-js-glue", - "version": "0.1.2", - "license": "MIT", - "devDependencies": { - "@parcel/packager-ts": "^2.8.0", - "@parcel/transformer-typescript-types": "^2.8.0", - "@types/jest": "^29.2.3", - "jest": "^29.3.1", - "parcel": "^2.8.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.3" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/@lezer/common": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.12.tgz", - "integrity": "sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig==", - "dev": true - }, - "node_modules/@lezer/lr": { - "version": "0.15.8", - "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.8.tgz", - "integrity": "sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg==", - "dev": true, - "dependencies": { - "@lezer/common": "^0.15.0" - } - }, - "node_modules/@lmdb/lmdb-darwin-arm64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.5.2.tgz", - "integrity": "sha512-+F8ioQIUN68B4UFiIBYu0QQvgb9FmlKw2ctQMSBfW2QBrZIxz9vD9jCGqTCPqZBRbPHAS/vG1zSXnKqnS2ch/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@lmdb/lmdb-darwin-x64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.5.2.tgz", - "integrity": "sha512-KvPH56KRLLx4KSfKBx0m1r7GGGUMXm0jrKmNE7plbHlesZMuPJICtn07HYgQhj1LNsK7Yqwuvnqh1QxhJnF1EA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@lmdb/lmdb-linux-arm": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.5.2.tgz", - "integrity": "sha512-5kQAP21hAkfW5Bl+e0P57dV4dGYnkNIpR7f/GAh6QHlgXx+vp/teVj4PGRZaKAvt0GX6++N6hF8NnGElLDuIDw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@lmdb/lmdb-linux-arm64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.5.2.tgz", - "integrity": "sha512-aLl89VHL/wjhievEOlPocoefUyWdvzVrcQ/MHQYZm2JfV1jUsrbr/ZfkPPUFvZBf+VSE+Q0clWs9l29PCX1hTQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@lmdb/lmdb-linux-x64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.2.tgz", - "integrity": "sha512-xUdUfwDJLGjOUPH3BuPBt0NlIrR7f/QHKgu3GZIXswMMIihAekj2i97oI0iWG5Bok/b+OBjHPfa8IU9velnP/Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@lmdb/lmdb-win32-x64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.2.tgz", - "integrity": "sha512-zrBczSbXKxEyK2ijtbRdICDygRqWSRPpZMN5dD1T8VMEW5RIhIbwFWw2phDRXuBQdVDpSjalCIUMWMV2h3JaZA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@mischnic/json-sourcemap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@mischnic/json-sourcemap/-/json-sourcemap-0.1.0.tgz", - "integrity": "sha512-dQb3QnfNqmQNYA4nFSN/uLaByIic58gOXq4Y4XqLOWmOrw73KmJPt/HLyG0wvn1bnR6mBKs/Uwvkh+Hns1T0XA==", - "dev": true, - "dependencies": { - "@lezer/common": "^0.15.7", - "@lezer/lr": "^0.15.4", - "json5": "^2.2.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-2.2.0.tgz", - "integrity": "sha512-Z9LFPzfoJi4mflGWV+rv7o7ZbMU5oAU9VmzCgL240KnqDW65Y2HFCT3MW06/ITJSnbVLacmcEJA8phywK7JinQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-2.2.0.tgz", - "integrity": "sha512-vq0tT8sjZsy4JdSqmadWVw6f66UXqUCabLmUVHZwUFzMgtgoIIQjT4VVRHKvlof3P/dMCkbMJ5hB1oJ9OWHaaw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-2.2.0.tgz", - "integrity": "sha512-SaJ3Qq4lX9Syd2xEo9u3qPxi/OB+5JO/ngJKK97XDpa1C587H9EWYO6KD8995DAjSinWvdHKRrCOXVUC5fvGOg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-2.2.0.tgz", - "integrity": "sha512-hlxxLdRmPyq16QCutUtP8Tm6RDWcyaLsRssaHROatgnkOxdleMTgetf9JsdncL8vLh7FVy/RN9i3XR5dnb9cRA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-2.2.0.tgz", - "integrity": "sha512-94y5PJrSOqUNcFKmOl7z319FelCLAE0rz/jPCWS+UtdMZvpa4jrQd+cJPQCLp2Fes1yAW/YUQj/Di6YVT3c3Iw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-2.2.0.tgz", - "integrity": "sha512-XrC0JzsqQSvOyM3t04FMLO6z5gCuhPE6k4FXuLK5xf52ZbdvcFe1yBmo7meCew9B8G2f0T9iu9t3kfTYRYROgA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@parcel/bundler-default": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/bundler-default/-/bundler-default-2.8.0.tgz", - "integrity": "sha512-OvDDhxX4LwfGe7lYVMbJMzqNcDk8ydOqNw0Hra9WPgl0m5gju/eVIbDvot3JXp5F96FmV36uCxdODJhKTNoAzQ==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/graph": "2.8.0", - "@parcel/hash": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/cache": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/cache/-/cache-2.8.0.tgz", - "integrity": "sha512-k945hrafMDR2wyCKyZYgwypeLLuZWce6FzhgunI4taBUeVnNCcpFAWzbfOVQ39SqZTGDqG3MNT+VuehssHXxyg==", - "dev": true, - "dependencies": { - "@parcel/fs": "2.8.0", - "@parcel/logger": "2.8.0", - "@parcel/utils": "2.8.0", - "lmdb": "2.5.2" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "peerDependencies": { - "@parcel/core": "^2.8.0" - } - }, - "node_modules/@parcel/codeframe": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/codeframe/-/codeframe-2.8.0.tgz", - "integrity": "sha512-821d+KVcpEvJNMj9WMC39xXZK6zvRS/HUjQag2f3DkcRcZwk1uXJZdW6p1EB7C3e4e/0KSK3NTSVGEvbOSR+9w==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/compressor-raw": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/compressor-raw/-/compressor-raw-2.8.0.tgz", - "integrity": "sha512-tM49t0gDQnwJbrDCeoCn9LRc8inZ/TSPQTttJTfcmFHHFqEllI0ZDVG0AiQw5NOMQbBLYiKun1adXn8pkcPLEA==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/config-default": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/config-default/-/config-default-2.8.0.tgz", - "integrity": "sha512-j9g50QNSLjuNpY0TP01EgGJPxWNes9d+e8+N07Z5Wv0u+UUnJ2uIOpo7PVn7ullOGhm1f9lP4KsJenu5gWb+cg==", - "dev": true, - "dependencies": { - "@parcel/bundler-default": "2.8.0", - "@parcel/compressor-raw": "2.8.0", - "@parcel/namer-default": "2.8.0", - "@parcel/optimizer-css": "2.8.0", - "@parcel/optimizer-htmlnano": "2.8.0", - "@parcel/optimizer-image": "2.8.0", - "@parcel/optimizer-svgo": "2.8.0", - "@parcel/optimizer-terser": "2.8.0", - "@parcel/packager-css": "2.8.0", - "@parcel/packager-html": "2.8.0", - "@parcel/packager-js": "2.8.0", - "@parcel/packager-raw": "2.8.0", - "@parcel/packager-svg": "2.8.0", - "@parcel/reporter-dev-server": "2.8.0", - "@parcel/resolver-default": "2.8.0", - "@parcel/runtime-browser-hmr": "2.8.0", - "@parcel/runtime-js": "2.8.0", - "@parcel/runtime-react-refresh": "2.8.0", - "@parcel/runtime-service-worker": "2.8.0", - "@parcel/transformer-babel": "2.8.0", - "@parcel/transformer-css": "2.8.0", - "@parcel/transformer-html": "2.8.0", - "@parcel/transformer-image": "2.8.0", - "@parcel/transformer-js": "2.8.0", - "@parcel/transformer-json": "2.8.0", - "@parcel/transformer-postcss": "2.8.0", - "@parcel/transformer-posthtml": "2.8.0", - "@parcel/transformer-raw": "2.8.0", - "@parcel/transformer-react-refresh-wrap": "2.8.0", - "@parcel/transformer-svg": "2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "peerDependencies": { - "@parcel/core": "^2.8.0" - } - }, - "node_modules/@parcel/core": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/core/-/core-2.8.0.tgz", - "integrity": "sha512-udzbe3jjbpfKlRE9pdlROAa+lvAjS1L/AzN6r2j1y/Fsn7ze/NfvnCFw6o2YNIrXg002aQ7M1St/x1fdGfmVKA==", - "dev": true, - "dependencies": { - "@mischnic/json-sourcemap": "^0.1.0", - "@parcel/cache": "2.8.0", - "@parcel/diagnostic": "2.8.0", - "@parcel/events": "2.8.0", - "@parcel/fs": "2.8.0", - "@parcel/graph": "2.8.0", - "@parcel/hash": "2.8.0", - "@parcel/logger": "2.8.0", - "@parcel/package-manager": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/types": "2.8.0", - "@parcel/utils": "2.8.0", - "@parcel/workers": "2.8.0", - "abortcontroller-polyfill": "^1.1.9", - "base-x": "^3.0.8", - "browserslist": "^4.6.6", - "clone": "^2.1.1", - "dotenv": "^7.0.0", - "dotenv-expand": "^5.1.0", - "json5": "^2.2.0", - "msgpackr": "^1.5.4", - "nullthrows": "^1.1.1", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/diagnostic": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/diagnostic/-/diagnostic-2.8.0.tgz", - "integrity": "sha512-ERnk0zDvm0jQUSj1M+2PLiwVC6nWrtuFEuye6VGuxRDcp9NHbz6gwApeEYxFkPsb3TQPhNjnXXm5nmAw1bpWWw==", - "dev": true, - "dependencies": { - "@mischnic/json-sourcemap": "^0.1.0", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/events": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/events/-/events-2.8.0.tgz", - "integrity": "sha512-xqSZYY3oONM4IZm9+vhyFqX+KFIl145veIczUikwGJlcJZQfAAw736syPx6ecpB+m1EVg3AlvJWy7Lmel4Ak+Q==", - "dev": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/fs": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/fs/-/fs-2.8.0.tgz", - "integrity": "sha512-v3DbJlpl8v2/VRlZPw7cy+0myi0YfLblGZcwDvqIsWS35qyxD2rmtYV8u1BusonbgmJeaKiopSECmJkumt0jCw==", - "dev": true, - "dependencies": { - "@parcel/fs-search": "2.8.0", - "@parcel/types": "2.8.0", - "@parcel/utils": "2.8.0", - "@parcel/watcher": "^2.0.7", - "@parcel/workers": "2.8.0" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "peerDependencies": { - "@parcel/core": "^2.8.0" - } - }, - "node_modules/@parcel/fs-search": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/fs-search/-/fs-search-2.8.0.tgz", - "integrity": "sha512-yo7/Y8DCFlhOlIBb5SsRDTkM+7g0DY9sK57iw3hn2z1tGoIiIRptrieImFYSizs7HfDwDY/PMLfORmUdoReDzQ==", - "dev": true, - "dependencies": { - "detect-libc": "^1.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/graph": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/graph/-/graph-2.8.0.tgz", - "integrity": "sha512-JvAyvBpGmhZ30bi+hStQr52eu+InfJBoiN9Z/32byIWhXEl02EAOwfsPqAe+FGCsdgXnnCGg5F9ZCqwzZ9dwbw==", - "dev": true, - "dependencies": { - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/hash": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/hash/-/hash-2.8.0.tgz", - "integrity": "sha512-KV1+96t7Nukth5K7ldUXjVr8ZTH9Dohl49K0Tc+5Qkysif0OxwcDtpVDmcnrUnWmqdBX0AdoLY0Q2Nnly89n/w==", - "dev": true, - "dependencies": { - "detect-libc": "^1.0.3", - "xxhash-wasm": "^0.4.2" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/logger": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-2.8.0.tgz", - "integrity": "sha512-W+7rKsLxLUX6xRmP8PhGWcG48PqrzTPeMWpgSds5nXxAHEFh4cYbkwPKGoTU65a9xUDVyqNreHNIKyizgwAZHQ==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/events": "2.8.0" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/markdown-ansi": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/markdown-ansi/-/markdown-ansi-2.8.0.tgz", - "integrity": "sha512-xItzXmc3btFhJXsIbE946iaqE6STd2xe5H0zSIaZVXEeucCtMzcd4hxRELquxPstlrAOrrp/lrRpbAlMhso9iA==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/namer-default": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/namer-default/-/namer-default-2.8.0.tgz", - "integrity": "sha512-cVCx2kJA/Bv7O9pVad1UOibaybR/B+QdWV8Ols8HH4lC2gyjLBXEIR0uuPSEbkGwMEcofG6zA3MwsoPa6r5lBg==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/node-resolver-core": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/node-resolver-core/-/node-resolver-core-2.8.0.tgz", - "integrity": "sha512-cECSh08NSRt1csmmMeKxlnO6ZhXRTuRijkHKFa4iG5hPL+3Cu04YGhuK/QWlP5vNCPVrH3ISlhzlPU5fAi/nEg==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/optimizer-css": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-css/-/optimizer-css-2.8.0.tgz", - "integrity": "sha512-T5r3gZVm1xFw6l//iLkzLDUvFzNTUvL5kAtyU5gS5yH/dg7eCS09Km/c2anViQnmXwFUt7zIlBovj1doxAVNSw==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.0", - "browserslist": "^4.6.6", - "lightningcss": "^1.16.1", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/optimizer-htmlnano": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-htmlnano/-/optimizer-htmlnano-2.8.0.tgz", - "integrity": "sha512-NxEKTRvue/WAU+XbQGfNIU6c7chDekdkwwv9YnCxHEOhnBu4Ok+2tdmCtPuA+4UUNszGxXlaHMnqSrjmqX2S6Q==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0", - "htmlnano": "^2.0.0", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "svgo": "^2.4.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/optimizer-image": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-image/-/optimizer-image-2.8.0.tgz", - "integrity": "sha512-66eSoCCGZVRiY6U4OqqYrhQcBcHI9cOkIEbxadZYOF4cJhsskjUDJR0jLb4j2PE6QxUNYlyj5OglQqRLwhz7vA==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "@parcel/workers": "2.8.0", - "detect-libc": "^1.0.3" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/optimizer-svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-svgo/-/optimizer-svgo-2.8.0.tgz", - "integrity": "sha512-qQzM32CzJJuniFaTZDspVn/Vtz/PJ/f89+FckLpWZJVWNihgwTHC1/F0YTDH8g6czNw5ZijwQ3xBVuJQYyIXsQ==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "svgo": "^2.4.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/optimizer-terser": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-terser/-/optimizer-terser-2.8.0.tgz", - "integrity": "sha512-slS6GWQ3u418WtJmlqlA5Njljcq4OaEdDDR2ifEwltG8POv+hsvD5AAoM2XB0GJwY97TQtdMbBu2DuDF3yM/1Q==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1", - "terser": "^5.2.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/package-manager": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/package-manager/-/package-manager-2.8.0.tgz", - "integrity": "sha512-n4FgerAX1lTKKTgxmiocnos47Y+b0L60iwU6Q4cC2n4KQNRuNyfhxFXwWcqHstR9wa72JgPaDgo4k0l3Bk8FZw==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/fs": "2.8.0", - "@parcel/logger": "2.8.0", - "@parcel/types": "2.8.0", - "@parcel/utils": "2.8.0", - "@parcel/workers": "2.8.0", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "peerDependencies": { - "@parcel/core": "^2.8.0" - } - }, - "node_modules/@parcel/packager-css": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/packager-css/-/packager-css-2.8.0.tgz", - "integrity": "sha512-tv/Bto0P6fXjqQ9uCZ8/6b/+38Zr/N2MC7/Nbflzww/lp0k2+kkE9MVJJDr5kST/SzTBRrhbDo+yTbtdZikJYg==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/packager-html": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/packager-html/-/packager-html-2.8.0.tgz", - "integrity": "sha512-4x09v/bt767rxwGTuEw82CjheoOtIKNu4sx1gqwQOz9QowKPniXOIaD+0XmLiARdzRErucf0sL19QHfNcPAhUw==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0", - "@parcel/types": "2.8.0", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/packager-js": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/packager-js/-/packager-js-2.8.0.tgz", - "integrity": "sha512-Tn2EtWM1TEdj4t5pt0QjBDzqrXrfRTL3WsdMipZwDSuX04KS0jedJINHjh46HOMwyfJxLbUg3xkGX7F5mYQj5g==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/hash": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.0", - "globals": "^13.2.0", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/packager-raw": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/packager-raw/-/packager-raw-2.8.0.tgz", - "integrity": "sha512-s3VniER3X2oNTlfytBGIQF+UZFVNLFWuVu1IkZ8Wg6uYQffrExDlbNDcmFCDcfvcejL3Ch5igP+L6N00f6+wAQ==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/packager-svg": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/packager-svg/-/packager-svg-2.8.0.tgz", - "integrity": "sha512-+BSpdPiNjlAne28nOjG2AyiOejAehe/+X9MxL2FIpPP7UBLNc2ekaM0mDTR5iY45YtZa57oyErBT/U6wZ1TCjw==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0", - "@parcel/types": "2.8.0", - "@parcel/utils": "2.8.0", - "posthtml": "^0.16.4" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/plugin": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.8.0.tgz", - "integrity": "sha512-Tsf+7nDg7KauvTVY6rGc7CmgJruKSwJ54KJ9s5nYFFP9nfwmyqbayCi9xOxicWU9zIHfuF5Etwf17lcA0oAvzw==", - "dev": true, - "dependencies": { - "@parcel/types": "2.8.0" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/reporter-cli": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/reporter-cli/-/reporter-cli-2.8.0.tgz", - "integrity": "sha512-ea4/Lp+2jDbzb/tfTgUKzYU51FK8wcewDoYNr06uL+wvx/vzYIDG0jHfzaOTasREnm7ECDr1Zu2Iknrgk1STqQ==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0", - "@parcel/types": "2.8.0", - "@parcel/utils": "2.8.0", - "chalk": "^4.1.0", - "term-size": "^2.2.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/reporter-dev-server": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/reporter-dev-server/-/reporter-dev-server-2.8.0.tgz", - "integrity": "sha512-wg6hUrQ8vUmvlP2fg8YEzYndmq7hWZ21ZgBv4So1Z65I+Qav85Uox7bjGLCSJwEAjdjFKfhV9RGULGzqh8vcAQ==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/resolver-default": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/resolver-default/-/resolver-default-2.8.0.tgz", - "integrity": "sha512-kO5W+O3Ql6NXNFS6lvfSSt1R+PxO1atNLYxZdVSM6+QQxRMiztfqzZs//RM+oUp+af6muDSUPlNs+RORX0fing==", - "dev": true, - "dependencies": { - "@parcel/node-resolver-core": "2.8.0", - "@parcel/plugin": "2.8.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/runtime-browser-hmr": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.8.0.tgz", - "integrity": "sha512-zV5wGGvm1cDwWAzkwPUaKh6inWYKxq67YWY4G396PXLMxddM9SQC1c7iFM60OPnD4A+BMOLOy7N6//20h15Dlg==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/runtime-js": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/runtime-js/-/runtime-js-2.8.0.tgz", - "integrity": "sha512-IwT1rX8ZamoYZv0clfswZemfXcIfk+YXwNsqXwzzh6TaMGagj/ZZl1llkn7ERQFq4EoLEoDGGkxqsrJjBp9NDQ==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/runtime-react-refresh": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/runtime-react-refresh/-/runtime-react-refresh-2.8.0.tgz", - "integrity": "sha512-a6uuZWkl+mJur2WLZKmpEqq1P06tvRwqGefYbE26DWpwXwU9dLpfnv/nT0hqCmVDHd2TkMyCffolSmq1vY05ew==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "react-error-overlay": "6.0.9", - "react-refresh": "^0.9.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/runtime-service-worker": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/runtime-service-worker/-/runtime-service-worker-2.8.0.tgz", - "integrity": "sha512-Q3Q2O/axQbFi/5Z+BidLB3qhmYdZLTMDagZtsmyH7CktDkZVNV/0UoOGYlqoK06T4cww3XjLSEomXbBu9TlQKQ==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/source-map": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@parcel/source-map/-/source-map-2.1.1.tgz", - "integrity": "sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==", - "dev": true, - "dependencies": { - "detect-libc": "^1.0.3" - }, - "engines": { - "node": "^12.18.3 || >=14" - } - }, - "node_modules/@parcel/transformer-babel": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-babel/-/transformer-babel-2.8.0.tgz", - "integrity": "sha512-ie+wFe9pucdnRyX2PTN9amOHrhr/IOwUEAfTz/3dPydOYCuX7ErEngCpI9fBzdYE2AV6/noEwC2Mjeoyz9mT2A==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.0", - "browserslist": "^4.6.6", - "json5": "^2.2.0", - "nullthrows": "^1.1.1", - "semver": "^5.7.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-css": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-css/-/transformer-css-2.8.0.tgz", - "integrity": "sha512-jCMQSfsxCoepblBAHCYMuNWNPQlqasoD6PfNftMdTlv12aUcnjNIYO9600TVLTL799CrEohljbXcfFn6hDGVWw==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.0", - "browserslist": "^4.6.6", - "lightningcss": "^1.16.1", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-html": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-html/-/transformer-html-2.8.0.tgz", - "integrity": "sha512-KLcZCWSIItZ1s12Sav3uvfTrwhX92craN9u7V3qUs8ld7ompTKsCdnf+gYmeCyISb5yiFDyYBvTGc1bOXvaDRQ==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/hash": "2.8.0", - "@parcel/plugin": "2.8.0", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "posthtml-parser": "^0.10.1", - "posthtml-render": "^3.0.0", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-image": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-image/-/transformer-image-2.8.0.tgz", - "integrity": "sha512-hJGsZxGlGEkiUvN8kCxA4DhB6/WrHzcIlZZYEgEien9pLctyc6np6idjdcyudPAhH3LwBPkiyeUfCvLAOA1zkA==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "@parcel/workers": "2.8.0", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "peerDependencies": { - "@parcel/core": "^2.8.0" - } - }, - "node_modules/@parcel/transformer-inline-string": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-inline-string/-/transformer-inline-string-2.8.0.tgz", - "integrity": "sha512-YBBgolTygr93hos4f5/xkM8VqP+Wc2exeXOyJfVCJJEaSVseXVdF8JtuZLlrcqOkw+ZC3nJtD4CEu+Glz9zCRg==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-js": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-js/-/transformer-js-2.8.0.tgz", - "integrity": "sha512-C5WTkDRiJGBB9tZa1mBsZwsqZjYEKkOa4mdVym3dMokwhFLUga8WtK7kGw4fmXIq41U8ip4orywj+Rd4mvGVWg==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.0", - "@parcel/workers": "2.8.0", - "@swc/helpers": "^0.4.12", - "browserslist": "^4.6.6", - "detect-libc": "^1.0.3", - "nullthrows": "^1.1.1", - "regenerator-runtime": "^0.13.7", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "peerDependencies": { - "@parcel/core": "^2.8.0" - } - }, - "node_modules/@parcel/transformer-json": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-json/-/transformer-json-2.8.0.tgz", - "integrity": "sha512-Pp5gROSMpzFDEI6KA2APuSpft6eXZxFgTPV6Xx9pElqseod3iL5+RnpMNV/nv76Ai2bcMEiafus5Pb09vjHgbQ==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0", - "json5": "^2.2.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-postcss": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-postcss/-/transformer-postcss-2.8.0.tgz", - "integrity": "sha512-45Ij+cgwXprd1sCLmaMIlCbPz3eEwolGHizgZmXl5l4yjlE2wGyzodhxLpBk1PWu7OxxWRbLnJIlvMYf7Vfw0g==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/hash": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "clone": "^2.1.1", - "nullthrows": "^1.1.1", - "postcss-value-parser": "^4.2.0", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-posthtml": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-posthtml/-/transformer-posthtml-2.8.0.tgz", - "integrity": "sha512-KrkKBFDW5PNZpr2Ha711eIABQOiJQKvfwfVs3CVpJK5wSADkappDk7CQ0mISPjhamFJ6xx/sNsi7e871I8R9lg==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "posthtml-parser": "^0.10.1", - "posthtml-render": "^3.0.0", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-raw": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-raw/-/transformer-raw-2.8.0.tgz", - "integrity": "sha512-uEbj+kE70vg2Gmdji/AIXPK13s5aQRw7X+xWs3vNpY2oymyMRHbfx1izJFWBh+kxu6Yo6q6qsekkh2rNHEHIUA==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-react-refresh-wrap": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.8.0.tgz", - "integrity": "sha512-d7G6wBdlwVXLkhC7EO/3UkUOfEOJvsIsQUCEujsrdFF+nfBElXw/TZ+KP8UkmrwMdD0spU/8cKoTyi5k19vt6w==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "react-refresh": "^0.9.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-svg": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-svg/-/transformer-svg-2.8.0.tgz", - "integrity": "sha512-8S6yZoUTCbHOnuWY3M50fscTpI8414945I44fmed+C1e36TnWem8FifuVtGkRZeR8pokF453lmmwWG1eH/4U3w==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/hash": "2.8.0", - "@parcel/plugin": "2.8.0", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "posthtml-parser": "^0.10.1", - "posthtml-render": "^3.0.0", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/types": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/types/-/types-2.8.0.tgz", - "integrity": "sha512-DeN3vCnVl9onjtyWxpbP7LwRslVEko4kBaM7yILsuQjEnXmaIOsqIf6FQJOUOPBtQTFFNeQQ2qyf5XoO/rkJ8g==", - "dev": true, - "dependencies": { - "@parcel/cache": "2.8.0", - "@parcel/diagnostic": "2.8.0", - "@parcel/fs": "2.8.0", - "@parcel/package-manager": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/workers": "2.8.0", - "utility-types": "^3.10.0" - } - }, - "node_modules/@parcel/utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/utils/-/utils-2.8.0.tgz", - "integrity": "sha512-r4ACsGtW7zkMUIgwQyOVtPAFiy8L81gbz4tMIRSqyQKnkW7oEHcQ3uN1/LPxj2yfkyQLmhJxmtptLUy9j53rcw==", - "dev": true, - "dependencies": { - "@parcel/codeframe": "2.8.0", - "@parcel/diagnostic": "2.8.0", - "@parcel/hash": "2.8.0", - "@parcel/logger": "2.8.0", - "@parcel/markdown-ansi": "2.8.0", - "@parcel/source-map": "^2.1.1", - "chalk": "^4.1.0" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.7.tgz", - "integrity": "sha512-gc3hoS6e+2XdIQ4HHljDB1l0Yx2EWh/sBBtCEFNKGSMlwASWeAQsOY/fPbxOBcZ/pg0jBh4Ga+4xHlZc4faAEQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^3.2.1", - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/workers": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/workers/-/workers-2.8.0.tgz", - "integrity": "sha512-vAzoC/wPHLQnyy9P/TrSPftY8F3MhZqPTFi681mxVtLWA3t7wiNlw1zDVKRDP8m5XS1yQOr8Q56CAHyRexhc8g==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.0", - "@parcel/logger": "2.8.0", - "@parcel/types": "2.8.0", - "@parcel/utils": "2.8.0", - "chrome-trace-event": "^1.0.2", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "peerDependencies": { - "@parcel/core": "^2.8.0" - } - }, - "node_modules/@swc/helpers": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", - "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==", - "dev": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, - "node_modules/abortcontroller-polyfill": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz", - "integrity": "sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001436", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001436.tgz", - "integrity": "sha512-ZmWkKsnC2ifEPoWUvSAIGyOYwT+keAaaWPHiQ9DfMqS1t6tfuyFYoWR78TeZtznkEQ64+vGXH9cZrElwR2Mrxg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dev": true, - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dev": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dev": true, - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dotenv": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-7.0.0.tgz", - "integrity": "sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", - "dev": true - }, - "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true - }, - "node_modules/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "dev": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/get-port": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz", - "integrity": "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/globals": { - "version": "13.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", - "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/htmlnano": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-2.0.3.tgz", - "integrity": "sha512-S4PGGj9RbdgW8LhbILNK7W9JhmYP8zmDY7KDV/8eCiJBQJlbmltp5I0gv8c5ntLljfdxxfmJ+UJVSqyH4mb41A==", - "dev": true, - "dependencies": { - "cosmiconfig": "^7.0.1", - "posthtml": "^0.16.5", - "timsort": "^0.3.0" - }, - "peerDependencies": { - "cssnano": "^5.0.11", - "postcss": "^8.3.11", - "purgecss": "^5.0.0", - "relateurl": "^0.2.7", - "srcset": "4.0.0", - "svgo": "^2.8.0", - "terser": "^5.10.0", - "uncss": "^0.17.3" - }, - "peerDependenciesMeta": { - "cssnano": { - "optional": true - }, - "postcss": { - "optional": true - }, - "purgecss": { - "optional": true - }, - "relateurl": { - "optional": true - }, - "srcset": { - "optional": true - }, - "svgo": { - "optional": true - }, - "terser": { - "optional": true - }, - "uncss": { - "optional": true - } - } - }, - "node_modules/htmlparser2": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", - "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.2", - "domutils": "^2.8.0", - "entities": "^3.0.1" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-json": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz", - "integrity": "sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==", - "dev": true - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/lightningcss": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.17.1.tgz", - "integrity": "sha512-DwwM/YYqGwLLP3he41wzDXT/m+8jdEZ80i9ViQNLRgyhey3Vm6N7XHn+4o3PY6wSnVT23WLuaROIpbpIVTNOjg==", - "dev": true, - "dependencies": { - "detect-libc": "^1.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-darwin-arm64": "1.17.1", - "lightningcss-darwin-x64": "1.17.1", - "lightningcss-linux-arm-gnueabihf": "1.17.1", - "lightningcss-linux-arm64-gnu": "1.17.1", - "lightningcss-linux-arm64-musl": "1.17.1", - "lightningcss-linux-x64-gnu": "1.17.1", - "lightningcss-linux-x64-musl": "1.17.1", - "lightningcss-win32-x64-msvc": "1.17.1" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.17.1.tgz", - "integrity": "sha512-YTAHEy4XlzI3sMbUVjbPi9P7+N7lGcgl2JhCZhiQdRAEKnZLQch8kb5601sgESxdGXjgei7JZFqi/vVEk81wYg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.17.1.tgz", - "integrity": "sha512-UhXPUS2+yTTf5sXwUV0+8QY2x0bPGLgC/uhcknWSQMqWn1zGty4fFvH04D7f7ij0ujwSuN+Q0HtU7lgmMrPz0A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.17.1.tgz", - "integrity": "sha512-alUZumuznB6K/9yZ0zuZkODXUm8uRnvs9t0CL46CXN16Y2h4gOx5ahUCMlelUb7inZEsgJIoepgLsJzBUrSsBw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.17.1.tgz", - "integrity": "sha512-/1XaH2cOjDt+ivmgfmVFUYCA0MtfNWwtC4P8qVi53zEQ7P8euyyZ1ynykZOyKXW9Q0DzrwcLTh6+hxVLcbtGBg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.17.1.tgz", - "integrity": "sha512-/IgE7lYWFHCCQFTMIwtt+fXLcVOha8rcrNze1JYGPWNorO6NBc6MJo5u5cwn5qMMSz9fZCCDIlBBU4mGwjQszQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.17.1.tgz", - "integrity": "sha512-OyE802IAp4DB9vZrHlOyWunbHLM9dN08tJIKN/HhzzLKIHizubOWX6NMzUXMZLsaUrYwVAHHdyEA+712p8mMzA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.17.1.tgz", - "integrity": "sha512-ydwGgV3Usba5P53RAOqCA9MsRsbb8jFIEVhf7/BXFjpKNoIQyijVTXhwIgQr/oGwUNOHfgQ3F8ruiUjX/p2YKw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.17.1.tgz", - "integrity": "sha512-Ngqtx9NazaiAOk71XWwSsqgAuwYF+8PO6UYsoU7hAukdrSS98kwaBMEDw1igeIiZy1XD/4kh5KVnkjNf7ZOxVQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/lmdb": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.5.2.tgz", - "integrity": "sha512-V5V5Xa2Hp9i2XsbDALkBTeHXnBXh/lEmk9p22zdr7jtuOIY9TGhjK6vAvTpOOx9IKU4hJkRWZxn/HsvR1ELLtA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "msgpackr": "^1.5.4", - "node-addon-api": "^4.3.0", - "node-gyp-build-optional-packages": "5.0.3", - "ordered-binary": "^1.2.4", - "weak-lru-cache": "^1.2.2" - }, - "optionalDependencies": { - "@lmdb/lmdb-darwin-arm64": "2.5.2", - "@lmdb/lmdb-darwin-x64": "2.5.2", - "@lmdb/lmdb-linux-arm": "2.5.2", - "@lmdb/lmdb-linux-arm64": "2.5.2", - "@lmdb/lmdb-linux-x64": "2.5.2", - "@lmdb/lmdb-win32-x64": "2.5.2" - } - }, - "node_modules/lmdb/node_modules/node-addon-api": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", - "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", - "dev": true - }, - "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, - "node_modules/msgpackr": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.8.1.tgz", - "integrity": "sha512-05fT4J8ZqjYlR4QcRDIhLCYKUOHXk7C/xa62GzMKj74l3up9k2QZ3LgFc6qWdsPHl91QA2WLWqWc8b8t7GLNNw==", - "dev": true, - "optionalDependencies": { - "msgpackr-extract": "^2.2.0" - } - }, - "node_modules/msgpackr-extract": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-2.2.0.tgz", - "integrity": "sha512-0YcvWSv7ZOGl9Od6Y5iJ3XnPww8O7WLcpYMDwX+PAA/uXLDtyw94PJv9GLQV/nnp3cWlDhMoyKZIQLrx33sWog==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build-optional-packages": "5.0.3" - }, - "bin": { - "download-msgpackr-prebuilds": "bin/download-prebuilds.js" - }, - "optionalDependencies": { - "@msgpackr-extract/msgpackr-extract-darwin-arm64": "2.2.0", - "@msgpackr-extract/msgpackr-extract-darwin-x64": "2.2.0", - "@msgpackr-extract/msgpackr-extract-linux-arm": "2.2.0", - "@msgpackr-extract/msgpackr-extract-linux-arm64": "2.2.0", - "@msgpackr-extract/msgpackr-extract-linux-x64": "2.2.0", - "@msgpackr-extract/msgpackr-extract-win32-x64": "2.2.0" - } - }, - "node_modules/node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true - }, - "node_modules/node-gyp-build": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz", - "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==", - "dev": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/node-gyp-build-optional-packages": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz", - "integrity": "sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA==", - "dev": true, - "bin": { - "node-gyp-build-optional-packages": "bin.js", - "node-gyp-build-optional-packages-optional": "optional.js", - "node-gyp-build-optional-packages-test": "build-test.js" - } - }, - "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/nullthrows": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", - "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", - "dev": true - }, - "node_modules/ordered-binary": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.4.0.tgz", - "integrity": "sha512-EHQ/jk4/a9hLupIKxTfUsQRej1Yd/0QLQs3vGvIqg5ZtCYSzNhkzHoZc7Zf4e4kUlDaC3Uw8Q/1opOLNN2OKRQ==", - "dev": true - }, - "node_modules/parcel": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/parcel/-/parcel-2.8.0.tgz", - "integrity": "sha512-p7Fo75CeMw5HC1luovYpBjzPbAJv/Gn7lxcs4f0LxcwBCWbkQ73zHgJXJQqnM38qQABEYEiQq6000+j+k5U/Mw==", - "dev": true, - "dependencies": { - "@parcel/config-default": "2.8.0", - "@parcel/core": "2.8.0", - "@parcel/diagnostic": "2.8.0", - "@parcel/events": "2.8.0", - "@parcel/fs": "2.8.0", - "@parcel/logger": "2.8.0", - "@parcel/package-manager": "2.8.0", - "@parcel/reporter-cli": "2.8.0", - "@parcel/reporter-dev-server": "2.8.0", - "@parcel/utils": "2.8.0", - "chalk": "^4.1.0", - "commander": "^7.0.0", - "get-port": "^4.2.0", - "v8-compile-cache": "^2.0.0" - }, - "bin": { - "parcel": "lib/bin.js" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true - }, - "node_modules/posthtml": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.16.6.tgz", - "integrity": "sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ==", - "dev": true, - "dependencies": { - "posthtml-parser": "^0.11.0", - "posthtml-render": "^3.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/posthtml-parser": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.10.2.tgz", - "integrity": "sha512-PId6zZ/2lyJi9LiKfe+i2xv57oEjJgWbsHGGANwos5AvdQp98i6AtamAl8gzSVFGfQ43Glb5D614cvZf012VKg==", - "dev": true, - "dependencies": { - "htmlparser2": "^7.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/posthtml-render": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-3.0.0.tgz", - "integrity": "sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==", - "dev": true, - "dependencies": { - "is-json": "^2.0.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/posthtml/node_modules/posthtml-parser": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.11.0.tgz", - "integrity": "sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==", - "dev": true, - "dependencies": { - "htmlparser2": "^7.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/react-error-overlay": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", - "integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==", - "dev": true - }, - "node_modules/react-refresh": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.9.0.tgz", - "integrity": "sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", - "dev": true - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dev": true, - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/term-size": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser": { - "version": "5.16.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz", - "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", - "dev": true - }, - "node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", - "dev": true - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", - "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist-lint": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/utility-types": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", - "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/weak-lru-cache": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", - "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", - "dev": true - }, - "node_modules/xxhash-wasm": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz", - "integrity": "sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA==", - "dev": true - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/zig-js": { - "resolved": "../vendor/zig-js/js", - "link": true - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true - }, - "@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "@lezer/common": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.12.tgz", - "integrity": "sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig==", - "dev": true - }, - "@lezer/lr": { - "version": "0.15.8", - "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.8.tgz", - "integrity": "sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg==", - "dev": true, - "requires": { - "@lezer/common": "^0.15.0" - } - }, - "@lmdb/lmdb-darwin-arm64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.5.2.tgz", - "integrity": "sha512-+F8ioQIUN68B4UFiIBYu0QQvgb9FmlKw2ctQMSBfW2QBrZIxz9vD9jCGqTCPqZBRbPHAS/vG1zSXnKqnS2ch/A==", - "dev": true, - "optional": true - }, - "@lmdb/lmdb-darwin-x64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.5.2.tgz", - "integrity": "sha512-KvPH56KRLLx4KSfKBx0m1r7GGGUMXm0jrKmNE7plbHlesZMuPJICtn07HYgQhj1LNsK7Yqwuvnqh1QxhJnF1EA==", - "dev": true, - "optional": true - }, - "@lmdb/lmdb-linux-arm": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.5.2.tgz", - "integrity": "sha512-5kQAP21hAkfW5Bl+e0P57dV4dGYnkNIpR7f/GAh6QHlgXx+vp/teVj4PGRZaKAvt0GX6++N6hF8NnGElLDuIDw==", - "dev": true, - "optional": true - }, - "@lmdb/lmdb-linux-arm64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.5.2.tgz", - "integrity": "sha512-aLl89VHL/wjhievEOlPocoefUyWdvzVrcQ/MHQYZm2JfV1jUsrbr/ZfkPPUFvZBf+VSE+Q0clWs9l29PCX1hTQ==", - "dev": true, - "optional": true - }, - "@lmdb/lmdb-linux-x64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.2.tgz", - "integrity": "sha512-xUdUfwDJLGjOUPH3BuPBt0NlIrR7f/QHKgu3GZIXswMMIihAekj2i97oI0iWG5Bok/b+OBjHPfa8IU9velnP/Q==", - "dev": true, - "optional": true - }, - "@lmdb/lmdb-win32-x64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.2.tgz", - "integrity": "sha512-zrBczSbXKxEyK2ijtbRdICDygRqWSRPpZMN5dD1T8VMEW5RIhIbwFWw2phDRXuBQdVDpSjalCIUMWMV2h3JaZA==", - "dev": true, - "optional": true - }, - "@mischnic/json-sourcemap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@mischnic/json-sourcemap/-/json-sourcemap-0.1.0.tgz", - "integrity": "sha512-dQb3QnfNqmQNYA4nFSN/uLaByIic58gOXq4Y4XqLOWmOrw73KmJPt/HLyG0wvn1bnR6mBKs/Uwvkh+Hns1T0XA==", - "dev": true, - "requires": { - "@lezer/common": "^0.15.7", - "@lezer/lr": "^0.15.4", - "json5": "^2.2.1" - } - }, - "@msgpackr-extract/msgpackr-extract-darwin-arm64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-2.2.0.tgz", - "integrity": "sha512-Z9LFPzfoJi4mflGWV+rv7o7ZbMU5oAU9VmzCgL240KnqDW65Y2HFCT3MW06/ITJSnbVLacmcEJA8phywK7JinQ==", - "dev": true, - "optional": true - }, - "@msgpackr-extract/msgpackr-extract-darwin-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-2.2.0.tgz", - "integrity": "sha512-vq0tT8sjZsy4JdSqmadWVw6f66UXqUCabLmUVHZwUFzMgtgoIIQjT4VVRHKvlof3P/dMCkbMJ5hB1oJ9OWHaaw==", - "dev": true, - "optional": true - }, - "@msgpackr-extract/msgpackr-extract-linux-arm": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-2.2.0.tgz", - "integrity": "sha512-SaJ3Qq4lX9Syd2xEo9u3qPxi/OB+5JO/ngJKK97XDpa1C587H9EWYO6KD8995DAjSinWvdHKRrCOXVUC5fvGOg==", - "dev": true, - "optional": true - }, - "@msgpackr-extract/msgpackr-extract-linux-arm64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-2.2.0.tgz", - "integrity": "sha512-hlxxLdRmPyq16QCutUtP8Tm6RDWcyaLsRssaHROatgnkOxdleMTgetf9JsdncL8vLh7FVy/RN9i3XR5dnb9cRA==", - "dev": true, - "optional": true - }, - "@msgpackr-extract/msgpackr-extract-linux-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-2.2.0.tgz", - "integrity": "sha512-94y5PJrSOqUNcFKmOl7z319FelCLAE0rz/jPCWS+UtdMZvpa4jrQd+cJPQCLp2Fes1yAW/YUQj/Di6YVT3c3Iw==", - "dev": true, - "optional": true - }, - "@msgpackr-extract/msgpackr-extract-win32-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-2.2.0.tgz", - "integrity": "sha512-XrC0JzsqQSvOyM3t04FMLO6z5gCuhPE6k4FXuLK5xf52ZbdvcFe1yBmo7meCew9B8G2f0T9iu9t3kfTYRYROgA==", - "dev": true, - "optional": true - }, - "@parcel/bundler-default": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/bundler-default/-/bundler-default-2.8.0.tgz", - "integrity": "sha512-OvDDhxX4LwfGe7lYVMbJMzqNcDk8ydOqNw0Hra9WPgl0m5gju/eVIbDvot3JXp5F96FmV36uCxdODJhKTNoAzQ==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/graph": "2.8.0", - "@parcel/hash": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1" - } - }, - "@parcel/cache": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/cache/-/cache-2.8.0.tgz", - "integrity": "sha512-k945hrafMDR2wyCKyZYgwypeLLuZWce6FzhgunI4taBUeVnNCcpFAWzbfOVQ39SqZTGDqG3MNT+VuehssHXxyg==", - "dev": true, - "requires": { - "@parcel/fs": "2.8.0", - "@parcel/logger": "2.8.0", - "@parcel/utils": "2.8.0", - "lmdb": "2.5.2" - } - }, - "@parcel/codeframe": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/codeframe/-/codeframe-2.8.0.tgz", - "integrity": "sha512-821d+KVcpEvJNMj9WMC39xXZK6zvRS/HUjQag2f3DkcRcZwk1uXJZdW6p1EB7C3e4e/0KSK3NTSVGEvbOSR+9w==", - "dev": true, - "requires": { - "chalk": "^4.1.0" - } - }, - "@parcel/compressor-raw": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/compressor-raw/-/compressor-raw-2.8.0.tgz", - "integrity": "sha512-tM49t0gDQnwJbrDCeoCn9LRc8inZ/TSPQTttJTfcmFHHFqEllI0ZDVG0AiQw5NOMQbBLYiKun1adXn8pkcPLEA==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0" - } - }, - "@parcel/config-default": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/config-default/-/config-default-2.8.0.tgz", - "integrity": "sha512-j9g50QNSLjuNpY0TP01EgGJPxWNes9d+e8+N07Z5Wv0u+UUnJ2uIOpo7PVn7ullOGhm1f9lP4KsJenu5gWb+cg==", - "dev": true, - "requires": { - "@parcel/bundler-default": "2.8.0", - "@parcel/compressor-raw": "2.8.0", - "@parcel/namer-default": "2.8.0", - "@parcel/optimizer-css": "2.8.0", - "@parcel/optimizer-htmlnano": "2.8.0", - "@parcel/optimizer-image": "2.8.0", - "@parcel/optimizer-svgo": "2.8.0", - "@parcel/optimizer-terser": "2.8.0", - "@parcel/packager-css": "2.8.0", - "@parcel/packager-html": "2.8.0", - "@parcel/packager-js": "2.8.0", - "@parcel/packager-raw": "2.8.0", - "@parcel/packager-svg": "2.8.0", - "@parcel/reporter-dev-server": "2.8.0", - "@parcel/resolver-default": "2.8.0", - "@parcel/runtime-browser-hmr": "2.8.0", - "@parcel/runtime-js": "2.8.0", - "@parcel/runtime-react-refresh": "2.8.0", - "@parcel/runtime-service-worker": "2.8.0", - "@parcel/transformer-babel": "2.8.0", - "@parcel/transformer-css": "2.8.0", - "@parcel/transformer-html": "2.8.0", - "@parcel/transformer-image": "2.8.0", - "@parcel/transformer-js": "2.8.0", - "@parcel/transformer-json": "2.8.0", - "@parcel/transformer-postcss": "2.8.0", - "@parcel/transformer-posthtml": "2.8.0", - "@parcel/transformer-raw": "2.8.0", - "@parcel/transformer-react-refresh-wrap": "2.8.0", - "@parcel/transformer-svg": "2.8.0" - } - }, - "@parcel/core": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/core/-/core-2.8.0.tgz", - "integrity": "sha512-udzbe3jjbpfKlRE9pdlROAa+lvAjS1L/AzN6r2j1y/Fsn7ze/NfvnCFw6o2YNIrXg002aQ7M1St/x1fdGfmVKA==", - "dev": true, - "requires": { - "@mischnic/json-sourcemap": "^0.1.0", - "@parcel/cache": "2.8.0", - "@parcel/diagnostic": "2.8.0", - "@parcel/events": "2.8.0", - "@parcel/fs": "2.8.0", - "@parcel/graph": "2.8.0", - "@parcel/hash": "2.8.0", - "@parcel/logger": "2.8.0", - "@parcel/package-manager": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/types": "2.8.0", - "@parcel/utils": "2.8.0", - "@parcel/workers": "2.8.0", - "abortcontroller-polyfill": "^1.1.9", - "base-x": "^3.0.8", - "browserslist": "^4.6.6", - "clone": "^2.1.1", - "dotenv": "^7.0.0", - "dotenv-expand": "^5.1.0", - "json5": "^2.2.0", - "msgpackr": "^1.5.4", - "nullthrows": "^1.1.1", - "semver": "^5.7.1" - } - }, - "@parcel/diagnostic": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/diagnostic/-/diagnostic-2.8.0.tgz", - "integrity": "sha512-ERnk0zDvm0jQUSj1M+2PLiwVC6nWrtuFEuye6VGuxRDcp9NHbz6gwApeEYxFkPsb3TQPhNjnXXm5nmAw1bpWWw==", - "dev": true, - "requires": { - "@mischnic/json-sourcemap": "^0.1.0", - "nullthrows": "^1.1.1" - } - }, - "@parcel/events": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/events/-/events-2.8.0.tgz", - "integrity": "sha512-xqSZYY3oONM4IZm9+vhyFqX+KFIl145veIczUikwGJlcJZQfAAw736syPx6ecpB+m1EVg3AlvJWy7Lmel4Ak+Q==", - "dev": true - }, - "@parcel/fs": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/fs/-/fs-2.8.0.tgz", - "integrity": "sha512-v3DbJlpl8v2/VRlZPw7cy+0myi0YfLblGZcwDvqIsWS35qyxD2rmtYV8u1BusonbgmJeaKiopSECmJkumt0jCw==", - "dev": true, - "requires": { - "@parcel/fs-search": "2.8.0", - "@parcel/types": "2.8.0", - "@parcel/utils": "2.8.0", - "@parcel/watcher": "^2.0.7", - "@parcel/workers": "2.8.0" - } - }, - "@parcel/fs-search": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/fs-search/-/fs-search-2.8.0.tgz", - "integrity": "sha512-yo7/Y8DCFlhOlIBb5SsRDTkM+7g0DY9sK57iw3hn2z1tGoIiIRptrieImFYSizs7HfDwDY/PMLfORmUdoReDzQ==", - "dev": true, - "requires": { - "detect-libc": "^1.0.3" - } - }, - "@parcel/graph": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/graph/-/graph-2.8.0.tgz", - "integrity": "sha512-JvAyvBpGmhZ30bi+hStQr52eu+InfJBoiN9Z/32byIWhXEl02EAOwfsPqAe+FGCsdgXnnCGg5F9ZCqwzZ9dwbw==", - "dev": true, - "requires": { - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1" - } - }, - "@parcel/hash": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/hash/-/hash-2.8.0.tgz", - "integrity": "sha512-KV1+96t7Nukth5K7ldUXjVr8ZTH9Dohl49K0Tc+5Qkysif0OxwcDtpVDmcnrUnWmqdBX0AdoLY0Q2Nnly89n/w==", - "dev": true, - "requires": { - "detect-libc": "^1.0.3", - "xxhash-wasm": "^0.4.2" - } - }, - "@parcel/logger": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-2.8.0.tgz", - "integrity": "sha512-W+7rKsLxLUX6xRmP8PhGWcG48PqrzTPeMWpgSds5nXxAHEFh4cYbkwPKGoTU65a9xUDVyqNreHNIKyizgwAZHQ==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/events": "2.8.0" - } - }, - "@parcel/markdown-ansi": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/markdown-ansi/-/markdown-ansi-2.8.0.tgz", - "integrity": "sha512-xItzXmc3btFhJXsIbE946iaqE6STd2xe5H0zSIaZVXEeucCtMzcd4hxRELquxPstlrAOrrp/lrRpbAlMhso9iA==", - "dev": true, - "requires": { - "chalk": "^4.1.0" - } - }, - "@parcel/namer-default": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/namer-default/-/namer-default-2.8.0.tgz", - "integrity": "sha512-cVCx2kJA/Bv7O9pVad1UOibaybR/B+QdWV8Ols8HH4lC2gyjLBXEIR0uuPSEbkGwMEcofG6zA3MwsoPa6r5lBg==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "nullthrows": "^1.1.1" - } - }, - "@parcel/node-resolver-core": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/node-resolver-core/-/node-resolver-core-2.8.0.tgz", - "integrity": "sha512-cECSh08NSRt1csmmMeKxlnO6ZhXRTuRijkHKFa4iG5hPL+3Cu04YGhuK/QWlP5vNCPVrH3ISlhzlPU5fAi/nEg==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1", - "semver": "^5.7.1" - } - }, - "@parcel/optimizer-css": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-css/-/optimizer-css-2.8.0.tgz", - "integrity": "sha512-T5r3gZVm1xFw6l//iLkzLDUvFzNTUvL5kAtyU5gS5yH/dg7eCS09Km/c2anViQnmXwFUt7zIlBovj1doxAVNSw==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.0", - "browserslist": "^4.6.6", - "lightningcss": "^1.16.1", - "nullthrows": "^1.1.1" - } - }, - "@parcel/optimizer-htmlnano": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-htmlnano/-/optimizer-htmlnano-2.8.0.tgz", - "integrity": "sha512-NxEKTRvue/WAU+XbQGfNIU6c7chDekdkwwv9YnCxHEOhnBu4Ok+2tdmCtPuA+4UUNszGxXlaHMnqSrjmqX2S6Q==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0", - "htmlnano": "^2.0.0", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "svgo": "^2.4.0" - } - }, - "@parcel/optimizer-image": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-image/-/optimizer-image-2.8.0.tgz", - "integrity": "sha512-66eSoCCGZVRiY6U4OqqYrhQcBcHI9cOkIEbxadZYOF4cJhsskjUDJR0jLb4j2PE6QxUNYlyj5OglQqRLwhz7vA==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "@parcel/workers": "2.8.0", - "detect-libc": "^1.0.3" - } - }, - "@parcel/optimizer-svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-svgo/-/optimizer-svgo-2.8.0.tgz", - "integrity": "sha512-qQzM32CzJJuniFaTZDspVn/Vtz/PJ/f89+FckLpWZJVWNihgwTHC1/F0YTDH8g6czNw5ZijwQ3xBVuJQYyIXsQ==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "svgo": "^2.4.0" - } - }, - "@parcel/optimizer-terser": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-terser/-/optimizer-terser-2.8.0.tgz", - "integrity": "sha512-slS6GWQ3u418WtJmlqlA5Njljcq4OaEdDDR2ifEwltG8POv+hsvD5AAoM2XB0GJwY97TQtdMbBu2DuDF3yM/1Q==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1", - "terser": "^5.2.0" - } - }, - "@parcel/package-manager": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/package-manager/-/package-manager-2.8.0.tgz", - "integrity": "sha512-n4FgerAX1lTKKTgxmiocnos47Y+b0L60iwU6Q4cC2n4KQNRuNyfhxFXwWcqHstR9wa72JgPaDgo4k0l3Bk8FZw==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/fs": "2.8.0", - "@parcel/logger": "2.8.0", - "@parcel/types": "2.8.0", - "@parcel/utils": "2.8.0", - "@parcel/workers": "2.8.0", - "semver": "^5.7.1" - } - }, - "@parcel/packager-css": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/packager-css/-/packager-css-2.8.0.tgz", - "integrity": "sha512-tv/Bto0P6fXjqQ9uCZ8/6b/+38Zr/N2MC7/Nbflzww/lp0k2+kkE9MVJJDr5kST/SzTBRrhbDo+yTbtdZikJYg==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1" - } - }, - "@parcel/packager-html": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/packager-html/-/packager-html-2.8.0.tgz", - "integrity": "sha512-4x09v/bt767rxwGTuEw82CjheoOtIKNu4sx1gqwQOz9QowKPniXOIaD+0XmLiARdzRErucf0sL19QHfNcPAhUw==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0", - "@parcel/types": "2.8.0", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5" - } - }, - "@parcel/packager-js": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/packager-js/-/packager-js-2.8.0.tgz", - "integrity": "sha512-Tn2EtWM1TEdj4t5pt0QjBDzqrXrfRTL3WsdMipZwDSuX04KS0jedJINHjh46HOMwyfJxLbUg3xkGX7F5mYQj5g==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/hash": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.0", - "globals": "^13.2.0", - "nullthrows": "^1.1.1" - } - }, - "@parcel/packager-raw": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/packager-raw/-/packager-raw-2.8.0.tgz", - "integrity": "sha512-s3VniER3X2oNTlfytBGIQF+UZFVNLFWuVu1IkZ8Wg6uYQffrExDlbNDcmFCDcfvcejL3Ch5igP+L6N00f6+wAQ==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0" - } - }, - "@parcel/packager-svg": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/packager-svg/-/packager-svg-2.8.0.tgz", - "integrity": "sha512-+BSpdPiNjlAne28nOjG2AyiOejAehe/+X9MxL2FIpPP7UBLNc2ekaM0mDTR5iY45YtZa57oyErBT/U6wZ1TCjw==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0", - "@parcel/types": "2.8.0", - "@parcel/utils": "2.8.0", - "posthtml": "^0.16.4" - } - }, - "@parcel/plugin": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.8.0.tgz", - "integrity": "sha512-Tsf+7nDg7KauvTVY6rGc7CmgJruKSwJ54KJ9s5nYFFP9nfwmyqbayCi9xOxicWU9zIHfuF5Etwf17lcA0oAvzw==", - "dev": true, - "requires": { - "@parcel/types": "2.8.0" - } - }, - "@parcel/reporter-cli": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/reporter-cli/-/reporter-cli-2.8.0.tgz", - "integrity": "sha512-ea4/Lp+2jDbzb/tfTgUKzYU51FK8wcewDoYNr06uL+wvx/vzYIDG0jHfzaOTasREnm7ECDr1Zu2Iknrgk1STqQ==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0", - "@parcel/types": "2.8.0", - "@parcel/utils": "2.8.0", - "chalk": "^4.1.0", - "term-size": "^2.2.1" - } - }, - "@parcel/reporter-dev-server": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/reporter-dev-server/-/reporter-dev-server-2.8.0.tgz", - "integrity": "sha512-wg6hUrQ8vUmvlP2fg8YEzYndmq7hWZ21ZgBv4So1Z65I+Qav85Uox7bjGLCSJwEAjdjFKfhV9RGULGzqh8vcAQ==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0" - } - }, - "@parcel/resolver-default": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/resolver-default/-/resolver-default-2.8.0.tgz", - "integrity": "sha512-kO5W+O3Ql6NXNFS6lvfSSt1R+PxO1atNLYxZdVSM6+QQxRMiztfqzZs//RM+oUp+af6muDSUPlNs+RORX0fing==", - "dev": true, - "requires": { - "@parcel/node-resolver-core": "2.8.0", - "@parcel/plugin": "2.8.0" - } - }, - "@parcel/runtime-browser-hmr": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.8.0.tgz", - "integrity": "sha512-zV5wGGvm1cDwWAzkwPUaKh6inWYKxq67YWY4G396PXLMxddM9SQC1c7iFM60OPnD4A+BMOLOy7N6//20h15Dlg==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0" - } - }, - "@parcel/runtime-js": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/runtime-js/-/runtime-js-2.8.0.tgz", - "integrity": "sha512-IwT1rX8ZamoYZv0clfswZemfXcIfk+YXwNsqXwzzh6TaMGagj/ZZl1llkn7ERQFq4EoLEoDGGkxqsrJjBp9NDQ==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1" - } - }, - "@parcel/runtime-react-refresh": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/runtime-react-refresh/-/runtime-react-refresh-2.8.0.tgz", - "integrity": "sha512-a6uuZWkl+mJur2WLZKmpEqq1P06tvRwqGefYbE26DWpwXwU9dLpfnv/nT0hqCmVDHd2TkMyCffolSmq1vY05ew==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "react-error-overlay": "6.0.9", - "react-refresh": "^0.9.0" - } - }, - "@parcel/runtime-service-worker": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/runtime-service-worker/-/runtime-service-worker-2.8.0.tgz", - "integrity": "sha512-Q3Q2O/axQbFi/5Z+BidLB3qhmYdZLTMDagZtsmyH7CktDkZVNV/0UoOGYlqoK06T4cww3XjLSEomXbBu9TlQKQ==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1" - } - }, - "@parcel/source-map": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@parcel/source-map/-/source-map-2.1.1.tgz", - "integrity": "sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==", - "dev": true, - "requires": { - "detect-libc": "^1.0.3" - } - }, - "@parcel/transformer-babel": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-babel/-/transformer-babel-2.8.0.tgz", - "integrity": "sha512-ie+wFe9pucdnRyX2PTN9amOHrhr/IOwUEAfTz/3dPydOYCuX7ErEngCpI9fBzdYE2AV6/noEwC2Mjeoyz9mT2A==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.0", - "browserslist": "^4.6.6", - "json5": "^2.2.0", - "nullthrows": "^1.1.1", - "semver": "^5.7.0" - } - }, - "@parcel/transformer-css": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-css/-/transformer-css-2.8.0.tgz", - "integrity": "sha512-jCMQSfsxCoepblBAHCYMuNWNPQlqasoD6PfNftMdTlv12aUcnjNIYO9600TVLTL799CrEohljbXcfFn6hDGVWw==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.0", - "browserslist": "^4.6.6", - "lightningcss": "^1.16.1", - "nullthrows": "^1.1.1" - } - }, - "@parcel/transformer-html": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-html/-/transformer-html-2.8.0.tgz", - "integrity": "sha512-KLcZCWSIItZ1s12Sav3uvfTrwhX92craN9u7V3qUs8ld7ompTKsCdnf+gYmeCyISb5yiFDyYBvTGc1bOXvaDRQ==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/hash": "2.8.0", - "@parcel/plugin": "2.8.0", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "posthtml-parser": "^0.10.1", - "posthtml-render": "^3.0.0", - "semver": "^5.7.1" - } - }, - "@parcel/transformer-image": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-image/-/transformer-image-2.8.0.tgz", - "integrity": "sha512-hJGsZxGlGEkiUvN8kCxA4DhB6/WrHzcIlZZYEgEien9pLctyc6np6idjdcyudPAhH3LwBPkiyeUfCvLAOA1zkA==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "@parcel/workers": "2.8.0", - "nullthrows": "^1.1.1" - } - }, - "@parcel/transformer-inline-string": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-inline-string/-/transformer-inline-string-2.8.0.tgz", - "integrity": "sha512-YBBgolTygr93hos4f5/xkM8VqP+Wc2exeXOyJfVCJJEaSVseXVdF8JtuZLlrcqOkw+ZC3nJtD4CEu+Glz9zCRg==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0" - } - }, - "@parcel/transformer-js": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-js/-/transformer-js-2.8.0.tgz", - "integrity": "sha512-C5WTkDRiJGBB9tZa1mBsZwsqZjYEKkOa4mdVym3dMokwhFLUga8WtK7kGw4fmXIq41U8ip4orywj+Rd4mvGVWg==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.0", - "@parcel/workers": "2.8.0", - "@swc/helpers": "^0.4.12", - "browserslist": "^4.6.6", - "detect-libc": "^1.0.3", - "nullthrows": "^1.1.1", - "regenerator-runtime": "^0.13.7", - "semver": "^5.7.1" - } - }, - "@parcel/transformer-json": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-json/-/transformer-json-2.8.0.tgz", - "integrity": "sha512-Pp5gROSMpzFDEI6KA2APuSpft6eXZxFgTPV6Xx9pElqseod3iL5+RnpMNV/nv76Ai2bcMEiafus5Pb09vjHgbQ==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0", - "json5": "^2.2.0" - } - }, - "@parcel/transformer-postcss": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-postcss/-/transformer-postcss-2.8.0.tgz", - "integrity": "sha512-45Ij+cgwXprd1sCLmaMIlCbPz3eEwolGHizgZmXl5l4yjlE2wGyzodhxLpBk1PWu7OxxWRbLnJIlvMYf7Vfw0g==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/hash": "2.8.0", - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "clone": "^2.1.1", - "nullthrows": "^1.1.1", - "postcss-value-parser": "^4.2.0", - "semver": "^5.7.1" - } - }, - "@parcel/transformer-posthtml": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-posthtml/-/transformer-posthtml-2.8.0.tgz", - "integrity": "sha512-KrkKBFDW5PNZpr2Ha711eIABQOiJQKvfwfVs3CVpJK5wSADkappDk7CQ0mISPjhamFJ6xx/sNsi7e871I8R9lg==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "posthtml-parser": "^0.10.1", - "posthtml-render": "^3.0.0", - "semver": "^5.7.1" - } - }, - "@parcel/transformer-raw": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-raw/-/transformer-raw-2.8.0.tgz", - "integrity": "sha512-uEbj+kE70vg2Gmdji/AIXPK13s5aQRw7X+xWs3vNpY2oymyMRHbfx1izJFWBh+kxu6Yo6q6qsekkh2rNHEHIUA==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0" - } - }, - "@parcel/transformer-react-refresh-wrap": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.8.0.tgz", - "integrity": "sha512-d7G6wBdlwVXLkhC7EO/3UkUOfEOJvsIsQUCEujsrdFF+nfBElXw/TZ+KP8UkmrwMdD0spU/8cKoTyi5k19vt6w==", - "dev": true, - "requires": { - "@parcel/plugin": "2.8.0", - "@parcel/utils": "2.8.0", - "react-refresh": "^0.9.0" - } - }, - "@parcel/transformer-svg": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/transformer-svg/-/transformer-svg-2.8.0.tgz", - "integrity": "sha512-8S6yZoUTCbHOnuWY3M50fscTpI8414945I44fmed+C1e36TnWem8FifuVtGkRZeR8pokF453lmmwWG1eH/4U3w==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/hash": "2.8.0", - "@parcel/plugin": "2.8.0", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "posthtml-parser": "^0.10.1", - "posthtml-render": "^3.0.0", - "semver": "^5.7.1" - } - }, - "@parcel/types": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/types/-/types-2.8.0.tgz", - "integrity": "sha512-DeN3vCnVl9onjtyWxpbP7LwRslVEko4kBaM7yILsuQjEnXmaIOsqIf6FQJOUOPBtQTFFNeQQ2qyf5XoO/rkJ8g==", - "dev": true, - "requires": { - "@parcel/cache": "2.8.0", - "@parcel/diagnostic": "2.8.0", - "@parcel/fs": "2.8.0", - "@parcel/package-manager": "2.8.0", - "@parcel/source-map": "^2.1.1", - "@parcel/workers": "2.8.0", - "utility-types": "^3.10.0" - } - }, - "@parcel/utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/utils/-/utils-2.8.0.tgz", - "integrity": "sha512-r4ACsGtW7zkMUIgwQyOVtPAFiy8L81gbz4tMIRSqyQKnkW7oEHcQ3uN1/LPxj2yfkyQLmhJxmtptLUy9j53rcw==", - "dev": true, - "requires": { - "@parcel/codeframe": "2.8.0", - "@parcel/diagnostic": "2.8.0", - "@parcel/hash": "2.8.0", - "@parcel/logger": "2.8.0", - "@parcel/markdown-ansi": "2.8.0", - "@parcel/source-map": "^2.1.1", - "chalk": "^4.1.0" - } - }, - "@parcel/watcher": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.7.tgz", - "integrity": "sha512-gc3hoS6e+2XdIQ4HHljDB1l0Yx2EWh/sBBtCEFNKGSMlwASWeAQsOY/fPbxOBcZ/pg0jBh4Ga+4xHlZc4faAEQ==", - "dev": true, - "requires": { - "node-addon-api": "^3.2.1", - "node-gyp-build": "^4.3.0" - } - }, - "@parcel/workers": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@parcel/workers/-/workers-2.8.0.tgz", - "integrity": "sha512-vAzoC/wPHLQnyy9P/TrSPftY8F3MhZqPTFi681mxVtLWA3t7wiNlw1zDVKRDP8m5XS1yQOr8Q56CAHyRexhc8g==", - "dev": true, - "requires": { - "@parcel/diagnostic": "2.8.0", - "@parcel/logger": "2.8.0", - "@parcel/types": "2.8.0", - "@parcel/utils": "2.8.0", - "chrome-trace-event": "^1.0.2", - "nullthrows": "^1.1.1" - } - }, - "@swc/helpers": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", - "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==", - "dev": true, - "requires": { - "tslib": "^2.4.0" - } - }, - "@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, - "abortcontroller-polyfill": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz", - "integrity": "sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==", - "dev": true - }, - "acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, - "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001436", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001436.tgz", - "integrity": "sha512-ZmWkKsnC2ifEPoWUvSAIGyOYwT+keAaaWPHiQ9DfMqS1t6tfuyFYoWR78TeZtznkEQ64+vGXH9cZrElwR2Mrxg==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - }, - "cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, - "css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - } - }, - "css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "requires": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - } - }, - "css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true - }, - "csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "requires": { - "css-tree": "^1.1.2" - } - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dev": true - }, - "dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "dependencies": { - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true - } - } - }, - "domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true - }, - "domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - } - }, - "dotenv": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-7.0.0.tgz", - "integrity": "sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==", - "dev": true - }, - "dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true - }, - "entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "get-port": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz", - "integrity": "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==", - "dev": true - }, - "globals": { - "version": "13.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", - "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "htmlnano": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-2.0.3.tgz", - "integrity": "sha512-S4PGGj9RbdgW8LhbILNK7W9JhmYP8zmDY7KDV/8eCiJBQJlbmltp5I0gv8c5ntLljfdxxfmJ+UJVSqyH4mb41A==", - "dev": true, - "requires": { - "cosmiconfig": "^7.0.1", - "posthtml": "^0.16.5", - "timsort": "^0.3.0" - } - }, - "htmlparser2": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", - "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.2", - "domutils": "^2.8.0", - "entities": "^3.0.1" - } - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-json": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz", - "integrity": "sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true - }, - "lightningcss": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.17.1.tgz", - "integrity": "sha512-DwwM/YYqGwLLP3he41wzDXT/m+8jdEZ80i9ViQNLRgyhey3Vm6N7XHn+4o3PY6wSnVT23WLuaROIpbpIVTNOjg==", - "dev": true, - "requires": { - "detect-libc": "^1.0.3", - "lightningcss-darwin-arm64": "1.17.1", - "lightningcss-darwin-x64": "1.17.1", - "lightningcss-linux-arm-gnueabihf": "1.17.1", - "lightningcss-linux-arm64-gnu": "1.17.1", - "lightningcss-linux-arm64-musl": "1.17.1", - "lightningcss-linux-x64-gnu": "1.17.1", - "lightningcss-linux-x64-musl": "1.17.1", - "lightningcss-win32-x64-msvc": "1.17.1" - } - }, - "lightningcss-darwin-arm64": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.17.1.tgz", - "integrity": "sha512-YTAHEy4XlzI3sMbUVjbPi9P7+N7lGcgl2JhCZhiQdRAEKnZLQch8kb5601sgESxdGXjgei7JZFqi/vVEk81wYg==", - "dev": true, - "optional": true - }, - "lightningcss-darwin-x64": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.17.1.tgz", - "integrity": "sha512-UhXPUS2+yTTf5sXwUV0+8QY2x0bPGLgC/uhcknWSQMqWn1zGty4fFvH04D7f7ij0ujwSuN+Q0HtU7lgmMrPz0A==", - "dev": true, - "optional": true - }, - "lightningcss-linux-arm-gnueabihf": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.17.1.tgz", - "integrity": "sha512-alUZumuznB6K/9yZ0zuZkODXUm8uRnvs9t0CL46CXN16Y2h4gOx5ahUCMlelUb7inZEsgJIoepgLsJzBUrSsBw==", - "dev": true, - "optional": true - }, - "lightningcss-linux-arm64-gnu": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.17.1.tgz", - "integrity": "sha512-/1XaH2cOjDt+ivmgfmVFUYCA0MtfNWwtC4P8qVi53zEQ7P8euyyZ1ynykZOyKXW9Q0DzrwcLTh6+hxVLcbtGBg==", - "dev": true, - "optional": true - }, - "lightningcss-linux-arm64-musl": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.17.1.tgz", - "integrity": "sha512-/IgE7lYWFHCCQFTMIwtt+fXLcVOha8rcrNze1JYGPWNorO6NBc6MJo5u5cwn5qMMSz9fZCCDIlBBU4mGwjQszQ==", - "dev": true, - "optional": true - }, - "lightningcss-linux-x64-gnu": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.17.1.tgz", - "integrity": "sha512-OyE802IAp4DB9vZrHlOyWunbHLM9dN08tJIKN/HhzzLKIHizubOWX6NMzUXMZLsaUrYwVAHHdyEA+712p8mMzA==", - "dev": true, - "optional": true - }, - "lightningcss-linux-x64-musl": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.17.1.tgz", - "integrity": "sha512-ydwGgV3Usba5P53RAOqCA9MsRsbb8jFIEVhf7/BXFjpKNoIQyijVTXhwIgQr/oGwUNOHfgQ3F8ruiUjX/p2YKw==", - "dev": true, - "optional": true - }, - "lightningcss-win32-x64-msvc": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.17.1.tgz", - "integrity": "sha512-Ngqtx9NazaiAOk71XWwSsqgAuwYF+8PO6UYsoU7hAukdrSS98kwaBMEDw1igeIiZy1XD/4kh5KVnkjNf7ZOxVQ==", - "dev": true, - "optional": true - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "lmdb": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.5.2.tgz", - "integrity": "sha512-V5V5Xa2Hp9i2XsbDALkBTeHXnBXh/lEmk9p22zdr7jtuOIY9TGhjK6vAvTpOOx9IKU4hJkRWZxn/HsvR1ELLtA==", - "dev": true, - "requires": { - "@lmdb/lmdb-darwin-arm64": "2.5.2", - "@lmdb/lmdb-darwin-x64": "2.5.2", - "@lmdb/lmdb-linux-arm": "2.5.2", - "@lmdb/lmdb-linux-arm64": "2.5.2", - "@lmdb/lmdb-linux-x64": "2.5.2", - "@lmdb/lmdb-win32-x64": "2.5.2", - "msgpackr": "^1.5.4", - "node-addon-api": "^4.3.0", - "node-gyp-build-optional-packages": "5.0.3", - "ordered-binary": "^1.2.4", - "weak-lru-cache": "^1.2.2" - }, - "dependencies": { - "node-addon-api": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", - "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", - "dev": true - } - } - }, - "mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, - "msgpackr": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.8.1.tgz", - "integrity": "sha512-05fT4J8ZqjYlR4QcRDIhLCYKUOHXk7C/xa62GzMKj74l3up9k2QZ3LgFc6qWdsPHl91QA2WLWqWc8b8t7GLNNw==", - "dev": true, - "requires": { - "msgpackr-extract": "^2.2.0" - } - }, - "msgpackr-extract": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-2.2.0.tgz", - "integrity": "sha512-0YcvWSv7ZOGl9Od6Y5iJ3XnPww8O7WLcpYMDwX+PAA/uXLDtyw94PJv9GLQV/nnp3cWlDhMoyKZIQLrx33sWog==", - "dev": true, - "optional": true, - "requires": { - "@msgpackr-extract/msgpackr-extract-darwin-arm64": "2.2.0", - "@msgpackr-extract/msgpackr-extract-darwin-x64": "2.2.0", - "@msgpackr-extract/msgpackr-extract-linux-arm": "2.2.0", - "@msgpackr-extract/msgpackr-extract-linux-arm64": "2.2.0", - "@msgpackr-extract/msgpackr-extract-linux-x64": "2.2.0", - "@msgpackr-extract/msgpackr-extract-win32-x64": "2.2.0", - "node-gyp-build-optional-packages": "5.0.3" - } - }, - "node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true - }, - "node-gyp-build": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz", - "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==", - "dev": true - }, - "node-gyp-build-optional-packages": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz", - "integrity": "sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA==", - "dev": true - }, - "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true - }, - "nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "requires": { - "boolbase": "^1.0.0" - } - }, - "nullthrows": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", - "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", - "dev": true - }, - "ordered-binary": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.4.0.tgz", - "integrity": "sha512-EHQ/jk4/a9hLupIKxTfUsQRej1Yd/0QLQs3vGvIqg5ZtCYSzNhkzHoZc7Zf4e4kUlDaC3Uw8Q/1opOLNN2OKRQ==", - "dev": true - }, - "parcel": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/parcel/-/parcel-2.8.0.tgz", - "integrity": "sha512-p7Fo75CeMw5HC1luovYpBjzPbAJv/Gn7lxcs4f0LxcwBCWbkQ73zHgJXJQqnM38qQABEYEiQq6000+j+k5U/Mw==", - "dev": true, - "requires": { - "@parcel/config-default": "2.8.0", - "@parcel/core": "2.8.0", - "@parcel/diagnostic": "2.8.0", - "@parcel/events": "2.8.0", - "@parcel/fs": "2.8.0", - "@parcel/logger": "2.8.0", - "@parcel/package-manager": "2.8.0", - "@parcel/reporter-cli": "2.8.0", - "@parcel/reporter-dev-server": "2.8.0", - "@parcel/utils": "2.8.0", - "chalk": "^4.1.0", - "commander": "^7.0.0", - "get-port": "^4.2.0", - "v8-compile-cache": "^2.0.0" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true - }, - "posthtml": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.16.6.tgz", - "integrity": "sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ==", - "dev": true, - "requires": { - "posthtml-parser": "^0.11.0", - "posthtml-render": "^3.0.0" - }, - "dependencies": { - "posthtml-parser": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.11.0.tgz", - "integrity": "sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==", - "dev": true, - "requires": { - "htmlparser2": "^7.1.1" - } - } - } - }, - "posthtml-parser": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.10.2.tgz", - "integrity": "sha512-PId6zZ/2lyJi9LiKfe+i2xv57oEjJgWbsHGGANwos5AvdQp98i6AtamAl8gzSVFGfQ43Glb5D614cvZf012VKg==", - "dev": true, - "requires": { - "htmlparser2": "^7.1.1" - } - }, - "posthtml-render": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-3.0.0.tgz", - "integrity": "sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==", - "dev": true, - "requires": { - "is-json": "^2.0.1" - } - }, - "react-error-overlay": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", - "integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==", - "dev": true - }, - "react-refresh": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.9.0.tgz", - "integrity": "sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==", - "dev": true - }, - "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dev": true, - "requires": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - } - }, - "term-size": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", - "dev": true - }, - "terser": { - "version": "5.16.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz", - "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==", - "dev": true, - "requires": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", - "dev": true - }, - "tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typescript": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", - "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", - "dev": true - }, - "update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "utility-types": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", - "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==", - "dev": true - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "weak-lru-cache": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", - "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", - "dev": true - }, - "xxhash-wasm": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz", - "integrity": "sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA==", - "dev": true - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true - }, - "zig-js": { - "version": "file:../vendor/zig-js/js", - "requires": { - "@parcel/packager-ts": "^2.8.0", - "@parcel/transformer-typescript-types": "^2.8.0", - "@types/jest": "^29.2.3", - "jest": "^29.3.1", - "parcel": "^2.8.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.3" - } - } - } -} diff --git a/example/package.json b/example/package.json deleted file mode 100644 index e884e5c6c..000000000 --- a/example/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "ghostty example", - "version": "0.1.0", - "description": "Example showing ghostty and wasm.", - "source": "index.html", - "browserslist": "> 0.5%, last 2 versions, not dead", - "scripts": { - "start": "parcel", - "build": "parcel build", - "check": "tsc --noEmit" - }, - "author": "Mitchell Hashimoto", - "license": "MIT", - "devDependencies": { - "@parcel/transformer-inline-string": "^2.8.0", - "parcel": "^2.8.0", - "typescript": "^4.9.3" - }, - "dependencies": { - "zig-js": "file:../vendor/zig-js/js" - } -} diff --git a/example/zig-vt/README.md b/example/zig-vt/README.md new file mode 100644 index 000000000..f985d4105 --- /dev/null +++ b/example/zig-vt/README.md @@ -0,0 +1,14 @@ +# Example: `ghostty-vt` Zig Module + +This contains a simple example of how to use the `ghostty-vt` Zig module +exported by Ghostty to have access to a production grade terminal emulator. + +Requires the Zig version stated in the `build.zig.zon` file. + +## Usage + +Run the program: + +```shell-session +zig build run +``` diff --git a/example/zig-vt/build.zig b/example/zig-vt/build.zig new file mode 100644 index 000000000..d52ea7ce7 --- /dev/null +++ b/example/zig-vt/build.zig @@ -0,0 +1,44 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const run_step = b.step("run", "Run the app"); + const test_step = b.step("test", "Run unit tests"); + + const exe_mod = b.createModule(.{ + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + }); + + // You'll want to use a lazy dependency here so that ghostty is only + // downloaded if you actually need it. + if (b.lazyDependency("ghostty", .{})) |dep| { + exe_mod.addImport( + "ghostty-vt", + dep.module("ghostty-vt"), + ); + } + + // Exe + const exe = b.addExecutable(.{ + .name = "zig_vt", + .root_module = exe_mod, + }); + b.installArtifact(exe); + + // Run + const run_cmd = b.addRunArtifact(exe); + run_cmd.step.dependOn(b.getInstallStep()); + if (b.args) |args| run_cmd.addArgs(args); + run_step.dependOn(&run_cmd.step); + + // Test + const exe_unit_tests = b.addTest(.{ + .root_module = exe_mod, + }); + const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); + test_step.dependOn(&run_exe_unit_tests.step); +} diff --git a/example/zig-vt/build.zig.zon b/example/zig-vt/build.zig.zon new file mode 100644 index 000000000..852e736ca --- /dev/null +++ b/example/zig-vt/build.zig.zon @@ -0,0 +1,24 @@ +.{ + .name = .zig_vt, + .version = "0.0.0", + .fingerprint = 0x6045575a7a8387e6, + .minimum_zig_version = "0.14.1", + .dependencies = .{ + // Ghostty dependency. In reality, you'd probably use a URL-based + // dependency like the one showed (and commented out) below this one. + // We use a path dependency here for simplicity and to ensure our + // examples always test against the source they're bundled with. + .ghostty = .{ .path = "../../" }, + + // Example of what a URL-based dependency looks like: + // .ghostty = .{ + // .url = "https://github.com/ghostty-org/ghostty/archive/COMMIT.tar.gz", + // .hash = "N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO36s", + // }, + }, + .paths = .{ + "build.zig", + "build.zig.zon", + "src", + }, +} diff --git a/example/zig-vt/src/main.zig b/example/zig-vt/src/main.zig new file mode 100644 index 000000000..f57c70087 --- /dev/null +++ b/example/zig-vt/src/main.zig @@ -0,0 +1,26 @@ +const std = @import("std"); +const ghostty_vt = @import("ghostty-vt"); + +pub fn main() !void { + // Use a debug allocator so we get leak checking. You probably want + // to replace this for release builds. + var gpa: std.heap.DebugAllocator(.{}) = .init; + defer _ = gpa.deinit(); + const alloc = gpa.allocator(); + + // Initialize a terminal. + var t: ghostty_vt.Terminal = try .init(alloc, .{ + .cols = 6, + .rows = 40, + }); + defer t.deinit(alloc); + + // Write some text. It'll wrap because this is too long for our + // columns size above (6). + try t.printString("Hello, World!"); + + // Get the plain string view of the terminal screen. + const str = try t.plainString(alloc); + defer alloc.free(str); + std.debug.print("{s}\n", .{str}); +} diff --git a/src/build/Config.zig b/src/build/Config.zig index 746021930..474674d3a 100644 --- a/src/build/Config.zig +++ b/src/build/Config.zig @@ -8,6 +8,7 @@ const builtin = @import("builtin"); const ApprtRuntime = @import("../apprt/runtime.zig").Runtime; const FontBackend = @import("../font/backend.zig").Backend; const RendererBackend = @import("../renderer/backend.zig").Backend; +const TerminalBuildOptions = @import("../terminal/build_options.zig").Options; const XCFramework = @import("GhosttyXCFramework.zig"); const WasmTarget = @import("../os/wasm/target.zig").Target; const expandPath = @import("../os/path.zig").expand; @@ -37,6 +38,7 @@ font_backend: FontBackend = .freetype, x11: bool = false, wayland: bool = false, sentry: bool = true, +simd: bool = true, i18n: bool = true, wasm_shared: bool = true, @@ -173,6 +175,12 @@ pub fn init(b: *std.Build) !Config { } }; + config.simd = b.option( + bool, + "simd", + "Build with SIMD-accelerated code paths. Results in significant performance improvements.", + ) orelse true; + config.wayland = b.option( bool, "gtk-wayland", @@ -453,6 +461,7 @@ pub fn addOptions(self: *const Config, step: *std.Build.Step.Options) !void { step.addOption(bool, "x11", self.x11); step.addOption(bool, "wayland", self.wayland); step.addOption(bool, "sentry", self.sentry); + step.addOption(bool, "simd", self.simd); step.addOption(bool, "i18n", self.i18n); step.addOption(ApprtRuntime, "app_runtime", self.app_runtime); step.addOption(FontBackend, "font_backend", self.font_backend); @@ -482,6 +491,23 @@ pub fn addOptions(self: *const Config, step: *std.Build.Step.Options) !void { ); } +/// Returns the build options for the terminal module. This assumes a +/// Ghostty executable being built. Callers should modify this as needed. +pub fn terminalOptions(self: *const Config) TerminalBuildOptions { + return .{ + .artifact = .ghostty, + .simd = self.simd, + .oniguruma = true, + .slow_runtime_safety = switch (self.optimize) { + .Debug => true, + .ReleaseSafe, + .ReleaseSmall, + .ReleaseFast, + => false, + }, + }; +} + /// Returns a baseline CPU target retaining all the other CPU configs. pub fn baselineTarget(self: *const Config) std.Build.ResolvedTarget { // Set our cpu model as baseline. There may need to be other modifications diff --git a/src/build/GhosttyZig.zig b/src/build/GhosttyZig.zig new file mode 100644 index 000000000..f175eb957 --- /dev/null +++ b/src/build/GhosttyZig.zig @@ -0,0 +1,49 @@ +//! GhosttyZig generates the Zig modules that Ghostty exports +//! for downstream usage. +const GhosttyZig = @This(); + +const std = @import("std"); +const Config = @import("Config.zig"); +const SharedDeps = @import("SharedDeps.zig"); + +vt: *std.Build.Module, + +pub fn init( + b: *std.Build, + cfg: *const Config, + deps: *const SharedDeps, +) !GhosttyZig { + // General build options + const general_options = b.addOptions(); + try cfg.addOptions(general_options); + + // Terminal module build options + var vt_options = cfg.terminalOptions(); + vt_options.artifact = .lib; + // We presently don't allow Oniguruma in our Zig module at all. + // We should expose this as a build option in the future so we can + // conditionally do this. + vt_options.oniguruma = false; + + const vt = b.addModule("ghostty-vt", .{ + .root_source_file = b.path("src/lib_vt.zig"), + .target = cfg.target, + .optimize = cfg.optimize, + + // SIMD require libc/libcpp (both) but otherwise we don't care. + .link_libc = if (cfg.simd) true else null, + .link_libcpp = if (cfg.simd) true else null, + }); + vt.addOptions("build_options", general_options); + vt_options.add(b, vt); + + // We always need unicode tables + deps.unicode_tables.addModuleImport(vt); + + // If SIMD is enabled, add all our SIMD dependencies. + if (cfg.simd) { + try SharedDeps.addSimd(b, vt, null); + } + + return .{ .vt = vt }; +} diff --git a/src/build/SharedDeps.zig b/src/build/SharedDeps.zig index ab5b0d8bf..d6f6a05bf 100644 --- a/src/build/SharedDeps.zig +++ b/src/build/SharedDeps.zig @@ -107,6 +107,9 @@ pub fn add( // Every exe gets build options populated step.root_module.addOptions("build_options", self.options); + // Every exe needs the terminal options + self.config.terminalOptions().add(b, step.root_module); + // Freetype _ = b.systemIntegrationOption("freetype", .{}); // Shows it in help if (self.config.font_backend.hasFreetype()) { @@ -266,21 +269,6 @@ pub fn add( } } - // Simdutf - if (b.systemIntegrationOption("simdutf", .{})) { - step.linkSystemLibrary2("simdutf", dynamic_link_opts); - } else { - if (b.lazyDependency("simdutf", .{ - .target = target, - .optimize = optimize, - })) |simdutf_dep| { - step.linkLibrary(simdutf_dep.artifact("simdutf")); - try static_libs.append( - simdutf_dep.artifact("simdutf").getEmittedBin(), - ); - } - } - // Sentry if (self.config.sentry) { if (b.lazyDependency("sentry", .{ @@ -309,6 +297,13 @@ pub fn add( } } + // Simd + if (self.config.simd) try addSimd( + b, + step.root_module, + &static_libs, + ); + // Wasm we do manually since it is such a different build. if (step.rootModuleTarget().cpu.arch == .wasm32) { if (b.lazyDependency("zig_js", .{ @@ -343,35 +338,8 @@ pub fn add( step.addIncludePath(b.path("src/apprt/gtk")); } - // C++ files + // libcpp is required for various dependencies step.linkLibCpp(); - step.addIncludePath(b.path("src")); - { - // From hwy/detect_targets.h - const HWY_AVX3_SPR: c_int = 1 << 4; - const HWY_AVX3_ZEN4: c_int = 1 << 6; - const HWY_AVX3_DL: c_int = 1 << 7; - const HWY_AVX3: c_int = 1 << 8; - - // Zig 0.13 bug: https://github.com/ziglang/zig/issues/20414 - // To workaround this we just disable AVX512 support completely. - // The performance difference between AVX2 and AVX512 is not - // significant for our use case and AVX512 is very rare on consumer - // hardware anyways. - const HWY_DISABLED_TARGETS: c_int = HWY_AVX3_SPR | HWY_AVX3_ZEN4 | HWY_AVX3_DL | HWY_AVX3; - - step.addCSourceFiles(.{ - .files = &.{ - "src/simd/base64.cpp", - "src/simd/codepoint_width.cpp", - "src/simd/index_of.cpp", - "src/simd/vt.cpp", - }, - .flags = if (step.rootModuleTarget().cpu.arch == .x86_64) &.{ - b.fmt("-DHWY_DISABLED_TARGETS={}", .{HWY_DISABLED_TARGETS}), - } else &.{}, - }); - } // We always require the system SDK so that our system headers are available. // This makes things like `os/log.h` available for cross-compiling. @@ -481,24 +449,6 @@ pub fn add( try static_libs.append(cimgui_dep.artifact("cimgui").getEmittedBin()); } - // Highway - if (b.lazyDependency("highway", .{ - .target = target, - .optimize = optimize, - })) |highway_dep| { - step.linkLibrary(highway_dep.artifact("highway")); - try static_libs.append(highway_dep.artifact("highway").getEmittedBin()); - } - - // utfcpp - This is used as a dependency on our hand-written C++ code - if (b.lazyDependency("utfcpp", .{ - .target = target, - .optimize = optimize, - })) |utfcpp_dep| { - step.linkLibrary(utfcpp_dep.artifact("utfcpp")); - try static_libs.append(utfcpp_dep.artifact("utfcpp").getEmittedBin()); - } - // Fonts { // JetBrains Mono @@ -700,6 +650,79 @@ fn addGtkNg( } } +/// Add only the dependencies required for `Config.simd` enbled. This also +/// adds all the simd source files for compilation. +pub fn addSimd( + b: *std.Build, + m: *std.Build.Module, + static_libs: ?*LazyPathList, +) !void { + const target = m.resolved_target.?; + const optimize = m.optimize.?; + + // Simdutf + if (b.systemIntegrationOption("simdutf", .{})) { + m.linkSystemLibrary("simdutf", dynamic_link_opts); + } else { + if (b.lazyDependency("simdutf", .{ + .target = target, + .optimize = optimize, + })) |simdutf_dep| { + m.linkLibrary(simdutf_dep.artifact("simdutf")); + if (static_libs) |v| try v.append( + simdutf_dep.artifact("simdutf").getEmittedBin(), + ); + } + } + + // Highway + if (b.lazyDependency("highway", .{ + .target = target, + .optimize = optimize, + })) |highway_dep| { + m.linkLibrary(highway_dep.artifact("highway")); + if (static_libs) |v| try v.append(highway_dep.artifact("highway").getEmittedBin()); + } + + // utfcpp - This is used as a dependency on our hand-written C++ code + if (b.lazyDependency("utfcpp", .{ + .target = target, + .optimize = optimize, + })) |utfcpp_dep| { + m.linkLibrary(utfcpp_dep.artifact("utfcpp")); + if (static_libs) |v| try v.append(utfcpp_dep.artifact("utfcpp").getEmittedBin()); + } + + // SIMD C++ files + m.addIncludePath(b.path("src")); + { + // From hwy/detect_targets.h + const HWY_AVX3_SPR: c_int = 1 << 4; + const HWY_AVX3_ZEN4: c_int = 1 << 6; + const HWY_AVX3_DL: c_int = 1 << 7; + const HWY_AVX3: c_int = 1 << 8; + + // Zig 0.13 bug: https://github.com/ziglang/zig/issues/20414 + // To workaround this we just disable AVX512 support completely. + // The performance difference between AVX2 and AVX512 is not + // significant for our use case and AVX512 is very rare on consumer + // hardware anyways. + const HWY_DISABLED_TARGETS: c_int = HWY_AVX3_SPR | HWY_AVX3_ZEN4 | HWY_AVX3_DL | HWY_AVX3; + + m.addCSourceFiles(.{ + .files = &.{ + "src/simd/base64.cpp", + "src/simd/codepoint_width.cpp", + "src/simd/index_of.cpp", + "src/simd/vt.cpp", + }, + .flags = if (target.result.cpu.arch == .x86_64) &.{ + b.fmt("-DHWY_DISABLED_TARGETS={}", .{HWY_DISABLED_TARGETS}), + } else &.{}, + }); + } +} + /// Creates the resources that can be prebuilt for our dist build. pub fn gtkNgDistResources( b: *std.Build, diff --git a/src/build/UnicodeTables.zig b/src/build/UnicodeTables.zig index 6733b5315..0f558b708 100644 --- a/src/build/UnicodeTables.zig +++ b/src/build/UnicodeTables.zig @@ -64,11 +64,19 @@ pub fn init(b: *std.Build) !UnicodeTables { /// Add the "unicode_tables" import. pub fn addImport(self: *const UnicodeTables, step: *std.Build.Step.Compile) void { self.props_output.addStepDependencies(&step.step); - step.root_module.addAnonymousImport("unicode_tables", .{ + self.symbols_output.addStepDependencies(&step.step); + self.addModuleImport(step.root_module); +} + +/// Add the "unicode_tables" import to a module. +pub fn addModuleImport( + self: *const UnicodeTables, + module: *std.Build.Module, +) void { + module.addAnonymousImport("unicode_tables", .{ .root_source_file = self.props_output, }); - self.symbols_output.addStepDependencies(&step.step); - step.root_module.addAnonymousImport("symbols_tables", .{ + module.addAnonymousImport("symbols_tables", .{ .root_source_file = self.symbols_output, }); } diff --git a/src/build/main.zig b/src/build/main.zig index af99802df..0ee41352b 100644 --- a/src/build/main.zig +++ b/src/build/main.zig @@ -18,6 +18,7 @@ pub const GhosttyI18n = @import("GhosttyI18n.zig"); pub const GhosttyXcodebuild = @import("GhosttyXcodebuild.zig"); pub const GhosttyXCFramework = @import("GhosttyXCFramework.zig"); pub const GhosttyWebdata = @import("GhosttyWebdata.zig"); +pub const GhosttyZig = @import("GhosttyZig.zig"); pub const HelpStrings = @import("HelpStrings.zig"); pub const SharedDeps = @import("SharedDeps.zig"); pub const UnicodeTables = @import("UnicodeTables.zig"); diff --git a/src/config/Config.zig b/src/config/Config.zig index 9a40dc0e4..1ef9de947 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -19,7 +19,6 @@ const ArenaAllocator = std.heap.ArenaAllocator; const global_state = &@import("../global.zig").state; const fontpkg = @import("../font/main.zig"); const inputpkg = @import("../input.zig"); -const terminal = @import("../terminal/main.zig"); const internal_os = @import("../os/main.zig"); const cli = @import("../cli.zig"); @@ -39,6 +38,16 @@ const RepeatableStringMap = @import("RepeatableStringMap.zig"); pub const Path = @import("path.zig").Path; pub const RepeatablePath = @import("path.zig").RepeatablePath; +// We do this instead of importing all of terminal/main.zig to +// limit the dependency graph. This is important because some things +// like the `ghostty-build-data` binary depend on the Config but don't +// want to include all the other stuff. +const terminal = struct { + const CursorStyle = @import("../terminal/cursor.zig").Style; + const color = @import("../terminal/color.zig"); + const x11_color = @import("../terminal/x11_color.zig"); +}; + const log = std.log.scoped(.config); /// Used on Unixes for some defaults. diff --git a/src/fastmem.zig b/src/fastmem.zig index 687c057af..bdea44155 100644 --- a/src/fastmem.zig +++ b/src/fastmem.zig @@ -2,13 +2,20 @@ const std = @import("std"); const builtin = @import("builtin"); const assert = std.debug.assert; -/// Same as std.mem.copyForwards but prefers libc memmove if it is available -/// because it is generally much faster. +/// Same as std.mem.copyForwards/Backwards but prefers libc memmove if it is +/// available because it is generally much faster. pub inline fn move(comptime T: type, dest: []T, source: []const T) void { if (builtin.link_libc) { _ = memmove(dest.ptr, source.ptr, source.len * @sizeOf(T)); } else { - std.mem.copyForwards(T, dest, source); + // Depending on the ordering of the copy, we need to use the + // proper call here. Unfortunately this function call is + // too generic to know this at comptime. + if (@intFromPtr(dest.ptr) <= @intFromPtr(source.ptr)) { + std.mem.copyForwards(T, dest, source); + } else { + std.mem.copyBackwards(T, dest, source); + } } } diff --git a/src/lib_vt.zig b/src/lib_vt.zig new file mode 100644 index 000000000..d375a89d2 --- /dev/null +++ b/src/lib_vt.zig @@ -0,0 +1,70 @@ +//! This is the public API of the ghostty-vt Zig module. +//! +//! WARNING: The API is not guaranteed to be stable. +//! +//! The functionality is extremely stable, since it is extracted +//! directly from Ghostty which has been used in real world scenarios +//! by thousands of users for years. However, the API itself (functions, +//! types, etc.) may change without warning. We're working on stabilizing +//! this in the future. + +// The public API below reproduces a lot of terminal/main.zig but +// is separate because (1) we need our root file to be in `src/` +// so we can access other directories and (2) we may want to withhold +// parts of `terminal` that are not ready for public consumption +// or are too Ghostty-internal. +const terminal = @import("terminal/main.zig"); + +pub const apc = terminal.apc; +pub const dcs = terminal.dcs; +pub const osc = terminal.osc; +pub const point = terminal.point; +pub const color = terminal.color; +pub const device_status = terminal.device_status; +pub const kitty = terminal.kitty; +pub const modes = terminal.modes; +pub const page = terminal.page; +pub const parse_table = terminal.parse_table; +pub const search = terminal.search; +pub const size = terminal.size; +pub const x11_color = terminal.x11_color; + +pub const Charset = terminal.Charset; +pub const CharsetSlot = terminal.Slots; +pub const CharsetActiveSlot = terminal.ActiveSlot; +pub const Cell = page.Cell; +pub const Coordinate = point.Coordinate; +pub const CSI = Parser.Action.CSI; +pub const DCS = Parser.Action.DCS; +pub const MouseShape = terminal.MouseShape; +pub const Page = page.Page; +pub const PageList = terminal.PageList; +pub const Parser = terminal.Parser; +pub const Pin = PageList.Pin; +pub const Point = point.Point; +pub const Screen = terminal.Screen; +pub const ScreenType = Terminal.ScreenType; +pub const Selection = terminal.Selection; +pub const SizeReportStyle = terminal.SizeReportStyle; +pub const StringMap = terminal.StringMap; +pub const Style = terminal.Style; +pub const Terminal = terminal.Terminal; +pub const Stream = terminal.Stream; +pub const Cursor = Screen.Cursor; +pub const CursorStyle = Screen.CursorStyle; +pub const CursorStyleReq = terminal.CursorStyle; +pub const DeviceAttributeReq = terminal.DeviceAttributeReq; +pub const Mode = modes.Mode; +pub const ModePacked = modes.ModePacked; +pub const ModifyKeyFormat = terminal.ModifyKeyFormat; +pub const ProtectedMode = terminal.ProtectedMode; +pub const StatusLineType = terminal.StatusLineType; +pub const StatusDisplay = terminal.StatusDisplay; +pub const EraseDisplay = terminal.EraseDisplay; +pub const EraseLine = terminal.EraseLine; +pub const TabClear = terminal.TabClear; +pub const Attribute = terminal.Attribute; + +test { + _ = terminal; +} diff --git a/src/os/TempDir.zig b/src/os/TempDir.zig index 7d3a34c84..f2e9992c4 100644 --- a/src/os/TempDir.zig +++ b/src/os/TempDir.zig @@ -6,7 +6,8 @@ const std = @import("std"); const builtin = @import("builtin"); const testing = std.testing; const Dir = std.fs.Dir; -const internal_os = @import("main.zig"); +const allocTmpDir = @import("file.zig").allocTmpDir; +const freeTmpDir = @import("file.zig").freeTmpDir; const log = std.log.scoped(.tempdir); @@ -31,8 +32,8 @@ pub fn init() !TempDir { const dir = dir: { const cwd = std.fs.cwd(); - const tmp_dir = internal_os.allocTmpDir(std.heap.page_allocator) orelse break :dir cwd; - defer internal_os.freeTmpDir(std.heap.page_allocator, tmp_dir); + const tmp_dir = allocTmpDir(std.heap.page_allocator) orelse break :dir cwd; + defer freeTmpDir(std.heap.page_allocator, tmp_dir); break :dir try cwd.openDir(tmp_dir, .{}); }; diff --git a/src/simd/base64.zig b/src/simd/base64.zig index 778fbfe3e..88b97bb03 100644 --- a/src/simd/base64.zig +++ b/src/simd/base64.zig @@ -1,4 +1,62 @@ const std = @import("std"); +const options = @import("build_options"); +const assert = std.debug.assert; +const scalar_decoder = @import("base64_scalar.zig").scalar_decoder; + +const log = std.log.scoped(.simd_base64); + +pub fn maxLen(input: []const u8) usize { + if (comptime options.simd) return ghostty_simd_base64_max_length( + input.ptr, + input.len, + ); + + return maxLenScalar(input); +} + +fn maxLenScalar(input: []const u8) usize { + return scalar_decoder.calcSizeForSlice(scalarInput(input)) catch |err| { + log.warn("failed to calculate base64 size for payload: {}", .{err}); + return 0; + }; +} + +pub fn decode(input: []const u8, output: []u8) error{Base64Invalid}![]const u8 { + if (comptime options.simd) { + const res = ghostty_simd_base64_decode( + input.ptr, + input.len, + output.ptr, + ); + if (res < 0) return error.Base64Invalid; + return output[0..@intCast(res)]; + } + + return decodeScalar(input, output); +} + +fn decodeScalar( + input_raw: []const u8, + output: []u8, +) error{Base64Invalid}![]const u8 { + const input = scalarInput(input_raw); + const size = maxLenScalar(input); + if (size == 0) return ""; + assert(output.len >= size); + scalar_decoder.decode( + output, + scalarInput(input), + ) catch return error.Base64Invalid; + return output[0..size]; +} + +/// For non-SIMD enabled builds, we trim the padding from the end of the +/// base64 input in order to get identical output with the SIMD version. +fn scalarInput(input: []const u8) []const u8 { + var i: usize = 0; + while (input[input.len - i - 1] == '=') i += 1; + return input[0 .. input.len - i]; +} // base64.cpp extern "c" fn ghostty_simd_base64_max_length( @@ -11,16 +69,6 @@ extern "c" fn ghostty_simd_base64_decode( output: [*]u8, ) isize; -pub fn maxLen(input: []const u8) usize { - return ghostty_simd_base64_max_length(input.ptr, input.len); -} - -pub fn decode(input: []const u8, output: []u8) error{Base64Invalid}![]const u8 { - const res = ghostty_simd_base64_decode(input.ptr, input.len, output.ptr); - if (res < 0) return error.Base64Invalid; - return output[0..@intCast(res)]; -} - test "base64 maxLen" { const testing = std.testing; const len = maxLen("aGVsbG8gd29ybGQ="); diff --git a/src/simd/base64_scalar.zig b/src/simd/base64_scalar.zig new file mode 100644 index 000000000..4172ed107 --- /dev/null +++ b/src/simd/base64_scalar.zig @@ -0,0 +1,147 @@ +const std = @import("std"); +const assert = std.debug.assert; + +pub const scalar_decoder: Base64Decoder = .init( + std.base64.standard_alphabet_chars, + null, +); + +/// Copied from Zig 0.14.1 stdlib and commented out the invalid padding +/// scenarios, because Kitty Graphics requires a decoder that doesn't care +/// about invalid padding scenarios. +const Base64Decoder = struct { + const invalid_char: u8 = 0xff; + const invalid_char_tst: u32 = 0xff000000; + + const Error = error{ + InvalidCharacter, + InvalidPadding, + NoSpaceLeft, + }; + + /// e.g. 'A' => 0. + /// `invalid_char` for any value not in the 64 alphabet chars. + char_to_index: [256]u8, + fast_char_to_index: [4][256]u32, + pad_char: ?u8, + + pub fn init(alphabet_chars: [64]u8, pad_char: ?u8) Base64Decoder { + var result = Base64Decoder{ + .char_to_index = [_]u8{invalid_char} ** 256, + .fast_char_to_index = .{[_]u32{invalid_char_tst} ** 256} ** 4, + .pad_char = pad_char, + }; + + var char_in_alphabet = [_]bool{false} ** 256; + for (alphabet_chars, 0..) |c, i| { + assert(!char_in_alphabet[c]); + assert(pad_char == null or c != pad_char.?); + + const ci = @as(u32, @intCast(i)); + result.fast_char_to_index[0][c] = ci << 2; + result.fast_char_to_index[1][c] = (ci >> 4) | ((ci & 0x0f) << 12); + result.fast_char_to_index[2][c] = ((ci & 0x3) << 22) | ((ci & 0x3c) << 6); + result.fast_char_to_index[3][c] = ci << 16; + + result.char_to_index[c] = @as(u8, @intCast(i)); + char_in_alphabet[c] = true; + } + return result; + } + + /// Return the maximum possible decoded size for a given input length - The actual length may be less if the input includes padding. + /// `InvalidPadding` is returned if the input length is not valid. + pub fn calcSizeUpperBound(decoder: *const Base64Decoder, source_len: usize) Error!usize { + var result = source_len / 4 * 3; + const leftover = source_len % 4; + if (decoder.pad_char != null) { + if (leftover % 4 != 0) return error.InvalidPadding; + } else { + if (leftover % 4 == 1) return error.InvalidPadding; + result += leftover * 3 / 4; + } + return result; + } + + /// Return the exact decoded size for a slice. + /// `InvalidPadding` is returned if the input length is not valid. + pub fn calcSizeForSlice(decoder: *const Base64Decoder, source: []const u8) Error!usize { + const source_len = source.len; + var result = try decoder.calcSizeUpperBound(source_len); + if (decoder.pad_char) |pad_char| { + if (source_len >= 1 and source[source_len - 1] == pad_char) result -= 1; + if (source_len >= 2 and source[source_len - 2] == pad_char) result -= 1; + } + return result; + } + + /// dest.len must be what you get from ::calcSize. + /// Invalid characters result in `error.InvalidCharacter`. + /// Invalid padding results in `error.InvalidPadding`. + pub fn decode(decoder: *const Base64Decoder, dest: []u8, source: []const u8) Error!void { + if (decoder.pad_char != null and source.len % 4 != 0) return error.InvalidPadding; + var dest_idx: usize = 0; + var fast_src_idx: usize = 0; + var acc: u12 = 0; + var acc_len: u4 = 0; + var leftover_idx: ?usize = null; + while (fast_src_idx + 16 < source.len and dest_idx + 15 < dest.len) : ({ + fast_src_idx += 16; + dest_idx += 12; + }) { + var bits: u128 = 0; + inline for (0..4) |i| { + var new_bits: u128 = decoder.fast_char_to_index[0][source[fast_src_idx + i * 4]]; + new_bits |= decoder.fast_char_to_index[1][source[fast_src_idx + 1 + i * 4]]; + new_bits |= decoder.fast_char_to_index[2][source[fast_src_idx + 2 + i * 4]]; + new_bits |= decoder.fast_char_to_index[3][source[fast_src_idx + 3 + i * 4]]; + if ((new_bits & invalid_char_tst) != 0) return error.InvalidCharacter; + bits |= (new_bits << (24 * i)); + } + std.mem.writeInt(u128, dest[dest_idx..][0..16], bits, .little); + } + while (fast_src_idx + 4 < source.len and dest_idx + 3 < dest.len) : ({ + fast_src_idx += 4; + dest_idx += 3; + }) { + var bits = decoder.fast_char_to_index[0][source[fast_src_idx]]; + bits |= decoder.fast_char_to_index[1][source[fast_src_idx + 1]]; + bits |= decoder.fast_char_to_index[2][source[fast_src_idx + 2]]; + bits |= decoder.fast_char_to_index[3][source[fast_src_idx + 3]]; + if ((bits & invalid_char_tst) != 0) return error.InvalidCharacter; + std.mem.writeInt(u32, dest[dest_idx..][0..4], bits, .little); + } + const remaining = source[fast_src_idx..]; + for (remaining, fast_src_idx..) |c, src_idx| { + const d = decoder.char_to_index[c]; + if (d == invalid_char) { + if (decoder.pad_char == null or c != decoder.pad_char.?) return error.InvalidCharacter; + leftover_idx = src_idx; + break; + } + acc = (acc << 6) + d; + acc_len += 6; + if (acc_len >= 8) { + acc_len -= 8; + dest[dest_idx] = @as(u8, @truncate(acc >> acc_len)); + dest_idx += 1; + } + } + // if (acc_len > 4 or (acc & (@as(u12, 1) << acc_len) - 1) != 0) { + // return error.InvalidPadding; + // } + if (leftover_idx == null) return; + const leftover = source[leftover_idx.?..]; + if (decoder.pad_char) |pad_char| { + const padding_len = acc_len / 2; + var padding_chars: usize = 0; + for (leftover) |c| { + if (c != pad_char) { + return if (c == Base64Decoder.invalid_char) error.InvalidCharacter else error.InvalidPadding; + } + padding_chars += 1; + } + if (padding_chars != padding_len) return error.InvalidPadding; + } + } +}; diff --git a/src/simd/codepoint_width.zig b/src/simd/codepoint_width.zig index aab4bdd95..e097dbd61 100644 --- a/src/simd/codepoint_width.zig +++ b/src/simd/codepoint_width.zig @@ -1,11 +1,12 @@ const std = @import("std"); +const options = @import("build_options"); // vt.cpp extern "c" fn ghostty_simd_codepoint_width(u32) i8; pub fn codepointWidth(cp: u32) i8 { - //return @import("ziglyph").display_width.codePointWidth(@intCast(cp), .half); - return ghostty_simd_codepoint_width(cp); + if (comptime options.simd) return ghostty_simd_codepoint_width(cp); + return @import("ziglyph").display_width.codePointWidth(@intCast(cp), .half); } test "codepointWidth basic" { diff --git a/src/simd/index_of.zig b/src/simd/index_of.zig index b39605996..cea549b95 100644 --- a/src/simd/index_of.zig +++ b/src/simd/index_of.zig @@ -1,5 +1,6 @@ const std = @import("std"); const builtin = @import("builtin"); +const options = @import("build_options"); extern "c" fn ghostty_simd_index_of( needle: u8, @@ -8,8 +9,16 @@ extern "c" fn ghostty_simd_index_of( ) usize; pub fn indexOf(input: []const u8, needle: u8) ?usize { - const result = ghostty_simd_index_of(needle, input.ptr, input.len); - return if (result == input.len) null else result; + if (comptime options.simd) { + const result = ghostty_simd_index_of(needle, input.ptr, input.len); + return if (result == input.len) null else result; + } + + return indexOfScalar(input, needle); +} + +fn indexOfScalar(input: []const u8, needle: u8) ?usize { + return std.mem.indexOfScalar(u8, input, needle); } test "indexOf" { diff --git a/src/simd/main.zig b/src/simd/main.zig index bfcd68c0a..aabdd21d1 100644 --- a/src/simd/main.zig +++ b/src/simd/main.zig @@ -1,3 +1,6 @@ +//! SIMD-optimized routines. If `build_options.simd` is false, then the API +//! still works but we fall back to pure Zig scalar implementations. + const std = @import("std"); const codepoint_width = @import("codepoint_width.zig"); diff --git a/src/simd/vt.zig b/src/simd/vt.zig index dc1c0a511..8e974ad7e 100644 --- a/src/simd/vt.zig +++ b/src/simd/vt.zig @@ -1,4 +1,7 @@ const std = @import("std"); +const options = @import("build_options"); +const assert = std.debug.assert; +const indexOf = @import("index_of.zig").indexOf; // vt.cpp extern "c" fn ghostty_simd_decode_utf8_until_control_seq( @@ -17,15 +20,68 @@ pub fn utf8DecodeUntilControlSeq( input: []const u8, output: []u32, ) DecodeResult { - var decoded: usize = 0; - const consumed = ghostty_simd_decode_utf8_until_control_seq( - input.ptr, - input.len, - output.ptr, - &decoded, - ); + assert(output.len >= input.len); - return .{ .consumed = consumed, .decoded = decoded }; + if (comptime options.simd) { + var decoded: usize = 0; + const consumed = ghostty_simd_decode_utf8_until_control_seq( + input.ptr, + input.len, + output.ptr, + &decoded, + ); + + return .{ .consumed = consumed, .decoded = decoded }; + } + + return utf8DecodeUntilControlSeqScalar(input, output); +} + +fn utf8DecodeUntilControlSeqScalar( + input: []const u8, + output: []u32, +) DecodeResult { + // Find our escape + const idx = indexOf(input, 0x1B) orelse input.len; + const decode = input[0..idx]; + + // Go through and decode one item at a time. + var decode_offset: usize = 0; + var decode_count: usize = 0; + while (decode_offset < decode.len) { + const decode_rem = decode[decode_offset..]; + const cp_len = std.unicode.utf8ByteSequenceLength(decode_rem[0]) catch { + // Note, this is matching our SIMD behavior, but it is admittedly + // a bit weird. See our "decode invalid leading byte" test too. + // SIMD should be our source of truth then we copy behavior here. + break; + }; + + // If we don't have that number of bytes available. we finish. We + // assume this is a partial input and we defer to the future. + if (decode_rem.len < cp_len) break; + + // We have the bytes available, so move forward + const cp_bytes = decode_rem[0..cp_len]; + decode_offset += cp_len; + if (std.unicode.utf8Decode(cp_bytes)) |cp| { + output[decode_count] = @intCast(cp); + decode_count += 1; + } else |_| { + // If decoding failed, we replace the leading byte with the + // replacement char and then continue decoding after that + // byte. This matches the SIMD behavior and is tested by the + // "invalid UTF-8" tests. + output[decode_count] = 0xFFFD; + decode_count += 1; + decode_offset -= cp_len - 1; + } + } + + return .{ + .consumed = decode_offset, + .decoded = decode_count, + }; } test "decode no escape" { @@ -108,16 +164,18 @@ test "decode invalid UTF-8" { var output: [64]u32 = undefined; - // Invalid leading 1s + // Invalid leading 2-byte sequence { - const str = "hello\xc2\x00"; + const str = "hello\xc2\x01"; try testing.expectEqual(DecodeResult{ .consumed = 7, .decoded = 7, }, utf8DecodeUntilControlSeq(str, &output)); } + // Replacement will only replace the invalid leading byte. try testing.expectEqual(@as(u32, 0xFFFD), output[5]); + try testing.expectEqual(@as(u32, 0x01), output[6]); } // This is testing our current behavior so that we know we have to handle diff --git a/src/terminal/PageList.zig b/src/terminal/PageList.zig index a4136d7f3..b8e16dbf7 100644 --- a/src/terminal/PageList.zig +++ b/src/terminal/PageList.zig @@ -4,7 +4,7 @@ const PageList = @This(); const std = @import("std"); -const build_config = @import("../build_config.zig"); +const build_options = @import("terminal_options"); const Allocator = std.mem.Allocator; const assert = std.debug.assert; const fastmem = @import("../fastmem.zig"); @@ -1153,9 +1153,11 @@ const ReflowCursor = struct { self.page_cell.style_id = id; } - // Copy Kitty virtual placeholder status - if (cell.codepoint() == kitty.graphics.unicode.placeholder) { - self.page_row.kitty_virtual_placeholder = true; + if (comptime build_options.kitty_graphics) { + // Copy Kitty virtual placeholder status + if (cell.codepoint() == kitty.graphics.unicode.placeholder) { + self.page_row.kitty_virtual_placeholder = true; + } } self.cursorForward(); @@ -1492,7 +1494,7 @@ fn resizeWithoutReflow(self: *PageList, opts: Resize) !void { }, } - if (build_config.slow_runtime_safety) { + if (build_options.slow_runtime_safety) { assert(self.totalRows() >= self.rows); } } @@ -2524,7 +2526,7 @@ pub fn pin(self: *const PageList, pt: point.Point) ?Pin { /// pin points to is removed completely, the tracked pin will be updated /// to the top-left of the screen. pub fn trackPin(self: *PageList, p: Pin) Allocator.Error!*Pin { - if (build_config.slow_runtime_safety) assert(self.pinIsValid(p)); + if (build_options.slow_runtime_safety) assert(self.pinIsValid(p)); // Create our tracked pin const tracked = try self.pool.pins.create(); @@ -2556,7 +2558,7 @@ pub fn countTrackedPins(self: *const PageList) usize { pub fn pinIsValid(self: *const PageList, p: Pin) bool { // This is very slow so we want to ensure we only ever // call this during slow runtime safety builds. - comptime assert(build_config.slow_runtime_safety); + comptime assert(build_options.slow_runtime_safety); var it = self.pages.first; while (it) |node| : (it = node.next) { @@ -3234,7 +3236,7 @@ pub fn pageIterator( else self.getBottomRight(tl_pt) orelse return .{ .row = null }; - if (build_config.slow_runtime_safety) { + if (build_options.slow_runtime_safety) { assert(tl_pin.eql(bl_pin) or tl_pin.before(bl_pin)); } @@ -3510,7 +3512,7 @@ pub const Pin = struct { direction: Direction, limit: ?Pin, ) PageIterator { - if (build_config.slow_runtime_safety) { + if (build_options.slow_runtime_safety) { if (limit) |l| { // Check the order according to the iteration direction. switch (direction) { @@ -3560,7 +3562,7 @@ pub const Pin = struct { // Note: this is primarily unit tested as part of the Kitty // graphics deletion code. pub fn isBetween(self: Pin, top: Pin, bottom: Pin) bool { - if (build_config.slow_runtime_safety) { + if (build_options.slow_runtime_safety) { if (top.node == bottom.node) { // If top is bottom, must be ordered. assert(top.y <= bottom.y); @@ -8917,6 +8919,8 @@ test "PageList resize reflow less cols to wrap a multi-codepoint grapheme with a } test "PageList resize reflow less cols copy kitty placeholder" { + if (comptime !build_options.kitty_graphics) return error.SkipZigTest; + const testing = std.testing; const alloc = testing.allocator; @@ -8956,6 +8960,8 @@ test "PageList resize reflow less cols copy kitty placeholder" { } test "PageList resize reflow more cols clears kitty placeholder" { + if (comptime !build_options.kitty_graphics) return error.SkipZigTest; + const testing = std.testing; const alloc = testing.allocator; @@ -8997,6 +9003,8 @@ test "PageList resize reflow more cols clears kitty placeholder" { } test "PageList resize reflow wrap moves kitty placeholder" { + if (comptime !build_options.kitty_graphics) return error.SkipZigTest; + const testing = std.testing; const alloc = testing.allocator; diff --git a/src/terminal/Screen.zig b/src/terminal/Screen.zig index 67769923f..7be4d7c12 100644 --- a/src/terminal/Screen.zig +++ b/src/terminal/Screen.zig @@ -1,7 +1,7 @@ const Screen = @This(); const std = @import("std"); -const build_config = @import("../build_config.zig"); +const build_options = @import("terminal_options"); const Allocator = std.mem.Allocator; const assert = std.debug.assert; const ansi = @import("ansi.zig"); @@ -24,6 +24,8 @@ const Row = pagepkg.Row; const Cell = pagepkg.Cell; const Pin = PageList.Pin; +pub const CursorStyle = @import("cursor.zig").Style; + const log = std.log.scoped(.screen); /// The general purpose allocator to use for all memory allocations. @@ -64,7 +66,10 @@ protected_mode: ansi.ProtectedMode = .off, kitty_keyboard: kitty.KeyFlagStack = .{}, /// Kitty graphics protocol state. -kitty_images: kitty.graphics.ImageStorage = .{}, +kitty_images: if (build_options.kitty_graphics) + kitty.graphics.ImageStorage +else + struct {} = .{}, /// Dirty flags for the renderer. dirty: Dirty = .{}, @@ -141,22 +146,6 @@ pub const Cursor = struct { } }; -/// The visual style of the cursor. Whether or not it blinks -/// is determined by mode 12 (modes.zig). This mode is synchronized -/// with CSI q, the same as xterm. -pub const CursorStyle = enum { - bar, // DECSCUSR 5, 6 - block, // DECSCUSR 1, 2 - underline, // DECSCUSR 3, 4 - - /// The cursor styles below aren't known by DESCUSR and are custom - /// implemented in Ghostty. They are reported as some standard style - /// if requested, though. - /// Hollow block cursor. This is a block cursor with the center empty. - /// Reported as DECSCUSR 1 or 2 (block). - block_hollow, -}; - /// Saved cursor state. pub const SavedCursor = struct { x: size.CellCountInt, @@ -222,7 +211,9 @@ pub fn init( } pub fn deinit(self: *Screen) void { - self.kitty_images.deinit(self.alloc, self); + if (comptime build_options.kitty_graphics) { + self.kitty_images.deinit(self.alloc, self); + } self.cursor.deinit(self.alloc); self.pages.deinit(); } @@ -232,7 +223,7 @@ pub fn deinit(self: *Screen) void { /// tests. This only asserts the screen specific data so callers should /// ensure they're also calling page integrity checks if necessary. pub fn assertIntegrity(self: *const Screen) void { - if (build_config.slow_runtime_safety) { + if (build_options.slow_runtime_safety) { // We don't run integrity checks on Valgrind because its soooooo slow, // Valgrind is our integrity checker, and we run these during unit // tests (non-Valgrind) anyways so we're verifying anyways. @@ -283,9 +274,11 @@ pub fn reset(self: *Screen) void { .page_cell = cursor_rac.cell, }; - // Reset kitty graphics storage - self.kitty_images.deinit(self.alloc, self); - self.kitty_images = .{ .dirty = true }; + if (comptime build_options.kitty_graphics) { + // Reset kitty graphics storage + self.kitty_images.deinit(self.alloc, self); + self.kitty_images = .{ .dirty = true }; + } // Reset our basic state self.saved_cursor = null; @@ -704,8 +697,10 @@ pub fn cursorDownScroll(self: *Screen) !void { assert(self.cursor.y == self.pages.rows - 1); defer self.assertIntegrity(); - // Scrolling dirties the images because it updates their placements pins. - self.kitty_images.dirty = true; + if (comptime build_options.kitty_graphics) { + // Scrolling dirties the images because it updates their placements pins. + self.kitty_images.dirty = true; + } // If we have no scrollback, then we shift all our rows instead. if (self.no_scrollback) { @@ -772,7 +767,7 @@ pub fn cursorDownScroll(self: *Screen) !void { // These assertions help catch some pagelist math errors. Our // x/y should be unchanged after the grow. - if (build_config.slow_runtime_safety) { + if (build_options.slow_runtime_safety) { const active = self.pages.pointFromPin( .active, page_pin, @@ -1168,10 +1163,12 @@ pub const Scroll = union(enum) { pub fn scroll(self: *Screen, behavior: Scroll) void { defer self.assertIntegrity(); - // No matter what, scrolling marks our image state as dirty since - // it could move placements. If there are no placements or no images - // this is still a very cheap operation. - self.kitty_images.dirty = true; + if (comptime build_options.kitty_graphics) { + // No matter what, scrolling marks our image state as dirty since + // it could move placements. If there are no placements or no images + // this is still a very cheap operation. + self.kitty_images.dirty = true; + } switch (behavior) { .active => self.pages.scroll(.{ .active = {} }), @@ -1190,10 +1187,12 @@ pub fn scrollClear(self: *Screen) !void { try self.pages.scrollClear(); self.cursorReload(); - // No matter what, scrolling marks our image state as dirty since - // it could move placements. If there are no placements or no images - // this is still a very cheap operation. - self.kitty_images.dirty = true; + if (comptime build_options.kitty_graphics) { + // No matter what, scrolling marks our image state as dirty since + // it could move placements. If there are no placements or no images + // this is still a very cheap operation. + self.kitty_images.dirty = true; + } } /// Returns true if the viewport is scrolled to the bottom of the screen. @@ -1313,14 +1312,16 @@ pub fn clearCells( if (cells.len == self.pages.cols) row.styled = false; } - if (row.kitty_virtual_placeholder and - cells.len == self.pages.cols) - { - for (cells) |c| { - if (c.codepoint() == kitty.graphics.unicode.placeholder) { - break; - } - } else row.kitty_virtual_placeholder = false; + if (comptime build_options.kitty_graphics) { + if (row.kitty_virtual_placeholder and + cells.len == self.pages.cols) + { + for (cells) |c| { + if (c.codepoint() == kitty.graphics.unicode.placeholder) { + break; + } + } else row.kitty_virtual_placeholder = false; + } } @memset(cells, self.blankCell()); @@ -1584,8 +1585,10 @@ fn resizeInternal( ) !void { defer self.assertIntegrity(); - // No matter what we mark our image state as dirty - self.kitty_images.dirty = true; + if (comptime build_options.kitty_graphics) { + // No matter what we mark our image state as dirty + self.kitty_images.dirty = true; + } // Release the cursor style while resizing just // in case the cursor ends up on a different page. diff --git a/src/terminal/StringMap.zig b/src/terminal/StringMap.zig index dde69d25e..ae34f5fc8 100644 --- a/src/terminal/StringMap.zig +++ b/src/terminal/StringMap.zig @@ -3,6 +3,7 @@ const StringMap = @This(); const std = @import("std"); +const build_options = @import("terminal_options"); const oni = @import("oniguruma"); const point = @import("point.zig"); const Selection = @import("Selection.zig"); @@ -19,7 +20,13 @@ pub fn deinit(self: StringMap, alloc: Allocator) void { } /// Returns an iterator that yields the next match of the given regex. -pub fn searchIterator( +/// Requires Ghostty to be compiled with regex support. +pub const searchIterator = if (build_options.oniguruma) + searchIteratorOni +else + void; + +fn searchIteratorOni( self: StringMap, regex: oni.Regex, ) SearchIterator { @@ -85,6 +92,8 @@ pub const Match = struct { }; test "StringMap searchIterator" { + if (comptime !build_options.oniguruma) return error.SkipZigTest; + const testing = std.testing; const alloc = testing.allocator; diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index 0d659eb9a..c9a1f1d1d 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -4,6 +4,7 @@ const Terminal = @This(); const std = @import("std"); +const build_options = @import("terminal_options"); const builtin = @import("builtin"); const assert = std.debug.assert; const testing = std.testing; @@ -679,8 +680,10 @@ fn printCell( // If this is a Kitty unicode placeholder then we need to mark the // row so that the renderer can lookup rows with these much faster. - if (c == kitty.graphics.unicode.placeholder) { - self.screen.cursor.page_row.kitty_virtual_placeholder = true; + if (comptime build_options.kitty_graphics) { + if (c == kitty.graphics.unicode.placeholder) { + self.screen.cursor.page_row.kitty_virtual_placeholder = true; + } } // We check for an active hyperlink first because setHyperlink @@ -1143,8 +1146,10 @@ pub fn index(self: *Terminal) !void { self.screen.cursor.x >= self.scrolling_region.left and self.screen.cursor.x <= self.scrolling_region.right) { - // Scrolling dirties the images because it updates their placements pins. - self.screen.kitty_images.dirty = true; + if (comptime build_options.kitty_graphics) { + // Scrolling dirties the images because it updates their placements pins. + self.screen.kitty_images.dirty = true; + } // If our scrolling region is at the top, we create scrollback. if (self.scrolling_region.top == 0 and @@ -1472,8 +1477,10 @@ pub fn insertLines(self: *Terminal, count: usize) void { self.screen.cursor.x < self.scrolling_region.left or self.screen.cursor.x > self.scrolling_region.right) return; - // Scrolling dirties the images because it updates their placements pins. - self.screen.kitty_images.dirty = true; + if (comptime build_options.kitty_graphics) { + // Scrolling dirties the images because it updates their placements pins. + self.screen.kitty_images.dirty = true; + } // At the end we need to return the cursor to the row it started on. const start_y = self.screen.cursor.y; @@ -1676,8 +1683,10 @@ pub fn deleteLines(self: *Terminal, count: usize) void { self.screen.cursor.x < self.scrolling_region.left or self.screen.cursor.x > self.scrolling_region.right) return; - // Scrolling dirties the images because it updates their placements pins. - self.screen.kitty_images.dirty = true; + if (comptime build_options.kitty_graphics) { + // Scrolling dirties the images because it updates their placements pins. + self.screen.kitty_images.dirty = true; + } // At the end we need to return the cursor to the row it started on. const start_y = self.screen.cursor.y; @@ -2136,12 +2145,14 @@ pub fn eraseDisplay( // Unsets pending wrap state self.screen.cursor.pending_wrap = false; - // Clear all Kitty graphics state for this screen - self.screen.kitty_images.delete( - self.screen.alloc, - self, - .{ .all = true }, - ); + if (comptime build_options.kitty_graphics) { + // Clear all Kitty graphics state for this screen + self.screen.kitty_images.delete( + self.screen.alloc, + self, + .{ .all = true }, + ); + } }, .complete => { @@ -2195,12 +2206,14 @@ pub fn eraseDisplay( // Unsets pending wrap state self.screen.cursor.pending_wrap = false; - // Clear all Kitty graphics state for this screen - self.screen.kitty_images.delete( - self.screen.alloc, - self, - .{ .all = true }, - ); + if (comptime build_options.kitty_graphics) { + // Clear all Kitty graphics state for this screen + self.screen.kitty_images.delete( + self.screen.alloc, + self, + .{ .all = true }, + ); + } // Cleared screen dirty bit self.flags.dirty.clear = true; @@ -2574,10 +2587,12 @@ pub fn switchScreen(self: *Terminal, t: ScreenType) ?*Screen { // Clear our selection self.screen.clearSelection(); - // Mark kitty images as dirty so they redraw. Without this set - // the images will remain where they were (the dirty bit on - // the screen only tracks the terminal grid, not the images). - self.screen.kitty_images.dirty = true; + if (comptime build_options.kitty_graphics) { + // Mark kitty images as dirty so they redraw. Without this set + // the images will remain where they were (the dirty bit on + // the screen only tracks the terminal grid, not the images). + self.screen.kitty_images.dirty = true; + } // Mark our terminal as dirty to redraw the grid. self.flags.dirty.clear = true; @@ -3862,6 +3877,8 @@ test "Terminal: print invoke charset single" { } test "Terminal: print kitty unicode placeholder" { + if (comptime !build_options.kitty_graphics) return error.SkipZigTest; + var t = try init(testing.allocator, .{ .cols = 10, .rows = 10 }); defer t.deinit(testing.allocator); diff --git a/src/terminal/apc.zig b/src/terminal/apc.zig index 26c59729a..a168da4a1 100644 --- a/src/terminal/apc.zig +++ b/src/terminal/apc.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const build_options = @import("terminal_options"); const assert = std.debug.assert; const Allocator = std.mem.Allocator; @@ -33,17 +34,22 @@ pub const Handler = struct { .identify => { switch (byte) { // Kitty graphics protocol - 'G' => self.state = .{ .kitty = kitty_gfx.CommandParser.init(alloc) }, + 'G' => self.state = if (comptime build_options.kitty_graphics) + .{ .kitty = kitty_gfx.CommandParser.init(alloc) } + else + .{ .ignore = {} }, // Unknown else => self.state = .{ .ignore = {} }, } }, - .kitty => |*p| p.feed(byte) catch |err| { - log.warn("kitty graphics protocol error: {}", .{err}); - self.state = .{ .ignore = {} }; - }, + .kitty => |*p| if (comptime build_options.kitty_graphics) { + p.feed(byte) catch |err| { + log.warn("kitty graphics protocol error: {}", .{err}); + self.state = .{ .ignore = {} }; + }; + } else unreachable, } } @@ -57,6 +63,8 @@ pub const Handler = struct { .inactive => unreachable, .ignore, .identify => null, .kitty => |*p| kitty: { + if (comptime !build_options.kitty_graphics) unreachable; + const command = p.complete() catch |err| { log.warn("kitty graphics protocol error: {}", .{err}); break :kitty null; @@ -81,23 +89,35 @@ pub const State = union(enum) { identify: void, /// Kitty graphics protocol - kitty: kitty_gfx.CommandParser, + kitty: if (build_options.kitty_graphics) + kitty_gfx.CommandParser + else + void, pub fn deinit(self: *State) void { switch (self.*) { .inactive, .ignore, .identify => {}, - .kitty => |*v| v.deinit(), + .kitty => |*v| if (comptime build_options.kitty_graphics) + v.deinit() + else + unreachable, } } }; /// Possible APC commands. pub const Command = union(enum) { - kitty: kitty_gfx.Command, + kitty: if (build_options.kitty_graphics) + kitty_gfx.Command + else + void, pub fn deinit(self: *Command, alloc: Allocator) void { switch (self.*) { - .kitty => |*v| v.deinit(alloc), + .kitty => |*v| if (comptime build_options.kitty_graphics) + v.deinit(alloc) + else + unreachable, } } }; @@ -113,6 +133,8 @@ test "unknown APC command" { } test "garbage Kitty command" { + if (comptime !build_options.kitty_graphics) return error.SkipZigTest; + const testing = std.testing; const alloc = testing.allocator; @@ -123,6 +145,8 @@ test "garbage Kitty command" { } test "Kitty command with overflow u32" { + if (comptime !build_options.kitty_graphics) return error.SkipZigTest; + const testing = std.testing; const alloc = testing.allocator; @@ -133,6 +157,8 @@ test "Kitty command with overflow u32" { } test "Kitty command with overflow i32" { + if (comptime !build_options.kitty_graphics) return error.SkipZigTest; + const testing = std.testing; const alloc = testing.allocator; @@ -143,6 +169,8 @@ test "Kitty command with overflow i32" { } test "valid Kitty command" { + if (comptime !build_options.kitty_graphics) return error.SkipZigTest; + const testing = std.testing; const alloc = testing.allocator; diff --git a/src/terminal/build_options.zig b/src/terminal/build_options.zig new file mode 100644 index 000000000..1b0449bbf --- /dev/null +++ b/src/terminal/build_options.zig @@ -0,0 +1,52 @@ +const std = @import("std"); + +pub const Options = struct { + /// The target artifact to build. This will gate some functionality. + artifact: Artifact, + + /// Whether Oniguruma regex support is available. If this isn't + /// available, some features will be disabled. This may be outdated, + /// but the specific disabled features are: + /// + /// - Kitty graphics protocol + /// - Tmux control mode + /// + oniguruma: bool, + + /// Whether to build SIMD-accelerated code paths. This pulls in more + /// build-time dependencies and adds libc as a runtime dependency, + /// but results in significant performance improvements. + simd: bool, + + /// True if we should enable the "slow" runtime safety checks. These + /// are runtime safety checks that are slower than typical and should + /// generally be disabled in production builds. + slow_runtime_safety: bool, + + /// Add the required build options for the terminal module. + pub fn add( + self: Options, + b: *std.Build, + m: *std.Build.Module, + ) void { + const opts = b.addOptions(); + opts.addOption(Artifact, "artifact", self.artifact); + opts.addOption(bool, "oniguruma", self.oniguruma); + opts.addOption(bool, "simd", self.simd); + opts.addOption(bool, "slow_runtime_safety", self.slow_runtime_safety); + + // These are synthesized based on other options. + opts.addOption(bool, "kitty_graphics", self.oniguruma); + opts.addOption(bool, "tmux_control_mode", self.oniguruma); + + m.addOptions("terminal_options", opts); + } +}; + +pub const Artifact = enum { + /// Ghostty application + ghostty, + + /// libghostty-vt, Zig module + lib, +}; diff --git a/src/terminal/cursor.zig b/src/terminal/cursor.zig new file mode 100644 index 000000000..136ee085a --- /dev/null +++ b/src/terminal/cursor.zig @@ -0,0 +1,15 @@ +/// The visual style of the cursor. Whether or not it blinks +/// is determined by mode 12 (modes.zig). This mode is synchronized +/// with CSI q, the same as xterm. +pub const Style = enum { + bar, // DECSCUSR 5, 6 + block, // DECSCUSR 1, 2 + underline, // DECSCUSR 3, 4 + + /// The cursor styles below aren't known by DESCUSR and are custom + /// implemented in Ghostty. They are reported as some standard style + /// if requested, though. + /// Hollow block cursor. This is a block cursor with the center empty. + /// Reported as DECSCUSR 1 or 2 (block). + block_hollow, +}; diff --git a/src/terminal/dcs.zig b/src/terminal/dcs.zig index db5f95c4f..e4d0f3de2 100644 --- a/src/terminal/dcs.zig +++ b/src/terminal/dcs.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const build_options = @import("terminal_options"); const assert = std.debug.assert; const Allocator = std.mem.Allocator; const terminal = @import("main.zig"); @@ -51,6 +52,11 @@ pub const Handler = struct { 0 => switch (dcs.final) { // Tmux control mode 'p' => tmux: { + if (comptime !build_options.tmux_control_mode) { + log.debug("tmux control mode not enabled in build, ignoring", .{}); + break :tmux null; + } + // Tmux control mode must start with ESC P 1000 p if (dcs.params.len != 1 or dcs.params[0] != 1000) break :tmux null; @@ -121,9 +127,11 @@ pub const Handler = struct { .ignore, => {}, - .tmux => |*tmux| return .{ - .tmux = (try tmux.put(byte)) orelse return null, - }, + .tmux => |*tmux| if (comptime build_options.tmux_control_mode) { + return .{ + .tmux = (try tmux.put(byte)) orelse return null, + }; + } else unreachable, .xtgettcap => |*list| { if (list.items.len >= self.max_bytes) { @@ -157,10 +165,10 @@ pub const Handler = struct { .ignore, => null, - .tmux => tmux: { + .tmux => if (comptime build_options.tmux_control_mode) tmux: { self.state.deinit(); break :tmux .{ .tmux = .{ .exit = {} } }; - }, + } else unreachable, .xtgettcap => |list| xtgettcap: { for (list.items, 0..) |b, i| { @@ -203,7 +211,10 @@ pub const Command = union(enum) { decrqss: DECRQSS, /// Tmux control mode - tmux: terminal.tmux.Notification, + tmux: if (build_options.tmux_control_mode) + terminal.tmux.Notification + else + void, pub fn deinit(self: Command) void { switch (self) { @@ -269,7 +280,10 @@ const State = union(enum) { }, /// Tmux control mode: https://github.com/tmux/tmux/wiki/Control-Mode - tmux: terminal.tmux.Client, + tmux: if (build_options.tmux_control_mode) + terminal.tmux.Client + else + void, pub fn deinit(self: *State) void { switch (self.*) { @@ -279,7 +293,9 @@ const State = union(enum) { .xtgettcap => |*v| v.deinit(), .decrqss => {}, - .tmux => |*v| v.deinit(), + .tmux => |*v| if (comptime build_options.tmux_control_mode) { + v.deinit(); + } else unreachable, } } }; @@ -395,6 +411,8 @@ test "DECRQSS invalid command" { } test "tmux enter and implicit exit" { + if (comptime !build_options.tmux_control_mode) return error.SkipZigTest; + const testing = std.testing; const alloc = testing.allocator; diff --git a/src/terminal/kitty.zig b/src/terminal/kitty.zig index 482919f9f..0868a7710 100644 --- a/src/terminal/kitty.zig +++ b/src/terminal/kitty.zig @@ -1,8 +1,10 @@ //! Types and functions related to Kitty protocols. +const build_options = @import("terminal_options"); + const key = @import("kitty/key.zig"); pub const color = @import("kitty/color.zig"); -pub const graphics = @import("kitty/graphics.zig"); +pub const graphics = if (build_options.kitty_graphics) @import("kitty/graphics.zig") else struct {}; pub const KeyFlags = key.Flags; pub const KeyFlagStack = key.FlagStack; diff --git a/src/terminal/kitty/graphics_image.zig b/src/terminal/kitty/graphics_image.zig index 54ed1b934..f32b70be2 100644 --- a/src/terminal/kitty/graphics_image.zig +++ b/src/terminal/kitty/graphics_image.zig @@ -9,9 +9,14 @@ const fastmem = @import("../../fastmem.zig"); const command = @import("graphics_command.zig"); const point = @import("../point.zig"); const PageList = @import("../PageList.zig"); -const internal_os = @import("../../os/main.zig"); const wuffs = @import("wuffs"); +const temp_dir = struct { + const TempDir = @import("../../os/TempDir.zig"); + const allocTmpDir = @import("../../os/file.zig").allocTmpDir; + const freeTmpDir = @import("../../os/file.zig").freeTmpDir; +}; + const log = std.log.scoped(.kitty_gfx); /// Maximum width or height of an image. Taken directly from Kitty. @@ -276,8 +281,8 @@ pub const LoadingImage = struct { fn isPathInTempDir(path: []const u8) bool { if (std.mem.startsWith(u8, path, "/tmp")) return true; if (std.mem.startsWith(u8, path, "/dev/shm")) return true; - if (internal_os.allocTmpDir(std.heap.page_allocator)) |dir| { - defer internal_os.freeTmpDir(std.heap.page_allocator, dir); + if (temp_dir.allocTmpDir(std.heap.page_allocator)) |dir| { + defer temp_dir.freeTmpDir(std.heap.page_allocator, dir); if (std.mem.startsWith(u8, path, dir)) return true; // The temporary dir is sometimes a symlink. On macOS for @@ -690,7 +695,7 @@ test "image load: temporary file without correct path" { const testing = std.testing; const alloc = testing.allocator; - var tmp_dir = try internal_os.TempDir.init(); + var tmp_dir = try temp_dir.TempDir.init(); defer tmp_dir.deinit(); const data = @embedFile("testdata/image-rgb-none-20x15-2147483647-raw.data"); try tmp_dir.dir.writeFile(.{ @@ -723,7 +728,7 @@ test "image load: rgb, not compressed, temporary file" { const testing = std.testing; const alloc = testing.allocator; - var tmp_dir = try internal_os.TempDir.init(); + var tmp_dir = try temp_dir.TempDir.init(); defer tmp_dir.deinit(); const data = @embedFile("testdata/image-rgb-none-20x15-2147483647-raw.data"); try tmp_dir.dir.writeFile(.{ @@ -760,7 +765,7 @@ test "image load: rgb, not compressed, regular file" { const testing = std.testing; const alloc = testing.allocator; - var tmp_dir = try internal_os.TempDir.init(); + var tmp_dir = try temp_dir.TempDir.init(); defer tmp_dir.deinit(); const data = @embedFile("testdata/image-rgb-none-20x15-2147483647-raw.data"); try tmp_dir.dir.writeFile(.{ @@ -795,7 +800,7 @@ test "image load: png, not compressed, regular file" { const testing = std.testing; const alloc = testing.allocator; - var tmp_dir = try internal_os.TempDir.init(); + var tmp_dir = try temp_dir.TempDir.init(); defer tmp_dir.deinit(); const data = @embedFile("testdata/image-png-none-50x76-2147483647-raw.data"); try tmp_dir.dir.writeFile(.{ diff --git a/src/terminal/main.zig b/src/terminal/main.zig index 74ffe6341..1fea9934e 100644 --- a/src/terminal/main.zig +++ b/src/terminal/main.zig @@ -1,4 +1,5 @@ const builtin = @import("builtin"); +const build_options = @import("terminal_options"); const charsets = @import("charsets.zig"); const sanitize = @import("sanitize.zig"); @@ -20,7 +21,7 @@ pub const page = @import("page.zig"); pub const parse_table = @import("parse_table.zig"); pub const search = @import("search.zig"); pub const size = @import("size.zig"); -pub const tmux = @import("tmux.zig"); +pub const tmux = if (build_options.tmux_control_mode) @import("tmux.zig") else struct {}; pub const x11_color = @import("x11_color.zig"); pub const Charset = charsets.Charset; diff --git a/src/terminal/mouse_shape.zig b/src/terminal/mouse_shape.zig index 23ab215d6..1e178c7ee 100644 --- a/src/terminal/mouse_shape.zig +++ b/src/terminal/mouse_shape.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const build_config = @import("../build_config.zig"); +const build_options = @import("terminal_options"); /// The possible cursor shapes. Not all app runtimes support these shapes. /// The shapes are always based on the W3C supported cursor styles so we @@ -48,13 +48,20 @@ pub const MouseShape = enum(c_int) { } /// Make this a valid gobject if we're in a GTK environment. - pub const getGObjectType = switch (build_config.app_runtime) { - .gtk => @import("gobject").ext.defineEnum( - MouseShape, - .{ .name = "GhosttyMouseShape" }, - ), + pub const getGObjectType = gtk: { + switch (build_options.artifact) { + .ghostty => {}, + .lib => break :gtk void, + } - .none => void, + break :gtk switch (@import("../build_config.zig").app_runtime) { + .gtk => @import("gobject").ext.defineEnum( + MouseShape, + .{ .name = "GhosttyMouseShape" }, + ), + + .none => void, + }; }; }; diff --git a/src/terminal/osc.zig b/src/terminal/osc.zig index 028fcdf0a..bd7337b42 100644 --- a/src/terminal/osc.zig +++ b/src/terminal/osc.zig @@ -11,7 +11,7 @@ const mem = std.mem; const assert = std.debug.assert; const Allocator = mem.Allocator; const RGB = @import("color.zig").RGB; -const kitty = @import("kitty.zig"); +const kitty_color = @import("kitty/color.zig"); const osc_color = @import("osc/color.zig"); pub const color = osc_color; @@ -132,7 +132,7 @@ pub const Command = union(enum) { /// Kitty color protocol, OSC 21 /// https://sw.kovidgoyal.net/kitty/color-stack/#id1 - kitty_color_protocol: kitty.color.OSC, + kitty_color_protocol: kitty_color.OSC, /// Show a desktop notification (OSC 9 or OSC 777) show_desktop_notification: struct { @@ -796,7 +796,7 @@ pub const Parser = struct { self.command = .{ .kitty_color_protocol = .{ - .list = std.ArrayList(kitty.color.OSC.Request).init(alloc), + .list = std.ArrayList(kitty_color.OSC.Request).init(alloc), }, }; @@ -1490,7 +1490,7 @@ pub const Parser = struct { return; } - const key = kitty.color.Kind.parse(self.temp_state.key) orelse { + const key = kitty_color.Kind.parse(self.temp_state.key) orelse { log.warn("unknown key in kitty color protocol: {s}", .{self.temp_state.key}); return; }; @@ -1504,7 +1504,7 @@ pub const Parser = struct { switch (self.command) { .kitty_color_protocol => |*v| { // Cap our allocation amount for our list. - if (v.list.items.len >= @as(usize, kitty.color.Kind.max) * 2) { + if (v.list.items.len >= @as(usize, kitty_color.Kind.max) * 2) { self.state = .invalid; log.warn("exceeded limit for number of keys in kitty color protocol, ignoring", .{}); return; @@ -2600,7 +2600,7 @@ test "OSC: hyperlink end" { test "OSC: kitty color protocol" { const testing = std.testing; - const Kind = kitty.color.Kind; + const Kind = kitty_color.Kind; var p: Parser = .initAlloc(testing.allocator); defer p.deinit(); diff --git a/src/terminal/page.zig b/src/terminal/page.zig index d870bd160..b1a24e9a9 100644 --- a/src/terminal/page.zig +++ b/src/terminal/page.zig @@ -1,6 +1,6 @@ const std = @import("std"); const builtin = @import("builtin"); -const build_config = @import("../build_config.zig"); +const build_options = @import("terminal_options"); const Allocator = std.mem.Allocator; const ArenaAllocator = std.heap.ArenaAllocator; const assert = std.debug.assert; @@ -182,8 +182,8 @@ pub const Page = struct { /// If this is true then verifyIntegrity will do nothing. This is /// only present with runtime safety enabled. - pause_integrity_checks: if (build_config.slow_runtime_safety) usize else void = - if (build_config.slow_runtime_safety) 0 else {}, + pause_integrity_checks: if (build_options.slow_runtime_safety) usize else void = + if (build_options.slow_runtime_safety) 0 else {}, /// Initialize a new page, allocating the required backing memory. /// The size of the initialized page defaults to the full capacity. @@ -307,7 +307,7 @@ pub const Page = struct { /// doing a lot of operations that would trigger integrity check /// violations but you know the page will end up in a consistent state. pub fn pauseIntegrityChecks(self: *Page, v: bool) void { - if (build_config.slow_runtime_safety) { + if (build_options.slow_runtime_safety) { if (v) { self.pause_integrity_checks += 1; } else { @@ -320,8 +320,11 @@ pub const Page = struct { /// when runtime safety is enabled. This is a no-op when runtime /// safety is disabled. This uses the libc allocator. pub fn assertIntegrity(self: *const Page) void { - if (comptime build_config.slow_runtime_safety) { - self.verifyIntegrity(std.heap.c_allocator) catch |err| { + if (comptime build_options.slow_runtime_safety) { + var debug_allocator: std.heap.DebugAllocator(.{}) = .init; + defer _ = debug_allocator.deinit(); + const alloc = debug_allocator.allocator(); + self.verifyIntegrity(alloc) catch |err| { log.err("page integrity violation, crashing. err={}", .{err}); @panic("page integrity violation"); }; @@ -351,7 +354,7 @@ pub const Page = struct { // tests (non-Valgrind) anyways so we're verifying anyways. if (std.valgrind.runningOnValgrind() > 0) return; - if (build_config.slow_runtime_safety) { + if (build_options.slow_runtime_safety) { if (self.pause_integrity_checks > 0) return; } @@ -760,7 +763,7 @@ pub const Page = struct { // This is an integrity check: if the row claims it doesn't // have managed memory then all cells must also not have // managed memory. - if (build_config.slow_runtime_safety) { + if (build_options.slow_runtime_safety) { for (other_cells) |cell| { assert(!cell.hasGrapheme()); assert(!cell.hyperlink); @@ -787,7 +790,7 @@ pub const Page = struct { if (src_cell.hasGrapheme()) { // To prevent integrity checks flipping. This will // get fixed up when we check the style id below. - if (build_config.slow_runtime_safety) { + if (build_options.slow_runtime_safety) { dst_cell.style_id = style.default_id; } @@ -890,8 +893,10 @@ pub const Page = struct { error.NeedsRehash => return error.StyleSetNeedsRehash, } orelse src_cell.style_id; } - if (src_cell.codepoint() == kitty.graphics.unicode.placeholder) { - dst_row.kitty_virtual_placeholder = true; + if (comptime build_options.kitty_graphics) { + if (src_cell.codepoint() == kitty.graphics.unicode.placeholder) { + dst_row.kitty_virtual_placeholder = true; + } } } } @@ -914,7 +919,7 @@ pub const Page = struct { /// Get the cells for a row. pub fn getCells(self: *const Page, row: *Row) []Cell { - if (build_config.slow_runtime_safety) { + if (build_options.slow_runtime_safety) { const rows = self.rows.ptr(self.memory); const cells = self.cells.ptr(self.memory); assert(@intFromPtr(row) >= @intFromPtr(rows)); @@ -980,8 +985,10 @@ pub const Page = struct { dst.hyperlink = true; dst_row.hyperlink = true; } - if (src.codepoint() == kitty.graphics.unicode.placeholder) { - dst_row.kitty_virtual_placeholder = true; + if (comptime build_options.kitty_graphics) { + if (src.codepoint() == kitty.graphics.unicode.placeholder) { + dst_row.kitty_virtual_placeholder = true; + } } } } @@ -1002,7 +1009,9 @@ pub const Page = struct { src_row.grapheme = false; src_row.hyperlink = false; src_row.styled = false; - src_row.kitty_virtual_placeholder = false; + if (comptime build_options.kitty_graphics) { + src_row.kitty_virtual_placeholder = false; + } } } @@ -1100,14 +1109,16 @@ pub const Page = struct { if (cells.len == self.size.cols) row.styled = false; } - if (row.kitty_virtual_placeholder and - cells.len == self.size.cols) - { - for (cells) |c| { - if (c.codepoint() == kitty.graphics.unicode.placeholder) { - break; - } - } else row.kitty_virtual_placeholder = false; + if (comptime build_options.kitty_graphics) { + if (row.kitty_virtual_placeholder and + cells.len == self.size.cols) + { + for (cells) |c| { + if (c.codepoint() == kitty.graphics.unicode.placeholder) { + break; + } + } else row.kitty_virtual_placeholder = false; + } } // Zero the cells as u64s since empirically this seems @@ -1363,7 +1374,7 @@ pub const Page = struct { pub fn appendGrapheme(self: *Page, row: *Row, cell: *Cell, cp: u21) Allocator.Error!void { defer self.assertIntegrity(); - if (build_config.slow_runtime_safety) assert(cell.codepoint() != 0); + if (build_options.slow_runtime_safety) assert(cell.codepoint() != 0); const cell_offset = getOffset(Cell, self.memory, cell); var map = self.grapheme_map.map(self.memory); @@ -1436,7 +1447,7 @@ pub const Page = struct { /// there are scenarios where we want to move graphemes without changing /// the content tag. Callers beware but assertIntegrity should catch this. fn moveGrapheme(self: *Page, src: *Cell, dst: *Cell) void { - if (build_config.slow_runtime_safety) { + if (build_options.slow_runtime_safety) { assert(src.hasGrapheme()); assert(!dst.hasGrapheme()); } @@ -1453,7 +1464,7 @@ pub const Page = struct { /// Clear the graphemes for a given cell. pub fn clearGrapheme(self: *Page, row: *Row, cell: *Cell) void { defer self.assertIntegrity(); - if (build_config.slow_runtime_safety) assert(cell.hasGrapheme()); + if (build_options.slow_runtime_safety) assert(cell.hasGrapheme()); // Get our entry in the map, which must exist const cell_offset = getOffset(Cell, self.memory, cell); @@ -1929,6 +1940,9 @@ pub const Row = packed struct(u64) { /// True if this row contains a virtual placeholder for the Kitty /// graphics protocol. (U+10EEEE) + // Note: We keep this as memory-using even if the kitty graphics + // feature is disabled because we want to keep our padding and + // everything throughout the same. kitty_virtual_placeholder: bool = false, _padding: u23 = 0, diff --git a/src/terminal/stream.zig b/src/terminal/stream.zig index 29d8c42d3..a58e01576 100644 --- a/src/terminal/stream.zig +++ b/src/terminal/stream.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const build_options = @import("terminal_options"); const assert = std.debug.assert; const testing = std.testing; const simd = @import("../simd/main.zig"); @@ -64,8 +65,9 @@ pub fn Stream(comptime Handler: type) type { /// Process a string of characters. pub fn nextSlice(self: *Self, input: []const u8) !void { - // Debug mode disables the SIMD optimizations - if (comptime debug) { + // Disable SIMD optimizations if build requests it or if our + // manual debug mode is on. + if (comptime debug or !build_options.simd) { for (input) |c| try self.next(c); return; }