From d44f1d967733517cc65ed7adb09f70247a160e09 Mon Sep 17 00:00:00 2001 From: Surma Date: Thu, 12 Nov 2026 09:36:27 +0000 Subject: [PATCH 1/8] Build separate native and WASI pipelines with shared multicall names Checkpoint before integration and package validation. Assisted-by: SurmAgent:unknown [read] [edit] [bash] --- AGENTS.md | 8 +- docs/RUNNING.md | 19 +- flake.nix | 160 +- host/tests/it/p1.rs | 25 +- host/tests/packaged-builder.nu | 17 +- userland/brush/source/brush-shell/Cargo.toml | 2 +- userland/bundle.nu | 39 +- userland/coreutils/Cargo.toml | 5 + userland/coreutils/src/bin/arch.rs | 5 - userland/coreutils/src/bin/b2sum.rs | 5 - userland/coreutils/src/bin/base32.rs | 5 - userland/coreutils/src/bin/base64.rs | 5 - userland/coreutils/src/bin/basename.rs | 5 - userland/coreutils/src/bin/basenc.rs | 5 - userland/coreutils/src/bin/cat.rs | 5 - userland/coreutils/src/bin/cksum.rs | 5 - userland/coreutils/src/bin/comm.rs | 5 - userland/coreutils/src/bin/cp.rs | 5 - userland/coreutils/src/bin/csplit.rs | 5 - userland/coreutils/src/bin/cut.rs | 5 - userland/coreutils/src/bin/date.rs | 5 - userland/coreutils/src/bin/dd.rs | 5 - userland/coreutils/src/bin/dir.rs | 5 - userland/coreutils/src/bin/dircolors.rs | 5 - userland/coreutils/src/bin/dirname.rs | 5 - userland/coreutils/src/bin/echo.rs | 5 - userland/coreutils/src/bin/expand.rs | 5 - userland/coreutils/src/bin/expr.rs | 5 - userland/coreutils/src/bin/factor.rs | 5 - userland/coreutils/src/bin/false.rs | 5 - userland/coreutils/src/bin/fmt.rs | 5 - userland/coreutils/src/bin/fold.rs | 5 - userland/coreutils/src/bin/head.rs | 5 - userland/coreutils/src/bin/hostid.rs | 5 - userland/coreutils/src/bin/join.rs | 5 - userland/coreutils/src/bin/link.rs | 5 - userland/coreutils/src/bin/ln.rs | 5 - userland/coreutils/src/bin/ls.rs | 5 - userland/coreutils/src/bin/md5sum.rs | 5 - userland/coreutils/src/bin/mkdir.rs | 5 - userland/coreutils/src/bin/mktemp.rs | 5 - userland/coreutils/src/bin/mv.rs | 5 - userland/coreutils/src/bin/nice.rs | 5 - userland/coreutils/src/bin/nl.rs | 5 - userland/coreutils/src/bin/nproc.rs | 5 - userland/coreutils/src/bin/numfmt.rs | 5 - userland/coreutils/src/bin/od.rs | 5 - userland/coreutils/src/bin/paste.rs | 5 - userland/coreutils/src/bin/pathchk.rs | 5 - userland/coreutils/src/bin/pr.rs | 5 - userland/coreutils/src/bin/printenv.rs | 5 - userland/coreutils/src/bin/printf.rs | 5 - userland/coreutils/src/bin/ptx.rs | 5 - userland/coreutils/src/bin/pwd.rs | 5 - userland/coreutils/src/bin/readlink.rs | 5 - userland/coreutils/src/bin/realpath.rs | 5 - userland/coreutils/src/bin/rm.rs | 5 - userland/coreutils/src/bin/rmdir.rs | 5 - userland/coreutils/src/bin/seq.rs | 5 - userland/coreutils/src/bin/sha1sum.rs | 5 - userland/coreutils/src/bin/sha224sum.rs | 5 - userland/coreutils/src/bin/sha256sum.rs | 5 - userland/coreutils/src/bin/sha384sum.rs | 5 - userland/coreutils/src/bin/sha512sum.rs | 5 - userland/coreutils/src/bin/shred.rs | 5 - userland/coreutils/src/bin/shuf.rs | 5 - userland/coreutils/src/bin/sleep.rs | 5 - userland/coreutils/src/bin/sort.rs | 5 - userland/coreutils/src/bin/split.rs | 5 - userland/coreutils/src/bin/sum.rs | 5 - userland/coreutils/src/bin/tail.rs | 5 - userland/coreutils/src/bin/tee.rs | 5 - userland/coreutils/src/bin/test.rs | 5 - userland/coreutils/src/bin/touch.rs | 5 - userland/coreutils/src/bin/tr.rs | 5 - userland/coreutils/src/bin/true.rs | 5 - userland/coreutils/src/bin/truncate.rs | 5 - userland/coreutils/src/bin/tsort.rs | 5 - userland/coreutils/src/bin/tty.rs | 5 - userland/coreutils/src/bin/uname.rs | 5 - userland/coreutils/src/bin/unexpand.rs | 5 - userland/coreutils/src/bin/uniq.rs | 5 - userland/coreutils/src/bin/unlink.rs | 5 - userland/coreutils/src/bin/vdir.rs | 5 - userland/coreutils/src/bin/wc.rs | 5 - userland/coreutils/src/bin/yes.rs | 5 - userland/coreutils/src/main.rs | 100 + userland/preview1.nu | 16 +- userland/qjs/README.md | 14 +- userland/qjs/qjs.wasm | Bin 1571399 -> 0 bytes userland/qjs/source/.gitattributes | 4 + userland/qjs/source/.github/dependabot.yml | 7 + userland/qjs/source/.github/workflows/ci.yml | 920 + .../qjs/source/.github/workflows/docs.yml | 49 + .../source/.github/workflows/gc-stress.yml | 61 + .../qjs/source/.github/workflows/release.yml | 215 + .../source/.github/workflows/test-docs.yml | 23 + .../qjs/source/.github/workflows/tsan.yml | 32 + .../qjs/source/.github/workflows/valgrind.yml | 33 + userland/qjs/source/.gitignore | 15 + userland/qjs/source/.gitmodules | 5 + userland/qjs/source/CMakeLists.txt | 579 + userland/qjs/source/LICENSE | 24 + userland/qjs/source/Makefile | 149 + userland/qjs/source/README.md | 24 + userland/qjs/source/SECURITY.md | 14 + userland/qjs/source/amalgam.js | 53 + userland/qjs/source/api-test.c | 2495 + userland/qjs/source/builtin-array-fromasync.h | 121 + .../qjs/source/builtin-array-fromasync.js | 36 + .../qjs/source/builtin-iterator-zip-keyed.h | 313 + .../qjs/source/builtin-iterator-zip-keyed.js | 194 + userland/qjs/source/builtin-iterator-zip.h | 321 + userland/qjs/source/builtin-iterator-zip.js | 210 + userland/qjs/source/ctest.c | 17 + userland/qjs/source/cutils.h | 2021 + userland/qjs/source/cxxtest.cc | 2 + userland/qjs/source/docs/.gitignore | 20 + userland/qjs/source/docs/.nvmrc | 1 + userland/qjs/source/docs/babel.config.js | 3 + userland/qjs/source/docs/docs/building.md | 74 + userland/qjs/source/docs/docs/cli.md | 130 + .../docs/docs/developer-guide/_category_.json | 7 + .../source/docs/docs/developer-guide/api.md | 3 + .../docs/docs/developer-guide/internals.md | 117 + .../source/docs/docs/developer-guide/intro.md | 111 + userland/qjs/source/docs/docs/diff.md | 68 + userland/qjs/source/docs/docs/es_features.md | 11 + userland/qjs/source/docs/docs/installation.md | 34 + userland/qjs/source/docs/docs/intro.md | 33 + userland/qjs/source/docs/docs/projects.md | 116 + userland/qjs/source/docs/docs/stdlib.md | 605 + .../source/docs/docs/supported_platforms.md | 20 + userland/qjs/source/docs/docusaurus.config.js | 114 + userland/qjs/source/docs/package-lock.json | 14656 ++++ userland/qjs/source/docs/package.json | 42 + userland/qjs/source/docs/sidebars.js | 20 + userland/qjs/source/docs/src/css/custom.css | 30 + userland/qjs/source/docs/static/.nojekyll | 0 .../qjs/source/docs/static/img/favicon.ico | Bin 0 -> 3626 bytes userland/qjs/source/dtoa.c | 1619 + userland/qjs/source/dtoa.h | 87 + userland/qjs/source/examples/fib.c | 67 + userland/qjs/source/examples/fib_module.js | 10 + userland/qjs/source/examples/hello.js | 1 + userland/qjs/source/examples/hello_module.js | 6 + userland/qjs/source/examples/meson.build | 17 + userland/qjs/source/examples/pi_bigint.js | 118 + userland/qjs/source/examples/point.c | 154 + userland/qjs/source/examples/test_fib.js | 8 + userland/qjs/source/examples/test_point.js | 43 + userland/qjs/source/fuzz.c | 51 + userland/qjs/source/gc-stress-skip.txt | 3 + userland/qjs/source/gen/function_source.c | 82 + userland/qjs/source/gen/hello.c | 53 + userland/qjs/source/gen/hello_module.c | 107 + userland/qjs/source/gen/repl.c | 3018 + userland/qjs/source/gen/standalone.c | 319 + userland/qjs/source/gen/test_fib.c | 81 + userland/qjs/source/libregexp-opcode.h | 73 + userland/qjs/source/libregexp.c | 3522 + userland/qjs/source/libregexp.h | 101 + userland/qjs/source/libunicode-table.h | 5160 ++ userland/qjs/source/libunicode.c | 2074 + userland/qjs/source/libunicode.h | 172 + userland/qjs/source/list.h | 107 + userland/qjs/source/lre-test.c | 112 + userland/qjs/source/meson.build | 686 + userland/qjs/source/meson_options.txt | 6 + userland/qjs/source/qjs-wasi-reactor.c | 208 + userland/qjs/source/qjs.c | 777 + userland/qjs/source/qjs.man | 90 + userland/qjs/source/qjsc.c | 673 + userland/qjs/source/qjsc.man | 78 + userland/qjs/source/quickjs-atom.h | 279 + userland/qjs/source/quickjs-c-atomics.h | 54 + userland/qjs/source/quickjs-libc.c | 5085 ++ userland/qjs/source/quickjs-libc.h | 87 + userland/qjs/source/quickjs-opcode.h | 377 + userland/qjs/source/quickjs.c | 65028 ++++++++++++++++ userland/qjs/source/quickjs.h | 1514 + userland/qjs/source/repl.js | 1927 + userland/qjs/source/run-test262.c | 2384 + userland/qjs/source/standalone.js | 129 + userland/qjs/source/test262-fast.conf | 132 + userland/qjs/source/test262.conf | 284 + userland/qjs/source/test262_errors.txt | 40 + userland/qjs/source/tests.conf | 18 + .../tests/array-fromasync-enumerable.js | 23 + .../tests/array-sort-identical-values.js | 259 + userland/qjs/source/tests/assert.js | 49 + .../qjs/source/tests/atomics-store-leak.js | 36 + userland/qjs/source/tests/bug1296.js | 12 + userland/qjs/source/tests/bug1297.js | 22 + userland/qjs/source/tests/bug1301.js | 21 + userland/qjs/source/tests/bug1302.js | 24 + userland/qjs/source/tests/bug1305.js | 26 + userland/qjs/source/tests/bug1318.js | 54 + userland/qjs/source/tests/bug1352.js | 8 + userland/qjs/source/tests/bug1354.js | 6 + userland/qjs/source/tests/bug1355.js | 58 + userland/qjs/source/tests/bug1368.js | 72 + userland/qjs/source/tests/bug1430.js | 17 + userland/qjs/source/tests/bug1468.js | 25 + userland/qjs/source/tests/bug1498.js | 30 + userland/qjs/source/tests/bug1552.js | 87 + userland/qjs/source/tests/bug1557.js | 55 + userland/qjs/source/tests/bug1562.js | 65 + userland/qjs/source/tests/bug1564.js | 5 + userland/qjs/source/tests/bug1565.js | 16 + userland/qjs/source/tests/bug1571.js | 13 + userland/qjs/source/tests/bug1572.js | 18 + userland/qjs/source/tests/bug1591.js | 26 + userland/qjs/source/tests/bug1598.js | 22 + userland/qjs/source/tests/bug1625.js | 6 + userland/qjs/source/tests/bug1626.js | 74 + userland/qjs/source/tests/bug1627.js | 33 + userland/qjs/source/tests/bug1628.js | 53 + userland/qjs/source/tests/bug1661.js | 42 + .../tests/bug1672/Array.prototype.every.js | 7 + .../tests/bug1672/Array.prototype.filter.js | 7 + .../tests/bug1672/Array.prototype.find.js | 7 + .../bug1672/Array.prototype.findIndex.js | 7 + .../tests/bug1672/Array.prototype.findLast.js | 7 + .../bug1672/Array.prototype.findLastIndex.js | 7 + .../tests/bug1672/Array.prototype.forEach.js | 7 + .../tests/bug1672/Array.prototype.includes.js | 7 + .../tests/bug1672/Array.prototype.indexOf.js | 7 + .../bug1672/Array.prototype.lastIndexOf.js | 7 + .../tests/bug1672/Array.prototype.map.js | 7 + .../tests/bug1672/Array.prototype.reduce.js | 7 + .../bug1672/Array.prototype.reduceRight.js | 7 + .../tests/bug1672/Array.prototype.some.js | 7 + userland/qjs/source/tests/bug1683.js | 3 + userland/qjs/source/tests/bug1690.js | 6 + userland/qjs/source/tests/bug1691.js | 5 + userland/qjs/source/tests/bug1693.js | 80 + userland/qjs/source/tests/bug1730.js | 5 + userland/qjs/source/tests/bug1732.js | 3 + userland/qjs/source/tests/bug1735.js | 53 + userland/qjs/source/tests/bug1795.js | 97 + userland/qjs/source/tests/bug1835.js | 36 + userland/qjs/source/tests/bug39/1.js | 6 + userland/qjs/source/tests/bug39/2.js | 6 + userland/qjs/source/tests/bug39/3.js | 7 + userland/qjs/source/tests/bug488-upstream.js | 7 + userland/qjs/source/tests/bug492.js | 113 + userland/qjs/source/tests/bug493.js | 10 + userland/qjs/source/tests/bug567.js | 5 + userland/qjs/source/tests/bug633/0.js | 7 + userland/qjs/source/tests/bug633/1.js | 4 + userland/qjs/source/tests/bug633/2.js | 4 + userland/qjs/source/tests/bug633/3.js | 4 + userland/qjs/source/tests/bug645/0.js | 4 + userland/qjs/source/tests/bug645/1.js | 9 + userland/qjs/source/tests/bug645/2.js | 7 + userland/qjs/source/tests/bug648.js | 13 + userland/qjs/source/tests/bug652.js | 4 + userland/qjs/source/tests/bug741.js | 19 + userland/qjs/source/tests/bug775.js | 7 + userland/qjs/source/tests/bug776.js | 7 + userland/qjs/source/tests/bug832.js | 2 + userland/qjs/source/tests/bug858.js | 26 + userland/qjs/source/tests/bug904.js | 6 + userland/qjs/source/tests/bug988.js | 7 + userland/qjs/source/tests/bug999.js | 3 + .../source/tests/callsite-isconstructor.js | 30 + .../source/tests/callsite-native-position.js | 19 + .../qjs/source/tests/destructured-export.js | 20 + userland/qjs/source/tests/detect_module/0.js | 1 + userland/qjs/source/tests/detect_module/1.js | 2 + userland/qjs/source/tests/detect_module/2.js | 1 + userland/qjs/source/tests/detect_module/3.js | 8 + userland/qjs/source/tests/detect_module/4.js | 3 + .../tests/dynamic_import_rejection_handled.js | 7 + userland/qjs/source/tests/empty.js | 0 .../source/tests/fix_set_array_length-uaf.js | 6 + .../qjs/source/tests/fixture_cyclic_import.js | 2 + .../tests/fixture_import_attributes.json | 1 + .../source/tests/fixture_reexport_direct.js | 1 + .../source/tests/fixture_reexport_missing.js | 1 + .../source/tests/fixture_reexport_source.js | 1 + .../source/tests/fixture_string_exports.js | 12 + .../source/tests/fixture_throwing_module.js | 1 + .../source/tests/for-await-normal-close.js | 50 + userland/qjs/source/tests/function_source.js | 14 + .../source/tests/global-reference-column.js | 19 + .../tests/import-attributes-identity.js | 35 + .../qjs/source/tests/iterator-filter-leak.js | 21 + .../tests/iterator-tostringtag-setter.js | 44 + userland/qjs/source/tests/microbench.js | 1267 + .../qjs/source/tests/null_or_undefined.js | 38 + .../qjs/source/tests/parse-error-column.js | 46 + .../qjs/source/tests/reexport-error-module.js | 14 + .../resize_array_buffer_index_valueOf.js | 10 + userland/qjs/source/tests/str-pad-leak.js | 5 + .../tests/suspended-coroutine-closure-gc.js | 35 + ...suspended-coroutine-mapped-arguments-gc.js | 28 + .../tests/suspended-generator-closure-gc.js | 33 + userland/qjs/source/tests/test_array_to_gc.js | 69 + userland/qjs/source/tests/test_base64.js | 95 + userland/qjs/source/tests/test_bigint.js | 137 + userland/qjs/source/tests/test_bjson.js | 337 + userland/qjs/source/tests/test_builtin.js | 1362 + userland/qjs/source/tests/test_closure.js | 220 + .../qjs/source/tests/test_domexception.js | 52 + .../tests/test_dynamic_import_line_numbers.js | 42 + .../source/tests/test_for_of_line_numbers.js | 50 + userland/qjs/source/tests/test_language.js | 1151 + userland/qjs/source/tests/test_loop.js | 367 + .../qjs/source/tests/test_queue_microtask.js | 39 + userland/qjs/source/tests/test_std.js | 372 + .../qjs/source/tests/test_string_exports.js | 25 + userland/qjs/source/tests/test_worker.js | 43 + .../qjs/source/tests/test_worker_module.js | 30 + .../tests/typedarray-lastindexof-shrink.js | 73 + .../tests/typedarray-set-invalid-index.js | 50 + .../source/tests/typedarray-slice-overlap.js | 48 + .../tests/typedarray-subarray-species.js | 82 + userland/qjs/source/tests/wasi-stack-limit.js | 22 + userland/qjs/source/unicode_download.sh | 26 + userland/qjs/source/unicode_gen.c | 3617 + userland/qjs/source/unicode_gen_def.h | 326 + userland/qjs/source/update-version.sh | 32 + userland/tools.json | 355 + 325 files changed, 134189 insertions(+), 506 deletions(-) delete mode 100644 userland/coreutils/src/bin/arch.rs delete mode 100644 userland/coreutils/src/bin/b2sum.rs delete mode 100644 userland/coreutils/src/bin/base32.rs delete mode 100644 userland/coreutils/src/bin/base64.rs delete mode 100644 userland/coreutils/src/bin/basename.rs delete mode 100644 userland/coreutils/src/bin/basenc.rs delete mode 100644 userland/coreutils/src/bin/cat.rs delete mode 100644 userland/coreutils/src/bin/cksum.rs delete mode 100644 userland/coreutils/src/bin/comm.rs delete mode 100644 userland/coreutils/src/bin/cp.rs delete mode 100644 userland/coreutils/src/bin/csplit.rs delete mode 100644 userland/coreutils/src/bin/cut.rs delete mode 100644 userland/coreutils/src/bin/date.rs delete mode 100644 userland/coreutils/src/bin/dd.rs delete mode 100644 userland/coreutils/src/bin/dir.rs delete mode 100644 userland/coreutils/src/bin/dircolors.rs delete mode 100644 userland/coreutils/src/bin/dirname.rs delete mode 100644 userland/coreutils/src/bin/echo.rs delete mode 100644 userland/coreutils/src/bin/expand.rs delete mode 100644 userland/coreutils/src/bin/expr.rs delete mode 100644 userland/coreutils/src/bin/factor.rs delete mode 100644 userland/coreutils/src/bin/false.rs delete mode 100644 userland/coreutils/src/bin/fmt.rs delete mode 100644 userland/coreutils/src/bin/fold.rs delete mode 100644 userland/coreutils/src/bin/head.rs delete mode 100644 userland/coreutils/src/bin/hostid.rs delete mode 100644 userland/coreutils/src/bin/join.rs delete mode 100644 userland/coreutils/src/bin/link.rs delete mode 100644 userland/coreutils/src/bin/ln.rs delete mode 100644 userland/coreutils/src/bin/ls.rs delete mode 100644 userland/coreutils/src/bin/md5sum.rs delete mode 100644 userland/coreutils/src/bin/mkdir.rs delete mode 100644 userland/coreutils/src/bin/mktemp.rs delete mode 100644 userland/coreutils/src/bin/mv.rs delete mode 100644 userland/coreutils/src/bin/nice.rs delete mode 100644 userland/coreutils/src/bin/nl.rs delete mode 100644 userland/coreutils/src/bin/nproc.rs delete mode 100644 userland/coreutils/src/bin/numfmt.rs delete mode 100644 userland/coreutils/src/bin/od.rs delete mode 100644 userland/coreutils/src/bin/paste.rs delete mode 100644 userland/coreutils/src/bin/pathchk.rs delete mode 100644 userland/coreutils/src/bin/pr.rs delete mode 100644 userland/coreutils/src/bin/printenv.rs delete mode 100644 userland/coreutils/src/bin/printf.rs delete mode 100644 userland/coreutils/src/bin/ptx.rs delete mode 100644 userland/coreutils/src/bin/pwd.rs delete mode 100644 userland/coreutils/src/bin/readlink.rs delete mode 100644 userland/coreutils/src/bin/realpath.rs delete mode 100644 userland/coreutils/src/bin/rm.rs delete mode 100644 userland/coreutils/src/bin/rmdir.rs delete mode 100644 userland/coreutils/src/bin/seq.rs delete mode 100644 userland/coreutils/src/bin/sha1sum.rs delete mode 100644 userland/coreutils/src/bin/sha224sum.rs delete mode 100644 userland/coreutils/src/bin/sha256sum.rs delete mode 100644 userland/coreutils/src/bin/sha384sum.rs delete mode 100644 userland/coreutils/src/bin/sha512sum.rs delete mode 100644 userland/coreutils/src/bin/shred.rs delete mode 100644 userland/coreutils/src/bin/shuf.rs delete mode 100644 userland/coreutils/src/bin/sleep.rs delete mode 100644 userland/coreutils/src/bin/sort.rs delete mode 100644 userland/coreutils/src/bin/split.rs delete mode 100644 userland/coreutils/src/bin/sum.rs delete mode 100644 userland/coreutils/src/bin/tail.rs delete mode 100644 userland/coreutils/src/bin/tee.rs delete mode 100644 userland/coreutils/src/bin/test.rs delete mode 100644 userland/coreutils/src/bin/touch.rs delete mode 100644 userland/coreutils/src/bin/tr.rs delete mode 100644 userland/coreutils/src/bin/true.rs delete mode 100644 userland/coreutils/src/bin/truncate.rs delete mode 100644 userland/coreutils/src/bin/tsort.rs delete mode 100644 userland/coreutils/src/bin/tty.rs delete mode 100644 userland/coreutils/src/bin/uname.rs delete mode 100644 userland/coreutils/src/bin/unexpand.rs delete mode 100644 userland/coreutils/src/bin/uniq.rs delete mode 100644 userland/coreutils/src/bin/unlink.rs delete mode 100644 userland/coreutils/src/bin/vdir.rs delete mode 100644 userland/coreutils/src/bin/wc.rs delete mode 100644 userland/coreutils/src/bin/yes.rs create mode 100644 userland/coreutils/src/main.rs delete mode 100644 userland/qjs/qjs.wasm create mode 100644 userland/qjs/source/.gitattributes create mode 100644 userland/qjs/source/.github/dependabot.yml create mode 100644 userland/qjs/source/.github/workflows/ci.yml create mode 100644 userland/qjs/source/.github/workflows/docs.yml create mode 100644 userland/qjs/source/.github/workflows/gc-stress.yml create mode 100644 userland/qjs/source/.github/workflows/release.yml create mode 100644 userland/qjs/source/.github/workflows/test-docs.yml create mode 100644 userland/qjs/source/.github/workflows/tsan.yml create mode 100644 userland/qjs/source/.github/workflows/valgrind.yml create mode 100644 userland/qjs/source/.gitignore create mode 100644 userland/qjs/source/.gitmodules create mode 100644 userland/qjs/source/CMakeLists.txt create mode 100644 userland/qjs/source/LICENSE create mode 100644 userland/qjs/source/Makefile create mode 100644 userland/qjs/source/README.md create mode 100644 userland/qjs/source/SECURITY.md create mode 100644 userland/qjs/source/amalgam.js create mode 100644 userland/qjs/source/api-test.c create mode 100644 userland/qjs/source/builtin-array-fromasync.h create mode 100644 userland/qjs/source/builtin-array-fromasync.js create mode 100644 userland/qjs/source/builtin-iterator-zip-keyed.h create mode 100644 userland/qjs/source/builtin-iterator-zip-keyed.js create mode 100644 userland/qjs/source/builtin-iterator-zip.h create mode 100644 userland/qjs/source/builtin-iterator-zip.js create mode 100644 userland/qjs/source/ctest.c create mode 100644 userland/qjs/source/cutils.h create mode 100644 userland/qjs/source/cxxtest.cc create mode 100644 userland/qjs/source/docs/.gitignore create mode 100644 userland/qjs/source/docs/.nvmrc create mode 100644 userland/qjs/source/docs/babel.config.js create mode 100644 userland/qjs/source/docs/docs/building.md create mode 100644 userland/qjs/source/docs/docs/cli.md create mode 100644 userland/qjs/source/docs/docs/developer-guide/_category_.json create mode 100644 userland/qjs/source/docs/docs/developer-guide/api.md create mode 100644 userland/qjs/source/docs/docs/developer-guide/internals.md create mode 100644 userland/qjs/source/docs/docs/developer-guide/intro.md create mode 100644 userland/qjs/source/docs/docs/diff.md create mode 100644 userland/qjs/source/docs/docs/es_features.md create mode 100644 userland/qjs/source/docs/docs/installation.md create mode 100644 userland/qjs/source/docs/docs/intro.md create mode 100644 userland/qjs/source/docs/docs/projects.md create mode 100644 userland/qjs/source/docs/docs/stdlib.md create mode 100644 userland/qjs/source/docs/docs/supported_platforms.md create mode 100644 userland/qjs/source/docs/docusaurus.config.js create mode 100644 userland/qjs/source/docs/package-lock.json create mode 100644 userland/qjs/source/docs/package.json create mode 100644 userland/qjs/source/docs/sidebars.js create mode 100644 userland/qjs/source/docs/src/css/custom.css create mode 100644 userland/qjs/source/docs/static/.nojekyll create mode 100644 userland/qjs/source/docs/static/img/favicon.ico create mode 100644 userland/qjs/source/dtoa.c create mode 100644 userland/qjs/source/dtoa.h create mode 100644 userland/qjs/source/examples/fib.c create mode 100644 userland/qjs/source/examples/fib_module.js create mode 100644 userland/qjs/source/examples/hello.js create mode 100644 userland/qjs/source/examples/hello_module.js create mode 100644 userland/qjs/source/examples/meson.build create mode 100644 userland/qjs/source/examples/pi_bigint.js create mode 100644 userland/qjs/source/examples/point.c create mode 100644 userland/qjs/source/examples/test_fib.js create mode 100644 userland/qjs/source/examples/test_point.js create mode 100644 userland/qjs/source/fuzz.c create mode 100644 userland/qjs/source/gc-stress-skip.txt create mode 100644 userland/qjs/source/gen/function_source.c create mode 100644 userland/qjs/source/gen/hello.c create mode 100644 userland/qjs/source/gen/hello_module.c create mode 100644 userland/qjs/source/gen/repl.c create mode 100644 userland/qjs/source/gen/standalone.c create mode 100644 userland/qjs/source/gen/test_fib.c create mode 100644 userland/qjs/source/libregexp-opcode.h create mode 100644 userland/qjs/source/libregexp.c create mode 100644 userland/qjs/source/libregexp.h create mode 100644 userland/qjs/source/libunicode-table.h create mode 100644 userland/qjs/source/libunicode.c create mode 100644 userland/qjs/source/libunicode.h create mode 100644 userland/qjs/source/list.h create mode 100644 userland/qjs/source/lre-test.c create mode 100644 userland/qjs/source/meson.build create mode 100644 userland/qjs/source/meson_options.txt create mode 100644 userland/qjs/source/qjs-wasi-reactor.c create mode 100644 userland/qjs/source/qjs.c create mode 100644 userland/qjs/source/qjs.man create mode 100644 userland/qjs/source/qjsc.c create mode 100644 userland/qjs/source/qjsc.man create mode 100644 userland/qjs/source/quickjs-atom.h create mode 100644 userland/qjs/source/quickjs-c-atomics.h create mode 100644 userland/qjs/source/quickjs-libc.c create mode 100644 userland/qjs/source/quickjs-libc.h create mode 100644 userland/qjs/source/quickjs-opcode.h create mode 100644 userland/qjs/source/quickjs.c create mode 100644 userland/qjs/source/quickjs.h create mode 100644 userland/qjs/source/repl.js create mode 100644 userland/qjs/source/run-test262.c create mode 100644 userland/qjs/source/standalone.js create mode 100644 userland/qjs/source/test262-fast.conf create mode 100644 userland/qjs/source/test262.conf create mode 100644 userland/qjs/source/test262_errors.txt create mode 100644 userland/qjs/source/tests.conf create mode 100644 userland/qjs/source/tests/array-fromasync-enumerable.js create mode 100644 userland/qjs/source/tests/array-sort-identical-values.js create mode 100644 userland/qjs/source/tests/assert.js create mode 100644 userland/qjs/source/tests/atomics-store-leak.js create mode 100644 userland/qjs/source/tests/bug1296.js create mode 100644 userland/qjs/source/tests/bug1297.js create mode 100644 userland/qjs/source/tests/bug1301.js create mode 100644 userland/qjs/source/tests/bug1302.js create mode 100644 userland/qjs/source/tests/bug1305.js create mode 100644 userland/qjs/source/tests/bug1318.js create mode 100644 userland/qjs/source/tests/bug1352.js create mode 100644 userland/qjs/source/tests/bug1354.js create mode 100644 userland/qjs/source/tests/bug1355.js create mode 100644 userland/qjs/source/tests/bug1368.js create mode 100644 userland/qjs/source/tests/bug1430.js create mode 100644 userland/qjs/source/tests/bug1468.js create mode 100644 userland/qjs/source/tests/bug1498.js create mode 100644 userland/qjs/source/tests/bug1552.js create mode 100644 userland/qjs/source/tests/bug1557.js create mode 100644 userland/qjs/source/tests/bug1562.js create mode 100644 userland/qjs/source/tests/bug1564.js create mode 100644 userland/qjs/source/tests/bug1565.js create mode 100644 userland/qjs/source/tests/bug1571.js create mode 100644 userland/qjs/source/tests/bug1572.js create mode 100644 userland/qjs/source/tests/bug1591.js create mode 100644 userland/qjs/source/tests/bug1598.js create mode 100644 userland/qjs/source/tests/bug1625.js create mode 100644 userland/qjs/source/tests/bug1626.js create mode 100644 userland/qjs/source/tests/bug1627.js create mode 100644 userland/qjs/source/tests/bug1628.js create mode 100644 userland/qjs/source/tests/bug1661.js create mode 100644 userland/qjs/source/tests/bug1672/Array.prototype.every.js create mode 100644 userland/qjs/source/tests/bug1672/Array.prototype.filter.js create mode 100644 userland/qjs/source/tests/bug1672/Array.prototype.find.js create mode 100644 userland/qjs/source/tests/bug1672/Array.prototype.findIndex.js create mode 100644 userland/qjs/source/tests/bug1672/Array.prototype.findLast.js create mode 100644 userland/qjs/source/tests/bug1672/Array.prototype.findLastIndex.js create mode 100644 userland/qjs/source/tests/bug1672/Array.prototype.forEach.js create mode 100644 userland/qjs/source/tests/bug1672/Array.prototype.includes.js create mode 100644 userland/qjs/source/tests/bug1672/Array.prototype.indexOf.js create mode 100644 userland/qjs/source/tests/bug1672/Array.prototype.lastIndexOf.js create mode 100644 userland/qjs/source/tests/bug1672/Array.prototype.map.js create mode 100644 userland/qjs/source/tests/bug1672/Array.prototype.reduce.js create mode 100644 userland/qjs/source/tests/bug1672/Array.prototype.reduceRight.js create mode 100644 userland/qjs/source/tests/bug1672/Array.prototype.some.js create mode 100644 userland/qjs/source/tests/bug1683.js create mode 100644 userland/qjs/source/tests/bug1690.js create mode 100644 userland/qjs/source/tests/bug1691.js create mode 100644 userland/qjs/source/tests/bug1693.js create mode 100644 userland/qjs/source/tests/bug1730.js create mode 100644 userland/qjs/source/tests/bug1732.js create mode 100644 userland/qjs/source/tests/bug1735.js create mode 100644 userland/qjs/source/tests/bug1795.js create mode 100644 userland/qjs/source/tests/bug1835.js create mode 100644 userland/qjs/source/tests/bug39/1.js create mode 100644 userland/qjs/source/tests/bug39/2.js create mode 100644 userland/qjs/source/tests/bug39/3.js create mode 100644 userland/qjs/source/tests/bug488-upstream.js create mode 100644 userland/qjs/source/tests/bug492.js create mode 100644 userland/qjs/source/tests/bug493.js create mode 100644 userland/qjs/source/tests/bug567.js create mode 100644 userland/qjs/source/tests/bug633/0.js create mode 100644 userland/qjs/source/tests/bug633/1.js create mode 100644 userland/qjs/source/tests/bug633/2.js create mode 100644 userland/qjs/source/tests/bug633/3.js create mode 100644 userland/qjs/source/tests/bug645/0.js create mode 100644 userland/qjs/source/tests/bug645/1.js create mode 100644 userland/qjs/source/tests/bug645/2.js create mode 100644 userland/qjs/source/tests/bug648.js create mode 100644 userland/qjs/source/tests/bug652.js create mode 100644 userland/qjs/source/tests/bug741.js create mode 100644 userland/qjs/source/tests/bug775.js create mode 100644 userland/qjs/source/tests/bug776.js create mode 100644 userland/qjs/source/tests/bug832.js create mode 100644 userland/qjs/source/tests/bug858.js create mode 100644 userland/qjs/source/tests/bug904.js create mode 100644 userland/qjs/source/tests/bug988.js create mode 100644 userland/qjs/source/tests/bug999.js create mode 100644 userland/qjs/source/tests/callsite-isconstructor.js create mode 100644 userland/qjs/source/tests/callsite-native-position.js create mode 100644 userland/qjs/source/tests/destructured-export.js create mode 100644 userland/qjs/source/tests/detect_module/0.js create mode 100644 userland/qjs/source/tests/detect_module/1.js create mode 100644 userland/qjs/source/tests/detect_module/2.js create mode 100644 userland/qjs/source/tests/detect_module/3.js create mode 100644 userland/qjs/source/tests/detect_module/4.js create mode 100644 userland/qjs/source/tests/dynamic_import_rejection_handled.js create mode 100644 userland/qjs/source/tests/empty.js create mode 100644 userland/qjs/source/tests/fix_set_array_length-uaf.js create mode 100644 userland/qjs/source/tests/fixture_cyclic_import.js create mode 100644 userland/qjs/source/tests/fixture_import_attributes.json create mode 100644 userland/qjs/source/tests/fixture_reexport_direct.js create mode 100644 userland/qjs/source/tests/fixture_reexport_missing.js create mode 100644 userland/qjs/source/tests/fixture_reexport_source.js create mode 100644 userland/qjs/source/tests/fixture_string_exports.js create mode 100644 userland/qjs/source/tests/fixture_throwing_module.js create mode 100644 userland/qjs/source/tests/for-await-normal-close.js create mode 100644 userland/qjs/source/tests/function_source.js create mode 100644 userland/qjs/source/tests/global-reference-column.js create mode 100644 userland/qjs/source/tests/import-attributes-identity.js create mode 100644 userland/qjs/source/tests/iterator-filter-leak.js create mode 100644 userland/qjs/source/tests/iterator-tostringtag-setter.js create mode 100644 userland/qjs/source/tests/microbench.js create mode 100644 userland/qjs/source/tests/null_or_undefined.js create mode 100644 userland/qjs/source/tests/parse-error-column.js create mode 100644 userland/qjs/source/tests/reexport-error-module.js create mode 100644 userland/qjs/source/tests/resize_array_buffer_index_valueOf.js create mode 100644 userland/qjs/source/tests/str-pad-leak.js create mode 100644 userland/qjs/source/tests/suspended-coroutine-closure-gc.js create mode 100644 userland/qjs/source/tests/suspended-coroutine-mapped-arguments-gc.js create mode 100644 userland/qjs/source/tests/suspended-generator-closure-gc.js create mode 100644 userland/qjs/source/tests/test_array_to_gc.js create mode 100644 userland/qjs/source/tests/test_base64.js create mode 100644 userland/qjs/source/tests/test_bigint.js create mode 100644 userland/qjs/source/tests/test_bjson.js create mode 100644 userland/qjs/source/tests/test_builtin.js create mode 100644 userland/qjs/source/tests/test_closure.js create mode 100644 userland/qjs/source/tests/test_domexception.js create mode 100644 userland/qjs/source/tests/test_dynamic_import_line_numbers.js create mode 100644 userland/qjs/source/tests/test_for_of_line_numbers.js create mode 100644 userland/qjs/source/tests/test_language.js create mode 100644 userland/qjs/source/tests/test_loop.js create mode 100644 userland/qjs/source/tests/test_queue_microtask.js create mode 100644 userland/qjs/source/tests/test_std.js create mode 100644 userland/qjs/source/tests/test_string_exports.js create mode 100644 userland/qjs/source/tests/test_worker.js create mode 100644 userland/qjs/source/tests/test_worker_module.js create mode 100644 userland/qjs/source/tests/typedarray-lastindexof-shrink.js create mode 100644 userland/qjs/source/tests/typedarray-set-invalid-index.js create mode 100644 userland/qjs/source/tests/typedarray-slice-overlap.js create mode 100644 userland/qjs/source/tests/typedarray-subarray-species.js create mode 100644 userland/qjs/source/tests/wasi-stack-limit.js create mode 100755 userland/qjs/source/unicode_download.sh create mode 100644 userland/qjs/source/unicode_gen.c create mode 100644 userland/qjs/source/unicode_gen_def.h create mode 100755 userland/qjs/source/update-version.sh create mode 100644 userland/tools.json diff --git a/AGENTS.md b/AGENTS.md index 2cd5575..319a320 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -56,7 +56,13 @@ nix develop -c nu userland/bundle.nu nix develop -c cargo build -p git --target wasm32-wasip2 --release ``` -`nix flake check` checks the packaged host, its bundle, and sandbox-compatible tests. +`nix build` uses separate Crane pipelines for the native host and WASI userland. +Go tools and QuickJS build separately. Nix assembles the bundle without `bundle.nu`. +Both Nix and the incremental development bundle read the command names from `userland/tools.json`. +Coreutils, diffutils, procps, and brush use relative symlinks to one binary each. + +`nix flake check` checks the packaged host, its bundle, and the whole host/VFS test suite. +Sandbox-incompatible tests print an explicit skip reason instead of a flake-level filter. ## Tests diff --git a/docs/RUNNING.md b/docs/RUNNING.md index 4c4e4fe..30295b8 100644 --- a/docs/RUNNING.md +++ b/docs/RUNNING.md @@ -9,7 +9,14 @@ Keep the complete world folder between starts. ## Build and start Run host commands from a checkout of the `v3` branch on Citadel. -Use Nix with flakes. The package supplies the native Rust builder and its tools. +Use Nix with flakes and the `pipe-operators` experimental feature. +The package supplies the native Rust builder and its tools. + +`nix build` builds the host and userland through separate Crane pipelines. +The userland pipeline targets `wasm32-wasip2`. +Separate Go derivations build awk and esbuild for WASI preview1. +QuickJS builds from its vendored C sources with WASI clang. +Nix assembles the final bundle without the development bundle script. The package entry point is: @@ -30,11 +37,15 @@ The source-tree bundle builder is: nix develop -c nu userland/bundle.nu ``` -It builds the world commands and creates `target/userland/bundle` by default. -It snapshots committed source, not uncommitted edits. +It builds the world commands incrementally with the configured Cargo cache. +Pass a destination to place the bundle under your shared executor target directory. +The script snapshots the current source files, including uncommitted edits. The source archive includes the complete `config/`, `skills/`, and `extensions/` directories. The bundle contains plain source files. `sausage init` creates their repository and its first commit on `main`. -The world copier preserves symlinks, including dangling links in the source tree. +Both bundle builders read `userland/tools.json` for the package and command names. +Coreutils, diffutils, procps, and brush each occupy one real binary in `bin/`. +Their command names are relative symlinks to those binaries. +The world copier preserves these symlinks and dangling links in the source tree. A fresh development world needs no manual source copy. The bundle includes `/bin/web.wasm` and an enabled `/etc/systemd/system/web.service`. World init starts that service on `0.0.0.0:8080`. diff --git a/flake.nix b/flake.nix index d5aea4f..2fc82a8 100644 --- a/flake.nix +++ b/flake.nix @@ -15,18 +15,22 @@ flake-utils.lib.eachSystem flake-utils.lib.allSystems (system: let pkgs = import nixpkgs { inherit system; overlays = [ rust-overlay.overlays.default ]; }; + inherit (pkgs) lib; rust = pkgs.rust-bin.stable.latest.default.override { targets = [ "wasm32-wasip2" ]; extensions = [ "rust-src" ]; }; craneLib = (crane.mkLib pkgs).overrideToolchain rust; - src = pkgs.nix-gitignore.gitignoreSource [] ./.; - mold = pkgs.lib.optionals pkgs.stdenv.hostPlatform.isLinux [ pkgs.mold ]; - hostTarget = pkgs.lib.toUpper (builtins.replaceStrings [ "-" ] [ "_" ] pkgs.stdenv.hostPlatform.rust.rustcTarget); + src = ./. |> pkgs.nix-gitignore.gitignoreSource []; + tools = ./userland/tools.json |> builtins.readFile |> builtins.fromJSON; + commandArgs = tools |> builtins.filter (t: t.package != null) + |> map (t: t.package) |> lib.unique |> map (p: "-p ${p}") |> lib.concatStringsSep " "; + mold = lib.optionals pkgs.stdenv.hostPlatform.isLinux [ pkgs.mold ]; + hostTarget = pkgs.stdenv.hostPlatform.rust.rustcTarget |> builtins.replaceStrings [ "-" ] [ "_" ] |> lib.toUpper; moldVar = "CARGO_TARGET_${hostTarget}_RUSTFLAGS"; - moldEnv = pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux { ${moldVar} = "-C link-arg=-fuse-ld=mold"; }; + moldEnv = lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux { ${moldVar} = "-C link-arg=-fuse-ld=mold"; }; builderTools = [ kache.packages.${system}.default pkgs.bubblewrap pkgs.nushell pkgs.wasm-tools pkgs.bash pkgs.coreutils ]; - runtimePath = pkgs.lib.makeBinPath ([ rust pkgs.stdenv.cc ] ++ builderTools ++ mold); + runtimePath = [ rust pkgs.stdenv.cc ] ++ builderTools ++ mold |> lib.makeBinPath; wasiCc = pkgs.pkgsCross.wasi32.stdenv.cc; wasiCcEnv = { CC_wasm32_wasip2 = "${wasiCc}/bin/${wasiCc.targetPrefix}cc"; @@ -41,7 +45,7 @@ aarch64-darwin = "sha256-Wu/9jVoMG3msHXCvg9WxkJllX9nGRaeU3EPxAfd5g4w="; }.${system}; }; - # rusty_v8's documented archive hook prevents downloads inside the Nix sandbox. + # rusty_v8's archive hook prevents downloads inside the Nix sandbox. v8Env = { RUSTY_V8_ARCHIVE = v8Archive; }; cwdInit = pkgs.runCommand "sausage-cwd-init" { nativeBuildInputs = [ rust pkgs.nushell pkgs.wasm-tools ]; } '' cp -r ${./userland/cwd-init} cwd-init @@ -50,60 +54,93 @@ mkdir $out cp cwd-init/init.o $out/ ''; - linker = pkgs.writeScript "sausage-wasi-link.nu" ("#!${pkgs.nushell}/bin/nu\n" + builtins.readFile ./userland/cwd-init/link.nu); - members = (builtins.fromTOML (builtins.readFile ./Cargo.toml)).workspace.members; - commands = builtins.filter (p: pkgs.lib.hasPrefix "userland/" p && !(pkgs.lib.hasPrefix "userland/brush/" p)) members; - commandArgs = pkgs.lib.concatMapStringsSep " " (p: "-p " + (builtins.fromTOML (builtins.readFile (./. + "/${p}/Cargo.toml"))).package.name) commands; + linker = pkgs.runCommand "sausage-wasi-link" { nativeBuildInputs = [ pkgs.nushell ]; } '' + cp ${./userland/cwd-init/link.nu} $out + chmod +x $out + patchShebangs $out + ''; common = { pname = "sausage"; version = "0.3.0"; inherit src; strictDeps = true; - buildInputs = [ pkgs.openssl ]; - nativeBuildInputs = [ pkgs.pkg-config pkgs.cmake pkgs.python3 pkgs.perl pkgs.nushell pkgs.wasm-tools pkgs.go ] ++ mold; + nativeBuildInputs = [ pkgs.pkg-config pkgs.cmake pkgs.python3 pkgs.perl pkgs.nushell pkgs.wasm-tools ]; + # The WASI linker initializes each guest's cwd before main. SAUSAGE_CWD_INIT = "${cwdInit}/init.o"; CARGO_TARGET_WASM32_WASIP2_LINKER = linker; CARGO_TARGET_WASM32_WASIP2_RUSTFLAGS = "-C link-arg=sausage-cwd-init"; - GOTOOLCHAIN = "local"; - } // v8Env // wasiCcEnv // moldEnv; - cargoArtifacts = craneLib.buildDepsOnly (common // { # Registry gix crates need the real APIs of the local WASI patches. extraDummyScript = '' chmod -R u+w $out/userland/git/vendor cp -r ${./userland/git/vendor}/. $out/userland/git/vendor/ ''; - buildPhaseCargoCommand = '' - cargoWithProfile build --locked -p sausage -p sausage-vfs - cargoWithProfile build --locked --target wasm32-wasip2 ${commandArgs} - cargoWithProfile build --locked --target wasm32-wasip2 -p brush-shell --no-default-features --features minimal,tokio/time - ''; - doCheck = false; - }); - userland = craneLib.mkCargoDerivation (common // { - inherit cargoArtifacts; - pname = "sausage-userland"; - preBuild = '' - export CARGO_TARGET_DIR="$PWD/target" - export GOCACHE="$TMPDIR/go-cache" - ''; - buildPhaseCargoCommand = "nu userland/bundle.nu"; - doCheck = false; - installPhaseCommand = '' - mkdir -p $out - cp -a target/userland/bundle/. $out/ - test -f $out/bin/web.wasm - test -f $out/srv/www/index.html - test -f $out/etc/systemd/system/web.service - test -f $out/etc/systemd/system/multi-user.target.wants/web.service - ''; - doInstallCargoArtifacts = false; - dontCheckForBrokenSymlinks = true; - }); - sausageUnwrapped = craneLib.buildPackage (common // { - inherit cargoArtifacts; - doNotRemoveReferencesToVendorDir = true; + } // wasiCcEnv; + hostArgs = common // v8Env // moldEnv // { cargoExtraArgs = "--locked -p sausage"; + buildInputs = [ pkgs.openssl ]; + nativeBuildInputs = common.nativeBuildInputs ++ mold; doCheck = false; + }; + hostArtifacts = craneLib.buildDepsOnly hostArgs; + userlandArgs = common // { + pname = "sausage-userland"; + CARGO_BUILD_TARGET = "wasm32-wasip2"; + cargoExtraArgs = "--locked ${commandArgs}"; + doCheck = false; + }; + userlandArtifacts = craneLib.buildDepsOnly userlandArgs; + userland = craneLib.buildPackage (userlandArgs // { cargoArtifacts = userlandArtifacts; }); + goTool = name: source: subPackages: + (pkgs.buildGoModule { + pname = "sausage-${name}"; + version = "vendored"; + src = source; + inherit subPackages; + vendorHash = null; + env.CGO_ENABLED = "0"; + ldflags = [ "-s" "-w" ]; + doCheck = false; + dontStrip = true; + postInstall = '' + mv $out/bin/wasip1_wasm/* $out/bin/${name}.wasm + rmdir $out/bin/wasip1_wasm + ''; + }).overrideAttrs (old: { env = old.env // { GOOS = "wasip1"; GOARCH = "wasm"; }; }); + awk = goTool "awk" ./userland/goawk/source [ "." ]; + esbuild = goTool "esbuild" ./userland/esbuild/source [ "cmd/esbuild" ]; + qjs = pkgs.stdenv.mkDerivation { + pname = "sausage-qjs"; + version = "0.18.0"; + src = ./userland/qjs/source; + nativeBuildInputs = [ pkgs.cmake pkgs.llvmPackages_21.lld ]; + cmakeFlags = [ "-DCMAKE_SYSTEM_NAME=WASI" "-DCMAKE_C_COMPILER=${wasiCcEnv.CC_wasm32_wasip2}" "-DCMAKE_AR=${wasiCcEnv.AR_wasm32_wasip2}" "-DCMAKE_RANLIB=${wasiCc}/bin/${wasiCc.targetPrefix}ranlib" ]; + buildFlags = [ "qjs_exe" ]; + installPhase = '' + runHook preInstall + mkdir -p $out/bin + cp qjs $out/bin/qjs.wasm + runHook postInstall + ''; + dontStrip = true; + }; + bundle = pkgs.runCommand "sausage-bundle" {} '' + mkdir -p $out/bin $out/src/sausage $out/etc/sausage $out/etc/systemd/system/multi-user.target.wants $out/srv/www + ${tools |> map (t: '' + cp ${(if t.package != null then userland else { inherit awk esbuild qjs; }.${t.binary})}/bin/${t.binary}.wasm $out/bin/ + ${t.names |> map (name: '' + ${lib.optionalString (name != t.binary) "ln -s ${t.binary}.wasm $out/bin/${name}.wasm"} + ln -s ${t.binary}.wasm $out/bin/${name} + '') |> lib.concatStrings} + '') |> lib.concatStrings} + cp -R --no-preserve=mode ${src}/. $out/src/sausage/ + cp ${./config/config.yaml} $out/etc/sausage/config.yaml + cp ${./userland/web/web.service} $out/etc/systemd/system/web.service + touch $out/etc/systemd/system/multi-user.target.wants/web.service + cp ${./userland/web/index.html} ${./userland/web/credentials.js} ${./userland/web/credentials-view.js} $out/srv/www/ + ''; + sausageUnwrapped = craneLib.buildPackage (hostArgs // { + cargoArtifacts = hostArtifacts; + doNotRemoveReferencesToVendorDir = true; }); # Keep the wrapper separate from crane's removal of toolchain references. sausage = pkgs.symlinkJoin { @@ -111,40 +148,35 @@ paths = [ sausageUnwrapped ]; nativeBuildInputs = [ pkgs.makeWrapper ]; postBuild = '' - wrapProgram $out/bin/sausage --set-default SAUSAGE_USERLAND ${userland} \ + wrapProgram $out/bin/sausage --set-default SAUSAGE_USERLAND ${bundle} \ --prefix PATH : ${runtimePath} \ --set-default CC_wasm32_wasip2 ${wasiCcEnv.CC_wasm32_wasip2} \ --set-default AR_wasm32_wasip2 ${wasiCcEnv.AR_wasm32_wasip2} \ - ${pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isLinux "--set-default ${moldVar} '-C link-arg=-fuse-ld=mold'"} + ${lib.optionalString pkgs.stdenv.hostPlatform.isLinux "--set-default ${moldVar} '-C link-arg=-fuse-ld=mold'"} ''; meta.mainProgram = "sausage"; }; in { - packages.default = sausage; + packages = { default = sausage; inherit bundle userland awk esbuild qjs; }; checks.package = sausage; - checks.tests = craneLib.mkCargoDerivation (common // { - inherit cargoArtifacts; - pnameSuffix = "-test"; - nativeBuildInputs = common.nativeBuildInputs ++ [ pkgs.git ]; + checks.tests = craneLib.cargoTest (hostArgs // { + cargoArtifacts = hostArtifacts; + cargoExtraArgs = "--locked -p sausage -p sausage-vfs"; + cargoTestExtraArgs = "-- --nocapture"; doCheck = true; - buildPhaseCargoCommand = ""; - checkPhaseCargoCommand = '' - cargoWithProfile test --locked -p sausage -p sausage-vfs --lib - cargoWithProfile test --locked -p sausage --test it -- harness:: p1:: durable:: cred:: cred_ --skip undo_harness:: - cargoWithProfile test --locked -p sausage-vfs --test layers --test regressions --test streams --test wasi - ''; + nativeBuildInputs = hostArgs.nativeBuildInputs ++ [ pkgs.git ]; + SAUSAGE_TEST_NO_BUILDER_SANDBOX = "1"; + SAUSAGE_USERLAND = bundle; preCheck = '' - export SAUSAGE_USERLAND="${userland}" export SAUSAGE_CACHE="$TMPDIR/sausage-cache" export CARGO_TARGET_DIR="$PWD/target" export RUST_BACKTRACE=1 mkdir -p target/userland - ln -s ${userland} target/bundle - ln -s ${userland} target/userland/bundle + ln -s ${bundle} target/bundle + ln -s ${bundle} target/userland/bundle ''; - doInstallCargoArtifacts = false; }); - checks.shell = pkgs.runCommand "sausage-shell" { } '' + checks.shell = pkgs.runCommand "sausage-shell" {} '' export SAUSAGE_CACHE="$TMPDIR/sausage-cache" ${sausage}/bin/sausage sh "$TMPDIR/world" -c \ 'set -e; echo hi | tr a-z A-Z; git --version; rg --version; awk "BEGIN {print 42}"; echo payload > /payload; tar -cf /test.tar /payload; tar -tf /test.tar; qjs -e "console.log(42)"; box --help; cargo --help; undo list' > output @@ -159,7 +191,7 @@ ''; apps.default = { type = "app"; program = "${sausage}/bin/sausage"; }; devShells.default = pkgs.mkShell (v8Env // wasiCcEnv // moldEnv // { - packages = [ rust pkgs.wasmtime pkgs.openssl pkgs.pkg-config ] ++ builderTools ++ mold; + packages = [ rust pkgs.wasmtime pkgs.openssl pkgs.pkg-config pkgs.go pkgs.cmake pkgs.llvmPackages_21.lld ] ++ builderTools ++ mold; }); }); } diff --git a/host/tests/it/p1.rs b/host/tests/it/p1.rs index 9df2813..eafe70b 100644 --- a/host/tests/it/p1.rs +++ b/host/tests/it/p1.rs @@ -78,15 +78,24 @@ async fn bundle_copy_and_real_shell() -> anyhow::Result<()> { for entry in std::fs::read_dir(dir.path().join("world/bin"))? { let entry = entry?; if entry.file_type()?.is_symlink() { - assert_eq!( - std::fs::read_link(entry.path())?, - PathBuf::from(format!("{}.wasm", entry.file_name().to_string_lossy())) - ); + let target = std::fs::read_link(entry.path())?; + assert_eq!(target.components().count(), 1, "{target:?}"); + assert_eq!(target.extension().unwrap(), "wasm"); + assert!(std::fs::symlink_metadata(entry.path().parent().unwrap().join(target))?.is_file()); } else { assert_eq!(entry.path().extension().unwrap(), "wasm"); assert_eq!(entry.metadata()?.nlink(), 1); } } + let tools: Vec = serde_json::from_str(include_str!("../../../userland/tools.json"))?; + for tool in tools { + let binary = format!("{}.wasm", tool["binary"].as_str().unwrap()); + let bin = dir.path().join("world/bin"); + assert!(std::fs::symlink_metadata(bin.join(&binary))?.is_file()); + for name in tool["names"].as_array().unwrap() { + assert_eq!(std::fs::read_link(bin.join(name.as_str().unwrap()))?, PathBuf::from(&binary)); + } + } assert!(world.root.stat("/usr/local/bin", true).await?.directory); let writable = world .root @@ -244,12 +253,16 @@ async fn bundle_copy_and_real_shell() -> anyhow::Result<()> { let expected: String = (1..=10000).map(|n| format!("{n}\n")).collect(); assert_eq!(actual, expected); let source_cat = std::fs::read(bundle.join("bin/cat.wasm"))?; + std::fs::write( + dir.path().join("world/bin/replacement.wasm"), + wat::parse_str(r#"(module (memory (export "memory") 1) (func (export "_start")))"#)?, + )?; let head = std::fs::read(dir.path().join("world/bin/head.wasm"))?; let mut out = Vec::new(); assert_eq!( exec.exec( Command::Shell( - "cp /bin/true.wasm /bin/cat.wasm; cat /test.txt; head -n 1 /test.txt".into() + "rm /bin/cat /bin/cat.wasm; cp /bin/replacement.wasm /bin/cat.wasm; ln -s cat.wasm /bin/cat; cat /test.txt; head -n 1 /test.txt".into() ), Options::default(), &mut |stream, bytes| { @@ -266,7 +279,7 @@ async fn bundle_copy_and_real_shell() -> anyhow::Result<()> { assert_eq!(std::fs::read(dir.path().join("world/bin/head.wasm"))?, head); assert_eq!( exec.exec( - Command::Shell("cp /bin/true.wasm /usr/local/bin/head.wasm; head /test.txt".into()), + Command::Shell("cp /bin/replacement.wasm /usr/local/bin/head.wasm; head /test.txt".into()), Options::default(), &mut |_, bytes| assert!(bytes.is_empty()) ) diff --git a/host/tests/packaged-builder.nu b/host/tests/packaged-builder.nu index e4e6e39..9c5e589 100644 --- a/host/tests/packaged-builder.nu +++ b/host/tests/packaged-builder.nu @@ -10,20 +10,29 @@ def main [host: path = 'result/bin/sausage'] { print --stderr --no-newline $initialized.stderr if $initialized.exit_code != 0 { error make {msg: 'packaged host init failed'} } let script = r#'set -e +/bin/printf 'coreutils OK\n' +printf 'same\n' > /same +cmp /same /same +diff /same /same +ps | grep -q PID +sh -c 'echo sh OK' +bash -c 'echo bash OK' +qjs -e 'console.log("qjs source OK")' mkdir -p /src/projects cd /src/projects cargo new packaged-probe --vcs none printf 'fn main() { println!("packaged builder OK"); }\n' > packaged-probe/src/main.rs cd packaged-probe -cargo build --release -./target/wasm32-wasip2/release/packaged-probe.wasm +cargo run --release '# let result = (^$host sh $world -c $script | complete) print --no-newline $result.stdout print --stderr --no-newline $result.stderr if $result.exit_code != 0 { error make {msg: 'packaged builder failed'} } - if not ($result.stdout | lines | any {|line| $line == 'packaged builder OK' }) { - error make {msg: 'compiled program did not produce its expected output'} + for expected in ['coreutils OK' 'sh OK' 'bash OK' 'qjs source OK' 'packaged builder OK'] { + if not ($result.stdout | lines | any {|line| $line == $expected }) { + error make {msg: $'packaged check did not print: ($expected)'} + } } rm --recursive --force $temporary print 'Packaged builder check passed.' diff --git a/userland/brush/source/brush-shell/Cargo.toml b/userland/brush/source/brush-shell/Cargo.toml index 7502ae3..74c1bdd 100644 --- a/userland/brush/source/brush-shell/Cargo.toml +++ b/userland/brush/source/brush-shell/Cargo.toml @@ -67,7 +67,7 @@ harness = false [features] # Input backends. Each can be enabled for any target, and is offered where it # works (see `build.rs`), so the defaults suit every target. -default = ["basic", "reedline", "minimal", "vt"] +default = ["minimal", "tokio/time"] basic = ["brush-interactive/basic"] minimal = ["brush-interactive/minimal"] reedline = ["brush-interactive/reedline"] diff --git a/userland/bundle.nu b/userland/bundle.nu index 3034d80..4f70166 100644 --- a/userland/bundle.nu +++ b/userland/bundle.nu @@ -1,5 +1,5 @@ #!/usr/bin/env nu -# Build independent commands and plain source files. World creation initializes their repository. +# Build the shared tool list incrementally and copy plain sources for world initialization. def main [destination?: path] { let here = ($env.FILE_PWD | path expand) let destination = ($destination | default ($here | path join .. target userland bundle) | path expand) @@ -12,32 +12,29 @@ def main [destination?: path] { } let manifest = ($here | path join .. Cargo.toml) let metadata = (^cargo metadata --manifest-path $manifest --no-deps --format-version 1 | from json) - let packages = ($metadata.packages | where {|p| - ($p.id in $metadata.workspace_members) and ($p.manifest_path | str starts-with $here) and not ($p.manifest_path | str starts-with ($here | path join brush source)) - }) - let arguments = ($packages | where {|p| $p.targets | any {|t| 'bin' in $t.kind } } | each {|p| ['-p' $p.name] } | flatten) + let tools = (open ($here | path join tools.json)) + let packages = ($tools | where package != null | get package | uniq) + let arguments = ($packages | each {|p| ['-p' $p] } | flatten) do { cd $here; ^cargo build --manifest-path $manifest --release --locked --target wasm32-wasip2 ...$arguments } if $env.LAST_EXIT_CODE != 0 { error make {msg: 'userland build failed'} } - ^nu ($here | path join brush build.nu) - if $env.LAST_EXIT_CODE != 0 { error make {msg: 'brush build failed'} } + if ($bin | path exists) { rm --recursive --force $bin } mkdir $bin ^nu ($here | path join preview1.nu) $bin if $env.LAST_EXIT_CODE != 0 { error make {msg: 'preview1 build failed'} } - for package in $packages { - let tools = ($package.manifest_path | path dirname | path join tools.txt) - for binary in ($package.targets | where {|t| 'bin' in $t.kind }) { - let source = ($metadata.target_directory | path join wasm32-wasip2 release $'($binary.name).wasm') - let names = if ($tools | path exists) { open --raw $tools | lines | where {|s| ($s | str trim) != '' } } else { [$binary.name] } - for name in $names { - ^cp --remove-destination $source ($bin | path join $'($name).wasm') - if $env.LAST_EXIT_CODE != 0 { error make {msg: $'bundle copy failed: ($name)'} } - } - } + for tool in ($tools | where package != null) { + let source = ($metadata.target_directory | path join wasm32-wasip2 release $'($tool.binary).wasm') + ^cp --remove-destination $source ($bin | path join $'($tool.binary).wasm') + if $env.LAST_EXIT_CODE != 0 { error make {msg: $'bundle copy failed: ($tool.binary)'} } } - let brush = ($metadata.target_directory | path join wasm32-wasip2 release brush.wasm) - for name in [sh bash] { - ^cp --remove-destination $brush ($bin | path join $'($name).wasm') - if $env.LAST_EXIT_CODE != 0 { error make {msg: 'brush copy failed'} } + for tool in $tools { + for name in $tool.names { + if $name != $tool.binary { + ^ln -s $'($tool.binary).wasm' ($bin | path join $'($name).wasm') + if $env.LAST_EXIT_CODE != 0 { error make {msg: $'tool alias failed: ($name).wasm'} } + } + ^ln -s $'($tool.binary).wasm' ($bin | path join $name) + if $env.LAST_EXIT_CODE != 0 { error make {msg: $'tool alias failed: ($name)'} } + } } let units = ($destination | path join etc systemd system) mkdir ($units | path join multi-user.target.wants) diff --git a/userland/coreutils/Cargo.toml b/userland/coreutils/Cargo.toml index 8471e58..2bb5358 100644 --- a/userland/coreutils/Cargo.toml +++ b/userland/coreutils/Cargo.toml @@ -2,6 +2,11 @@ name = "sausage-coreutils" version = "0.1.0" edition = "2024" +autobins = false + +[[bin]] +name = "coreutils" +path = "src/main.rs" [dependencies] rustix = { version = "1.1.6", features = ["std"] } diff --git a/userland/coreutils/src/bin/arch.rs b/userland/coreutils/src/bin/arch.rs deleted file mode 100644 index f682a17..0000000 --- a/userland/coreutils/src/bin/arch.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the arch command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("arch").expect("utility supplies localization"); - std::process::exit(uu_arch::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/b2sum.rs b/userland/coreutils/src/bin/b2sum.rs deleted file mode 100644 index d21bbd5..0000000 --- a/userland/coreutils/src/bin/b2sum.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the b2sum command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("b2sum").expect("utility supplies localization"); - std::process::exit(uu_b2sum::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/base32.rs b/userland/coreutils/src/bin/base32.rs deleted file mode 100644 index 4a0c434..0000000 --- a/userland/coreutils/src/bin/base32.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the base32 command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("base32").expect("utility supplies localization"); - std::process::exit(uu_base32::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/base64.rs b/userland/coreutils/src/bin/base64.rs deleted file mode 100644 index 79e0ce9..0000000 --- a/userland/coreutils/src/bin/base64.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the base64 command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("base64").expect("utility supplies localization"); - std::process::exit(uu_base64::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/basename.rs b/userland/coreutils/src/bin/basename.rs deleted file mode 100644 index 234fc0a..0000000 --- a/userland/coreutils/src/bin/basename.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the basename command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("basename").expect("utility supplies localization"); - std::process::exit(uu_basename::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/basenc.rs b/userland/coreutils/src/bin/basenc.rs deleted file mode 100644 index 05c22fb..0000000 --- a/userland/coreutils/src/bin/basenc.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the basenc command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("basenc").expect("utility supplies localization"); - std::process::exit(uu_basenc::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/cat.rs b/userland/coreutils/src/bin/cat.rs deleted file mode 100644 index 0f4ff1b..0000000 --- a/userland/coreutils/src/bin/cat.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the cat command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("cat").expect("utility supplies localization"); - std::process::exit(uu_cat::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/cksum.rs b/userland/coreutils/src/bin/cksum.rs deleted file mode 100644 index 58294cd..0000000 --- a/userland/coreutils/src/bin/cksum.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the cksum command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("cksum").expect("utility supplies localization"); - std::process::exit(uu_cksum::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/comm.rs b/userland/coreutils/src/bin/comm.rs deleted file mode 100644 index 51ef1e5..0000000 --- a/userland/coreutils/src/bin/comm.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the comm command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("comm").expect("utility supplies localization"); - std::process::exit(uu_comm::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/cp.rs b/userland/coreutils/src/bin/cp.rs deleted file mode 100644 index c320dd0..0000000 --- a/userland/coreutils/src/bin/cp.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the cp command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("cp").expect("utility supplies localization"); - std::process::exit(uu_cp::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/csplit.rs b/userland/coreutils/src/bin/csplit.rs deleted file mode 100644 index 8d24215..0000000 --- a/userland/coreutils/src/bin/csplit.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the csplit command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("csplit").expect("utility supplies localization"); - std::process::exit(uu_csplit::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/cut.rs b/userland/coreutils/src/bin/cut.rs deleted file mode 100644 index bc1dbf4..0000000 --- a/userland/coreutils/src/bin/cut.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the cut command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("cut").expect("utility supplies localization"); - std::process::exit(uu_cut::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/date.rs b/userland/coreutils/src/bin/date.rs deleted file mode 100644 index 7f95526..0000000 --- a/userland/coreutils/src/bin/date.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the date command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("date").expect("utility supplies localization"); - std::process::exit(uu_date::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/dd.rs b/userland/coreutils/src/bin/dd.rs deleted file mode 100644 index 1475ca2..0000000 --- a/userland/coreutils/src/bin/dd.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the dd command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("dd").expect("utility supplies localization"); - std::process::exit(uu_dd::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/dir.rs b/userland/coreutils/src/bin/dir.rs deleted file mode 100644 index 76c0d22..0000000 --- a/userland/coreutils/src/bin/dir.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the dir command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("ls").expect("utility supplies localization"); - std::process::exit(uu_dir::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/dircolors.rs b/userland/coreutils/src/bin/dircolors.rs deleted file mode 100644 index aaa7527..0000000 --- a/userland/coreutils/src/bin/dircolors.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the dircolors command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("dircolors").expect("utility supplies localization"); - std::process::exit(uu_dircolors::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/dirname.rs b/userland/coreutils/src/bin/dirname.rs deleted file mode 100644 index 3fe4ff4..0000000 --- a/userland/coreutils/src/bin/dirname.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the dirname command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("dirname").expect("utility supplies localization"); - std::process::exit(uu_dirname::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/echo.rs b/userland/coreutils/src/bin/echo.rs deleted file mode 100644 index dd479b5..0000000 --- a/userland/coreutils/src/bin/echo.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the echo command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("echo").expect("utility supplies localization"); - std::process::exit(uu_echo::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/expand.rs b/userland/coreutils/src/bin/expand.rs deleted file mode 100644 index 3e0b0ca..0000000 --- a/userland/coreutils/src/bin/expand.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the expand command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("expand").expect("utility supplies localization"); - std::process::exit(uu_expand::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/expr.rs b/userland/coreutils/src/bin/expr.rs deleted file mode 100644 index 001ec55..0000000 --- a/userland/coreutils/src/bin/expr.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the expr command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("expr").expect("utility supplies localization"); - std::process::exit(uu_expr::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/factor.rs b/userland/coreutils/src/bin/factor.rs deleted file mode 100644 index 71cd796..0000000 --- a/userland/coreutils/src/bin/factor.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the factor command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("factor").expect("utility supplies localization"); - std::process::exit(uu_factor::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/false.rs b/userland/coreutils/src/bin/false.rs deleted file mode 100644 index cf3a464..0000000 --- a/userland/coreutils/src/bin/false.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the false command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("false").expect("utility supplies localization"); - std::process::exit(uu_false::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/fmt.rs b/userland/coreutils/src/bin/fmt.rs deleted file mode 100644 index ad6d2ac..0000000 --- a/userland/coreutils/src/bin/fmt.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the fmt command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("fmt").expect("utility supplies localization"); - std::process::exit(uu_fmt::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/fold.rs b/userland/coreutils/src/bin/fold.rs deleted file mode 100644 index caa0eb5..0000000 --- a/userland/coreutils/src/bin/fold.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the fold command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("fold").expect("utility supplies localization"); - std::process::exit(uu_fold::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/head.rs b/userland/coreutils/src/bin/head.rs deleted file mode 100644 index eb0fbf4..0000000 --- a/userland/coreutils/src/bin/head.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the head command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("head").expect("utility supplies localization"); - std::process::exit(uu_head::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/hostid.rs b/userland/coreutils/src/bin/hostid.rs deleted file mode 100644 index 4966820..0000000 --- a/userland/coreutils/src/bin/hostid.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the hostid command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("hostid").expect("utility supplies localization"); - std::process::exit(uu_hostid::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/join.rs b/userland/coreutils/src/bin/join.rs deleted file mode 100644 index 3831cc4..0000000 --- a/userland/coreutils/src/bin/join.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the join command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("join").expect("utility supplies localization"); - std::process::exit(uu_join::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/link.rs b/userland/coreutils/src/bin/link.rs deleted file mode 100644 index 956480f..0000000 --- a/userland/coreutils/src/bin/link.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the link command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("link").expect("utility supplies localization"); - std::process::exit(uu_link::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/ln.rs b/userland/coreutils/src/bin/ln.rs deleted file mode 100644 index c893121..0000000 --- a/userland/coreutils/src/bin/ln.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the ln command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("ln").expect("utility supplies localization"); - std::process::exit(uu_ln::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/ls.rs b/userland/coreutils/src/bin/ls.rs deleted file mode 100644 index 5545e9e..0000000 --- a/userland/coreutils/src/bin/ls.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the ls command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("ls").expect("utility supplies localization"); - std::process::exit(uu_ls::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/md5sum.rs b/userland/coreutils/src/bin/md5sum.rs deleted file mode 100644 index 735797e..0000000 --- a/userland/coreutils/src/bin/md5sum.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the md5sum command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("md5sum").expect("utility supplies localization"); - std::process::exit(uu_md5sum::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/mkdir.rs b/userland/coreutils/src/bin/mkdir.rs deleted file mode 100644 index c2f8923..0000000 --- a/userland/coreutils/src/bin/mkdir.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the mkdir command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("mkdir").expect("utility supplies localization"); - std::process::exit(uu_mkdir::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/mktemp.rs b/userland/coreutils/src/bin/mktemp.rs deleted file mode 100644 index 71e0781..0000000 --- a/userland/coreutils/src/bin/mktemp.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the mktemp command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("mktemp").expect("utility supplies localization"); - std::process::exit(uu_mktemp::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/mv.rs b/userland/coreutils/src/bin/mv.rs deleted file mode 100644 index f62bfb1..0000000 --- a/userland/coreutils/src/bin/mv.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the mv command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("mv").expect("utility supplies localization"); - std::process::exit(uu_mv::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/nice.rs b/userland/coreutils/src/bin/nice.rs deleted file mode 100644 index b31f52d..0000000 --- a/userland/coreutils/src/bin/nice.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the nice command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("nice").expect("utility supplies localization"); - std::process::exit(uu_nice::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/nl.rs b/userland/coreutils/src/bin/nl.rs deleted file mode 100644 index 0a50d3c..0000000 --- a/userland/coreutils/src/bin/nl.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the nl command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("nl").expect("utility supplies localization"); - std::process::exit(uu_nl::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/nproc.rs b/userland/coreutils/src/bin/nproc.rs deleted file mode 100644 index fcc81f2..0000000 --- a/userland/coreutils/src/bin/nproc.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the nproc command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("nproc").expect("utility supplies localization"); - std::process::exit(uu_nproc::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/numfmt.rs b/userland/coreutils/src/bin/numfmt.rs deleted file mode 100644 index 07829ae..0000000 --- a/userland/coreutils/src/bin/numfmt.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the numfmt command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("numfmt").expect("utility supplies localization"); - std::process::exit(uu_numfmt::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/od.rs b/userland/coreutils/src/bin/od.rs deleted file mode 100644 index cab0501..0000000 --- a/userland/coreutils/src/bin/od.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the od command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("od").expect("utility supplies localization"); - std::process::exit(uu_od::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/paste.rs b/userland/coreutils/src/bin/paste.rs deleted file mode 100644 index 17559db..0000000 --- a/userland/coreutils/src/bin/paste.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the paste command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("paste").expect("utility supplies localization"); - std::process::exit(uu_paste::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/pathchk.rs b/userland/coreutils/src/bin/pathchk.rs deleted file mode 100644 index 0a919d9..0000000 --- a/userland/coreutils/src/bin/pathchk.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the pathchk command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("pathchk").expect("utility supplies localization"); - std::process::exit(uu_pathchk::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/pr.rs b/userland/coreutils/src/bin/pr.rs deleted file mode 100644 index 0ca52d0..0000000 --- a/userland/coreutils/src/bin/pr.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the pr command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("pr").expect("utility supplies localization"); - std::process::exit(uu_pr::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/printenv.rs b/userland/coreutils/src/bin/printenv.rs deleted file mode 100644 index a3f3800..0000000 --- a/userland/coreutils/src/bin/printenv.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the printenv command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("printenv").expect("utility supplies localization"); - std::process::exit(uu_printenv::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/printf.rs b/userland/coreutils/src/bin/printf.rs deleted file mode 100644 index 720c8a7..0000000 --- a/userland/coreutils/src/bin/printf.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the printf command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("printf").expect("utility supplies localization"); - std::process::exit(uu_printf::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/ptx.rs b/userland/coreutils/src/bin/ptx.rs deleted file mode 100644 index a5d7fa7..0000000 --- a/userland/coreutils/src/bin/ptx.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the ptx command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("ptx").expect("utility supplies localization"); - std::process::exit(uu_ptx::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/pwd.rs b/userland/coreutils/src/bin/pwd.rs deleted file mode 100644 index c62049f..0000000 --- a/userland/coreutils/src/bin/pwd.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the pwd command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("pwd").expect("utility supplies localization"); - std::process::exit(uu_pwd::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/readlink.rs b/userland/coreutils/src/bin/readlink.rs deleted file mode 100644 index 5fb109b..0000000 --- a/userland/coreutils/src/bin/readlink.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the readlink command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("readlink").expect("utility supplies localization"); - std::process::exit(uu_readlink::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/realpath.rs b/userland/coreutils/src/bin/realpath.rs deleted file mode 100644 index fb4e428..0000000 --- a/userland/coreutils/src/bin/realpath.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the realpath command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("realpath").expect("utility supplies localization"); - std::process::exit(uu_realpath::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/rm.rs b/userland/coreutils/src/bin/rm.rs deleted file mode 100644 index f1a3549..0000000 --- a/userland/coreutils/src/bin/rm.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the rm command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("rm").expect("utility supplies localization"); - std::process::exit(uu_rm::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/rmdir.rs b/userland/coreutils/src/bin/rmdir.rs deleted file mode 100644 index ee5edc1..0000000 --- a/userland/coreutils/src/bin/rmdir.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the rmdir command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("rmdir").expect("utility supplies localization"); - std::process::exit(uu_rmdir::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/seq.rs b/userland/coreutils/src/bin/seq.rs deleted file mode 100644 index b6ed06d..0000000 --- a/userland/coreutils/src/bin/seq.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the seq command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("seq").expect("utility supplies localization"); - std::process::exit(uu_seq::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/sha1sum.rs b/userland/coreutils/src/bin/sha1sum.rs deleted file mode 100644 index c601c6e..0000000 --- a/userland/coreutils/src/bin/sha1sum.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the sha1sum command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("sha1sum").expect("utility supplies localization"); - std::process::exit(uu_sha1sum::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/sha224sum.rs b/userland/coreutils/src/bin/sha224sum.rs deleted file mode 100644 index 96be305..0000000 --- a/userland/coreutils/src/bin/sha224sum.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the sha224sum command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("sha224sum").expect("utility supplies localization"); - std::process::exit(uu_sha224sum::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/sha256sum.rs b/userland/coreutils/src/bin/sha256sum.rs deleted file mode 100644 index d8935f8..0000000 --- a/userland/coreutils/src/bin/sha256sum.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the sha256sum command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("sha256sum").expect("utility supplies localization"); - std::process::exit(uu_sha256sum::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/sha384sum.rs b/userland/coreutils/src/bin/sha384sum.rs deleted file mode 100644 index 8897db2..0000000 --- a/userland/coreutils/src/bin/sha384sum.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the sha384sum command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("sha384sum").expect("utility supplies localization"); - std::process::exit(uu_sha384sum::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/sha512sum.rs b/userland/coreutils/src/bin/sha512sum.rs deleted file mode 100644 index 2cdcc6e..0000000 --- a/userland/coreutils/src/bin/sha512sum.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the sha512sum command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("sha512sum").expect("utility supplies localization"); - std::process::exit(uu_sha512sum::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/shred.rs b/userland/coreutils/src/bin/shred.rs deleted file mode 100644 index 55b5aa8..0000000 --- a/userland/coreutils/src/bin/shred.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the shred command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("shred").expect("utility supplies localization"); - std::process::exit(uu_shred::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/shuf.rs b/userland/coreutils/src/bin/shuf.rs deleted file mode 100644 index 641ee63..0000000 --- a/userland/coreutils/src/bin/shuf.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the shuf command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("shuf").expect("utility supplies localization"); - std::process::exit(uu_shuf::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/sleep.rs b/userland/coreutils/src/bin/sleep.rs deleted file mode 100644 index 0ab1a97..0000000 --- a/userland/coreutils/src/bin/sleep.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the sleep command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("sleep").expect("utility supplies localization"); - std::process::exit(uu_sleep::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/sort.rs b/userland/coreutils/src/bin/sort.rs deleted file mode 100644 index c89f40e..0000000 --- a/userland/coreutils/src/bin/sort.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the sort command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("sort").expect("utility supplies localization"); - std::process::exit(uu_sort::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/split.rs b/userland/coreutils/src/bin/split.rs deleted file mode 100644 index 737e83f..0000000 --- a/userland/coreutils/src/bin/split.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the split command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("split").expect("utility supplies localization"); - std::process::exit(uu_split::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/sum.rs b/userland/coreutils/src/bin/sum.rs deleted file mode 100644 index 9b80e68..0000000 --- a/userland/coreutils/src/bin/sum.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the sum command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("sum").expect("utility supplies localization"); - std::process::exit(uu_sum::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/tail.rs b/userland/coreutils/src/bin/tail.rs deleted file mode 100644 index b497795..0000000 --- a/userland/coreutils/src/bin/tail.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the tail command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("tail").expect("utility supplies localization"); - std::process::exit(uu_tail::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/tee.rs b/userland/coreutils/src/bin/tee.rs deleted file mode 100644 index 42bae96..0000000 --- a/userland/coreutils/src/bin/tee.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the tee command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("tee").expect("utility supplies localization"); - std::process::exit(uu_tee::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/test.rs b/userland/coreutils/src/bin/test.rs deleted file mode 100644 index 8a9f8f4..0000000 --- a/userland/coreutils/src/bin/test.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the test command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("test").expect("utility supplies localization"); - std::process::exit(uu_test::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/touch.rs b/userland/coreutils/src/bin/touch.rs deleted file mode 100644 index d81624a..0000000 --- a/userland/coreutils/src/bin/touch.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the touch command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("touch").expect("utility supplies localization"); - std::process::exit(uu_touch::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/tr.rs b/userland/coreutils/src/bin/tr.rs deleted file mode 100644 index ddf2acb..0000000 --- a/userland/coreutils/src/bin/tr.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the tr command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("tr").expect("utility supplies localization"); - std::process::exit(uu_tr::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/true.rs b/userland/coreutils/src/bin/true.rs deleted file mode 100644 index 63979b6..0000000 --- a/userland/coreutils/src/bin/true.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the true command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("true").expect("utility supplies localization"); - std::process::exit(uu_true::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/truncate.rs b/userland/coreutils/src/bin/truncate.rs deleted file mode 100644 index 5bca57f..0000000 --- a/userland/coreutils/src/bin/truncate.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the truncate command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("truncate").expect("utility supplies localization"); - std::process::exit(uu_truncate::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/tsort.rs b/userland/coreutils/src/bin/tsort.rs deleted file mode 100644 index 7babdb8..0000000 --- a/userland/coreutils/src/bin/tsort.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the tsort command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("tsort").expect("utility supplies localization"); - std::process::exit(uu_tsort::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/tty.rs b/userland/coreutils/src/bin/tty.rs deleted file mode 100644 index aeab75f..0000000 --- a/userland/coreutils/src/bin/tty.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the tty command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("tty").expect("utility supplies localization"); - std::process::exit(uu_tty::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/uname.rs b/userland/coreutils/src/bin/uname.rs deleted file mode 100644 index a8c8953..0000000 --- a/userland/coreutils/src/bin/uname.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the uname command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("uname").expect("utility supplies localization"); - std::process::exit(uu_uname::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/unexpand.rs b/userland/coreutils/src/bin/unexpand.rs deleted file mode 100644 index 7753075..0000000 --- a/userland/coreutils/src/bin/unexpand.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the unexpand command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("unexpand").expect("utility supplies localization"); - std::process::exit(uu_unexpand::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/uniq.rs b/userland/coreutils/src/bin/uniq.rs deleted file mode 100644 index 5891b29..0000000 --- a/userland/coreutils/src/bin/uniq.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the uniq command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("uniq").expect("utility supplies localization"); - std::process::exit(uu_uniq::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/unlink.rs b/userland/coreutils/src/bin/unlink.rs deleted file mode 100644 index 0249957..0000000 --- a/userland/coreutils/src/bin/unlink.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the unlink command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("unlink").expect("utility supplies localization"); - std::process::exit(uu_unlink::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/vdir.rs b/userland/coreutils/src/bin/vdir.rs deleted file mode 100644 index c3b426d..0000000 --- a/userland/coreutils/src/bin/vdir.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the vdir command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("ls").expect("utility supplies localization"); - std::process::exit(uu_vdir::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/wc.rs b/userland/coreutils/src/bin/wc.rs deleted file mode 100644 index b866eaf..0000000 --- a/userland/coreutils/src/bin/wc.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the wc command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("wc").expect("utility supplies localization"); - std::process::exit(uu_wc::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/bin/yes.rs b/userland/coreutils/src/bin/yes.rs deleted file mode 100644 index ac14fcf..0000000 --- a/userland/coreutils/src/bin/yes.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Implements the yes command as an independent WASI binary. -fn main() { - uucore::locale::setup_localization("yes").expect("utility supplies localization"); - std::process::exit(uu_yes::uumain(uucore::args_os())); -} \ No newline at end of file diff --git a/userland/coreutils/src/main.rs b/userland/coreutils/src/main.rs new file mode 100644 index 0000000..28a9028 --- /dev/null +++ b/userland/coreutils/src/main.rs @@ -0,0 +1,100 @@ +//! Dispatch the bundled uutils commands by argv[0], or as coreutils . +fn main() { + let argv: Vec<_> = std::env::args_os().collect(); + let invoked = std::path::Path::new(&argv[0]).file_stem().unwrap(); + let second = invoked == "coreutils"; + if second { + if argv.len() < 2 { + eprintln!("Usage: coreutils [arguments...]"); + std::process::exit(2); + } + uucore::set_utility_is_second_arg(); + } + let name = uucore::util_name(); + let name = name.strip_suffix(".wasm").unwrap_or(name); + let locale = match name { "dir" | "vdir" => "ls", _ => name }; + uucore::locale::setup_localization(locale).expect("utility supplies localization"); + let args = uucore::args_os().skip(usize::from(second)); + let code = match name { + "arch" => uu_arch::uumain(args), + "b2sum" => uu_b2sum::uumain(args), + "base32" => uu_base32::uumain(args), + "base64" => uu_base64::uumain(args), + "basename" => uu_basename::uumain(args), + "basenc" => uu_basenc::uumain(args), + "cat" => uu_cat::uumain(args), + "cksum" => uu_cksum::uumain(args), + "comm" => uu_comm::uumain(args), + "cp" => uu_cp::uumain(args), + "csplit" => uu_csplit::uumain(args), + "cut" => uu_cut::uumain(args), + "date" => uu_date::uumain(args), + "dd" => uu_dd::uumain(args), + "dir" => uu_dir::uumain(args), + "dircolors" => uu_dircolors::uumain(args), + "dirname" => uu_dirname::uumain(args), + "echo" => uu_echo::uumain(args), + "expand" => uu_expand::uumain(args), + "expr" => uu_expr::uumain(args), + "factor" => uu_factor::uumain(args), + "false" => uu_false::uumain(args), + "fmt" => uu_fmt::uumain(args), + "fold" => uu_fold::uumain(args), + "head" => uu_head::uumain(args), + "hostid" => uu_hostid::uumain(args), + "join" => uu_join::uumain(args), + "link" => uu_link::uumain(args), + "ln" => uu_ln::uumain(args), + "ls" => uu_ls::uumain(args), + "md5sum" => uu_md5sum::uumain(args), + "mkdir" => uu_mkdir::uumain(args), + "mktemp" => uu_mktemp::uumain(args), + "mv" => uu_mv::uumain(args), + "nice" => uu_nice::uumain(args), + "nl" => uu_nl::uumain(args), + "nproc" => uu_nproc::uumain(args), + "numfmt" => uu_numfmt::uumain(args), + "od" => uu_od::uumain(args), + "paste" => uu_paste::uumain(args), + "pathchk" => uu_pathchk::uumain(args), + "pr" => uu_pr::uumain(args), + "printenv" => uu_printenv::uumain(args), + "printf" => uu_printf::uumain(args), + "ptx" => uu_ptx::uumain(args), + "pwd" => uu_pwd::uumain(args), + "readlink" => uu_readlink::uumain(args), + "realpath" => uu_realpath::uumain(args), + "rm" => uu_rm::uumain(args), + "rmdir" => uu_rmdir::uumain(args), + "seq" => uu_seq::uumain(args), + "sha1sum" => uu_sha1sum::uumain(args), + "sha224sum" => uu_sha224sum::uumain(args), + "sha256sum" => uu_sha256sum::uumain(args), + "sha384sum" => uu_sha384sum::uumain(args), + "sha512sum" => uu_sha512sum::uumain(args), + "shred" => uu_shred::uumain(args), + "shuf" => uu_shuf::uumain(args), + "sleep" => uu_sleep::uumain(args), + "sort" => uu_sort::uumain(args), + "split" => uu_split::uumain(args), + "sum" => uu_sum::uumain(args), + "tail" => uu_tail::uumain(args), + "tee" => uu_tee::uumain(args), + "test" => uu_test::uumain(args), + "touch" => uu_touch::uumain(args), + "tr" => uu_tr::uumain(args), + "true" => uu_true::uumain(args), + "truncate" => uu_truncate::uumain(args), + "tsort" => uu_tsort::uumain(args), + "tty" => uu_tty::uumain(args), + "uname" => uu_uname::uumain(args), + "unexpand" => uu_unexpand::uumain(args), + "uniq" => uu_uniq::uumain(args), + "unlink" => uu_unlink::uumain(args), + "vdir" => uu_vdir::uumain(args), + "wc" => uu_wc::uumain(args), + "yes" => uu_yes::uumain(args), + _ => { eprintln!("coreutils: unknown utility: {name}"); 127 } + }; + std::process::exit(code); +} diff --git a/userland/preview1.nu b/userland/preview1.nu index e315946..663c830 100644 --- a/userland/preview1.nu +++ b/userland/preview1.nu @@ -1,8 +1,8 @@ #!/usr/bin/env nu -# Build pinned Go commands offline and copy the pinned QuickJS release. +# Build the pinned Go tools and QuickJS C sources for WASI preview1 during development. def main [bin: path] { let here = $env.FILE_PWD - let target = $env.CARGO_TARGET_DIR + let target = ($env.CARGO_TARGET_DIR | path expand) mkdir $target $bin for tool in [ {name: awk, source: goawk, package: '.'} @@ -19,11 +19,11 @@ def main [bin: path] { ^cp --remove-destination $output ($bin | path join $'($tool.name).wasm') if $env.LAST_EXIT_CODE != 0 { error make {msg: 'preview1 bundle copy failed'} } } - let qjs = ($here | path join qjs qjs.wasm) - let hash = (open --raw $qjs | hash sha256) - if $hash != '2c218412cb8b17e46ee91bea7556ec38f5b9b6bd6312fddd3ceeed14aa71eaaa' { - error make {msg: 'QuickJS release hash mismatch'} - } - ^cp --remove-destination $qjs ($bin | path join qjs.wasm) + let build = ($target | path join qjs) + ^cmake -S ($here | path join qjs source) -B $build -DCMAKE_SYSTEM_NAME=WASI $'-DCMAKE_C_COMPILER=($env.CC_wasm32_wasip2)' $'-DCMAKE_AR=($env.AR_wasm32_wasip2)' $'-DCMAKE_RANLIB=($env.AR_wasm32_wasip2 | str replace "-ar" "-ranlib")' -DCMAKE_BUILD_TYPE=Release + if $env.LAST_EXIT_CODE != 0 { error make {msg: 'QuickJS configure failed'} } + ^cmake --build $build --target qjs_exe --parallel + if $env.LAST_EXIT_CODE != 0 { error make {msg: 'QuickJS build failed'} } + ^cp --remove-destination ($build | path join qjs) ($bin | path join qjs.wasm) if $env.LAST_EXIT_CODE != 0 { error make {msg: 'QuickJS bundle copy failed'} } } diff --git a/userland/qjs/README.md b/userland/qjs/README.md index e99fce7..c6e507b 100644 --- a/userland/qjs/README.md +++ b/userland/qjs/README.md @@ -1,13 +1,13 @@ # QuickJS-ng -The bundle includes the unmodified WASI preview1 command from QuickJS-ng v0.18.0. +Sausage builds QuickJS-ng v0.18.0 from the unmodified C sources in `source/`. +The Nix package uses the existing WASI clang toolchain and upstream's CMake `qjs_exe` target. +The development bundle uses the same sources and target through `userland/preview1.nu`. +Neither path downloads a prebuilt executable. -- URL: https://github.com/quickjs-ng/quickjs/releases/download/v0.18.0/qjs-wasi.wasm -- SHA-256: `2c218412cb8b17e46ee91bea7556ec38f5b9b6bd6312fddd3ceeed14aa71eaaa` -- License: MIT. https://github.com/quickjs-ng/quickjs/blob/v0.18.0/LICENSE - -`userland/preview1.nu` checks the hash before it copies the binary. -The binary is committed so bundle builds do not download it. +- Source: https://github.com/quickjs-ng/quickjs/tree/v0.18.0 +- License: MIT. See `source/LICENSE`. +- Upstream WASI build: https://github.com/quickjs-ng/quickjs/blob/v0.18.0/.github/workflows/ci.yml ```sh qjs -e 'console.log(6 * 7)' diff --git a/userland/qjs/qjs.wasm b/userland/qjs/qjs.wasm deleted file mode 100644 index 95ed60a4db98b8fe883fe8a51e665b1aa0d477e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1571399 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

r94K#ozP8=Dz+t?UcVOs@|I=3v2{AHkV2}h0+ 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

&Eu{CH29TbL2jE?o7 zxiN02KS60y0Uj2dplJ-y@BkBX=`RQkXmE0dHB&$w1x}=z$?*_0#VRm38bcBzC?_GC z4W4RO0{PbwW(Qwd5a;FI5>O=mWU+dy_euR!C4UPugf zJLn8%6` zS^-dkaAZYUf8A|AYdY`cH2HAk({-03ygCYtd3H1Xwvj}_wHBUi} zW$2L`%%I4Gk3EBi-JnB+;6&hvQV=Ra{0}x6R2ag-5M%_X-mN!dG60P$g03yX9DxUA zIVBdy<@N5MCJU&FLDL~l?FWEvJq?|C})GmU!hqQW-%A2Ex-jj1Op_( zpa?n%3gk!7^(Nrpa%4~hU0}lrT0Ww|)WHP0+6Z)PJ1f$`lc3y*z@UpWz-PZGaf7Y| z=5ah+m&M1!$^imQ92^{sEZ{jg9!G~PJ}w53CFI^y8t?v96rN$3c&X0`s+y6< zq)=8&u|QAfg5SN%iMhNN+yVfZ@`X`}6FeXVnjZxXNFg7;1R2xf%z_-h1a${u_z1MA zh6TJ*3Vga2)Hn|CLUR_-Jx`#`wx9`EP)9(415}uU+X*O_XtF?0>VmtL1A4#}I3yjJ z6gd^ZXXLPf^8~yKMBa=E_6)*ww7`IG41@Rv%Y{#1{ZQA#mWqQNir5?ts@}jWiMgSh zqwxd=7kJG*I0DU>z%xPIjz>WI8XONZDsq6DlH88RL3^?skAcz(GbpWq`JlAIgp^jG zJxb6?R`AUbqiF@XZ3<5-ppZnQ74TFuqv{Emz=REae>Y-0q+C=orA`xzynHqprtP?kbNp#py4UVGA0hlnm0)G za07I^E-1-!K(0my&tE$pWK`r(;C4I+O01xC%B8`?qsZg97bMIDHWj);4;0)A+>YR# z?A)Mm2aRkpfKGw|4aIQ^Oab*UAv-YG9hpH{6Lb#}lcPo!Y+xBOL=74x1eM>8OzujY zpwViexO!Tt~>s7NEKcY$CV^#E4jn%m_NcgbQTP4@MnPN-KeTL#S(!xp+YZD)?4x zPy?7nff2kGnFVyD!w0bXFN~nkH!cOnEXQBq#pP&43aCMQ=|iDum!9s;=mcG6`+|HXh9G57jnHc%;M=M z_IM&XmY87OV(hU5s_fZ8jUDjB0;2qacK1Msg@RH7C_6!-A9>|Jw#Wjn{D+N(KpJ?U zt}5vAR`4+B|Nr2;$>jL&KQs7dI>%SHz>{W<0w|;A(4l2W7Z==uhR+m(ukVt8+y@Kl zw1a28;Adnp@_?Fgpk_O~Fa{r;1X_|~#-ssG;?Qh}@Rb@$5`bk#aIc)&v_%&^OF&Ko?Mr|;4Z1KL$7q8B3n<({gJICVCg`qRP>Y-&bsm8aWmE{_C}@D; zOj;M=o613n7Chty922j=nr%rHvgL+s44`_)PqLYo7djefL2OSCpr2r6C;BfTI;uD3O zC=5PO7<3&nm;pMHkHc|)T^1iR18Ds@$V#+B_tYW%FR%<~c+CwmNe1exfVZlHEHp+| zgEU4Bo>EkCY+x!fV^RU@01s%uYD-6CvmF^B27@hvcL6~W42XiOG|(cp*zEogOALe8!TyTJ-T>&n4{V4x-7prg-0F@QQ|0vaLIV3JUTBx?l@ z$CaQl68Ja;wDpb{rvL>EsM!d*9>dWTR97-MUigJPxC9IeNGD2J8 z;20hBlq?Q6(*27Ip{a{C&5rg)hW zmjWlKea)f3sK5bkUvpt^UvuDUUvro-fdUHTFi>g2p#UmXKmm(oW}FpiW}E{ƒH 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

-Xy22FN!Gfm<(24w9%ayn_m}Ed# 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%0D_@Qjlm@p zBWPU(XiWvUpi+QbukgMu47`X3s<0r07qrtvi3PO3oy8qo!Ln#FOF)+xVweM(Cju`# zcwZL*T9t#m5E-&^1k?b7EDb{*a09sx>H_eB5=O*=5@ctBR$Zf%gy5Ds(vA)2f_3mE z^pI&oBwN6%MwuKyeQuD~l~@#5K;Fk#QUcKkFKt1sK6qIOI-UvKDFB}>1W^g;M?sd9 zLDpQuy$V_@1S_e*)?>9CX(1tebQEU2666*Y@G^JMG#&gjs0XOa+~IOqmbrrtwgWG7 zM=bVcQ~(cSU_Z$Uw$FuaxgywD*1bxQ)B#S7D7&+RVQcN`peY8r##V_@fpz9yu-9R0 zYoQD9pb;{m9(3<8#1Y`Lg%uf*Hcvy>!GrcafM$BZikT2PV#T~!OZ7dK0h*^w2r-WIe{gbTEeO<*%< z#s++Q3uv{YEms7s zJOQUh(9#>UVCZifO@P@p;wUL9bjO?HB5 z6I?bUrB2Y!CXml7z)P7x!|i+sc2d(VD>vxSN>I9G#o6KoogM(P z|3RGsE2QYBYGr`$3N_HCDCmJ2pxgtBB*)qHS&p;oL49M~1wOQpcVvX*9YTftIyUg? zVfeMI7Z|dYpj!Yzv5COY%8=w@A9NI9V1wm`sfEI?s{0mw~h|!{g?CfO&?d*k~nglE0l|cJbq3IHI zN~8iu5{QEBlQ@_R;{9QQjM=h7w+=*SImUSNvVu0-+<-0+gVf%j`3~@+NN8II;&P~O zz&jKgbh?oiKB4W_4B6~r zOQ*qYXPoU^h(;tEkS0_>4RG**p=^#^ph*hQ+C?r$&^e=!)(~h20<>ikbm5F62Q>Gv zgGSpgFl0g2WGS$7A7W%=tcRo$yg33?YJlPdv{MAp-h))?(EJQ>EO=cq<8pX^1T-Rq zuRj8AW)U(SS6vG(4Y+?J`~dQa0ys<^8MFA98JQSBtL?zC0&+d5rv!36a!vuIPMCYy zKmm#5T4433i~U};x^cQQl64yqnhqk;SlS_z@Sw1Y*7#gPZJoqV}8Xn&Rx z18B7%$jddLMK}!&ETAPt450ZukYEMa4H`@b7!^Sy@954|V1RVOC)Bs_b1N`%HzIqU z2(LpL>WGL_pv>}!o>zc45*-vFAPibu2=XR)K3M`XA1a{0qQC@R zGyz(t!2z03;(!d(f%iKLW+_2#n%7{GP+-dfEh&L5*I-p(gD%%#gDuwpcllVME2CL) zt&C=ct&GMxFAF|(h*g6LI$;cQH>k}3TE54Qv|NK-ffcl58?^q5LlHC%r@)4>Tmzi@ z*g)K|pWV!J&gP0mjSVJ1T8w<3)lNt#GbSntz z#674$1%(`J={z{%1Qggn(Fi`x+?)wCanEVS!~+^b2H)2C|37n~z(sI0%$bQc^4XcrtSXni~A0t0qO&@MP;M+OBBaQ_#y1RXM54cP_9j@Sjqy7jQZ0Q3AaK)xJnt|BO>b9F3NWCJaY~ ztH26fo5c!Qo5c#6ABFCYVh1f_Vuh^D0#l&7lN}p&)E6m&1{e>l2Q2`B+_nf!;*K1O zpvA}FgSVOCl`j)$n*pfu1r_?37elf-awxFE3Lj9R&jjySaDeX8>|o{P1m$ng?kLP{ zQ%sP?0S_lPXn_~<1}V^0?BD}i6j;H_v(RpWRA8`Xlmcx428W7M6R4a7mHX`QrkWxL z4|sl#RReo1ML~N2*lW(ea2-Cze^xdTc!@WWbg)iI#j z3Z(P@e{d&=WBGPP&`Nc%KIBdiq!@wLE&IW0@Rj?4pfn9~0M=>?dD|$4!AN}{uxq## zxS<_V28J|OUM48_|9=C=R4`Y8`wx>6>-HqjJ#C=sL4g&rgNPTjDT)JhkqZ-O?-P?N zFDqp4u4Csl0}GO^WjVm6Y&cZz}5_<`n;8PFSTu)QqcW}6_6 zW*ew21kL1#W*hz2TY_6Dh#brYx#$Ufy(PH$49dZrpgIku*@m&+lH?K?e6=fhSvdan zmSCrXIu@WEkNDPG!eSS^69&369eSQVq;!EdYQU#sf}%@-+wnVt0_a%JTcAC&N|1xP z^CQ4pX25F|85DRRW+?J1K#shDWJFK{U6E6P2fUvf>_pItD#-F*R>(0loC-Y9!>^be zphq7fy8wJ-7cb)67f?qObYYPaALtYx&;n`j4RCy*+wJ%jnAU*L-R6Oo9SjP*3Oq`J z&SVTO#Nh zQ$AgET~q{_#EG+c%zt$`x+|?V;y5X=pG>O zz!qreApz3N2j5-C;P|p1%V-B=@frALQSh7~^b`Vk41&@K3s@1jkqH?Sg18(q(~L6S zuE4S!6h)x=0D&P%5j0)`9K42M-cN^A;jiM$Np$wW48N05Ii z6qyy+pmhXjZio%kZpJ?14r;Q2N8CXT6R`Ji9lD1Yt7L?(CIWen4U%X;H{RA{DPc<_ zY~Yzn@Rdx^5(PAV1D$AM@Boc4fm=+Vh3=qD!;o$bijWeA0&^Bk0@4Io%?s+6f_MT@SAfBBUevIL+y}3eo)62y3L=AG8KPv zg`IB!iWZz@DiO(5mw^FWnF^_%*twCaEYQpE=UMc;qpRjNfyu+7Y2wSpre~GjbQ;9 z!vZq~w51X>QYrx3;wX>>IRP0oXby@K1)dTm2GGt(4h2pHhCf`OQzAGN7_t;W-2^5_ zP((31fH(Po?mR}i`wO(Y3R+Twy}-f54H5!hmjh`taD!&jI5e09AcFwlljA{WevGz+4DBa)S+W=?NF;NQ*)c0otC( z2AU({QeX$MIpIfTaKQG6qS^r(z66g)fDYsYEwAAQop1%V3+b>7MzCm>5}N`$=!`{3 zr(FONBA_dzJf%TPPa$CjDICBZe9&3QH6UG}LkN`EprZq9kkJ7y*m2O@3M`1+-@(Sh zSO=Oo2i2*>XLa}qZJ_u;%kmIsAx9-Bkt_$z_%eVT<--d*Y84)lY%n2E@PjsMqE<1W z(~3}o5qmQRq#L|onGsqIav&;U&?a1vJP3p83}~7GS0kXB5L9P?#Gy$6UX6g$3Ah>o zB@b}IfUF1roi)z}sXsX2wF0D`gMVRgCk>!5*K)*AS*oG zgHI^~g&If+D9u9?KB!V;1WgHZyMu-ez;-LJ^D#3sfKG-&vjH5OkTY^Y{eM{AKve}E z)B|tY=HXW00UdjcnlC_uwQy^g7#NwjLHUITAP!>YU35^^qjCE}Fpervx=@lFoL{xg=OVEr&&Mg^Yb+ZA~sD*!+;^MaXT`C&%FXUUx5cS z%m>-#!3)~m#{*w8fMx`E?g;KzmK@=%)WhsFU8iuL_XA5ve0!m59g&61v7bVmq znL#stptAt>(XfC zK`Z7MKs`%#P~(FUJnW;$0Xj(!rkE4N0iAK7$OSqE1KvVlhaP4CD$^mo6_owdpaufB z0uy+A5`6xa0vG5cb$B7l2|gl&oe4a?$pD!VK|RtBT#9mligSo8E1F(Vod9ZAL1eM$ z1#jF}1RKNc&dZ_zK0b>BQhP}j*x|@7fSg8wCk&ZDd*LCD0I_)7c|q$5m_W8e+yXAW zVGiK|ZTkQ>V!<1mpa)w(>;@%8n0uHVP{M%>SAY%|!s!ZT&?0_NpC6p;z%6GM(0Pvx zpalZpv3Esg1#XD5z(E4_B{STM5Wj)W5C`p(Vo(H4`+!o3D=!Opk{glMK#8d&3*Bixn8XA!3Dz%G;O6I6;8x(t z=03;H%u>e+nx%3erG*SC9l(<~SbI32o-iY*@c>PDp!NZ*T@V6ownA^iQ2-5+Jpo;P z!XN;d%7qLI6f{HclmYE4fgS=6>NTW5UVs$4 z(E1kSEKs8n+?0Z}h9N~Ua%%*d#z0jRxLeN(s)$j#^^j$R;Onj&85B7cAa=mp5a9b0 zSP}Op98Bg#v>`yZD8R;nSrqudZ3xg_D$rS(0+7iyh;dLSgEs6P^FSKQ*#FPy>fD#&wpc869r?YS>Fnd8SC=yU)Rp3-)1|8wc2x^~j zDlla$aVkQ0gMnp1qm1Aa*uXOm3S0_23Y?A%3QUk1oEO#?2DNXQ9YE)Xg8G^eRg76m zC`!2@y+m;Ig6dQBs+_eWqh0cYeI|ov|6X_msLINLV07@{pjtr({cv9b9s0+Da`zB) zca8$90;4&z1}H9}IbEOytP`3%3_!V-!Ljo`WQ7jO)=uy~6xd>DXaNP%3Vh0Wuj9Vr}; z=}2&tfGvP}1(Yj6i=!0S9YIBkMwY-Ca7n=iT2;h~JWQ#?XwD3=7VLgVs|*?vAlHJn zudtgl3xI+PgcVpEpEA0EE^SeSoOfXWDSj9n&&~rS1xCpJ7N~!b3}RGZRp2ydmT+W( z%o;FgG6#S*G=oON90foJSAaB^cmP1D){)Ilcw^;wd%-#Jm>R0q_J9$jb=6(}!`n5}V_5 z&_1fypmAG}$Dr0jq6pkeV~3o^2HDOB8d(F~O#~XD0`<$-VSOXeW~+KHUPi~IpiBs^ z7r?b2r0@d84z~gm_iio@#(LOQ;-ED-%&--LSZ4#EWeL>X;JCt7EP|sBG%Nuc#|O0% zV3&!5H)(;k;)wR2nOXp`0xuPilL4NnFWqD86{>=6$hz{AQLR0Bh5@I|zXcIcf2t50HVcRDlH6FCpgXsZ&u=14!O<7x%AvqltHAHNR!N{%Nl-x`n3qX`b1i6np^y`3D~gIZb31y+MJ&J4?1i?&q5GJjO>x+P7K$98c{)}F4h0@Zc7Z*h$`)iDn}QJNI$>7OIgy}? zlGs6u4A~WU*C_DSC~+tV)F|;N2!?~lWH{F<@+fdD2M^OJ@IwZWz?c3)%1}_qgB!KX z3cL#3P{%{+10=_Tya&FK%aK7~9jH(NIRd&20W`XZQoew50wk%T*QlJZf(256aB@S_ zKPZtiDS(@o;OvA}b%2gIg|@{&O%jOnp>27PR{$li0n^06R$p)SnfA?O$c(Ucto33K}sn8P)>rXu@$l12edJ2PyOsc>Lpx7}3M|>68$CcBJOySS z(8wXEw+fnGQD71P*GizVLqE6#3tSbbtOcKuqQvCL2pfjvW#Cp|;Xca744!TRT}TLt zIC6&AVKq6pa0M4ZpeZfzMMR)s3(yKnP!|_VqlO)PemS)CRe;Sufig8D1|Z!~2pilT zh0HReUq#Kz%FfEb3L3tJwcVfv^L`~x1ZTWk?%zr!07jCL`#E zHAe>Uy=suYCOhaTVFeCPY0x>OprH+DXH$_KRD*IreFn|l20^^c3eXc9APpW!&lVEE zP(|Qi!oF-2+M&QRNd?;G2yL=J!yKFzAQm8JJxIQRhA*g`g#{&2U?Pv1L*@s-yZ=FJ zW}#&eYGAUV1ST}jKsUl*1SSWl3&XfvkpmPnpzClLKzmXkL8-v*DXj?33FHJ3w0D3f zh!_>%tvZk^Kz$?7Vp}!^W)EovD9cM4QaEF8F|vYMAK1%1xY3|p?h1_D4?(lG%=L^l zpl$QeKpPYp34XFOaz=u$qDId~EG*!dhflY`;~jFNJ19r+aKKhkvnhbig8)sFfR^|{ zwG_WCj6yUSJVFoPO-;QWUi#Gqmn#D@khXl4pL5~v7L4Gw6~ zoI2>zPEJUE10PAv!mYpwx`kbV-D5!VTNahF*i%qV1nU~DWF@T2Ym*EjKQJT zk>G7n(4rEQlNl5sjYYH?i?limo;EN`E_Ou8#f-J&f`~#h7c^kOr)NV}eSzDBET9wl z*}=OlKqq;5fo|cWZ^^~1zz#Yr-cuU1s2x(Nv4e^-1vbhnGtf?ny=<(YaU;-)cr4g1 zVS$G*5xEb%uN2xoQA8Wb1PjBPLg2&zX_|n_UX#uh!09@rjry3ygNUi{%^$2bnK~5Y)ZWLzYwn(xlaDmofDlz9M@jwr4QQ%SFhA#Kw2Cb6>4F-Us7PPJobc6ykXg&fwFP{bK z&p@{Jfu>Bj1h#;>!BU``#6VdLboVe16E~+mOa-L3;(ECqsY+rceqZs6mkO2zvt%#U%I!I#%vb=)p>@1up1m2He(+ zLJC|U2s*Ha2Yg@+FZ93~UIiY|zI|TMO*5cLRc^>>23*k747fn28E`9rrei?~p8=HU zL8lpTK~6IOQ{c*i8Gdk(BWP-b7qk?dTY(qp>;hiIO*6cpp%9dv&#;^QKqCf_WC=?3 zkev&l9dh`0E`W!cK{*$Ex&rK8LeOvzFX~AYT%dXl6rc)_n*(`4-VjjWg&bJJ3yK8L z^@^bU3>#d8+`|ItyJ4NN4uX!zL6<#)P9lR2(4+R2K?wt~nE^UX20DtJeYp~^J|mYB zvm>t?=w4|BW=CUC0RjpK4W<*IB@+@kSsF|Nu8eV;<1KG6Qqa@(-}- z2IkBb3akojNJ*Skfn}{ZvjKR?fI^nQhc?jVu+Th)7`J9o0BuxO;04X-LrX!Bp`ZhB zIAEKeL1_&->Y&7}z>)=-+IYEm? zIL(=<>3q;3LmXKOyx?7ckU|`^asyoILxK`iT`3?3C3vkMXsr|}LCH)+P=ah3rGcK&}BWKZN88Mz_=VaVSp0>XowEo<$k=7ddC2?fP)pfshSmj1QED= z0!0tBScWuXz$3A|;Fwb4g)Rl>MVmi_>g0y5HwI~Bg-)kptA{|_6QI+nJm3|!Y@nnD zo-S_+)(dvL%heM0G<2hR^S6$47CB289_^4utpaja=KRn6~Ex! zLZAo({25>&*a6%mNS6ug-WQd%Ho zH!MjU5oVyW0+b&?J1aOem^eT*59A(3(99#Kkp?PLF;Xm~0YqeyMOz90@hC36P>;fs zJEVyK2`NZ(ADpl-<{Oyd1ODKk1ucW%fu80A$%~*86I2ZGBGyU43IVKM1ZPSvNIlL4 zO|@K*R10t7!CZ;ehq&~j`4HSS0d3BQ_>mWsSqOO%9H-DWD)KIW|fo6D^LB|V1Oow;}l2AB6+cj_; zMh6+T=THFMa*2Ex9V_-z8#om>6L~@7ZlLKFP`E?8IS;^x=PR%)g2W+N8kEnF2A-J} zK%@Ae>(-(Ez%}&F16oxH9-9U&s8nD_DfyMa*S3MIVd8dFP=qWwH&6tv1pqY$A#3u% zA!eY+2x>QTK-<31k`3JMh4eHbjSxs^L1jVZ9=N9onwCXMsgR|vpza&k=nr*K&@ccE zF@V;NaVTI(IG|$PkrC9x0J#@*?H+tW5G26N4Qf_Ex=!Gm=6S(=Qw0w2VHhlsgY_>@ z2dxKU5J2?&zzuH+Nbvw`e}gjusNF52$fUpux-C=$oY24xM-I@DcYImk&J5`AW@ZIG z=xLlxu+umpb6Xv(;4P8(Tdtrw2Rsr4JvInr4`}8Kbm}G_yz$JSzz1nOLr&e~1GQ|K zFizbBS73Y?O=~_!4h24GMLu}bmk)f37Za%I%b~#J2)i^JEWo0`1oAIvz=g?-i3j8y zP%Q+ly|^416u2Sf45(|zp}?IDnZi=w1=UL&;2tlmK?iE&aUj=8O3Vrz3e29;O3?NS z=u9pJ=4>UfHt-Tya7my5sz$**U-11z3ZUssa6N!#JGh(!FY<<_B2Zfzl0(5Eisj}| z=n^7u{3=3rTq5ZOmyy^DD-PJ=B~VWTe!>kKsJDXIEaFCK4uPEsYKnu3LP*h}!~rdV zInYXANS^~#+CwX5NU;Mpf&;n_mk0;K`{``lf7zJWL8sG_w1C)=0le-9xzB@^uR+TZ z89^HrAUng9pqtPOp{aqzk+Be*AV36orx>Ic#SWfxc4SZlU9ZauT8t0hZ>I>|EeT3- zph^T(uYnG0Q2_631l_XE%*4RW%njYc2+9Fq8IXFAEE6N>-aeQtX#1(70O()?&`vGL z);ey`s%lp7wg&LgL?Cx*FfpJhfLyH01-({XflHU+z=q}q21mw1=oU$3b%Qb%c#|2-en>dr(ZQsEbAY##aDlcJLu5g5hq6r&6x0grS&sGKxC5URz=o-S6SUt%i31jK9Ei|`L>vbq z;@BPQvq04;*h`?@E!?1mGNAJx*`bp-pfk51NggE!g7*|*Us}fjtBkl6co4f>7c(+} z*0g~=3ThfCu`G9F&vFEf_#qV%pcU_+(gBjSA(Pmk30Kg-6nMoEKRCZFS7HS%rw7F` zXze8Ik|Stk3u&K2%0G026c`*A&4$!`kkxnKQV+CW2{aV`mIb_ok`30pLM*(442VK6 z^ac-0L0wHuV+%Cg2(yRKpg3F|sFDY@GZ^44Gf0ye>Pb+G0<=qxak&C`bNM#V04Zpp z5O};qfej?gktF~TW_PRy39~q|WPwhF-~k;Vlzya+m zfET~AD1kP)E5LMfD1lb_q3h;?Sb)A7#sz%m6)NY@q@w;vZ))?Fa#C0 z(AnW^Ss*K5XQG4dT7q0*&kk#av2Z)qE3$zq8wD2d$>@xrwLzf6Pr+ggjvtRhR?|0w z)>uk`(mF^IRP2Eh0BVbj9n>OYLu!$+DX@T!VuiHGKzG+Fuw%5y*g%G{f!v8Q*a1fG@dcc7z8x8~14r@Vy{RupDlXtpvXi9TeK&>_<$VW(0W%PrCrL zXcm0>q<~{RMjHZ>y3lem+j1p#1r|pEXr@(UMOxJdF2*<%K^d7d2fB3Yn2 zCIsezrfifz8bHl=T?PinbKu*vnRFQ#9gjhnj?9ispo4gs98WX2DKSff>N6#F$G!Dg zj-dOY!LLvnsbKaXOMpt zm>dhT;Aa9rmfM4FB-sePx&hMdfh^t!r%FhH2Wm`#%|>gUvV)c&D=27uRwfrp|{$^Z_~ z5x~-*CAwgXBosKny)t%4uZ$huD+3F#fF{Gi*&dX+Wk8Yc3fe0VDjFOmz$afbKu`At zo$$i~*|1ojrNj)YLO{g~Xhe)fgGmMw`0(To@+^y^L>6=e2D&mA6phfaGf??$09$m* z$UTvZkqfCHA#Wsxn1Tef7XhgrUT;@|+C#nb^Be+EU81Ss6V z83r|xaDpldE~G@lrNDuxD8P+hPK=5IeAovUXj};;k-%ofxD~(_NkC_Sh5s3z`c8sERa)SNsd*41Jr5(IjA0bE*WU#6?{Gh%wi8n zzX)U#C~iPkR)ETUaDAr4m%@$F0BzGNdHSu?E~D;ewj9ff=+BoXe4`#IfOreIe*vF!sVC$A$(L z&?0;eP+x?Dhm~7_8`PTu^=LsBF+&{=DqG;|r%^osKA4mpRF!}xY1ly}3a7w)P{e^& zK647p1u;R<&8om_#-syoeX?pW=|I8@(#8TE-UW(!9ca`maUe|KfS3Rp?_qU31Ukyz zkr5J*;1t87z=E7iK$pmX69blX0_sPCk`Op2Le8(lmQKK@rs3**Vc&CvsK^yq9Yx?J z8RQI3@{Q795&@N&prgmp%1qEO5K@uY$^|~kjI|#54j}RhMm8Qsc!k9V9ooe)w923W zE)6B1^RpkoXQ#7*ibQb71C(MRMI$@t${UF+P;Ud;UIxptYcOqL0(WbmD+t)(SKe@d zR}gS0a6nfOfUmsa0F^?Z6$FqgZ@8f=2)H3v-f)9f5P)WMpjX~-KvxiOfL0K2g3Ajf z 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

!I4p*9W>GiotFe{nS{3CIf7v$&vgo% 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μ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 z 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⪚Vneg+09&`}QHwwo0r$S;zhMz1u}M2>l& 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 PQ>@Ja8W7h_ttbHiNcy=t diff --git a/userland/qjs/source/.gitattributes b/userland/qjs/source/.gitattributes new file mode 100644 index 0000000..0fb7975 --- /dev/null +++ b/userland/qjs/source/.gitattributes @@ -0,0 +1,4 @@ +# Don't show changes in generated files when doing git diff + +gen/** -diff +builtin-*.h -diff diff --git a/userland/qjs/source/.github/dependabot.yml b/userland/qjs/source/.github/dependabot.yml new file mode 100644 index 0000000..700707c --- /dev/null +++ b/userland/qjs/source/.github/dependabot.yml @@ -0,0 +1,7 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/userland/qjs/source/.github/workflows/ci.yml b/userland/qjs/source/.github/workflows/ci.yml new file mode 100644 index 0000000..9e5738e --- /dev/null +++ b/userland/qjs/source/.github/workflows/ci.yml @@ -0,0 +1,920 @@ +name: ci + +on: + pull_request: + paths: + - '**' + - '!.gitignore' + - '!LICENSE' + - '!README.md' + - '!docs/**' + - '!examples/**' + - '.github/workflows/ci.yml' + push: + branches: + - master + paths: + - '**' + - '!.gitignore' + - '!LICENSE' + - '!README.md' + - '!docs/**' + - '!examples/**' + - '.github/workflows/ci.yml' + +jobs: + codegen: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - name: build + run: | + make codegen + - name: Check if the git repository is clean + run: (exit "$(git status --porcelain --untracked-files=no | head -255 | wc -l)") || (echo "Dirty git tree"; git diff; exit 1) + + ci: + runs-on: ${{ matrix.config.os }} + name: ${{ matrix.config.os }} (${{ matrix.config.configType }}${{ matrix.config.arch }}) + env: + ASAN_OPTIONS: halt_on_error=1 + MSAN_OPTIONS: halt_on_error=1 + UBSAN_OPTIONS: halt_on_error=1 + defaults: + run: + shell: ${{ matrix.config.arch == '' && 'sh' || 'alpine.sh' }} {0} + + strategy: + fail-fast: false + matrix: + config: + # see https://github.com/quickjs-ng/quickjs/issues/879 - tl;dr flaky + #- { os: ubuntu-24.04-arm, configType: Debug } + #- { os: ubuntu-24.04-arm, configType: Release, runTest262: true } + - { os: ubuntu-latest, configType: Debug } + - { os: ubuntu-latest, configType: Release, runTest262: true } + - { os: ubuntu-latest, configType: examples } + - { os: ubuntu-latest, configType: shared } + - { os: ubuntu-latest, configType: asan+ubsan, runTest262: true } + - { os: ubuntu-latest, configType: msan } + - { os: ubuntu-latest, configType: tcc } + - { os: ubuntu-latest, arch: x86, runTest262: true } + - { os: ubuntu-latest, arch: riscv64 } + + - { os: macos-15, configType: Debug } + - { os: macos-15, configType: Release } + - { os: macos-15, configType: examples } + - { os: macos-15, configType: shared } + - { os: macos-15, configType: asan+ubsan, runTest262: true } + steps: + - uses: actions/checkout@v7 + with: + submodules: true + + - name: install TCC + if: ${{ matrix.config.configType == 'tcc' }} + run: | + pushd "$RUNNER_TEMP" + git clone https://repo.or.cz/tinycc.git + cd tinycc + git checkout c21576f8a32715ab439690d18184b0e02022bbbd + ./configure + make + sudo make install + tcc -v + popd + echo "CC=tcc" >> $GITHUB_ENV; + + - name: Install extra dependencies + if: ${{ matrix.config.arch != '' }} + shell: 'sh' + run: | + sudo apt update && sudo apt install -y binfmt-support + + - name: Setup Alpine + if: ${{ matrix.config.arch != '' }} + uses: quickjs-ng/setup-alpine@master + with: + arch: ${{ matrix.config.arch }} + packages: "build-base make cmake git" + apk-tools-url: https://raw.githubusercontent.com/quickjs-ng/apk-for-ci/refs/heads/master/apk.static#!sha256!34bb1a96f0258982377a289392d4ea9f3f4b767a4bb5806b1b87179b79ad8a1c + + - name: uname + run: uname -a + + - name: Set build ENV vars + run: | + if [ "${{ matrix.config.configType }}" = "Debug" ]; then + echo "BUILD_TYPE=Debug" >> $GITHUB_ENV; + elif [ "${{ matrix.config.configType }}" = "examples" ]; then + echo "QJS_BUILD_EXAMPLES=ON" >> $GITHUB_ENV; + elif [ "${{ matrix.config.configType }}" = "shared" ]; then + echo "BUILD_SHARED_LIBS=ON" >> $GITHUB_ENV; + elif [ "${{ matrix.config.configType }}" = "asan+ubsan" ]; then + echo "BUILD_TYPE=RelWithDebInfo" >> $GITHUB_ENV; + echo "QJS_ENABLE_ASAN=ON" >> $GITHUB_ENV; + echo "QJS_ENABLE_UBSAN=ON" >> $GITHUB_ENV; + elif [ "${{ matrix.config.configType }}" = "msan" ]; then + echo "BUILD_TYPE=RelWithDebInfo" >> $GITHUB_ENV; + echo "QJS_ENABLE_MSAN=ON" >> $GITHUB_ENV; + echo "CC=clang" >> $GITHUB_ENV; + fi + + - name: build + run: | + make \ + BUILD_TYPE=$BUILD_TYPE \ + QJS_BUILD_EXAMPLES=$QJS_BUILD_EXAMPLES \ + BUILD_SHARED_LIBS=$BUILD_SHARED_LIBS \ + QJS_ENABLE_ASAN=$QJS_ENABLE_ASAN \ + QJS_ENABLE_UBSAN=$QJS_ENABLE_UBSAN \ + QJS_ENABLE_MSAN=$QJS_ENABLE_MSAN + + - name: stats + if: ${{ matrix.config.configType != 'examples' }} + run: | + make stats + + - name: cxxtest + run: | + make cxxtest + + - name: test + if: ${{ matrix.config.configType != 'examples' }} + run: | + make test + + - name: test examples + if: ${{ matrix.config.configType == 'examples' }} + run: | + cp build/fib.so examples/ + cp build/point.so examples/ + ./build/qjs examples/test_fib.js + ./build/qjs examples/test_point.js + ./build/qjs tests/test_bjson.js + ./build/function_source + + - name: test 262 + if: ${{ matrix.config.runTest262 }} + run: | + git submodule update --init --checkout --depth 1 + make test262 + + - name: test standalone + run: | + ./build/qjs -c examples/hello.js -o hello + ./hello + + - name: test api + run: | + ./build/api-test + + - name: test lre + run: | + ./build/lre-test + + windows-msvc: + runs-on: ${{ matrix.config.os }} + strategy: + fail-fast: false + matrix: + config: + - { arch: x64, vsArch: x64, buildType: Debug, os: windows-latest, msvc: 18 } + - { arch: x64, vsArch: x64, buildType: Release, os: windows-latest, msvc: 18 } + - { arch: Win32, vsArch: x86, buildType: Debug, os: windows-latest, msvc: 18 } + - { arch: Win32, vsArch: x86, buildType: Release, os: windows-latest, msvc: 18 } + - { arch: ARM64, vsArch: arm64, buildType: Debug, os: windows-11-arm, msvc: 18 } + - { arch: ARM64, vsArch: arm64, buildType: Release, os: windows-11-arm, msvc: 18 } + steps: + - uses: actions/checkout@v7 + - name: build + run: | + cmake -B build -DQJS_BUILD_WERROR=ON -DQJS_BUILD_EXAMPLES=ON -G "Visual Studio ${{matrix.config.msvc}}" -A ${{matrix.config.arch}} + cmake --build build --config ${{matrix.config.buildType}} + - name: stats + run: | + build\${{matrix.config.buildType}}\qjs.exe -qd + - name: test + run: | + cp build\${{matrix.config.buildType}}\fib.dll examples\ + cp build\${{matrix.config.buildType}}\point.dll examples\ + build\${{matrix.config.buildType}}\qjs.exe examples\test_fib.js + build\${{matrix.config.buildType}}\qjs.exe examples\test_point.js + build\${{matrix.config.buildType}}\run-test262.exe -c tests.conf + build\${{matrix.config.buildType}}\function_source.exe + - name: test standalone + run: | + build\${{matrix.config.buildType}}\qjs.exe -c examples\hello.js -o hello.exe + .\hello.exe + - name: test api + run: | + build\${{matrix.config.buildType}}\api-test.exe + - name: test lre + run: | + build\${{matrix.config.buildType}}\lre-test.exe + - name: Set up Visual Studio shell + uses: egor-tensin/vs-shell@v2 + with: + arch: ${{ matrix.config.vsArch }} + - name: cxxtest + run: | + cl.exe /DJS_NAN_BOXING=0 /Zs cxxtest.cc + cl.exe /DJS_NAN_BOXING=1 /Zs cxxtest.cc + + windows-clang: + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + buildType: [Debug, Release] + steps: + - uses: actions/checkout@v7 + - name: install ninja + run: | + choco install ninja + ninja.exe --version + - name: build + run: | + git submodule update --init --checkout --depth 1 + cmake -B build -DQJS_BUILD_EXAMPLES=ON -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -DCMAKE_C_COMPILER=clang.exe -G "Ninja" + cmake --build build --config ${{matrix.buildType}} + - name: stats + run: | + build\qjs.exe -qd + - name: cxxtest + run: | + clang.exe -D JS_NAN_BOXING=0 -fsyntax-only cxxtest.cc + clang.exe -D JS_NAN_BOXING=1 -fsyntax-only cxxtest.cc + - name: test + run: | + cp build\fib.dll examples\ + cp build\point.dll examples\ + build\qjs.exe examples\test_fib.js + build\qjs.exe examples\test_point.js + build\run-test262.exe -c tests.conf + build\function_source.exe + + windows-clang-cl: + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + buildType: [Debug, Release] + steps: + - uses: actions/checkout@v7 + - name: build + run: | + git submodule update --init --checkout --depth 1 + cmake -B build -DQJS_BUILD_WERROR=ON -DQJS_BUILD_EXAMPLES=ON -G "Visual Studio 18" -T ClangCL + cmake --build build --config ${{matrix.buildType}} + - name: stats + run: | + build\${{matrix.buildType}}\qjs.exe -qd + - name: cxxtest + run: | + clang-cl.exe /DJS_NAN_BOXING=0 /Zs cxxtest.cc + clang-cl.exe /DJS_NAN_BOXING=1 /Zs cxxtest.cc + - name: test + run: | + cp build\${{matrix.buildType}}\fib.dll examples\ + cp build\${{matrix.buildType}}\point.dll examples\ + build\${{matrix.buildType}}\qjs.exe examples\test_fib.js + build\${{matrix.buildType}}\qjs.exe examples\test_point.js + build\${{matrix.buildType}}\run-test262.exe -c tests.conf + build\${{matrix.buildType}}\function_source.exe + - name: test api + run: | + build\${{matrix.buildType}}\api-test.exe + - name: test lre + run: | + build\${{matrix.buildType}}\lre-test.exe + + windows-ninja: + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + buildType: [Debug, Release] + steps: + - uses: actions/checkout@v7 + - name: install ninja + run: | + choco install ninja + ninja.exe --version + - name: build + run: | + git submodule update --init --checkout --depth 1 + cmake -B build -DQJS_BUILD_WERROR=ON -DQJS_BUILD_EXAMPLES=ON -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -G "Ninja" + cmake --build build + - name: stats + run: | + build\qjs.exe -qd + - name: test + run: | + cp build\fib.dll examples\ + cp build\point.dll examples\ + build\qjs.exe examples\test_fib.js + build\qjs.exe examples\test_point.js + build\run-test262.exe -c tests.conf + build\function_source.exe + - name: test api + run: | + build\api-test.exe + - name: test lre + run: | + build\lre-test.exe + + windows-sdk: + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + arch: [x64, Win32] + buildType: [Debug, Release] + steps: + - uses: actions/checkout@v7 + - name: Install windows sdk + uses: ChristopheLav/windows-sdk-install@v1 + with: + version-sdk: 26100 + features: 'OptionId.DesktopCPPx86,OptionId.DesktopCPPx64' + - name: build + run: | + cmake -B build -DQJS_BUILD_WERROR=ON -DQJS_BUILD_EXAMPLES=ON -DCMAKE_SYSTEM_VERSION="10.0.26100.0" -A ${{matrix.arch}} + cmake --build build --config ${{matrix.buildType}} + - name: stats + run: | + build\${{matrix.buildType}}\qjs.exe -qd + - name: test + run: | + cp build\${{matrix.buildType}}\fib.dll examples\ + cp build\${{matrix.buildType}}\point.dll examples\ + build\${{matrix.buildType}}\qjs.exe examples\test_fib.js + build\${{matrix.buildType}}\qjs.exe examples\test_point.js + build\${{matrix.buildType}}\run-test262.exe -c tests.conf + build\${{matrix.buildType}}\function_source.exe + - name: test api + run: | + build\${{matrix.buildType}}\api-test.exe + - name: test lre + run: | + build\${{matrix.buildType}}\lre-test.exe + + windows-mingw: + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + buildType: [Debug, Release] + sys: + - mingw32 + - mingw64 + - clang64 + - ucrt64 + defaults: + run: + shell: msys2 {0} + steps: + - uses: actions/checkout@v7 + - name: Setup MSYS2 + uses: msys2/setup-msys2@v2 + with: + update: true + msystem: ${{matrix.sys}} + install: >- + git + make + pacboy: >- + cmake:p + ninja:p + toolchain:p + - name: build + run: | + make BUILD_TYPE=${{matrix.buildType}} + - name: stats + run: | + make stats + ldd build/qjs + - name: cxxtest + if: ${{ matrix.sys != 'clang64' }} + run: | + make cxxtest + - name: cxxtest + if: ${{ matrix.sys == 'clang64' }} + run: | + make cxxtest CXX=clang++ + - name: test + run: | + make test + - name: test standalone + run: | + ./build/qjs -c examples/hello.js -o hello.exe + ./hello + - name: test api + run: | + ./build/api-test + - name: test lre + run: | + ./build/lre-test + windows-mingw-shared: + runs-on: windows-latest + defaults: + run: + shell: msys2 {0} + steps: + - uses: actions/checkout@v7 + - name: Setup MSYS2 + uses: msys2/setup-msys2@v2 + with: + install: >- + git + make + pacboy: >- + cmake:p + ninja:p + toolchain:p + - name: build + run: | + make BUILD_SHARED_LIBS=ON + ldd build/qjs + - name: stats + run: | + make stats + + emscripten: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: mymindstorm/setup-emsdk@v16 + - name: check emsdk + run: emcc -v + - name: build + run: | + emcmake cmake -B build -DQJS_BUILD_WERROR=ON -DQJS_BUILD_LIBC=ON + emmake make -C build qjs_wasm "-j$(getconf _NPROCESSORS_ONLN)" + - name: result + run: ls -lh build + wasi: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v7 + - uses: jcbhmr/setup-wasmtime@v2 + - name: setup wasi-sdk + run: | + wget -nv https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-29/wasi-sdk-29.0-x86_64-linux.deb -P "$RUNNER_TEMP" + sudo apt install "$RUNNER_TEMP/wasi-sdk-29.0-x86_64-linux.deb" + - name: test + run: | + cmake -B build -DQJS_BUILD_WERROR=ON -DCMAKE_TOOLCHAIN_FILE=/opt/wasi-sdk/share/cmake/wasi-sdk.cmake + make -C build qjs_exe + wasmtime run build/qjs -qd + echo "console.log('hello wasi!');" > t.js + wasmtime run --dir . build/qjs t.js + wasmtime run --dir . build/qjs --stack-size 64K tests/wasi-stack-limit.js + wasmtime run --dir . build/qjs tests/wasi-stack-limit.js + - name: build wasi reactor + run: | + cmake -B build -DQJS_BUILD_WERROR=ON -DCMAKE_TOOLCHAIN_FILE=/opt/wasi-sdk/share/cmake/wasi-sdk.cmake -DQJS_WASI_REACTOR=ON + make -C build qjs_wasi + ls -lh build/qjs.wasm + - name: check wasi reactor exports + run: | + exports=$(/opt/wasi-sdk/bin/llvm-nm --extern-only --defined-only --just-symbol-name build/qjs.wasm) + expected=( + # Reactor entry points + qjs_init qjs_init_argv qjs_get_context qjs_destroy + # libc allocator + malloc free realloc calloc + # Some of core JS_EXTERN API + JS_NewRuntime JS_FreeRuntime JS_NewContext JS_FreeContext + JS_Eval JS_FreeValue JS_GetException JS_ToCStringLen2 + # Some of quickjs-libc JS_LIBC_EXTERN API + js_std_add_helpers js_std_init_handlers + ) + missing=0 + for sym in "${expected[@]}"; do + echo "$exports" | grep -qx "$sym" || { echo "missing export: $sym"; missing=1; } + done + exit $missing + - name: check wasi reactor table is exported and growable + shell: node {0} + run: | + const m = new WebAssembly.Module(require('fs').readFileSync('build/qjs.wasm')); + const imports = {}; + for (const i of WebAssembly.Module.imports(m)) (imports[i.module] ??= {})[i.name] = () => {}; + new WebAssembly.Instance(m, imports).exports.__indirect_function_table.grow(1); + + cosmopolitan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - name: setup cosmocc + run: | + wget -nv https://github.com/jart/cosmopolitan/releases/download/4.0.2/cosmocc-4.0.2.zip -P "$RUNNER_TEMP" + mkdir -p "$RUNNER_TEMP/cosmocc" + unzip -q "$RUNNER_TEMP/cosmocc-4.0.2.zip" -d "$RUNNER_TEMP/cosmocc" + echo "$RUNNER_TEMP/cosmocc/bin" >> "$GITHUB_PATH" + - name: setup ape loader + run: | + sudo cp "$RUNNER_TEMP/cosmocc/bin/ape-x86_64.elf" /usr/bin/ape + sudo sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' > /proc/sys/fs/binfmt_misc/register" + sudo sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:' > /proc/sys/fs/binfmt_misc/register" + - name: build + run: | + cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=cosmocc -DCMAKE_AR="$(command -v cosmoar)" + cmake --build build -j$(getconf _NPROCESSORS_ONLN) + - name: stats + run: | + build/qjs -qd + - name: test + run: | + build/run-test262 -c tests.conf + + cygwin: + runs-on: windows-latest + defaults: + run: + shell: C:\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' + env: + CYGWIN_NOWINPATH: 1 + CHERE_INVOKING: 1 + steps: + - name: Set up Cygwin + uses: cygwin/cygwin-install-action@master + with: + packages: make cmake gcc-g++ bash + + - uses: actions/checkout@v7 + + - name: build + run: make + + - name: stats + run: make stats + + - name: cxxtest + run: | + make cxxtest + + - name: test + run: make test + + - name: test api + run: | + ./build/api-test + + - name: test lre + run: | + ./build/lre-test + + openbsd: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - name: build + test + uses: vmactions/openbsd-vm@v1 + with: + usesh: true + prepare: | + pkg_add cmake gmake + run: | + gmake + gmake stats + + freebsd: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - name: build + test + uses: vmactions/freebsd-vm@v1 + with: + usesh: true + prepare: | + pkg install -y cmake gmake + run: | + gmake + gmake stats + + android: + runs-on: ubuntu-latest + container: reactnativecommunity/react-native-android:v13.0 + steps: + - uses: actions/checkout@v7 + - name: Configure android arm64 + # see build options you can use in https://developer.android.com/ndk/guides/cmake + run: | + mkdir build + cd build + "$ANDROID_HOME/cmake/3.22.1/bin/cmake" "-DCMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk/26.0.10792818/build/cmake/android.toolchain.cmake" -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_PLATFORM=android-24 -DQJS_BUILD_LIBC=ON .. + - name: Build android arm64 + run: | + "$ANDROID_HOME/cmake/3.22.1/bin/cmake" --build build --target qjs + ls -lh build + + ios: + runs-on: macos-latest + steps: + - uses: actions/checkout@v7 + - name: configure + run: | + cmake -B build -GXcode -DQJS_BUILD_WERROR=ON -DCMAKE_SYSTEM_NAME:STRING=iOS -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED:BOOL=NO -DQJS_BUILD_LIBC=ON + - name: build + run: | + cmake --build build --config Release --target qjs + ls -lh build + + mimalloc-linux: + runs-on: ubuntu-24.04 + env: + QJS_BUILD_CLI_WITH_MIMALLOC: ON + MIMALLOC_SHOW_STATS: 1 + steps: + - uses: actions/checkout@v7 + - name: install dependencies + run: | + sudo apt update && sudo apt -y install libmimalloc-dev + - name: build + run: | + make + - name: cxxtest + run: | + make cxxtest + - name: test + run: | + make test + + mimalloc-macos: + runs-on: macos-latest + env: + QJS_BUILD_CLI_WITH_STATIC_MIMALLOC: ON + MIMALLOC_SHOW_STATS: 1 + steps: + - uses: actions/checkout@v7 + - name: install dependencies + run: | + brew install mimalloc + - name: build + run: | + make + - name: cxxtest + run: | + make cxxtest + - name: test + run: | + make test + + amalgam: + strategy: + matrix: + # TODO(bnoordhuis) test on windows + config: + - { os: ubuntu-latest } + - { os: macos-latest } + runs-on: ${{ matrix.config.os }} + steps: + - uses: actions/checkout@v7 + - name: build + run: | + make + - name: create amalgamation + run: | + make amalgam + - name: build amalgamation + run: | + unzip -d "$RUNNER_TEMP" build/quickjs-amalgam.zip + cc -Wall -I. -o "$RUNNER_TEMP/run-test262.o" -c run-test262.c + cc -Wall -I/ -DQJS_BUILD_LIBC -o "$RUNNER_TEMP/quickjs-amalgam.o" -c "$RUNNER_TEMP/quickjs-amalgam.c" + cc -o "$RUNNER_TEMP/run-test262" "$RUNNER_TEMP/run-test262.o" "$RUNNER_TEMP/quickjs-amalgam.o" -lm + - name: test + run: | + make test RUN262="$RUNNER_TEMP/run-test262" + + jscheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - name: jscheck + run: | + make jscheck + + parserless: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - name: build + run: | + make QJS_DISABLE_PARSER=ON QJS_BUILD_EXAMPLES=ON + - name: test + run: | + ./build/hello + ./build/hello_module + + + meson: + runs-on: ${{ matrix.platform }} + name: meson on ${{ matrix.platform }} (${{ matrix.mode.name }} ${{ matrix.flavor }}, ${{ matrix.features.name }}) + strategy: + fail-fast: false + matrix: + flavor: + - debug + - release + features: + - name: default + args: "" + - name: libc + args: -Dlibc=true + - name: mimalloc + args: -Dcli_mimalloc=auto + mode: + - name: default + args: -Dtests=enabled + extra_envs: {} + + # Alternative compiler setups + - name: gcc + args: -Dtests=enabled + extra_envs: + CC: gcc + CXX: g++ + - name: clang + args: -Dtests=enabled + extra_envs: + CC: clang + CXX: clang++ + + - name: sanitize + args: >- + "-Db_sanitize=address,undefined" + extra_envs: {} + + # This is for MSVC, which only supports AddressSanitizer. + # https://learn.microsoft.com/en-us/cpp/sanitizers/ + - name: sanitize+asanonly + args: -Db_sanitize=address + extra_envs: + ASAN_OPTIONS: report_globals=0:halt_on_error=1:abort_on_error=1:print_summary=1 + + - name: clang+sanitize + args: >- + "-Db_sanitize=address,undefined" + "-Db_lundef=false" + extra_envs: + CC: clang + CXX: clang++ + - name: clang+msan + args: >- + "-Db_sanitize=memory" + "-Db_lundef=false" + extra_envs: + CC: clang + CXX: clang++ + + # default clang on GitHub hosted runners is from MSYS2. + # Use Visual Studio supplied clang-cl instead. + # clang-cl's AddressSanitizer does not support the debug CRT (/MDd), + # so force the release CRT (/MD) for both debug and release builds. + - name: clang-cl+sanitize + args: >- + "-Db_sanitize=address,undefined" + "-Db_lundef=false" + "-Db_vscrt=md" + extra_envs: + CC: clang-cl + CXX: clang-cl + # clang-cl's AddressSanitizer reports false positive + # global-buffer-overflows on pooled string literals on Windows, + # same as MSVC; disable global checks (covered on Linux). + ASAN_OPTIONS: report_globals=0:halt_on_error=1:abort_on_error=1:print_summary=1 + platform: + - ubuntu-latest + - windows-latest + - macos-latest + + exclude: + # clang-cl only makes sense on windows. + - platform: ubuntu-latest + mode: + name: clang-cl+sanitize + - platform: macos-latest + mode: + name: clang-cl+sanitize + + # Use clang-cl instead of MSYS2 clang. + # + # we already tested clang+sanitize on linux, + # if this doesn't work, it should be an issue for MSYS2 team to consider. + - platform: windows-latest + mode: + name: clang + - platform: windows-latest + mode: + name: clang+sanitize + - platform: windows-latest + mode: + name: clang+msan + + # MSVC-only sanitizers + - platform: ubuntu-latest + mode: + name: sanitize+asanonly + - platform: macos-latest + mode: + name: sanitize+asanonly + - platform: windows-latest + mode: + name: sanitize + + # clang is the default on macos + # also gcc is an alias to clang + - platform: macos-latest + mode: + name: clang + - platform: macos-latest + mode: + name: gcc + + # gcc is the default on linux + - platform: ubuntu-latest + mode: + name: gcc + + # only run sanitizer tests on linux + # + # gcc/clang's codegen shouldn't massively change across platforms, + # and linux supports most of the sanitizers. + - platform: macos-latest + mode: + name: clang+sanitize + - platform: macos-latest + mode: + # macos does not support msan + name: clang+msan + - platform: macos-latest + mode: + name: sanitize + + steps: + - name: Setup meson + run: | + pipx install meson ninja + - name: Install mimalloc + if: ${{ matrix.platform == 'ubuntu-latest' && matrix.features.name == 'mimalloc' }} + run: sudo apt update && sudo apt -y install libmimalloc-dev + - name: Install mimalloc + if: ${{ matrix.platform == 'macos-latest' && matrix.features.name == 'mimalloc' }} + run: brew install mimalloc + # TODO: Install mimalloc on Windows + # You need to: + # - checkout mimalloc + # - `msbuild mimalloc\ide\vs2022\mimalloc.sln` + # - not cmake, because https://github.com/microsoft/mimalloc/issues/575#issuecomment-1112723975 + # - it is possible to integrate vcpkg with meson, but: + # - 1. the above issue + # - 2. the vcpkg port of mimalloc is outdated, and still broken on server 2019 + # - or maintain a meson port for mimalloc (and ensure it behaves correctly) + # - Make it findable with cmake + # - not the simpler pkg-config. although there was pkg-config in PATH, + # but that was from strawberry perl and thus broken + # ... good job, microsoft :)))) + + - name: Checkout + uses: actions/checkout@v7 + - name: Activate MSVC and Configure + if: ${{ matrix.platform == 'windows-latest' }} + env: ${{ matrix.mode.extra_envs }} + run: | + $extraArgs = @() + if ($env:CC -eq 'clang-cl') { + # Newer clang-cl no longer emits the asan runtime /defaultlib directives + # when -fsanitize is passed through /clang:, and meson links with lld-link + # directly (not the clang driver), so the asan/ubsan runtime is never pulled + # in. Link it explicitly and make its directory discoverable at link and run + # time (the dynamic runtime ships as a DLL). + $runtimeDir = (clang -print-runtime-dir).Trim() + $env:LIB = "$runtimeDir;$env:LIB" + "LIB=$env:LIB" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + $runtimeDir | Out-File -FilePath $env:GITHUB_PATH -Append -Encoding utf8 + $libs = "clang_rt.asan_dynamic-x86_64.lib clang_rt.asan_dynamic_runtime_thunk-x86_64.lib" + $extraArgs = @("-Dc_link_args=$libs", "-Dcpp_link_args=$libs") + } + meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} ${{ matrix.mode.args }} ${{ matrix.features.args }} --vsenv @extraArgs + - name: Configuring + if: ${{ matrix.platform != 'windows-latest' }} + env: ${{ matrix.mode.extra_envs }} + run: | + meson setup build-${{ matrix.flavor }} --buildtype=${{ matrix.flavor }} ${{ matrix.mode.args }} ${{ matrix.features.args }} + - name: Building + run: | + meson compile -C build-${{ matrix.flavor }} + + - name: Running tests + env: ${{ matrix.mode.extra_envs }} + run: | + meson test -C build-${{ matrix.flavor }} --timeout-multiplier 5 --print-errorlogs + meson test --benchmark -C build-${{ matrix.flavor }} --timeout-multiplier 5 --print-errorlogs + - uses: actions/upload-artifact@v7 + if: ${{ failure() }} + with: + name: ${{ matrix.platform }}-${{ matrix.mode.name }}-${{ matrix.features.name }}-${{ matrix.flavor }}-logs + path: build-${{ matrix.flavor }}/meson-logs diff --git a/userland/qjs/source/.github/workflows/docs.yml b/userland/qjs/source/.github/workflows/docs.yml new file mode 100644 index 0000000..b5e0f89 --- /dev/null +++ b/userland/qjs/source/.github/workflows/docs.yml @@ -0,0 +1,49 @@ +name: Docs + +on: + push: + branches: + - master + paths: + - 'docs/**' + - '.github/workflows/*docs.yml' + +jobs: + build: + name: Build Docusaurus + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-node@v7 + with: + node-version-file: 'docs/.nvmrc' + - name: Install dependencies + working-directory: ./docs + run: npm install + - name: Build + working-directory: ./docs + run: npm run build + - name: Upload Build Artifact + uses: actions/upload-pages-artifact@v5 + with: + path: docs/build + + deploy: + name: Deploy to GitHub Pages + needs: build + + # Grant GITHUB_TOKEN the permissions required to make a Pages deployment + permissions: + pages: write # to deploy to Pages + id-token: write # to verify the deployment originates from an appropriate source + + # Deploy to the github-pages environment + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v5 diff --git a/userland/qjs/source/.github/workflows/gc-stress.yml b/userland/qjs/source/.github/workflows/gc-stress.yml new file mode 100644 index 0000000..e64a883 --- /dev/null +++ b/userland/qjs/source/.github/workflows/gc-stress.yml @@ -0,0 +1,61 @@ +name: gc-stress + +on: + pull_request: + paths: + - '**' + - '!.gitignore' + - '!LICENSE' + - '!README.md' + - '!docs/**' + - '!examples/**' + - '.github/workflows/gc-stress.yml' + push: + branches: + - master + paths: + - '**' + - '!.gitignore' + - '!LICENSE' + - '!README.md' + - '!docs/**' + - '!examples/**' + - '.github/workflows/gc-stress.yml' + +jobs: + gc-stress: + runs-on: ${{ matrix.os }} + name: ${{ matrix.os }} + timeout-minutes: 30 + defaults: + run: + shell: ${{ matrix.os == 'windows-latest' && 'msys2 {0}' || 'bash' }} + env: + ASAN_OPTIONS: halt_on_error=1:detect_leaks=0 + strategy: + fail-fast: false + matrix: + include: + - { os: ubuntu-latest, asan: 'ON' } + - { os: macos-latest, asan: 'ON' } + - { os: windows-latest, asan: 'OFF' } + steps: + - uses: actions/checkout@v7 + - name: Setup MSYS2 + if: matrix.os == 'windows-latest' + uses: msys2/setup-msys2@v2 + with: + install: >- + git + make + pacboy: >- + cmake:p + ninja:p + toolchain:p + - name: build & test + run: >- + make test + BUILD_TYPE=RelWithDebInfo + QJS_ENABLE_GC_STRESS=ON + QJS_ENABLE_ASAN=${{ matrix.asan }} + RUN262='build/run-test262 -x gc-stress-skip.txt' diff --git a/userland/qjs/source/.github/workflows/release.yml b/userland/qjs/source/.github/workflows/release.yml new file mode 100644 index 0000000..deede46 --- /dev/null +++ b/userland/qjs/source/.github/workflows/release.yml @@ -0,0 +1,215 @@ +name: release + +on: + pull_request: + push: + tags: + - "v*.*.*" + +jobs: + check_meson_version: + runs-on: ubuntu-22.04 + if: ${{ startsWith(github.ref, 'refs/tags/v') }} + steps: + - uses: actions/checkout@v7 + - name: install meson and ninja + run: | + pip install --upgrade meson ninja + - name: check meson version + run: | + MESON_VERSION=$(meson introspect meson.build --projectinfo | jq -r '.version') + test "${{ github.ref_name }}" = "v${MESON_VERSION}" + + linux: + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + arch: [aarch64, armv7, riscv64, x86, x86_64] + steps: + - uses: actions/checkout@v7 + - uses: quickjs-ng/setup-alpine@master + with: + # mimalloc v3 (mimalloc3-dev) lives in the edge testing repo; enable it. + # riscv64 has no v3 build there, so it falls back to mimalloc2-dev. + branch: edge + arch: ${{matrix.arch}} + extra-repositories: | + http://dl-cdn.alpinelinux.org/alpine/edge/testing + packages: "build-base make cmake ${{ matrix.arch == 'riscv64' && 'mimalloc2-dev' || 'mimalloc3-dev' }}" + apk-tools-url: https://raw.githubusercontent.com/quickjs-ng/apk-for-ci/refs/heads/master/apk.static#!sha256!34bb1a96f0258982377a289392d4ea9f3f4b767a4bb5806b1b87179b79ad8a1c + - name: build + shell: alpine.sh {0} + run: | + mkdir build + cd build + cmake -DQJS_BUILD_WERROR=ON -DQJS_BUILD_CLI_STATIC=ON -DQJS_BUILD_CLI_WITH_STATIC_MIMALLOC=ON .. + cd .. + cmake --build build --target qjs_exe -j$(getconf _NPROCESSORS_ONLN) + cmake --build build --target qjsc -j$(getconf _NPROCESSORS_ONLN) + mv build/qjs build/qjs-linux-${{matrix.arch}} + mv build/qjsc build/qjsc-linux-${{matrix.arch}} + - name: check + shell: alpine.sh {0} + run: | + file build/*-linux-${{matrix.arch}} + - name: upload + uses: actions/upload-artifact@v7 + with: + name: qjs-linux-${{matrix.arch}} + path: build/*-linux-${{matrix.arch}} + + macos: + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + arch: [arm64, x86_64] + steps: + - uses: actions/checkout@v7 + - name: install mimalloc + if: ${{ matrix.arch == 'arm64' }} + run: brew install mimalloc + - name: build + run: | + mkdir build + cd build + cmake -DCMAKE_OSX_ARCHITECTURES=${{matrix.arch}} -DQJS_BUILD_WERROR=ON ${{ matrix.arch == 'arm64' && '-DQJS_BUILD_CLI_WITH_STATIC_MIMALLOC=ON -DCMAKE_PREFIX_PATH=/opt/homebrew' || '' }} .. + make -j$(getconf _NPROCESSORS_ONLN) + - name: build amalgamation + if: ${{ matrix.arch == 'arm64' }} + run: make amalgam # writes build/quickjs-amalgam.zip; runs qjs natively on arm64 + - name: rename + run: | + mv build/qjs build/qjs-darwin-${{matrix.arch}} + mv build/qjsc build/qjsc-darwin-${{matrix.arch}} + - name: check + run: | + lipo -info build/qjs-darwin-${{matrix.arch}} build/qjsc-darwin-${{matrix.arch}} + - name: upload amalgamation + if: ${{ matrix.arch == 'arm64' }} + uses: actions/upload-artifact@v7 + with: + name: quickjs-amalgam.zip + path: build/quickjs-amalgam.zip + compression-level: 0 # already compressed + - name: upload + uses: actions/upload-artifact@v7 + with: + name: qjs-darwin-${{matrix.arch}} + path: build/*-darwin-${{matrix.arch}} + + windows: + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + arch: [x86, x86_64] + defaults: + run: + shell: msys2 {0} + steps: + - uses: actions/checkout@v7 + - name: Setup MSYS2 + uses: msys2/setup-msys2@v2 + with: + msystem: ${{ matrix.arch == 'x86' && 'mingw32' || 'ucrt64' }} + install: >- + git + make + pacboy: >- + cmake:p + ninja:p + toolchain:p + ${{ matrix.arch == 'x86_64' && 'mimalloc:p' || '' }} + - name: build + env: + QJS_BUILD_CLI_WITH_STATIC_MIMALLOC: ${{ matrix.arch == 'x86_64' && 'ON' || 'OFF' }} + run: | + make + mv build/qjs.exe build/qjs-windows-${{matrix.arch}}.exe + mv build/qjsc.exe build/qjsc-windows-${{matrix.arch}}.exe + - name: check + run: | + file build/qjs-windows-${{matrix.arch}}.exe + ldd build/qjs-windows-${{matrix.arch}}.exe build/qjsc-windows-${{matrix.arch}}.exe + - name: upload + uses: actions/upload-artifact@v7 + with: + name: qjs-windows-${{matrix.arch}} + path: build/*-windows-${{matrix.arch}}.exe + + wasi: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v7 + - name: setup wasi-sdk + run: | + wget -nv https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-29/wasi-sdk-29.0-x86_64-linux.deb -P "$RUNNER_TEMP" + sudo apt install "$RUNNER_TEMP/wasi-sdk-29.0-x86_64-linux.deb" + - name: build + run: | + cmake -B build -DCMAKE_TOOLCHAIN_FILE=/opt/wasi-sdk/share/cmake/wasi-sdk.cmake -DQJS_BUILD_WERROR=ON + make -C build qjs_exe + mv build/qjs build/qjs-wasi.wasm + - name: build wasi reactor + run: | + cmake -B build -DCMAKE_TOOLCHAIN_FILE=/opt/wasi-sdk/share/cmake/wasi-sdk.cmake -DQJS_BUILD_WERROR=ON -DQJS_WASI_REACTOR=ON + make -C build qjs_wasi + mv build/qjs.wasm build/qjs-wasi-reactor.wasm + - name: upload + uses: actions/upload-artifact@v7 + with: + name: qjs-wasi + path: | + build/qjs-wasi.wasm + build/qjs-wasi-reactor.wasm + + cosmopolitan: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v7 + - name: setup cosmocc + run: | + wget -nv https://github.com/jart/cosmopolitan/releases/download/4.0.2/cosmocc-4.0.2.zip -P "$RUNNER_TEMP" + mkdir -p "$RUNNER_TEMP/cosmocc" + unzip -q "$RUNNER_TEMP/cosmocc-4.0.2.zip" -d "$RUNNER_TEMP/cosmocc" + echo "$RUNNER_TEMP/cosmocc/bin" >> "$GITHUB_PATH" + - name: setup ape loader + run: | + sudo cp "$RUNNER_TEMP/cosmocc/bin/ape-x86_64.elf" /usr/bin/ape + sudo sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' > /proc/sys/fs/binfmt_misc/register" + sudo sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:' > /proc/sys/fs/binfmt_misc/register" + - name: build + run: | + cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=cosmocc -DCMAKE_AR="$(command -v cosmoar)" -DQJS_BUILD_CLI_STATIC=ON + cmake --build build --target qjs_exe -j$(getconf _NPROCESSORS_ONLN) + cmake --build build --target qjsc -j$(getconf _NPROCESSORS_ONLN) + mv build/qjs build/qjs-cosmo.com + mv build/qjsc build/qjsc-cosmo.com + - name: check + run: | + file build/*-cosmo.com + build/qjs-cosmo.com -qd + - name: upload + uses: actions/upload-artifact@v7 + with: + name: qjs-cosmo + path: build/*-cosmo.com + + upload-to-release: + needs: [linux, macos, windows, wasi, cosmopolitan, check_meson_version] + runs-on: ubuntu-22.04 + steps: + - name: get assets + uses: actions/download-artifact@v8 + with: + path: build + merge-multiple: true + - run: ls -R build + - name: release + if: ${{ startsWith(github.ref, 'refs/tags/v') }} + uses: softprops/action-gh-release@v3 + with: + files: | + build/* diff --git a/userland/qjs/source/.github/workflows/test-docs.yml b/userland/qjs/source/.github/workflows/test-docs.yml new file mode 100644 index 0000000..93784d5 --- /dev/null +++ b/userland/qjs/source/.github/workflows/test-docs.yml @@ -0,0 +1,23 @@ +name: Test Docs + +on: + pull_request: + paths: + - 'docs/**' + - '.github/workflows/*docs.yml' + +jobs: + test-docs: + name: Test Docusaurus build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-node@v7 + with: + node-version-file: 'docs/.nvmrc' + - name: Install dependencies + working-directory: ./docs + run: npm install + - name: Build + working-directory: ./docs + run: npm run build diff --git a/userland/qjs/source/.github/workflows/tsan.yml b/userland/qjs/source/.github/workflows/tsan.yml new file mode 100644 index 0000000..57f6e78 --- /dev/null +++ b/userland/qjs/source/.github/workflows/tsan.yml @@ -0,0 +1,32 @@ +name: tsan + +on: + push: + branches: + - master + paths: + - '**' + - '!.gitignore' + - '!LICENSE' + - '!README.md' + - '!docs/**' + - '!examples/**' + - '.github/workflows/tsan.yml' + - '.github/workflows/valgrind.yml' + workflow_dispatch: + +jobs: + linux: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + submodules: true + - name: build + run: | + cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DQJS_BUILD_WERROR=ON -DQJS_ENABLE_TSAN=ON + cmake --build build -j`nproc` + - name: test + run: | + git submodule update --init --checkout --depth 1 + ./build/run-test262 -m -c test262.conf -c test262-fast.conf -a diff --git a/userland/qjs/source/.github/workflows/valgrind.yml b/userland/qjs/source/.github/workflows/valgrind.yml new file mode 100644 index 0000000..b29b085 --- /dev/null +++ b/userland/qjs/source/.github/workflows/valgrind.yml @@ -0,0 +1,33 @@ +name: valgrind + +on: + push: + branches: + - master + paths: + - '**' + - '!.gitignore' + - '!LICENSE' + - '!README.md' + - '!docs/**' + - '!examples/**' + - '.github/workflows/tsan.yml' + - '.github/workflows/valgrind.yml' + workflow_dispatch: + +jobs: + linux: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + submodules: true + - name: install valgrind + run: sudo apt-get update && sudo apt-get install valgrind + - name: build + run: | + make BUILD_TYPE=RelWithDebInfo + - name: test + run: | + git submodule update --init --checkout --depth 1 + valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --error-exitcode=1 ./build/run-test262 -m -c test262.conf -c test262-fast.conf -a diff --git a/userland/qjs/source/.gitignore b/userland/qjs/source/.gitignore new file mode 100644 index 0000000..8268f6d --- /dev/null +++ b/userland/qjs/source/.gitignore @@ -0,0 +1,15 @@ +*.a +*.orig +*.so +.obj/ +build/ +build-*/ +unicode/ +.idea +cmake-* +.vs +out/ +CMakeUserPresets.json +fuzz +.vscode/ +microbench*.txt diff --git a/userland/qjs/source/.gitmodules b/userland/qjs/source/.gitmodules new file mode 100644 index 0000000..91828e0 --- /dev/null +++ b/userland/qjs/source/.gitmodules @@ -0,0 +1,5 @@ +[submodule "test262"] + path = test262 + url = https://github.com/tc39/test262 + shallow = true + update = none diff --git a/userland/qjs/source/CMakeLists.txt b/userland/qjs/source/CMakeLists.txt new file mode 100644 index 0000000..a9c5413 --- /dev/null +++ b/userland/qjs/source/CMakeLists.txt @@ -0,0 +1,579 @@ +cmake_minimum_required(VERSION 3.10) + +project(quickjs LANGUAGES C) + +include(CheckCCompilerFlag) +include(GNUInstallDirs) + +set(CMAKE_C_VISIBILITY_PRESET hidden) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS ON) +set(CMAKE_C_STANDARD 11) + +macro(xoption OPTION_NAME OPTION_TEXT OPTION_DEFAULT) + option(${OPTION_NAME} ${OPTION_TEXT} ${OPTION_DEFAULT}) + if(DEFINED ENV{${OPTION_NAME}}) + # Allow setting the option through an environment variable. + set(${OPTION_NAME} $ENV{${OPTION_NAME}}) + endif() + if(${OPTION_NAME}) + add_definitions(-D${OPTION_NAME}) + endif() + message(STATUS " ${OPTION_NAME}: ${${OPTION_NAME}}") +endmacro() + +# note: QJS_ENABLE_TSAN is currently incompatible with the other sanitizers but we +# don't explicitly check for that because who knows what the future will bring? +# QJS_ENABLE_MSAN only works with clang at the time of writing; also not checked +# for the same reason +xoption(BUILD_SHARED_LIBS "Build a shared library" OFF) +# if we ever require CMake 3.21, we can automatically detect this setting by looking at PROJECT_IS_TOP_LEVEL +# similar to how glslang does +xoption(QJS_ENABLE_INSTALL "Enable quickjs installation" ON) +xoption(QJS_BUILD_WERROR "Build with -Werror" OFF) +xoption(QJS_BUILD_EXAMPLES "Build examples" OFF) +xoption(QJS_BUILD_CLI_STATIC "Build a static qjs executable" OFF) +xoption(QJS_BUILD_CLI_WITH_MIMALLOC "Build the qjs executable with mimalloc" OFF) +xoption(QJS_BUILD_CLI_WITH_STATIC_MIMALLOC "Build the qjs executable with mimalloc (statically linked)" OFF) +xoption(QJS_DISABLE_PARSER "Disable JS source code parser" OFF) +xoption(QJS_ENABLE_ASAN "Enable AddressSanitizer (ASan)" OFF) +xoption(QJS_ENABLE_MSAN "Enable MemorySanitizer (MSan)" OFF) +xoption(QJS_ENABLE_TSAN "Enable ThreadSanitizer (TSan)" OFF) +xoption(QJS_ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan)" OFF) +xoption(QJS_ENABLE_GC_STRESS "Force a full GC before every allocation (GC stress test)" OFF) + +# Used to properly define JS_LIBC_EXTERN. +add_compile_definitions(QUICKJS_NG_BUILD) + +# MINGW doesn't exist in older cmake versions, newer versions don't know +# about CMAKE_COMPILER_IS_MINGW, and there is no unique CMAKE_C_COMPILER_ID +# for mingw-based compilers... +if(MINGW) + # do nothing +elseif(CMAKE_C_COMPILER MATCHES "mingw") + set(MINGW TRUE) +else() + set(MINGW FALSE) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "tvOS") + set(TVOS TRUE) +else() + set(TVOS FALSE) +endif() +if(CMAKE_SYSTEM_NAME STREQUAL "watchOS") + set(WATCHOS TRUE) +else() + set(WATCHOS FALSE) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") + set(SUNOS TRUE) +else() + set(SUNOS FALSE) +endif() + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "No build type selected, default to Release") + set(CMAKE_BUILD_TYPE "Release") +endif() + +message(STATUS "Building in ${CMAKE_BUILD_TYPE} mode") +message(STATUS "Building with ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION} on ${CMAKE_SYSTEM}") + +macro(xcheck_add_c_compiler_flag FLAG) + string(REPLACE "-" "" FLAG_NO_HYPHEN ${FLAG}) + check_c_compiler_flag(${FLAG} COMPILER_SUPPORTS_${FLAG_NO_HYPHEN}) + if(COMPILER_SUPPORTS_${FLAG_NO_HYPHEN}) + add_compile_options(${FLAG}) + endif() +endmacro() + +xcheck_add_c_compiler_flag(-Wall) +if(NOT MSVC AND NOT IOS AND NOT TVOS AND NOT WATCHOS) + if(QJS_BUILD_WERROR) + xcheck_add_c_compiler_flag(-Werror) + endif() + xcheck_add_c_compiler_flag(-Wextra) +endif() +xcheck_add_c_compiler_flag(-Wformat=2) +xcheck_add_c_compiler_flag(-Wno-implicit-fallthrough) +xcheck_add_c_compiler_flag(-Wno-sign-compare) +xcheck_add_c_compiler_flag(-Wno-missing-field-initializers) +xcheck_add_c_compiler_flag(-Wno-unused-parameter) +xcheck_add_c_compiler_flag(-Wno-unused-but-set-variable) +xcheck_add_c_compiler_flag(-Wno-unused-result) +xcheck_add_c_compiler_flag(-Wno-stringop-truncation) +xcheck_add_c_compiler_flag(-Wno-array-bounds) +if(NOT SUNOS) +xcheck_add_c_compiler_flag(-funsigned-char) +endif() + +# Clang on Windows without MSVC command line fails because the codebase uses +# functions like strcpy over strcpy_s +if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND WIN32 AND NOT MSVC) + add_compile_definitions(_CRT_SECURE_NO_WARNINGS) + add_compile_definitions(_CRT_NONSTDC_NO_DEPRECATE) +endif() + +# ClangCL is command line compatible with MSVC, so 'MSVC' is set. +if(MSVC) + xcheck_add_c_compiler_flag(-Wno-unsafe-buffer-usage) + xcheck_add_c_compiler_flag(-Wno-sign-conversion) + xcheck_add_c_compiler_flag(-Wno-nonportable-system-include-path) + xcheck_add_c_compiler_flag(-Wno-implicit-int-conversion) + xcheck_add_c_compiler_flag(-Wno-shorten-64-to-32) + xcheck_add_c_compiler_flag(-Wno-reserved-macro-identifier) + xcheck_add_c_compiler_flag(-Wno-reserved-identifier) + xcheck_add_c_compiler_flag(-Wdeprecated-declarations) + xcheck_add_c_compiler_flag(/experimental:c11atomics) + xcheck_add_c_compiler_flag(/wd4018) # -Wno-sign-conversion + xcheck_add_c_compiler_flag(/wd4061) # -Wno-implicit-fallthrough + xcheck_add_c_compiler_flag(/wd4100) # -Wno-unused-parameter + xcheck_add_c_compiler_flag(/wd4200) # -Wno-zero-length-array + xcheck_add_c_compiler_flag(/wd4242) # -Wno-shorten-64-to-32 + xcheck_add_c_compiler_flag(/wd4244) # -Wno-shorten-64-to-32 + xcheck_add_c_compiler_flag(/wd4245) # -Wno-sign-compare + xcheck_add_c_compiler_flag(/wd4267) # -Wno-shorten-64-to-32 + xcheck_add_c_compiler_flag(/wd4388) # -Wno-sign-compare + xcheck_add_c_compiler_flag(/wd4389) # -Wno-sign-compare + xcheck_add_c_compiler_flag(/wd4456) # Hides previous local declaration + xcheck_add_c_compiler_flag(/wd4457) # Hides function parameter + xcheck_add_c_compiler_flag(/wd4710) # Function not inlined + xcheck_add_c_compiler_flag(/wd4711) # Function was inlined + xcheck_add_c_compiler_flag(/wd4820) # Padding added after construct + xcheck_add_c_compiler_flag(/wd4996) # -Wdeprecated-declarations + xcheck_add_c_compiler_flag(/wd5045) # Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified +endif() + +# Set a 8MB default stack size on Windows. +# It defaults to 1MB on MSVC, which is the same as our current JS stack size, +# so it will overflow and crash otherwise. +# On MinGW it defaults to 2MB. +if(WIN32) + if(MSVC) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:8388608") + elseif(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT MINGW) + # Clang frontend (clang.exe) targeting the MSVC ABI (using lld-link) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Xlinker /STACK:8388608") + else() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--stack,8388608") + endif() +endif() + +# MacOS and GCC 11 or later need -Wno-maybe-uninitialized +# https://github.com/quickjs-ng/quickjs/issues/453 +if(APPLE AND CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 11) + xcheck_add_c_compiler_flag(-Wno-maybe-uninitialized) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "WASI") + add_compile_definitions( + _WASI_EMULATED_PROCESS_CLOCKS + _WASI_EMULATED_SIGNAL + ) + add_link_options( + -Wl,-z,stack-size=2097152 + -lwasi-emulated-process-clocks + -lwasi-emulated-signal + ) +endif() + +if(CMAKE_BUILD_TYPE MATCHES "Debug") + xcheck_add_c_compiler_flag(/Od) + xcheck_add_c_compiler_flag(-O0) + xcheck_add_c_compiler_flag(-ggdb) + xcheck_add_c_compiler_flag(-fno-omit-frame-pointer) +endif() + +if(BUILD_SHARED_LIBS) + message(STATUS "Building a shared library") +endif() + +if(QJS_ENABLE_ASAN) +message(STATUS "Building with ASan") +add_compile_options( + -fsanitize=address + -fno-sanitize-recover=all + -fno-omit-frame-pointer +) +add_link_options( + -fsanitize=address + -fno-sanitize-recover=all + -fno-omit-frame-pointer +) +endif() + +if(QJS_ENABLE_MSAN) +message(STATUS "Building with MSan") +add_compile_options( + -fsanitize=memory + -fno-sanitize-recover=all + -fno-omit-frame-pointer +) +add_link_options( + -fsanitize=memory + -fno-sanitize-recover=all + -fno-omit-frame-pointer +) +endif() + +if(QJS_ENABLE_TSAN) +message(STATUS "Building with TSan") +add_compile_options( + -fsanitize=thread + -fno-sanitize-recover=all + -fno-omit-frame-pointer +) +add_link_options( + -fsanitize=thread + -fno-sanitize-recover=all + -fno-omit-frame-pointer +) +endif() + +if(QJS_ENABLE_UBSAN) +message(STATUS "Building with UBSan") +add_compile_options( + -fsanitize=undefined + -fno-sanitize-recover=all + -fno-omit-frame-pointer +) +add_link_options( + -fsanitize=undefined + -fno-sanitize-recover=all + -fno-omit-frame-pointer +) +endif() + +if(QJS_ENABLE_GC_STRESS) +message(STATUS "Building with GC stress (FORCE_GC_AT_MALLOC)") +add_compile_definitions(FORCE_GC_AT_MALLOC) +endif() + + +# QuickJS library +# + +xoption(QJS_BUILD_LIBC "Build standard library modules as part of the library" OFF) +macro(add_qjs_libc_if_needed target) + if(NOT QJS_BUILD_LIBC) + target_link_libraries(${target} PRIVATE qjs-libc) + endif() +endmacro() +macro(add_static_if_needed target) + if(QJS_BUILD_CLI_STATIC OR MINGW) + target_link_options(${target} PRIVATE -static) + if(MINGW) + target_link_options(${target} PRIVATE -static-libgcc) + endif() + endif() +endmacro() + +set(qjs_sources + dtoa.c + libregexp.c + libunicode.c + quickjs.c +) + +if(QJS_BUILD_LIBC) + list(APPEND qjs_sources quickjs-libc.c) + # The definition must be added to the entire project. + add_compile_definitions(QJS_BUILD_LIBC) +endif() +list(APPEND qjs_defines _GNU_SOURCE) +if(WIN32) + # NB: Windows 7 is EOL and we are only supporting in so far as it doesn't interfere with progress. + list(APPEND qjs_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0601) +else() + # UNIX-y platforms. + list(APPEND qjs_libs m) +endif() +if(TVOS) + list(APPEND qjs_defines _TVOS) +endif() +if(WATCHOS) + list(APPEND qjs_defines _WATCHOS) +endif() +list(APPEND qjs_libs ${CMAKE_DL_LIBS}) +find_package(Threads) +if(NOT CMAKE_SYSTEM_NAME STREQUAL "WASI") + list(APPEND qjs_libs ${CMAKE_THREAD_LIBS_INIT}) +endif() + +add_library(qjs ${qjs_sources}) +target_compile_definitions(qjs PRIVATE ${qjs_defines}) +target_include_directories(qjs PUBLIC + $ + $ +) +target_link_libraries(qjs PUBLIC ${qjs_libs}) + +# Pass a compiler definition so that Windows gets its declspec's right. +get_target_property(QJS_LIB_TYPE qjs TYPE) +if(QJS_LIB_TYPE STREQUAL "SHARED_LIBRARY") + target_compile_definitions(qjs + PRIVATE BUILDING_QJS_SHARED + PUBLIC USING_QJS_SHARED + ) +endif() + +# An interface library for modules. +add_library(qjs_module_lib INTERFACE) +target_include_directories(qjs_module_lib INTERFACE + $ +) +target_compile_definitions(qjs_module_lib INTERFACE + QUICKJS_NG_MODULE_BUILD + $ +) +if(WIN32) + # Since Windows cannot resolve symbols at load time, we need to + # explicitly link it to qjs. + target_link_libraries(qjs_module_lib INTERFACE + qjs + ) +endif() + +if(NOT QJS_BUILD_LIBC) + add_library(qjs-libc STATIC quickjs-libc.c) + target_compile_definitions(qjs-libc PRIVATE ${qjs_defines}) + target_link_libraries(qjs-libc PRIVATE ${qjs_libs} qjs) +endif() + +if(EMSCRIPTEN) + add_executable(qjs_wasm ${qjs_sources}) + target_link_options(qjs_wasm PRIVATE + # in emscripten 3.x, this will be set to 16k which is too small for quickjs. #write sth. to force github rebuild + -sSTACK_SIZE=2097152 # let it be 2m = 2 * 1024 * 1024 = 2097152, otherwise, stack overflow may be occured at bootstrap + -sNO_INVOKE_RUN + -sNO_EXIT_RUNTIME + -sMODULARIZE # do not mess the global + -sEXPORT_ES6 # export js file to morden es module + -sEXPORT_NAME=getQuickJs # give a name + -sTEXTDECODER=1 # it will be 2 if we use -Oz, and that will cause js -> c string convertion fail + -sNO_DEFAULT_TO_CXX # this project is pure c project, no need for c plus plus handle + -sEXPORTED_RUNTIME_METHODS=ccall,cwrap + ) + target_compile_definitions(qjs_wasm PRIVATE ${qjs_defines}) + target_link_libraries(qjs_wasm PRIVATE m) +endif() + + +# QuickJS bytecode compiler +# + +add_executable(qjsc + qjsc.c +) +add_qjs_libc_if_needed(qjsc) +add_static_if_needed(qjsc) +target_compile_definitions(qjsc PRIVATE ${qjs_defines}) +target_link_libraries(qjsc PRIVATE qjs) + + +# QuickJS CLI +# + +add_executable(qjs_exe + gen/repl.c + gen/standalone.c + qjs.c +) +add_qjs_libc_if_needed(qjs_exe) +add_static_if_needed(qjs_exe) +set_target_properties(qjs_exe PROPERTIES + OUTPUT_NAME "qjs" + PDB_NAME "qjs_cli" + COMPILE_PDB_NAME "qjs_cli" +) +target_compile_definitions(qjs_exe PRIVATE ${qjs_defines}) +target_link_libraries(qjs_exe PRIVATE qjs) +if (NOT WIN32) + set_target_properties(qjs_exe PROPERTIES ENABLE_EXPORTS TRUE) +endif() + +# WASI Reactor +# + +if(CMAKE_SYSTEM_NAME STREQUAL "WASI") + option(QJS_WASI_REACTOR "Build WASI reactor (exports library functions, no _start)" OFF) + if(QJS_WASI_REACTOR) + add_executable(qjs_wasi + quickjs-libc.c + qjs-wasi-reactor.c + ) + set_target_properties(qjs_wasi PROPERTIES + OUTPUT_NAME "qjs" + SUFFIX ".wasm" + ) + target_compile_definitions(qjs PRIVATE BUILDING_QJS_SHARED) + target_compile_definitions(qjs_wasi PRIVATE ${qjs_defines} BUILDING_QJS_SHARED) + target_link_libraries(qjs_wasi qjs) + target_link_options(qjs_wasi PRIVATE + -mexec-model=reactor + # Export all symbols with default visibility (JS_EXTERN functions) + -Wl,--export-dynamic + # Memory management (libc symbols need explicit export) + -Wl,--export=malloc + -Wl,--export=free + -Wl,--export=realloc + -Wl,--export=calloc + # Enable hosts to pass callbacks to JS_SetInterruptHandler, + # JS_SetModuleLoaderFunc2, etc. + -Wl,--export-table + -Wl,--growable-table + ) + endif() +endif() + +if(QJS_BUILD_CLI_WITH_MIMALLOC OR QJS_BUILD_CLI_WITH_STATIC_MIMALLOC) + find_package(mimalloc REQUIRED) + target_compile_definitions(qjs_exe PRIVATE QJS_USE_MIMALLOC) + # Upstream mimalloc doesn't provide a way to know if both libraries are supported. + if(QJS_BUILD_CLI_WITH_STATIC_MIMALLOC) + target_link_libraries(qjs_exe PRIVATE mimalloc-static) + else() + target_link_libraries(qjs_exe PRIVATE mimalloc) + endif() +endif() + +# Test262 runner +# + +if(NOT EMSCRIPTEN) + add_executable(run-test262 + run-test262.c + ) + add_qjs_libc_if_needed(run-test262) + target_compile_definitions(run-test262 PRIVATE ${qjs_defines}) + target_link_libraries(run-test262 PRIVATE qjs) +endif() + +# C API tests +# + +add_executable(api-test + api-test.c +) +target_compile_definitions(api-test PRIVATE ${qjs_defines}) +target_link_libraries(api-test PRIVATE qjs) +add_qjs_libc_if_needed(api-test) + +add_executable(lre-test + lre-test.c + libregexp.c + libunicode.c +) +target_compile_definitions(lre-test PRIVATE ${qjs_defines}) + +# Unicode generator +# + +# Note: do not link libunicode.c here, it needs the generated libunicode-table.h, +# which would make it impossible to regenerate the table from scratch. +add_executable(unicode_gen EXCLUDE_FROM_ALL + unicode_gen.c +) +target_compile_definitions(unicode_gen PRIVATE ${qjs_defines}) + +add_executable(function_source + gen/function_source.c +) +add_qjs_libc_if_needed(function_source) +target_include_directories(function_source PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_compile_definitions(function_source PRIVATE ${qjs_defines}) +target_link_libraries(function_source PRIVATE qjs) + +# Examples +# + +if(QJS_BUILD_EXAMPLES) + if(WIN32 AND NOT (QJS_LIB_TYPE STREQUAL "SHARED_LIBRARY")) + message(AUTHOR_WARNING + "Binary modules used with static qjs on Windows. There might be\n" + "runtime errors when the module is used due to two copies of qjs\n" + "in memory.\n" + "Please use \"-DBUILD_SHARED_LIBS=true\" if possible." + ) + endif() + + add_executable(hello + gen/hello.c + ) + add_qjs_libc_if_needed(hello) + target_include_directories(hello PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_compile_definitions(hello PRIVATE ${qjs_defines}) + target_link_libraries(hello PRIVATE qjs) + + add_executable(hello_module + gen/hello_module.c + ) + add_qjs_libc_if_needed(hello_module) + target_include_directories(hello_module PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_compile_definitions(hello_module PRIVATE ${qjs_defines}) + target_link_libraries(hello_module PRIVATE qjs) + + add_library(fib MODULE examples/fib.c) + set_target_properties(fib PROPERTIES + PREFIX "" + ) + target_link_libraries(fib PRIVATE qjs_module_lib) + if(APPLE) + target_link_options(fib PRIVATE -undefined dynamic_lookup) + endif() + + add_library(point MODULE examples/point.c) + set_target_properties(point PROPERTIES + PREFIX "" + ) + target_link_libraries(point PRIVATE qjs_module_lib) + if(APPLE) + target_link_options(point PRIVATE -undefined dynamic_lookup) + endif() + + add_executable(test_fib + gen/test_fib.c + ) + add_qjs_libc_if_needed(test_fib) + target_include_directories(test_fib PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_compile_definitions(test_fib PRIVATE ${qjs_defines}) + target_link_libraries(test_fib PRIVATE qjs) + # Loads fib.so which depends on symbols from libqjs. + set_target_properties(test_fib PROPERTIES ENABLE_EXPORTS TRUE) +endif() + +# Install target +# + +if (QJS_ENABLE_INSTALL) + file(STRINGS quickjs.h quickjs_h REGEX QJS_VERSION) + string(REGEX MATCH "QJS_VERSION_MAJOR ([0-9]*)" _ "${quickjs_h}") + set(QJS_VERSION_MAJOR ${CMAKE_MATCH_1}) + string(REGEX MATCH "QJS_VERSION_MINOR ([0-9]*)" _ "${quickjs_h}") + set(QJS_VERSION_MINOR ${CMAKE_MATCH_1}) + string(REGEX MATCH "QJS_VERSION_PATCH ([0-9]*)" _ "${quickjs_h}") + set(QJS_VERSION_PATCH ${CMAKE_MATCH_1}) + set_target_properties(qjs PROPERTIES + VERSION ${QJS_VERSION_MAJOR}.${QJS_VERSION_MINOR}.${QJS_VERSION_PATCH} + SOVERSION ${QJS_VERSION_MAJOR} + ) + install(FILES quickjs.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + if(QJS_BUILD_LIBC) + install(FILES quickjs-libc.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + endif() + if(NOT IOS AND NOT TVOS AND NOT WATCHOS) + install(TARGETS qjs_exe RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(TARGETS qjsc RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(FILES qjs.man DESTINATION ${CMAKE_INSTALL_DATADIR}/man/man1 RENAME qjs.1) + install(FILES qjsc.man DESTINATION ${CMAKE_INSTALL_DATADIR}/man/man1 RENAME qjsc.1) + endif() + install(TARGETS qjs EXPORT qjsConfig + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(EXPORT qjsConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/qjs) + install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR}) + install(DIRECTORY examples DESTINATION ${CMAKE_INSTALL_DOCDIR}) +endif() diff --git a/userland/qjs/source/LICENSE b/userland/qjs/source/LICENSE new file mode 100644 index 0000000..fae6573 --- /dev/null +++ b/userland/qjs/source/LICENSE @@ -0,0 +1,24 @@ +The MIT License (MIT) + +Copyright (c) 2017-2026 Fabrice Bellard +Copyright (c) 2017-2024 Charlie Gordon +Copyright (c) 2023-2026 Ben Noordhuis +Copyright (c) 2023-2026 Saúl Ibarra Corretgé + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/userland/qjs/source/Makefile b/userland/qjs/source/Makefile new file mode 100644 index 0000000..1bf0c4a --- /dev/null +++ b/userland/qjs/source/Makefile @@ -0,0 +1,149 @@ +# +# QuickJS Javascript Engine +# +# Copyright (c) 2017-2026 Fabrice Bellard +# Copyright (c) 2017-2024 Charlie Gordon +# Copyright (c) 2023-2026 Ben Noordhuis +# Copyright (c) 2023-2026 Saúl Ibarra Corretgé +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +BUILD_DIR?=build +BUILD_TYPE?=Release +INSTALL_PREFIX?=/usr/local + +QJS=$(BUILD_DIR)/qjs +QJSC=$(BUILD_DIR)/qjsc +RUN262=$(BUILD_DIR)/run-test262 + +JOBS?=$(shell getconf _NPROCESSORS_ONLN) +ifeq ($(JOBS),) +JOBS := $(shell sysctl -n hw.ncpu) +endif +ifeq ($(JOBS),) +JOBS := $(shell nproc) +endif +ifeq ($(JOBS),) +JOBS := 4 +endif + +all: $(QJS) + +amalgam: TEMP := $(shell mktemp -d) +amalgam: $(QJS) + $(QJS) amalgam.js $(TEMP)/quickjs-amalgam.c + cp quickjs.h quickjs-libc.h $(TEMP) + cd $(TEMP) && zip -9 quickjs-amalgam.zip quickjs-amalgam.c quickjs.h quickjs-libc.h + cp $(TEMP)/quickjs-amalgam.zip $(BUILD_DIR) + cd $(TEMP) && $(RM) quickjs-amalgam.zip quickjs-amalgam.c quickjs.h quickjs-libc.h + $(RM) -d $(TEMP) + +fuzz: + clang -g -O1 -fsanitize=address,undefined,fuzzer -o fuzz fuzz.c + ./fuzz + +$(BUILD_DIR): + cmake -B $(BUILD_DIR) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DCMAKE_INSTALL_PREFIX=$(INSTALL_PREFIX) + +$(QJS): $(BUILD_DIR) + cmake --build $(BUILD_DIR) -j $(JOBS) + +$(QJSC): $(BUILD_DIR) + cmake --build $(BUILD_DIR) --target qjsc -j $(JOBS) + +install: $(QJS) $(QJSC) + cmake --build $(BUILD_DIR) --target install + +clean: + cmake --build $(BUILD_DIR) --target clean + +codegen: $(QJSC) + $(QJSC) -ss -o gen/repl.c -m repl.js + $(QJSC) -ss -o gen/standalone.c -m standalone.js + $(QJSC) -e -o gen/function_source.c tests/function_source.js + $(QJSC) -e -o gen/hello.c examples/hello.js + $(QJSC) -e -o gen/hello_module.c -m examples/hello_module.js + $(QJSC) -e -o gen/test_fib.c -m examples/test_fib.js + $(QJSC) -C -ss -o builtin-array-fromasync.h builtin-array-fromasync.js + $(QJSC) -C -ss -o builtin-iterator-zip.h builtin-iterator-zip.js + $(QJSC) -C -ss -o builtin-iterator-zip-keyed.h builtin-iterator-zip-keyed.js + +debug: + BUILD_TYPE=Debug $(MAKE) + +distclean: + @rm -rf $(BUILD_DIR) + +stats: $(QJS) + $(QJS) -qd + +jscheck: CFLAGS=-I. -D_GNU_SOURCE -DJS_CHECK_JSVALUE -Wall -Werror -fsyntax-only -c -o /dev/null +jscheck: + $(CC) $(CFLAGS) api-test.c + $(CC) $(CFLAGS) ctest.c + $(CC) $(CFLAGS) fuzz.c + $(CC) $(CFLAGS) gen/function_source.c + $(CC) $(CFLAGS) gen/hello.c + $(CC) $(CFLAGS) gen/hello_module.c + $(CC) $(CFLAGS) gen/repl.c + $(CC) $(CFLAGS) gen/standalone.c + $(CC) $(CFLAGS) gen/test_fib.c + $(CC) $(CFLAGS) qjs.c + $(CC) $(CFLAGS) qjsc.c + $(CC) $(CFLAGS) quickjs-libc.c + $(CC) $(CFLAGS) quickjs.c + $(CC) $(CFLAGS) run-test262.c + +# effectively .PHONY because it doesn't generate output +ctest: CFLAGS=-std=c11 -fsyntax-only -Wall -Wextra -Werror -pedantic +ctest: ctest.c quickjs.h + $(CC) $(CFLAGS) -DJS_NAN_BOXING=0 $< + $(CC) $(CFLAGS) -DJS_NAN_BOXING=1 $< + +# effectively .PHONY because it doesn't generate output +cxxtest: CXXFLAGS=-std=c++11 -fsyntax-only -Wall -Wextra -Werror -pedantic +cxxtest: cxxtest.cc quickjs.h + $(CXX) $(CXXFLAGS) -DJS_NAN_BOXING=0 $< + $(CXX) $(CXXFLAGS) -DJS_NAN_BOXING=1 $< + +test: $(QJS) + $(RUN262) -c tests.conf + +test262: $(QJS) + $(RUN262) -m -c test262.conf -a + +test262-fast: $(QJS) + $(RUN262) -m -c test262.conf -c test262-fast.conf -a + +test262-update: $(QJS) + $(RUN262) -u -c test262.conf -a -t 1 + +test262-check: $(QJS) + $(RUN262) -m -c test262.conf -E -a + +microbench: $(QJS) + $(QJS) tests/microbench.js + +unicode_gen: $(BUILD_DIR) + cmake --build $(BUILD_DIR) --target unicode_gen + +libunicode-table.h: unicode_gen + $(BUILD_DIR)/unicode_gen unicode $@ + +.PHONY: all amalgam ctest cxxtest debug fuzz jscheck install clean codegen distclean stats test test262 test262-update test262-check microbench unicode_gen $(QJS) $(QJSC) diff --git a/userland/qjs/source/README.md b/userland/qjs/source/README.md new file mode 100644 index 0000000..e4b0e34 --- /dev/null +++ b/userland/qjs/source/README.md @@ -0,0 +1,24 @@ +# ⚡️ QuickJS - A mighty JavaScript engine + +## Overview + +QuickJS is a small and embeddable JavaScript engine. It aims to support the latest +[ECMAScript] specification. + +This project is a _fork_ of the [original QuickJS project] by Fabrice Bellard and Charlie Gordon, after it went dormant, with the intent of reigniting its development. + +## Getting started + +Head over to the [project website] for instructions on how to get started and more +documentation. + +## Authors + +[@bnoordhuis], [@saghul], and many more [contributors]. + +[ECMAScript]: https://tc39.es/ecma262/ +[original QuickJS project]: https://bellard.org/quickjs +[@bnoordhuis]: https://github.com/bnoordhuis +[@saghul]: https://github.com/saghul +[contributors]: https://github.com/quickjs-ng/quickjs/graphs/contributors +[project website]: https://quickjs-ng.github.io/quickjs/ diff --git a/userland/qjs/source/SECURITY.md b/userland/qjs/source/SECURITY.md new file mode 100644 index 0000000..60d8963 --- /dev/null +++ b/userland/qjs/source/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +We no longer accept private security reports nor issue CVEs. Please file bug +reports in the [issue tracker](https://github.com/quickjs-ng/quickjs/issues). + +## Out of Scope + +**Bytecode hardening is out of scope.** QuickJS bytecode is not designed for +adversarial input. Loading untrusted bytecode (e.g. via `JS_ReadObject` with +`JS_READ_OBJ_BYTECODE`) is equivalent to executing untrusted native code, and +crashes, memory corruption, or sandbox escapes resulting from malformed or +malicious bytecode are not considered security vulnerabilities. Only load +bytecode you produced yourself or obtained from a trusted source. See the +documentation for `JS_READ_OBJ_BYTECODE` and `JS_READ_OBJ_SAB` for details. diff --git a/userland/qjs/source/amalgam.js b/userland/qjs/source/amalgam.js new file mode 100644 index 0000000..3749239 --- /dev/null +++ b/userland/qjs/source/amalgam.js @@ -0,0 +1,53 @@ +import {loadFile, writeFile} from "qjs:std" + +const cutils_h = loadFile("cutils.h") +const dtoa_c = loadFile("dtoa.c") +const dtoa_h = loadFile("dtoa.h") +const libregexp_c = loadFile("libregexp.c") +const libregexp_h = loadFile("libregexp.h") +const libregexp_opcode_h = loadFile("libregexp-opcode.h") +const libunicode_c = loadFile("libunicode.c") +const libunicode_h = loadFile("libunicode.h") +const libunicode_table_h = loadFile("libunicode-table.h") +const list_h = loadFile("list.h") +const quickjs_atom_h = loadFile("quickjs-atom.h") +const quickjs_c = loadFile("quickjs.c") +const quickjs_c_atomics_h = loadFile("quickjs-c-atomics.h") +const quickjs_h = loadFile("quickjs.h") +const quickjs_libc_c = loadFile("quickjs-libc.c") +const quickjs_libc_h = loadFile("quickjs-libc.h") +const quickjs_opcode_h = loadFile("quickjs-opcode.h") +const gen_builtin_array_fromasync_h = loadFile("builtin-array-fromasync.h") +const gen_builtin_iterator_zip_h = loadFile("builtin-iterator-zip.h") +const gen_builtin_iterator_zip_keyed_h = loadFile("builtin-iterator-zip-keyed.h") + +let source = "#if defined(QJS_BUILD_LIBC) && defined(__linux__) && !defined(_GNU_SOURCE)\n" + + "#define _GNU_SOURCE\n" + + "#endif\n" + + quickjs_c_atomics_h + + cutils_h + + dtoa_h + + list_h + + libunicode_h // exports lre_is_id_start, used by libregexp.h + + libregexp_h + + libunicode_table_h + + quickjs_h + + quickjs_c + + dtoa_c + + libregexp_c + + libunicode_c + + "#ifdef QJS_BUILD_LIBC\n" + + quickjs_libc_h + + quickjs_libc_c + + "#endif // QJS_BUILD_LIBC\n" +source = source.replace(/#include "quickjs-atom.h"/g, quickjs_atom_h) +source = source.replace(/#include "quickjs-opcode.h"/g, quickjs_opcode_h) +source = source.replace(/#include "libregexp-opcode.h"/g, libregexp_opcode_h) +source = source.replace(/#include "builtin-array-fromasync.h"/g, + gen_builtin_array_fromasync_h) +source = source.replace(/#include "builtin-iterator-zip.h"/g, + gen_builtin_iterator_zip_h) +source = source.replace(/#include "builtin-iterator-zip-keyed.h"/g, + gen_builtin_iterator_zip_keyed_h) +source = source.replace(/#include "[^"]+"/g, "") +writeFile(execArgv[2] ?? "quickjs-amalgam.c", source) diff --git a/userland/qjs/source/api-test.c b/userland/qjs/source/api-test.c new file mode 100644 index 0000000..744c55b --- /dev/null +++ b/userland/qjs/source/api-test.c @@ -0,0 +1,2495 @@ +#ifdef NDEBUG +#undef NDEBUG +#endif +#include +#include +#include +#include +#include "quickjs.h" +#include "quickjs-libc.h" +#include "cutils.h" + +static JSRuntime *new_runtime(void) +{ + JSRuntime *rt = JS_NewRuntime(); + + if (rt) + JS_SetDumpFlags(rt, JS_ABORT_ON_LEAKS); + return rt; +} + +static JSValue eval(JSContext *ctx, const char *code) +{ + return JS_Eval(ctx, code, strlen(code), "", JS_EVAL_TYPE_GLOBAL); +} + +static JSValue cfunc_callback(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + return JS_ThrowTypeError(ctx, "from cfunc"); +} + +static JSValue cfuncdata_callback(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, + int magic, JSValueConst *func_data) +{ + return JS_ThrowTypeError(ctx, "from cfuncdata"); +} + +static JSValue cclosure_callback(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, + int magic, void *func_data) +{ + return JS_ThrowTypeError(ctx, "from cclosure"); +} + +static bool closure_finalized = false; + +static void cclosure_opaque_finalize(void *opaque) +{ + if ((intptr_t)opaque == 12) + closure_finalized = true; +} + +static void cfunctions(void) +{ + uint32_t length; + const char *s; + JSValue ret, stack; + + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + JSValue cfunc = JS_NewCFunction(ctx, cfunc_callback, "cfunc", 42); + JSValue cfuncdata = + JS_NewCFunctionData2(ctx, cfuncdata_callback, "cfuncdata", + /*length*/1337, /*magic*/0, /*data_len*/0, NULL); + JSValue cclosure = + JS_NewCClosure(ctx, cclosure_callback, "cclosure", cclosure_opaque_finalize, + /*length*/0xC0DE, /*magic*/11, /*opaque*/(void*)12); + JSValue global = JS_GetGlobalObject(ctx); + JS_SetPropertyStr(ctx, global, "cfunc", cfunc); + JS_SetPropertyStr(ctx, global, "cfuncdata", cfuncdata); + JS_SetPropertyStr(ctx, global, "cclosure", cclosure); + JS_FreeValue(ctx, global); + + ret = eval(ctx, "cfunc.name"); + assert(!JS_IsException(ret)); + assert(JS_IsString(ret)); + s = JS_ToCString(ctx, ret); + JS_FreeValue(ctx, ret); + assert(s); + assert(!strcmp(s, "cfunc")); + JS_FreeCString(ctx, s); + ret = eval(ctx, "cfunc.length"); + assert(!JS_IsException(ret)); + assert(JS_IsNumber(ret)); + assert(0 == JS_ToUint32(ctx, &length, ret)); + assert(length == 42); + + ret = eval(ctx, "cfuncdata.name"); + assert(!JS_IsException(ret)); + assert(JS_IsString(ret)); + s = JS_ToCString(ctx, ret); + JS_FreeValue(ctx, ret); + assert(s); + assert(!strcmp(s, "cfuncdata")); + JS_FreeCString(ctx, s); + ret = eval(ctx, "cfuncdata.length"); + assert(!JS_IsException(ret)); + assert(JS_IsNumber(ret)); + assert(0 == JS_ToUint32(ctx, &length, ret)); + assert(length == 1337); + + ret = eval(ctx, "cclosure.name"); + assert(!JS_IsException(ret)); + assert(JS_IsString(ret)); + s = JS_ToCString(ctx, ret); + JS_FreeValue(ctx, ret); + assert(s); + assert(!strcmp(s, "cclosure")); + JS_FreeCString(ctx, s); + ret = eval(ctx, "cclosure.length"); + assert(!JS_IsException(ret)); + assert(JS_IsNumber(ret)); + assert(0 == JS_ToUint32(ctx, &length, ret)); + assert(length == 0xC0DE); + + ret = eval(ctx, "cfunc()"); + assert(JS_IsException(ret)); + ret = JS_GetException(ctx); + assert(JS_IsError(ret)); + stack = JS_GetPropertyStr(ctx, ret, "stack"); + assert(JS_IsString(stack)); + s = JS_ToCString(ctx, stack); + JS_FreeValue(ctx, stack); + assert(s); + assert(!strcmp(s, " at cfunc (native)\n at (:1:1)\n")); + JS_FreeCString(ctx, s); + s = JS_ToCString(ctx, ret); + JS_FreeValue(ctx, ret); + assert(s); + assert(!strcmp(s, "TypeError: from cfunc")); + JS_FreeCString(ctx, s); + + ret = eval(ctx, "cfuncdata()"); + assert(JS_IsException(ret)); + ret = JS_GetException(ctx); + assert(JS_IsError(ret)); + stack = JS_GetPropertyStr(ctx, ret, "stack"); + assert(JS_IsString(stack)); + s = JS_ToCString(ctx, stack); + JS_FreeValue(ctx, stack); + assert(s); + assert(!strcmp(s, " at cfuncdata (native)\n at (:1:1)\n")); + JS_FreeCString(ctx, s); + s = JS_ToCString(ctx, ret); + JS_FreeValue(ctx, ret); + assert(s); + assert(!strcmp(s, "TypeError: from cfuncdata")); + JS_FreeCString(ctx, s); + + ret = eval(ctx, "cclosure()"); + assert(JS_IsException(ret)); + ret = JS_GetException(ctx); + assert(JS_IsError(ret)); + stack = JS_GetPropertyStr(ctx, ret, "stack"); + assert(JS_IsString(stack)); + s = JS_ToCString(ctx, stack); + JS_FreeValue(ctx, stack); + assert(s); + assert(!strcmp(s, " at cclosure (native)\n at (:1:1)\n")); + JS_FreeCString(ctx, s); + s = JS_ToCString(ctx, ret); + JS_FreeValue(ctx, ret); + assert(s); + assert(!strcmp(s, "TypeError: from cclosure")); + JS_FreeCString(ctx, s); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + + assert(closure_finalized); +} + +#define MAX_TIME 10 + +static int timeout_interrupt_handler(JSContext *ctx, void *opaque) +{ + int *time = (int *)opaque; + return (*time)++ > MAX_TIME; +} + +static void sync_call(void) +{ + static const char code[] = +"(function() { \ + try { \ + while (true) {} \ + } catch (e) {} \ +})();"; + + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + int time = 0; + JS_SetInterruptHandler(rt, timeout_interrupt_handler, &time); + JSValue ret = eval(ctx, code); + assert(time > MAX_TIME); + assert(JS_IsException(ret)); + JS_FreeValue(ctx, ret); + assert(JS_HasException(ctx)); + JSValue e = JS_GetException(ctx); + assert(JS_IsUncatchableError(e)); + JS_FreeValue(ctx, e); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void async_call(void) +{ + static const char code[] = +"(async function() { \ + const loop = async () => { \ + await Promise.resolve(); \ + while (true) {} \ + }; \ + await loop().catch(() => {}); \ +})();"; + + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + int time = 0; + JS_SetInterruptHandler(rt, timeout_interrupt_handler, &time); + JSValue ret = eval(ctx, code); + assert(!JS_IsException(ret)); + JS_FreeValue(ctx, ret); + assert(JS_IsJobPending(rt)); + int r = 0; + while (JS_IsJobPending(rt)) { + r = JS_ExecutePendingJob(rt, &ctx); + } + assert(time > MAX_TIME); + assert(r == -1); + assert(JS_HasException(ctx)); + JSValue e = JS_GetException(ctx); + assert(JS_IsUncatchableError(e)); + JS_FreeValue(ctx, e); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void std_eval_interrupt_handler(void) +{ + static const char code[] = + "import * as std from 'std'; std.evalScript('for(;;){}')"; + JSRuntime *rt = new_runtime(); + js_std_init_handlers(rt); + JSContext *ctx = JS_NewContext(rt); + js_init_module_std(ctx, "std"); + int time = 0; + JS_SetInterruptHandler(rt, timeout_interrupt_handler, &time); + JSValue ret = + JS_Eval(ctx, code, strlen(code), "", JS_EVAL_TYPE_MODULE); + ret = js_std_await(ctx, ret); + assert(time > MAX_TIME); + assert(JS_IsException(ret)); + ret = JS_GetException(ctx); + assert(JS_IsError(ret)); + // uncatchable "interrupted" exception is turned into a regular exception + assert(!JS_IsUncatchableError(ret)); + const char *str = JS_ToCString(ctx, ret); + assert(str != NULL); + assert(strstr(str, "InternalError: interrupted")); + JS_FreeCString(ctx, str); + JS_FreeValue(ctx, ret); + uintptr_t interrupt_handler = js_std_cmd(/*GetInterruptHandler*/5, rt); + uintptr_t interrupt_opaque = js_std_cmd(/*GetInterruptOpaque*/6, rt); + assert(interrupt_handler == (uintptr_t)timeout_interrupt_handler); + assert(interrupt_opaque == (uintptr_t)&time); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static JSValue save_value(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + assert(argc == 1); + JSValue *p = (JSValue *)JS_GetContextOpaque(ctx); + *p = JS_DupValue(ctx, argv[0]); + return JS_UNDEFINED; +} + +static void async_call_stack_overflow(void) +{ + static const char code[] = +"(async function() { \ + const f = () => f(); \ + try { \ + await Promise.resolve(); \ + f(); \ + } catch (e) { \ + save_value(e); \ + } \ +})();"; + + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + JSValue value = JS_UNDEFINED; + JS_SetContextOpaque(ctx, &value); + JSValue global = JS_GetGlobalObject(ctx); + JS_SetPropertyStr(ctx, global, "save_value", JS_NewCFunction(ctx, save_value, "save_value", 1)); + JS_FreeValue(ctx, global); + JSValue ret = eval(ctx, code); + assert(!JS_IsException(ret)); + JS_FreeValue(ctx, ret); + assert(JS_IsJobPending(rt)); + int r = 0; + while (JS_IsJobPending(rt)) { + r = JS_ExecutePendingJob(rt, &ctx); + } + assert(r == 1); + assert(!JS_HasException(ctx)); + assert(JS_IsError(value)); // stack overflow should be caught + JS_FreeValue(ctx, value); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +// https://github.com/quickjs-ng/quickjs/issues/914 +static void raw_context_global_var(void) +{ + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContextRaw(rt); + JS_AddIntrinsicEval(ctx); + { + JSValue ret = eval(ctx, "globalThis"); + assert(JS_IsException(ret)); + JS_FreeValue(ctx, ret); + } + { + JSValue ret = eval(ctx, "var x = 42"); + assert(JS_IsUndefined(ret)); + JS_FreeValue(ctx, ret); + } + { + JSValue ret = eval(ctx, "function f() {}"); + assert(JS_IsUndefined(ret)); + JS_FreeValue(ctx, ret); + } + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void is_array(void) +{ + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + { + JSValue ret = eval(ctx, "[]"); + assert(!JS_IsException(ret)); + assert(JS_IsArray(ret)); + JS_FreeValue(ctx, ret); + } + { + JSValue ret = eval(ctx, "new Proxy([], {})"); + assert(!JS_IsException(ret)); + assert(!JS_IsArray(ret)); + assert(JS_IsProxy(ret)); + JSValue handler = JS_GetProxyHandler(ctx, ret); + JSValue target = JS_GetProxyTarget(ctx, ret); + assert(!JS_IsException(handler)); + assert(!JS_IsException(target)); + assert(!JS_IsProxy(handler)); + assert(!JS_IsProxy(target)); + assert(JS_IsObject(handler)); + assert(JS_IsArray(target)); + JS_FreeValue(ctx, handler); + JS_FreeValue(ctx, target); + JS_FreeValue(ctx, ret); + } + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static int loader_calls; + +static JSModuleDef *loader(JSContext *ctx, const char *name, void *opaque) +{ + loader_calls++; + assert(!strcmp(name, "b")); + static const char code[] = "export function f(x){}"; + JSValue ret = JS_Eval(ctx, code, strlen(code), "b", + JS_EVAL_TYPE_MODULE|JS_EVAL_FLAG_COMPILE_ONLY); + assert(!JS_IsException(ret)); + JSModuleDef *m = JS_VALUE_GET_PTR(ret); + assert(m); + JS_FreeValue(ctx, ret); + return m; +} + +static void module_serde(void) +{ + JSRuntime *rt = new_runtime(); + //JS_SetDumpFlags(rt, JS_DUMP_MODULE_RESOLVE); + JS_SetModuleLoaderFunc(rt, NULL, loader, NULL); + JSContext *ctx = JS_NewContext(rt); + static const char code[] = "import {f} from 'b'; f()"; + assert(loader_calls == 0); + JSValue mod = JS_Eval(ctx, code, strlen(code), "a", + JS_EVAL_TYPE_MODULE|JS_EVAL_FLAG_COMPILE_ONLY); + assert(loader_calls == 1); + assert(!JS_IsException(mod)); + assert(JS_IsModule(mod)); + size_t len = 0; + uint8_t *buf = JS_WriteObject(ctx, &len, mod, + JS_WRITE_OBJ_BYTECODE|JS_WRITE_OBJ_REFERENCE); + assert(buf); + assert(len > 0); + JS_FreeValue(ctx, mod); + assert(loader_calls == 1); + mod = JS_ReadObject(ctx, buf, len, JS_READ_OBJ_BYTECODE); + js_free(ctx, buf); + assert(loader_calls == 1); // 'b' is returned from cache + assert(!JS_IsException(mod)); + JSValue ret = JS_EvalFunction(ctx, mod); + assert(!JS_IsException(ret)); + assert(JS_IsPromise(ret)); + JSValue result = JS_PromiseResult(ctx, ret); + assert(!JS_IsException(result)); + assert(JS_IsUndefined(result)); + JS_FreeValue(ctx, result); + JS_FreeValue(ctx, ret); + JS_FreeValue(ctx, mod); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +struct rejection_counts { + int reject_count; + int handle_count; +}; + +static void rejection_counter(JSContext *ctx, JSValueConst promise, + JSValueConst reason, bool is_handled, void *opaque) +{ + struct rejection_counts *c = opaque; + if (is_handled) + c->handle_count++; + else + c->reject_count++; +} + +// A synchronous module that throws at top level must surface exactly one unhandled rejection +static void module_unhandled_rejection(void) +{ + struct rejection_counts c = {0, 0}; + JSRuntime *rt = new_runtime(); + JS_SetHostPromiseRejectionTracker(rt, rejection_counter, &c); + JSContext *ctx = JS_NewContext(rt); + + static const char code[] = "throw new Error('Nuke the entire site from orbit. It\\'s the only way to be sure.')"; + JSValue v = JS_Eval(ctx, code, strlen(code), "", JS_EVAL_TYPE_MODULE); + JS_FreeValue(ctx, v); + + JSContext *c1; + while (JS_ExecutePendingJob(rt, &c1) > 0) + ; + + // net unhandled rejections == (2 rejects - 1 handled) + assert(c.reject_count == 2); + assert(c.handle_count == 1); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void promise_mark_as_handled(void) +{ + struct rejection_counts c = {0, 0}; + JSRuntime *rt = new_runtime(); + JS_SetHostPromiseRejectionTracker(rt, rejection_counter, &c); + JSContext *ctx = JS_NewContext(rt); + JSContext *c1; + + // marking an already-rejected promise notifies the tracker exactly once + static const char code[] = "Promise.reject('kaboom')"; + JSValue promise = JS_Eval(ctx, code, strlen(code), "", JS_EVAL_TYPE_GLOBAL); + assert(JS_IsPromise(promise)); + while (JS_ExecutePendingJob(rt, &c1) > 0) + ; + assert(c.reject_count == 1); + assert(c.handle_count == 0); + JS_PromiseMarkAsHandled(ctx, promise); + assert(c.handle_count == 1); + JS_PromiseMarkAsHandled(ctx, promise); + assert(c.handle_count == 1); + JS_FreeValue(ctx, promise); + + // marking a pending promise suppresses the report when it later rejects + JSValue resolving_funcs[2]; + JSValue promise2 = JS_NewPromiseCapability(ctx, resolving_funcs); + JS_PromiseMarkAsHandled(ctx, promise2); + JSValue reason = JS_NewString(ctx, "unseen"); + JSValue ret = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, 1, + (JSValueConst *)&reason); + while (JS_ExecutePendingJob(rt, &c1) > 0) + ; + assert(c.reject_count == 1); + assert(c.handle_count == 1); + JS_FreeValue(ctx, ret); + JS_FreeValue(ctx, reason); + JS_FreeValue(ctx, resolving_funcs[0]); + JS_FreeValue(ctx, resolving_funcs[1]); + JS_FreeValue(ctx, promise2); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void promise_then(void) +{ + const char *s; + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + JSContext *c1; + JSValue got = JS_UNDEFINED; + JS_SetContextOpaque(ctx, &got); + + // the result promise is intrinsic: neither an overridden then() nor + // Symbol.species is consulted + static const char code[] = + "class P extends Promise {" + " static get [Symbol.species]() { throw new Error('species'); }" + " then() { throw new Error('then'); }" + "}" + "P.resolve('ok')"; + JSValue promise = eval(ctx, code); + assert(JS_IsPromise(promise)); + JSValue on_fulfilled = JS_NewCFunction(ctx, save_value, "onFulfilled", 1); + JSValue result = JS_PromiseThen(ctx, promise, on_fulfilled, JS_UNDEFINED); + assert(JS_IsPromise(result)); + while (JS_ExecutePendingJob(rt, &c1) > 0) + ; + s = JS_ToCString(ctx, got); + assert(s); + assert(!strcmp(s, "ok")); + JS_FreeCString(ctx, s); + JS_FreeValue(ctx, got); + assert(JS_PromiseState(ctx, result) == JS_PROMISE_FULFILLED); + JS_FreeValue(ctx, result); + JS_FreeValue(ctx, on_fulfilled); + JS_FreeValue(ctx, promise); + + // rejection handler receives the reason when the promise rejects later + JSValue resolving_funcs[2]; + JSValue promise2 = JS_NewPromiseCapability(ctx, resolving_funcs); + JSValue on_rejected = JS_NewCFunction(ctx, save_value, "onRejected", 1); + JSValue result2 = JS_PromiseThen(ctx, promise2, JS_UNDEFINED, on_rejected); + assert(JS_IsPromise(result2)); + got = JS_UNDEFINED; + JSValue reason = JS_NewString(ctx, "boom"); + JSValue ret = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, 1, + (JSValueConst *)&reason); + while (JS_ExecutePendingJob(rt, &c1) > 0) + ; + s = JS_ToCString(ctx, got); + assert(s); + assert(!strcmp(s, "boom")); + JS_FreeCString(ctx, s); + JS_FreeValue(ctx, got); + assert(JS_PromiseState(ctx, result2) == JS_PROMISE_FULFILLED); + JS_FreeValue(ctx, ret); + JS_FreeValue(ctx, reason); + JS_FreeValue(ctx, result2); + JS_FreeValue(ctx, on_rejected); + JS_FreeValue(ctx, resolving_funcs[0]); + JS_FreeValue(ctx, resolving_funcs[1]); + JS_FreeValue(ctx, promise2); + + // a non-promise argument is a TypeError + JSValue bad = JS_PromiseThen(ctx, JS_UNDEFINED, JS_UNDEFINED, JS_UNDEFINED); + assert(JS_IsException(bad)); + JSValue exc = JS_GetException(ctx); + JS_FreeValue(ctx, exc); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void runtime_cstring_free(void) +{ + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + // string -> cstring + JS_FreeCStringRT + { + JSValue ret = eval(ctx, "\"testStringPleaseIgnore\""); + assert(JS_IsString(ret)); + const char *s = JS_ToCString(ctx, ret); + assert(s); + assert(strcmp(s, "testStringPleaseIgnore") == 0); + JS_FreeCStringRT(rt, s); + JS_FreeValue(ctx, ret); + } + // string -> cstring + JS_FreeCStringRT, destroying the source value first + { + JSValue ret = eval(ctx, "\"testStringPleaseIgnore\""); + assert(JS_IsString(ret)); + const char *s = JS_ToCString(ctx, ret); + assert(s); + JS_FreeValue(ctx, ret); + assert(strcmp(s, "testStringPleaseIgnore") == 0); + JS_FreeCStringRT(rt, s); + } + // number -> cstring + JS_FreeCStringRT + { + JSValue ret = eval(ctx, "123987"); + assert(JS_IsNumber(ret)); + const char *s = JS_ToCString(ctx, ret); + assert(s); + assert(strcmp(s, "123987") == 0); + JS_FreeCStringRT(rt, s); + JS_FreeValue(ctx, ret); + } + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void utf16_string(void) +{ + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + { + JSValue v = JS_NewStringUTF16(ctx, NULL, 0); + assert(!JS_IsException(v)); + const char *s = JS_ToCString(ctx, v); + assert(s); + assert(!strcmp(s, "")); + JS_FreeCString(ctx, s); + JS_FreeValue(ctx, v); + } + { + JSValue v = JS_NewStringUTF16(ctx, (uint16_t[]){'o','k'}, 2); + assert(!JS_IsException(v)); + const char *s = JS_ToCString(ctx, v); + assert(s); + assert(!strcmp(s, "ok")); + JS_FreeCString(ctx, s); + size_t n; + const uint16_t *u = JS_ToCStringLenUTF16(ctx, &n, v); + assert(u); + assert(n == 2); + assert(u[0] == 'o'); + assert(u[1] == 'k'); + JS_FreeCStringUTF16(ctx, u); + JS_FreeValue(ctx, v); + } + { + JSValue v = JS_NewStringUTF16(ctx, (uint16_t[]){0xD800}, 1); + assert(!JS_IsException(v)); + const char *s = JS_ToCString(ctx, v); + assert(s); + // questionable but surrogates don't map to UTF-8 without WTF-8 + assert(!strcmp(s, "\xED\xA0\x80")); + JS_FreeCString(ctx, s); + size_t n; + const uint16_t *u = JS_ToCStringLenUTF16(ctx, &n, v); + assert(u); + assert(n == 1); + assert(u[0] == 0xD800); + JS_FreeCStringUTF16(ctx, u); + JS_FreeValue(ctx, v); + } + { + JSValue v = JS_NewStringLen(ctx, "ok", 2); // ascii -> ucs + assert(!JS_IsException(v)); + size_t n; + const uint16_t *u = JS_ToCStringLenUTF16(ctx, &n, v); + assert(u); + assert(n == 2); + assert(u[0] == 'o'); + assert(u[1] == 'k'); + JS_FreeCStringUTF16(ctx, u); + JS_FreeValue(ctx, v); + } + { + JSValue v = JS_NewStringUTF16(ctx, NULL, (size_t)INT_MAX + 1); + assert(JS_IsException(v)); + JSValue e = JS_GetException(ctx); + assert(JS_IsError(e)); + const char *s = JS_ToCString(ctx, e); + assert(s); + assert(strstr(s, "invalid string length") != NULL); + JS_FreeCString(ctx, s); + JS_FreeValue(ctx, e); + } + { + // create wide char slice string, see JS_STRING_SLICE_LEN_MAX + JSValue v = eval(ctx, "`\\uD800\\uDC00`.repeat(8192).slice(0, -1)"); + assert(!JS_IsException(v)); + size_t n; + const uint16_t *u = JS_ToCStringLenUTF16(ctx, &n, v); + assert(u); + assert(n == 2*8192-1); + assert(u[0] == 0xD800); + assert(u[1] == 0xDC00); + JS_FreeCStringUTF16(ctx, u); + JS_FreeValue(ctx, v); + } + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void weak_map_gc_check(void) +{ + static const char init_code[] = +"const map = new WeakMap(); \ +function addItem() { \ + const k = { \ + text: 'a', \ + }; \ + map.set(k, {k}); \ +}"; + static const char test_code[] = "addItem()"; + + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + + JSValue ret = eval(ctx, init_code); + assert(!JS_IsException(ret)); + + JSValue ret_test = eval(ctx, test_code); + assert(!JS_IsException(ret_test)); + JS_RunGC(rt); + JSMemoryUsage memory_usage; + JS_ComputeMemoryUsage(rt, &memory_usage); + + for (int i = 0; i < 3; i++) { + JSValue ret_test2 = eval(ctx, test_code); + assert(!JS_IsException(ret_test2)); + JS_RunGC(rt); + JSMemoryUsage memory_usage2; + JS_ComputeMemoryUsage(rt, &memory_usage2); + + assert(memory_usage.memory_used_count == memory_usage2.memory_used_count); + assert(memory_usage.memory_used_size == memory_usage2.memory_used_size); + JS_FreeValue(ctx, ret_test2); + } + + JS_FreeValue(ctx, ret); + JS_FreeValue(ctx, ret_test); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +struct { + int hook_type_call_count[4]; +} promise_hook_state; + +static void promise_hook_cb(JSContext *ctx, JSPromiseHookType type, + JSValueConst promise, JSValueConst parent_promise, + void *opaque) +{ + assert(type == JS_PROMISE_HOOK_INIT || + type == JS_PROMISE_HOOK_BEFORE || + type == JS_PROMISE_HOOK_AFTER || + type == JS_PROMISE_HOOK_RESOLVE); + promise_hook_state.hook_type_call_count[type]++; + assert(opaque == (void *)&promise_hook_state); + if (!JS_IsUndefined(parent_promise)) { + JSValue global_object = JS_GetGlobalObject(ctx); + JS_SetPropertyStr(ctx, global_object, "actual", + JS_DupValue(ctx, parent_promise)); + JS_FreeValue(ctx, global_object); + } +} + +static void promise_hook(void) +{ + int *cc = promise_hook_state.hook_type_call_count; + JSContext *unused; + JSRuntime *rt = new_runtime(); + //JS_SetDumpFlags(rt, JS_DUMP_PROMISE); + JS_SetPromiseHook(rt, promise_hook_cb, &promise_hook_state); + JSContext *ctx = JS_NewContext(rt); + JSValue global_object = JS_GetGlobalObject(ctx); + { + // empty module; creates an outer and inner module promise; + // JS_Eval returns the outer promise + JSValue ret = JS_Eval(ctx, "", 0, "", JS_EVAL_TYPE_MODULE); + assert(!JS_IsException(ret)); + assert(JS_IsPromise(ret)); + assert(JS_PROMISE_FULFILLED == JS_PromiseState(ctx, ret)); + JS_FreeValue(ctx, ret); + assert(2 == cc[JS_PROMISE_HOOK_INIT]); + assert(0 == cc[JS_PROMISE_HOOK_BEFORE]); + assert(0 == cc[JS_PROMISE_HOOK_AFTER]); + assert(2 == cc[JS_PROMISE_HOOK_RESOLVE]); + assert(!JS_IsJobPending(rt)); + } + memset(&promise_hook_state, 0, sizeof(promise_hook_state)); + { + // module with unresolved promise; the outer and inner module promises + // are resolved but not the user's promise + static const char code[] = "new Promise(() => {})"; + JSValue ret = JS_Eval(ctx, code, strlen(code), "", JS_EVAL_TYPE_MODULE); + assert(!JS_IsException(ret)); + assert(JS_IsPromise(ret)); + assert(JS_PROMISE_FULFILLED == JS_PromiseState(ctx, ret)); // outer module promise + JS_FreeValue(ctx, ret); + assert(3 == cc[JS_PROMISE_HOOK_INIT]); + assert(0 == cc[JS_PROMISE_HOOK_BEFORE]); + assert(0 == cc[JS_PROMISE_HOOK_AFTER]); + assert(2 == cc[JS_PROMISE_HOOK_RESOLVE]); // outer and inner module promise + assert(!JS_IsJobPending(rt)); + } + memset(&promise_hook_state, 0, sizeof(promise_hook_state)); + { + // module with resolved promise + static const char code[] = "new Promise((resolve,reject) => resolve())"; + JSValue ret = JS_Eval(ctx, code, strlen(code), "", JS_EVAL_TYPE_MODULE); + assert(!JS_IsException(ret)); + assert(JS_IsPromise(ret)); + assert(JS_PROMISE_FULFILLED == JS_PromiseState(ctx, ret)); // outer module promise + JS_FreeValue(ctx, ret); + assert(3 == cc[JS_PROMISE_HOOK_INIT]); + assert(0 == cc[JS_PROMISE_HOOK_BEFORE]); + assert(0 == cc[JS_PROMISE_HOOK_AFTER]); + assert(3 == cc[JS_PROMISE_HOOK_RESOLVE]); + assert(!JS_IsJobPending(rt)); + } + memset(&promise_hook_state, 0, sizeof(promise_hook_state)); + { + // module with rejected promise + static const char code[] = "new Promise((resolve,reject) => reject())"; + JSValue ret = JS_Eval(ctx, code, strlen(code), "", JS_EVAL_TYPE_MODULE); + assert(!JS_IsException(ret)); + assert(JS_IsPromise(ret)); + assert(JS_PROMISE_FULFILLED == JS_PromiseState(ctx, ret)); // outer module promise + JS_FreeValue(ctx, ret); + assert(3 == cc[JS_PROMISE_HOOK_INIT]); + assert(0 == cc[JS_PROMISE_HOOK_BEFORE]); + assert(0 == cc[JS_PROMISE_HOOK_AFTER]); + assert(2 == cc[JS_PROMISE_HOOK_RESOLVE]); + assert(!JS_IsJobPending(rt)); + } + memset(&promise_hook_state, 0, sizeof(promise_hook_state)); + { + // module with promise chain + static const char code[] = + "globalThis.count = 0;" + "globalThis.actual = undefined;" // set by promise_hook_cb + "globalThis.expected = new Promise(resolve => resolve());" + "expected.then(_ => count++)"; + JSValue ret = JS_Eval(ctx, code, strlen(code), "", JS_EVAL_TYPE_MODULE); + assert(!JS_IsException(ret)); + assert(JS_IsPromise(ret)); + assert(JS_PROMISE_FULFILLED == JS_PromiseState(ctx, ret)); // outer module promise + JS_FreeValue(ctx, ret); + assert(4 == cc[JS_PROMISE_HOOK_INIT]); + assert(0 == cc[JS_PROMISE_HOOK_BEFORE]); + assert(0 == cc[JS_PROMISE_HOOK_AFTER]); + assert(3 == cc[JS_PROMISE_HOOK_RESOLVE]); + JSValue v = JS_GetPropertyStr(ctx, global_object, "count"); + assert(!JS_IsException(v)); + int32_t count; + assert(0 == JS_ToInt32(ctx, &count, v)); + assert(0 == count); + JS_FreeValue(ctx, v); + assert(JS_IsJobPending(rt)); + assert(1 == JS_ExecutePendingJob(rt, &unused)); + assert(!JS_HasException(ctx)); + assert(4 == cc[JS_PROMISE_HOOK_INIT]); + assert(0 == cc[JS_PROMISE_HOOK_BEFORE]); + assert(0 == cc[JS_PROMISE_HOOK_AFTER]); + assert(4 == cc[JS_PROMISE_HOOK_RESOLVE]); + assert(!JS_IsJobPending(rt)); + v = JS_GetPropertyStr(ctx, global_object, "count"); + assert(!JS_IsException(v)); + assert(0 == JS_ToInt32(ctx, &count, v)); + assert(1 == count); + JS_FreeValue(ctx, v); + JSValue actual = JS_GetPropertyStr(ctx, global_object, "actual"); + JSValue expected = JS_GetPropertyStr(ctx, global_object, "expected"); + assert(!JS_IsException(actual)); + assert(!JS_IsException(expected)); + assert(JS_IsSameValue(ctx, actual, expected)); + JS_FreeValue(ctx, actual); + JS_FreeValue(ctx, expected); + } + memset(&promise_hook_state, 0, sizeof(promise_hook_state)); + { + // module with thenable; fires before and after hooks + static const char code[] = + "new Promise(resolve => resolve({then(resolve){ resolve() }}))"; + JSValue ret = JS_Eval(ctx, code, strlen(code), "", JS_EVAL_TYPE_MODULE); + assert(!JS_IsException(ret)); + assert(JS_IsPromise(ret)); + assert(JS_PROMISE_FULFILLED == JS_PromiseState(ctx, ret)); // outer module promise + JS_FreeValue(ctx, ret); + assert(3 == cc[JS_PROMISE_HOOK_INIT]); + assert(0 == cc[JS_PROMISE_HOOK_BEFORE]); + assert(0 == cc[JS_PROMISE_HOOK_AFTER]); + assert(2 == cc[JS_PROMISE_HOOK_RESOLVE]); + assert(JS_IsJobPending(rt)); + assert(1 == JS_ExecutePendingJob(rt, &unused)); + assert(!JS_HasException(ctx)); + assert(3 == cc[JS_PROMISE_HOOK_INIT]); + assert(1 == cc[JS_PROMISE_HOOK_BEFORE]); + assert(1 == cc[JS_PROMISE_HOOK_AFTER]); + assert(3 == cc[JS_PROMISE_HOOK_RESOLVE]); + assert(!JS_IsJobPending(rt)); + } + JS_FreeValue(ctx, global_object); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void dump_memory_usage(void) +{ + JSMemoryUsage stats; + + JSRuntime *rt = NULL; + JSContext *ctx = NULL; + + rt = new_runtime(); + ctx = JS_NewContext(rt); + + //JS_SetDumpFlags(rt, JS_DUMP_PROMISE); + + static const char code[] = + "globalThis.count = 0;" + "globalThis.actual = undefined;" // set by promise_hook_cb + "globalThis.expected = new Promise(resolve => resolve());" + "expected.then(_ => count++)"; + + JSValue evalVal = JS_Eval(ctx, code, strlen(code), "", 0); + JS_FreeValue(ctx, evalVal); + + FILE *temp = tmpfile(); + assert(temp != NULL); + JS_ComputeMemoryUsage(rt, &stats); + JS_DumpMemoryUsage(temp, &stats, rt); + // JS_DumpMemoryUsage(stdout, &stats, rt); + fclose(temp); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void new_errors(void) +{ + typedef struct { + const char name[16]; + JSValue (*func)(JSContext *, const char *, ...); + } Entry; + static const Entry entries[] = { + {"Error", JS_NewPlainError}, + {"InternalError", JS_NewInternalError}, + {"RangeError", JS_NewRangeError}, + {"ReferenceError", JS_NewReferenceError}, + {"SyntaxError", JS_NewSyntaxError}, + {"TypeError", JS_NewTypeError}, + }; + const Entry *e; + + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + for (e = entries; e < endof(entries); e++) { + JSValue obj = (*e->func)(ctx, "the %s", "needle"); + assert(!JS_IsException(obj)); + assert(JS_IsObject(obj)); + assert(JS_IsError(obj)); + const char *haystack = JS_ToCString(ctx, obj); + char needle[256]; + snprintf(needle, sizeof(needle), "%s: the needle", e->name); + assert(strstr(haystack, needle)); + JS_FreeCString(ctx, haystack); + JSValue stack = JS_GetPropertyStr(ctx, obj, "stack"); + assert(!JS_IsException(stack)); + assert(JS_IsString(stack)); + JS_FreeValue(ctx, stack); + JS_FreeValue(ctx, obj); + } + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +// JS_NewContext() already installs DOMException by way of +// JS_AddIntrinsicAToB(), so a host that also calls JS_AddIntrinsicDOMException() +// explicitly installs it twice. The second install must release the prototype +// the first one left in ctx->class_proto[] instead of overwriting the slot; +// new_runtime() aborts at JS_FreeRuntime() if it does not. +static void dom_exception_added_twice(void) +{ + JSValue ret; + const char *s; + int i; + + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + + // the implicit install left a working DOMException behind + ret = eval(ctx, "DOMException.prototype === " + "Object.getPrototypeOf(new DOMException)"); + assert(JS_ToBool(ctx, ret) == true); + JS_FreeValue(ctx, ret); + + // installing it again, repeatedly, must not leak the previous prototype + for (i = 0; i < 3; i++) + assert(JS_AddIntrinsicDOMException(ctx) == 0); + + // and the class prototype still matches the global constructor, i.e. the + // slot tracks the newest install rather than a freed or stale object + ret = eval(ctx, "DOMException.prototype === " + "Object.getPrototypeOf(new DOMException)"); + assert(JS_ToBool(ctx, ret) == true); + JS_FreeValue(ctx, ret); + + ret = eval(ctx, "new DOMException('m', 'InvalidCharacterError').name"); + assert(!JS_IsException(ret)); + s = JS_ToCString(ctx, ret); + assert(s); + assert(!strcmp(s, "InvalidCharacterError")); + JS_FreeCString(ctx, s); + JS_FreeValue(ctx, ret); + + // the internally thrown DOMExceptions pick up the current prototype too + ret = eval(ctx, "try { atob('a') } catch (e) { " + " e instanceof DOMException && e.name } "); + assert(!JS_IsException(ret)); + s = JS_ToCString(ctx, ret); + assert(s); + assert(!strcmp(s, "InvalidCharacterError")); + JS_FreeCString(ctx, s); + JS_FreeValue(ctx, ret); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void backtrace_oom_callsite_array(void) +{ + static const char setup_code[] = + "Error.prepareStackTrace = (e, frames) => frames;\n" + "globalThis.f = () => new Error();\n"; + JSValue global_object, func, ret; + JSMemoryUsage stats; + uint32_t headroom; + JSRuntime *rt; + JSContext *ctx; + + rt = new_runtime(); + ctx = JS_NewContext(rt); + global_object = JS_GetGlobalObject(ctx); + + ret = eval(ctx, setup_code); + assert(!JS_IsException(ret)); + JS_FreeValue(ctx, ret); + + func = JS_GetPropertyStr(ctx, global_object, "f"); + assert(JS_IsFunction(ctx, func)); + + for (headroom = 0; headroom < 2048; headroom++) { + JS_ComputeMemoryUsage(rt, &stats); + JS_SetMemoryLimit(rt, (size_t)stats.malloc_size + headroom); + ret = JS_Call(ctx, func, JS_UNDEFINED, 0, NULL); + JS_SetMemoryLimit(rt, 0); + JS_FreeValue(ctx, ret); + JS_FreeValue(ctx, JS_GetException(ctx)); + } + + JS_FreeValue(ctx, func); + JS_FreeValue(ctx, global_object); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void large_allocation_accounting(void) +{ + static const size_t block_size = 1024 * 1024; + JSMemoryUsage before, after; + JSValue ret, exception; + JSRuntime *rt; + JSContext *ctx; + const char *str; + + rt = new_runtime(); + ctx = JS_NewContext(rt); + + JS_ComputeMemoryUsage(rt, &before); + ret = eval(ctx, "globalThis.a = new Uint8Array(1024 * 1024)"); + assert(!JS_IsException(ret)); + JS_FreeValue(ctx, ret); + JS_ComputeMemoryUsage(rt, &after); + assert(after.malloc_size - before.malloc_size >= (int64_t)block_size); + + JS_ComputeMemoryUsage(rt, &before); + JS_SetMemoryLimit(rt, (size_t)before.malloc_size + 4 * block_size); + ret = eval(ctx, "globalThis.a = [];\n" + "for (let i = 0; i < 64; i++) {\n" + " // OOM exception should be uncatchable\n" + " try {\n" + " a.push(new Uint8Array(1024 * 1024));" + " } catch (e) {\n" + " throw 'unexpected exception';\n" + " }\n" + "}"); + assert(JS_IsException(ret)); + JS_SetMemoryLimit(rt, 0); + JS_ComputeMemoryUsage(rt, &after); + assert(after.malloc_size - before.malloc_size < (int64_t)(8 * block_size)); + + exception = JS_GetException(ctx); + assert(JS_IsError(exception)); + str = JS_ToCString(ctx, exception); + assert(str); + assert(!strcmp(str, "InternalError: out of memory")); + JS_FreeCString(ctx, str); + JS_FreeValue(ctx, exception); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void backtrace_oom_current_exception(void) +{ + static const char setup_code[] = + "globalThis.f = function() { missing; };\n" + "Object.defineProperty(f, 'name', { value: 'x'.repeat(2 * 1024 * 1024) });"; + JSMemoryUsage stats; + JSValue ret, exception; + JSRuntime *rt; + JSContext *ctx; + + rt = new_runtime(); + ctx = JS_NewContext(rt); + + ret = eval(ctx, setup_code); + assert(!JS_IsException(ret)); + JS_FreeValue(ctx, ret); + + JS_ComputeMemoryUsage(rt, &stats); + JS_SetMemoryLimit(rt, (size_t)stats.malloc_size + 128 * 1024); + + ret = eval(ctx, "f()"); + assert(JS_IsException(ret)); + assert(JS_HasException(ctx)); + exception = JS_GetException(ctx); + JS_FreeValue(ctx, exception); + JS_SetMemoryLimit(rt, 0); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void proxy_own_keys_huge_length(void) +{ + static const char setup_code[] = + "globalThis.p = new Proxy({}, {\n" + " ownKeys() { return { length: 0x20000000 }; },\n" + "});"; + JSMemoryUsage stats; + JSValue ret, exception; + JSRuntime *rt; + JSContext *ctx; + const char *str; + + rt = new_runtime(); + ctx = JS_NewContext(rt); + + ret = eval(ctx, setup_code); + assert(!JS_IsException(ret)); + JS_FreeValue(ctx, ret); + + JS_ComputeMemoryUsage(rt, &stats); + JS_SetMemoryLimit(rt, (size_t)stats.malloc_size + 128 * 1024); + + ret = eval(ctx, "Object.keys(p)"); + assert(JS_IsException(ret)); + JS_FreeValue(ctx, ret); + exception = JS_GetException(ctx); + str = JS_ToCString(ctx, exception); + assert(str); + /* the trap result has no index 0, so the first key must be rejected */ + assert(!strcmp(str, "TypeError: proxy: properties must be strings or symbols")); + JS_FreeCString(ctx, str); + JS_FreeValue(ctx, exception); + JS_SetMemoryLimit(rt, 0); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static int gop_get_own_property(JSContext *ctx, JSPropertyDescriptor *desc, + JSValueConst obj, JSAtom prop) +{ + const char *name; + int found; + + found = 0; + name = JS_AtomToCString(ctx, prop); + if (!name) + return -1; + if (!strcmp(name, "answer")) { + found = 1; + *desc = (JSPropertyDescriptor){ + .value = JS_NewInt32(ctx, 42), + .flags = JS_PROP_C_W_E | JS_PROP_HAS_VALUE, + }; + } + JS_FreeCString(ctx, name); + return found; +} + +static void global_object_prototype(void) +{ + static const char code[] = "answer"; + JSValue global_object, proto, ret; + JSClassID class_id; + JSRuntime *rt; + JSContext *ctx; + int32_t answer; + int res; + + { + rt = new_runtime(); + ctx = JS_NewContext(rt); + proto = JS_NewObject(ctx); + assert(JS_IsObject(proto)); + JSCFunctionListEntry prop = JS_PROP_INT32_DEF("answer", 42, JS_PROP_C_W_E); + JS_SetPropertyFunctionList(ctx, proto, &prop, 1); + global_object = JS_GetGlobalObject(ctx); + res = JS_SetPrototype(ctx, global_object, proto); + assert(res == true); + JS_FreeValue(ctx, global_object); + JS_FreeValue(ctx, proto); + ret = eval(ctx, code); + assert(!JS_IsException(ret)); + assert(JS_IsNumber(ret)); + res = JS_ToInt32(ctx, &answer, ret); + assert(res == 0); + assert(answer == 42); + JS_FreeValue(ctx, ret); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + } + { + JSClassExoticMethods exotic = (JSClassExoticMethods){ + .get_own_property = gop_get_own_property, + }; + JSClassDef def = (JSClassDef){ + .class_name = "Global Object", + .exotic = &exotic, + }; + rt = new_runtime(); + class_id = 0; + JS_NewClassID(rt, &class_id); + res = JS_NewClass(rt, class_id, &def); + assert(res == 0); + ctx = JS_NewContext(rt); + proto = JS_NewObjectClass(ctx, class_id); + assert(JS_IsObject(proto)); + global_object = JS_GetGlobalObject(ctx); + res = JS_SetPrototype(ctx, global_object, proto); + assert(res == true); + JS_FreeValue(ctx, global_object); + JS_FreeValue(ctx, proto); + ret = eval(ctx, code); + assert(!JS_IsException(ret)); + assert(JS_IsNumber(ret)); + res = JS_ToInt32(ctx, &answer, ret); + assert(res == 0); + assert(answer == 42); + JS_FreeValue(ctx, ret); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + } +} + +// https://github.com/quickjs-ng/quickjs/issues/1178 +static void slice_string_tocstring(void) +{ + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + JSValue ret = eval(ctx, "'.'.repeat(16384).slice(1, -1)"); + assert(!JS_IsException(ret)); + assert(JS_IsString(ret)); + const char *str = JS_ToCString(ctx, ret); + assert(strlen(str) == 16382); + JS_FreeCString(ctx, str); + JS_FreeValue(ctx, ret); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void immutable_array_buffer(void) +{ + JSValue obj, ret; + bool immutable; + char buf[96]; + int i, v; + + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + for (i = 0; i < 2; i++) { + obj = JS_NewObject(ctx); + immutable = (i == 0); + assert(-1 == JS_IsImmutableArrayBuffer(JS_NULL)); + assert(-1 == JS_IsImmutableArrayBuffer(JS_UNDEFINED)); + assert(-1 == JS_IsImmutableArrayBuffer(obj)); + assert(-1 == JS_SetImmutableArrayBuffer(JS_NULL, immutable)); + assert(-1 == JS_SetImmutableArrayBuffer(JS_UNDEFINED, immutable)); + assert(-1 == JS_SetImmutableArrayBuffer(obj, immutable)); + JS_FreeValue(ctx, obj); + } + obj = eval(ctx, "globalThis.ab = new ArrayBuffer(1)"); + assert(!JS_IsException(obj)); + assert(JS_IsArrayBuffer(obj)); + assert(!JS_IsImmutableArrayBuffer(obj)); + for (i = 1; i <= 3; i++) { + immutable = (i == 2); + if (i > 1) + JS_SetImmutableArrayBuffer(obj, immutable); + assert(immutable == JS_IsImmutableArrayBuffer(obj)); + snprintf(buf, sizeof(buf), + "var ta = new Uint8Array(ab); ta[0] = %d; ta[0]", i); + ret = eval(ctx, buf); + assert(!JS_IsException(ret)); + assert(JS_IsNumber(ret)); + assert(0 == JS_ToInt32(ctx, &v, ret)); + JS_FreeValue(ctx, ret); + if (immutable) { + assert(v != i); + } else { + assert(v == i); + } + } + JS_FreeValue(ctx, obj); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void *sab_test_alloc(void *opaque, size_t size) +{ + return malloc(size); +} + +static void sab_test_free(void *opaque, void *ptr) +{ + free(ptr); +} + +static void shared_array_buffer_growth(void) +{ + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + JSValue ret, exception; + + ret = eval(ctx, "new SharedArrayBuffer(16)"); + assert(!JS_IsException(ret)); + JS_FreeValue(ctx, ret); + + ret = eval(ctx, + "const sab = new SharedArrayBuffer(16, { maxByteLength: 16 });" + "sab.grow(16);" + "sab.byteLength === 16 && sab.maxByteLength === 16"); + assert(!JS_IsException(ret)); + assert(JS_IsBool(ret)); + assert(JS_VALUE_GET_BOOL(ret)); + JS_FreeValue(ctx, ret); + + ret = eval(ctx, "new SharedArrayBuffer(16, { maxByteLength: 16384 })"); + assert(JS_IsException(ret)); + assert(JS_HasException(ctx)); + exception = JS_GetException(ctx); + assert(JS_IsError(exception)); + JS_FreeValue(ctx, exception); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + + JSSharedArrayBufferFunctions funcs = { + .sab_alloc = sab_test_alloc, + .sab_free = sab_test_free, + .sab_dup = NULL, + .sab_opaque = NULL, + }; + + rt = new_runtime(); + JS_SetSharedArrayBufferFunctions(rt, &funcs); + ctx = JS_NewContext(rt); + ret = eval(ctx, + "const sab = new SharedArrayBuffer(16, { maxByteLength: 16384 });" + "const u8 = new Uint8Array(sab);" + "sab.grow(16384);" + "u8[1024] === 0 && u8.byteLength === 16384"); + assert(!JS_IsException(ret)); + assert(JS_IsBool(ret)); + assert(JS_VALUE_GET_BOOL(ret)); + JS_FreeValue(ctx, ret); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void get_uint8array(void) +{ + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + JSValue val; + uint8_t *p; + size_t size; + uint8_t buf[3] = { 1, 2, 3 }; + + val = eval(ctx, "new Uint8Array(0)"); + assert(!JS_IsException(val)); + p = JS_GetUint8Array(ctx, &size, val); + assert(p != NULL); + assert(size == 0); + JS_FreeValue(ctx, val); + + val = JS_NewUint8Array(ctx, NULL, 0, NULL, NULL, false); + assert(!JS_IsException(val)); + p = JS_GetUint8Array(ctx, &size, val); + assert(p != NULL); + assert(size == 0); + JS_FreeValue(ctx, val); + + val = JS_NewUint8ArrayCopy(ctx, NULL, 0); + assert(!JS_IsException(val)); + p = JS_GetUint8Array(ctx, &size, val); + assert(p != NULL); + assert(size == 0); + JS_FreeValue(ctx, val); + + val = JS_NewUint8ArrayCopy(ctx, buf, sizeof(buf)); + assert(!JS_IsException(val)); + p = JS_GetUint8Array(ctx, &size, val); + assert(p != NULL); + assert(size == 3); + assert(p[0] == 1 && p[1] == 2 && p[2] == 3); + JS_FreeValue(ctx, val); + + val = eval(ctx, "new Uint8Array([4, 5, 6])"); + assert(!JS_IsException(val)); + p = JS_GetUint8Array(ctx, &size, val); + assert(p != NULL); + assert(size == 3); + assert(p[0] == 4 && p[1] == 5 && p[2] == 6); + JS_FreeValue(ctx, val); + + val = eval(ctx, "new Int32Array(4)"); + assert(!JS_IsException(val)); + p = JS_GetUint8Array(ctx, &size, val); + assert(p == NULL); + assert(size == 0); + JS_FreeValue(ctx, val); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void new_symbol(void) +{ + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + JSValue global = JS_GetGlobalObject(ctx); + JSValue sym, ret; + + /* Local symbol with NULL description -> Symbol() */ + sym = JS_NewSymbol(ctx, NULL, false); + assert(!JS_IsException(sym)); + assert(JS_IsSymbol(sym)); + JS_SetPropertyStr(ctx, global, "sym_local_null", sym); + + ret = eval(ctx, "typeof sym_local_null === 'symbol' && sym_local_null.description === undefined && Symbol.keyFor(sym_local_null) === undefined"); + assert(JS_IsBool(ret)); + assert(JS_VALUE_GET_BOOL(ret)); + JS_FreeValue(ctx, ret); + + /* Global symbol with NULL description -> Symbol.for() -> Symbol.for('undefined') */ + sym = JS_NewSymbol(ctx, NULL, true); + assert(!JS_IsException(sym)); + assert(JS_IsSymbol(sym)); + JS_SetPropertyStr(ctx, global, "sym_global_null", sym); + + ret = eval(ctx, "typeof sym_global_null === 'symbol' && sym_global_null.description === 'undefined' && Symbol.keyFor(sym_global_null) === 'undefined'"); + assert(JS_IsBool(ret)); + assert(JS_VALUE_GET_BOOL(ret)); + JS_FreeValue(ctx, ret); + + /* Local symbol with description -> Symbol('test_local') */ + sym = JS_NewSymbol(ctx, "test_local", false); + assert(!JS_IsException(sym)); + assert(JS_IsSymbol(sym)); + JS_SetPropertyStr(ctx, global, "sym_local_str", sym); + + ret = eval(ctx, "sym_local_str.description === 'test_local' && Symbol.keyFor(sym_local_str) === undefined"); + assert(JS_IsBool(ret)); + assert(JS_VALUE_GET_BOOL(ret)); + JS_FreeValue(ctx, ret); + + /* Global symbol with description -> Symbol.for('test_global') */ + sym = JS_NewSymbol(ctx, "test_global", true); + assert(!JS_IsException(sym)); + assert(JS_IsSymbol(sym)); + JS_SetPropertyStr(ctx, global, "sym_global_str", sym); + + ret = eval(ctx, "sym_global_str.description === 'test_global' && Symbol.keyFor(sym_global_str) === 'test_global'"); + assert(JS_IsBool(ret)); + assert(JS_VALUE_GET_BOOL(ret)); + JS_FreeValue(ctx, ret); + + JS_FreeValue(ctx, global); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void bulk_free_macros(void) { + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + + JSValue val0 = JS_NewObject(ctx); + JSValue val1 = JS_NewArray(ctx); + JSValue val2 = JS_NewDate(ctx, 0.0); + + JSMemoryUsage mem_usage; + JS_ComputeMemoryUsage(rt, &mem_usage); + int obj_count = mem_usage.obj_count; + + JS_FreeValues(ctx, val0, val1); + JS_FreeValuesRT(rt, val2); + + // silly atoms to ensure qjs doesn't find built-ins that match + JSAtom atom0 = JS_NewAtom(ctx, "ALL!!"); + JSAtom atom1 = JS_NewAtom(ctx, "YOUR!!"); + JSAtom atom2 = JS_NewAtom(ctx, "ATOMS!!"); + JSAtom atom3 = JS_NewAtom(ctx, "ARE!!"); + JSAtom atom4 = JS_NewAtom(ctx, "BELONG!!"); + JSAtom atom5 = JS_NewAtom(ctx, "TO US!!"); + + JS_ComputeMemoryUsage(rt, &mem_usage); + assert((obj_count - 3) == mem_usage.obj_count); + int atom_count = mem_usage.atom_count; + + JS_FreeAtoms(ctx, atom1, atom3, atom4); + JS_FreeAtomsRT(rt, atom0, atom2, atom5); + + JS_ComputeMemoryUsage(rt, &mem_usage); + assert((atom_count - 6) == mem_usage.atom_count); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static int detach_free_count; + +static void *detach_realloc_func(JSRuntime *rt, void *opaque, void *ptr, + size_t size) +{ + if (size == 0) { + detach_free_count++; + free(ptr); + return NULL; + } + return realloc(ptr, size); +} + +static void detach_array_buffer_free_once(void) +{ + JSValue obj; + uint8_t *buf; + + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + + detach_free_count = 0; + buf = malloc(8); + obj = JS_NewArrayBuffer(ctx, buf, 8, /*max_len*/0, detach_realloc_func, + NULL, false); + assert(JS_IsArrayBuffer(obj)); + + /* detaching releases the backing store exactly once */ + JS_DetachArrayBuffer(ctx, obj); + assert(detach_free_count == 1); + + /* finalizing the detached buffer must not release it a second time */ + JS_FreeValue(ctx, obj); + assert(detach_free_count == 1); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void *realloc_array_buffer_data(JSRuntime *rt, void *opaque, void *ptr, + size_t size) +{ + if (size == 0) { + free(ptr); + return NULL; + } + return realloc(ptr, size); +} + +static void typed_array_sort_index_overflow(void) +{ + const size_t len = 0x40000010; /* 2**30 + 16 */ + JSMemoryUsage stats; + JSValue global, buffer, ret; + JSRuntime *rt; + JSContext *ctx; + uint8_t *buf; + + /* the data is never read, but keep it real memory so a regression + corrupts the heap in a way ASan can see rather than segfaulting */ + buf = calloc(1, len); + rt = new_runtime(); + ctx = JS_NewContext(rt); + + buffer = JS_NewArrayBuffer(ctx, buf, len, /*max_len*/0, + realloc_array_buffer_data, NULL, false); + assert(JS_IsArrayBuffer(buffer)); + global = JS_GetGlobalObject(ctx); + JS_SetPropertyStr(ctx, global, "buf", buffer); + JS_FreeValue(ctx, global); + + /* Cap memory so that the correctly computed 4 GB index array also + fails to allocate on 64 bit platforms; the undersized allocation a + 32 bit platform computes fits well within the cap. */ + JS_ComputeMemoryUsage(rt, &stats); + JS_SetMemoryLimit(rt, (size_t)stats.malloc_size + 1024 * 1024); + + ret = eval(ctx, "new Uint8Array(buf).sort((a, b) => a - b)"); + assert(JS_IsException(ret)); + assert(JS_HasException(ctx)); + JS_FreeValue(ctx, ret); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static int transfer_free_count; +static int transfer_realloc_count; + +static void *transfer_realloc_func(JSRuntime *rt, void *opaque, void *ptr, + size_t size) +{ + if (size == 0) { + transfer_free_count++; + free(ptr); + return NULL; + } + transfer_realloc_count++; + return realloc(ptr, size); +} + +/* a realloc function that can only free, never resize */ +static void *failing_realloc_func(JSRuntime *rt, void *opaque, void *ptr, + size_t size) +{ + if (size == 0) { + transfer_free_count++; + free(ptr); + } + return NULL; +} + +static JSValue make_external_ab(JSContext *ctx, uint8_t **pbuf, size_t len, + size_t max_len, + JSReallocArrayBufferDataFunc *realloc_func) +{ + uint8_t *buf = malloc(max_len > len ? max_len : len); + memset(buf, 0xAB, len); + JSValue obj = JS_NewArrayBuffer(ctx, buf, len, max_len, realloc_func, NULL, + /*is_shared*/false); + assert(JS_IsArrayBuffer(obj)); + JSValue global = JS_GetGlobalObject(ctx); + JS_SetPropertyStr(ctx, global, "ab", JS_DupValue(ctx, obj)); + JS_FreeValue(ctx, global); + *pbuf = buf; + return obj; +} + +static void transfer_external_array_buffer(void) +{ + JSValue obj, ret, exc, det; + const char *s; + uint8_t *buf, *p; + size_t i, size; + + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + + // same-length transfer succeeds and reuses the backing store; each variant + // detaches the source, so use a fresh buffer per iteration + { + static const char *const exprs[] = { + "ab.transfer()", "ab.transfer(8)", "ab.transferToFixedLength()", + "ab.transferToFixedLength(8)", "ab.transferToImmutable()", + }; + for (i = 0; i < countof(exprs); i++) { + transfer_free_count = 0; + transfer_realloc_count = 0; + obj = make_external_ab(ctx, &buf, 8, /*max_len*/0, + transfer_realloc_func); + + ret = eval(ctx, exprs[i]); + assert(!JS_IsException(ret)); + assert(JS_IsArrayBuffer(ret)); + assert(transfer_realloc_count == 0); + p = JS_GetArrayBuffer(ctx, &size, ret); + assert(p == buf); + assert(size == 8); + assert(p[0] == 0xAB && p[7] == 0xAB); + det = eval(ctx, "ab.detached"); + assert(JS_IsBool(det)); + assert(JS_VALUE_GET_BOOL(det)); + JS_FreeValue(ctx, det); + assert(transfer_free_count == 0); + JS_FreeValue(ctx, ret); + assert(transfer_free_count == 1); + + ret = eval(ctx, "globalThis.ab = undefined"); + JS_FreeValue(ctx, ret); + JS_FreeValue(ctx, obj); + assert(transfer_free_count == 1); + } + } + + // a length-changing transfer resizes the external store through the + // realloc function and hands it over to the new ArrayBuffer + { + static const struct { + const char *code; + size_t len; + } cases[] = { + { "ab.transfer(4)", 4 }, + { "ab.transfer(16)", 16 }, + { "ab.transferToFixedLength(4)", 4 }, + { "ab.transferToImmutable(16)", 16 }, + }; + for (i = 0; i < countof(cases); i++) { + transfer_free_count = 0; + transfer_realloc_count = 0; + obj = make_external_ab(ctx, &buf, 8, /*max_len*/0, + transfer_realloc_func); + + ret = eval(ctx, cases[i].code); + assert(!JS_IsException(ret)); + assert(JS_IsArrayBuffer(ret)); + assert(transfer_realloc_count == 1); + assert(transfer_free_count == 0); + p = JS_GetArrayBuffer(ctx, &size, ret); + assert(size == cases[i].len); + assert(p[0] == 0xAB && p[3] == 0xAB); + if (cases[i].len > 8) + assert(p[8] == 0 && p[15] == 0); // the grown tail is zeroed + det = eval(ctx, "ab.detached"); + assert(JS_IsBool(det)); + assert(JS_VALUE_GET_BOOL(det)); + JS_FreeValue(ctx, det); + + // the source handed the store over; releasing the new AB frees it + JS_FreeValue(ctx, ret); + assert(transfer_free_count == 1); + + ret = eval(ctx, "globalThis.ab = undefined"); + JS_FreeValue(ctx, ret); + JS_FreeValue(ctx, obj); + assert(transfer_free_count == 1); + } + } + + // a transfer that fails to realloc throws and leaves the source alone + { + transfer_free_count = 0; + obj = make_external_ab(ctx, &buf, 8, /*max_len*/0, + failing_realloc_func); + + ret = eval(ctx, "ab.transfer(16)"); + assert(JS_IsException(ret)); + JS_FreeValue(ctx, ret); + exc = JS_GetException(ctx); + assert(JS_IsError(exc)); + s = JS_ToCString(ctx, exc); + assert(s); + assert(strstr(s, "out of memory")); + JS_FreeCString(ctx, s); + JS_FreeValue(ctx, exc); + + det = eval(ctx, "ab.detached"); + assert(JS_IsBool(det)); + assert(!JS_VALUE_GET_BOOL(det)); + JS_FreeValue(ctx, det); + p = JS_GetArrayBuffer(ctx, &size, obj); + assert(p == buf && size == 8 && p[0] == 0xAB); + assert(transfer_free_count == 0); + + ret = eval(ctx, "globalThis.ab = undefined"); + JS_FreeValue(ctx, ret); + JS_FreeValue(ctx, obj); + assert(transfer_free_count == 1); + } + + // transfer(0) changes the length but doesn't realloc: it detaches the + // source (freeing the external store) and yields a fresh empty AB + { + transfer_free_count = 0; + transfer_realloc_count = 0; + obj = make_external_ab(ctx, &buf, 8, /*max_len*/0, + transfer_realloc_func); + + ret = eval(ctx, "ab.transfer(0)"); + assert(!JS_IsException(ret)); + assert(JS_IsArrayBuffer(ret)); + p = JS_GetArrayBuffer(ctx, &size, ret); + assert(size == 0); + assert(transfer_free_count == 1); + JS_FreeValue(ctx, ret); + + det = eval(ctx, "ab.detached"); + assert(JS_IsBool(det)); + assert(JS_VALUE_GET_BOOL(det)); + JS_FreeValue(ctx, det); + + ret = eval(ctx, "globalThis.ab = undefined"); + JS_FreeValue(ctx, ret); + JS_FreeValue(ctx, obj); + assert(transfer_free_count == 1); + } + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void resize_external_array_buffer(void) +{ + JSValue obj, global, ret, exc, det; + const char *s; + uint8_t *buf, *p; + size_t size; + + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + + transfer_free_count = 0; + transfer_realloc_count = 0; + obj = make_external_ab(ctx, &buf, 8, /*max_len*/16, transfer_realloc_func); + + ret = eval(ctx, "ab.resizable && ab.maxByteLength === 16"); + assert(JS_IsBool(ret)); + assert(JS_VALUE_GET_BOOL(ret)); + JS_FreeValue(ctx, ret); + + // growing reallocs through the callback and zeroes the new tail + ret = eval(ctx, "ab.resize(16), ab.byteLength"); + assert(!JS_IsException(ret)); + assert(JS_VALUE_GET_INT(ret) == 16); + JS_FreeValue(ctx, ret); + assert(transfer_realloc_count == 1); + p = JS_GetArrayBuffer(ctx, &size, obj); + assert(size == 16); + assert(p[0] == 0xAB && p[7] == 0xAB); + assert(p[8] == 0 && p[15] == 0); + + // and so does shrinking + ret = eval(ctx, "ab.resize(4), ab.byteLength"); + assert(!JS_IsException(ret)); + assert(JS_VALUE_GET_INT(ret) == 4); + JS_FreeValue(ctx, ret); + assert(transfer_realloc_count == 2); + p = JS_GetArrayBuffer(ctx, &size, obj); + assert(size == 4); + assert(p[0] == 0xAB && p[3] == 0xAB); + + // resizing past maxByteLength still throws, without calling the callback + ret = eval(ctx, "ab.resize(17)"); + assert(JS_IsException(ret)); + JS_FreeValue(ctx, ret); + exc = JS_GetException(ctx); + s = JS_ToCString(ctx, exc); + assert(s); + assert(strstr(s, "invalid array buffer length")); + JS_FreeCString(ctx, s); + JS_FreeValue(ctx, exc); + assert(transfer_realloc_count == 2); + + // a resizable external AB carries its maxByteLength across a transfer + ret = eval(ctx, "ab.transfer(8)"); + assert(!JS_IsException(ret)); + assert(transfer_realloc_count == 3); + det = eval(ctx, "ab.detached"); + assert(JS_IsBool(det)); + assert(JS_VALUE_GET_BOOL(det)); + JS_FreeValue(ctx, det); + global = JS_GetGlobalObject(ctx); + JS_SetPropertyStr(ctx, global, "ab2", ret); + JS_FreeValue(ctx, global); + ret = eval(ctx, "ab2.resizable && ab2.maxByteLength === 16"); + assert(JS_IsBool(ret)); + assert(JS_VALUE_GET_BOOL(ret)); + JS_FreeValue(ctx, ret); + ret = eval(ctx, "ab2.resize(16), ab2.byteLength"); + assert(!JS_IsException(ret)); + assert(JS_VALUE_GET_INT(ret) == 16); + JS_FreeValue(ctx, ret); + assert(transfer_realloc_count == 4); + + assert(transfer_free_count == 0); + ret = eval(ctx, "globalThis.ab = globalThis.ab2 = undefined"); + JS_FreeValue(ctx, ret); + JS_FreeValue(ctx, obj); + assert(transfer_free_count == 1); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +/* hands the buffer over to the runtime allocator, the way quickjs manages the + memory of ArrayBuffers it allocates itself */ +static void *runtime_realloc_func(JSRuntime *rt, void *opaque, void *ptr, + size_t size) +{ + return js_realloc_rt(rt, ptr, size); +} + +static void transfer_default_managed_array_buffer(void) +{ + JSValue obj, global, ret, det; + uint8_t *buf, *p; + size_t size; + + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + + buf = js_malloc(ctx, 8); + memset(buf, 0xAB, 8); + obj = JS_NewArrayBuffer(ctx, buf, 8, /*max_len*/0, + runtime_realloc_func, NULL, false); + assert(JS_IsArrayBuffer(obj)); + global = JS_GetGlobalObject(ctx); + JS_SetPropertyStr(ctx, global, "ab", JS_DupValue(ctx, obj)); + JS_FreeValue(ctx, global); + + ret = eval(ctx, "ab.transfer(16)"); + assert(!JS_IsException(ret)); + assert(JS_IsArrayBuffer(ret)); + p = JS_GetArrayBuffer(ctx, &size, ret); + assert(size == 16); + assert(p[0] == 0xAB && p[7] == 0xAB); + assert(p[8] == 0 && p[15] == 0); + det = eval(ctx, "ab.detached"); + assert(JS_IsBool(det)); + assert(JS_VALUE_GET_BOOL(det)); + JS_FreeValue(ctx, det); + JS_FreeValue(ctx, ret); + ret = eval(ctx, "globalThis.ab = undefined"); + JS_FreeValue(ctx, ret); + JS_FreeValue(ctx, obj); + + buf = js_malloc(ctx, 8); + memset(buf, 0xCD, 8); + obj = JS_NewArrayBuffer(ctx, buf, 8, /*max_len*/0, + runtime_realloc_func, NULL, false); + global = JS_GetGlobalObject(ctx); + JS_SetPropertyStr(ctx, global, "ab", JS_DupValue(ctx, obj)); + JS_FreeValue(ctx, global); + + ret = eval(ctx, "ab.transferToFixedLength(4)"); + assert(!JS_IsException(ret)); + p = JS_GetArrayBuffer(ctx, &size, ret); + assert(size == 4); + assert(p[0] == 0xCD && p[3] == 0xCD); + JS_FreeValue(ctx, ret); + ret = eval(ctx, "globalThis.ab = undefined"); + JS_FreeValue(ctx, ret); + JS_FreeValue(ctx, obj); + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void get_class_name(void) +{ + static const struct { + const char *code; + const char *name; + } builtins[] = { + { "({})", "Object" }, + { "[]", "Array" }, + { "new Error()", "Error" }, + { "new Date()", "Date" }, + { "/re/", "RegExp" }, + { "new Map()", "Map" }, + { "new ArrayBuffer(0)", "ArrayBuffer" }, + { "new Uint8Array(0)", "Uint8Array" }, + { "(function(){})", "Function" }, + }; + JSClassDef def = (JSClassDef){ .class_name = "MyClass" }; + JSClassID class_id, unregistered_class_id; + JSAtom atom, expected; + JSRuntime *rt; + JSContext *ctx; + const char *s; + JSValue obj; + size_t i; + + rt = new_runtime(); + class_id = 0; + JS_NewClassID(rt, &class_id); + assert(0 == JS_NewClass(rt, class_id, &def)); + + /* handed out by JS_NewClassID() but never passed to JS_NewClass() */ + unregistered_class_id = 0; + JS_NewClassID(rt, &unregistered_class_id); + + ctx = JS_NewContext(rt); + + /* the name of a class registered from C, not its class id */ + expected = JS_NewAtom(ctx, "MyClass"); + atom = JS_GetClassName(rt, class_id); + assert(atom == expected); + s = JS_AtomToCString(ctx, atom); + assert(s); + assert(!strcmp(s, "MyClass")); + JS_FreeCString(ctx, s); + JS_FreeAtom(ctx, atom); + JS_FreeAtom(ctx, expected); + + /* the names of the built-in classes */ + for (i = 0; i < countof(builtins); i++) { + obj = eval(ctx, builtins[i].code); + assert(!JS_IsException(obj)); + atom = JS_GetClassName(rt, JS_GetClassID(obj)); + assert(atom != JS_ATOM_NULL); + s = JS_AtomToCString(ctx, atom); + assert(s); + assert(!strcmp(s, builtins[i].name)); + JS_FreeCString(ctx, s); + JS_FreeAtom(ctx, atom); + JS_FreeValue(ctx, obj); + } + + /* class ids without a registered class have no name */ + assert(JS_ATOM_NULL == JS_GetClassName(rt, JS_INVALID_CLASS_ID)); + assert(JS_ATOM_NULL == JS_GetClassName(rt, unregistered_class_id)); + assert(JS_ATOM_NULL == JS_GetClassName(rt, class_id + 4096)); + + /* the caller owns the returned atom; the class keeps its own reference, + so releasing it repeatedly doesn't free the name out from under it */ + for (i = 0; i < 64; i++) + JS_FreeAtom(ctx, JS_GetClassName(rt, class_id)); + atom = JS_GetClassName(rt, class_id); + s = JS_AtomToCString(ctx, atom); + assert(s); + assert(!strcmp(s, "MyClass")); + JS_FreeCString(ctx, s); + JS_FreeAtom(ctx, atom); + + /* every registered class has a name, and it is a name rather than a + number: returning the class id instead produced a valid-looking atom, + either an unrelated predefined one for a small id or the id spelled out + in decimal for a large one, so check the whole table rather than the + handful of classes spelled out above */ + { + JSClassID id; + int registered = 0; + + for (id = 1; id < class_id + 16; id++) { + char decimal[32]; + if (!JS_IsRegisteredClass(rt, id)) + continue; + registered++; + atom = JS_GetClassName(rt, id); + assert(atom != JS_ATOM_NULL); + s = JS_AtomToCString(ctx, atom); + assert(s); + // a few internal classes are deliberately unnamed, but none is + // named after a number + snprintf(decimal, sizeof(decimal), "%u", (unsigned)id); + assert(strcmp(s, decimal)); + assert(s[0] < '0' || s[0] > '9'); + JS_FreeCString(ctx, s); + JS_FreeAtom(ctx, atom); + } + /* the built-ins alone are far more than this */ + assert(registered > 20); + } + + /* two classes sharing a name share the interned atom, and the name does + not depend on which context asks */ + { + JSClassDef def2 = (JSClassDef){ .class_name = "MyClass" }; + JSClassID class_id2 = 0; + JSContext *ctx2; + JSAtom a1, a2; + + JS_NewClassID(rt, &class_id2); + assert(0 == JS_NewClass(rt, class_id2, &def2)); + assert(class_id2 != class_id); + + a1 = JS_GetClassName(rt, class_id); + a2 = JS_GetClassName(rt, class_id2); + assert(a1 == a2); + JS_FreeAtom(ctx, a1); + JS_FreeAtom(ctx, a2); + + ctx2 = JS_NewContext(rt); + a1 = JS_GetClassName(rt, class_id); + a2 = JS_GetClassName(rt, class_id); + assert(a1 == a2); + JS_FreeAtom(ctx2, a1); + JS_FreeAtom(ctx2, a2); + JS_FreeContext(ctx2); + } + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +void object_from(void) +{ + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + JSValue t0 = JS_NewObject(ctx); + assert(!JS_IsException(t0)); + assert(JS_IsObject(t0)); + JSAtom prop = JS_NewAtomLen(ctx, "prop", 4); + assert(prop != JS_ATOM_NULL); + JSValue val = JS_NULL; + JSValue t1 = JS_NewObjectFrom(ctx, 1, &prop, &val); + assert(!JS_IsException(t1)); + assert(JS_IsObject(t1)); + uint32_t old_shape_hash_count = js_std_cmd(/*GetShapeHashCount*/4, rt); + JSValue t2 = JS_NewObjectFrom(ctx, 1, &prop, &val); + assert(!JS_IsException(t2)); + assert(JS_IsObject(t2)); + uint32_t new_shape_hash_count = js_std_cmd(/*GetShapeHashCount*/4, rt); + assert(old_shape_hash_count == new_shape_hash_count); + JS_FreeAtom(ctx, prop); + JS_FreeValue(ctx, t2); + JS_FreeValue(ctx, t1); + JS_FreeValue(ctx, t0); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +void add_intrinsic_bigint(void) +{ + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContextRaw(rt); + JS_AddIntrinsicBaseObjects(ctx); + JS_AddIntrinsicBigInt(ctx); + assert(!JS_HasException(ctx)); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +void new_typed_array(void) +{ + JSValueConst argv[4]; + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + uint8_t *buf = js_malloc(ctx, 8); + JSValue ab = JS_NewArrayBuffer(ctx, buf, 8, /*max_len*/0, NULL, NULL, false); + assert(JS_IsArrayBuffer(ab)); + for (int argc = 0; argc < (int)countof(argv); argc++) { + JSValue ret = JS_NewTypedArray(ctx, argc, argv, JS_TYPED_ARRAY_UINT8); + assert(!JS_IsException(ret)); + assert(JS_IsObject(ret)); + JS_FreeValue(ctx, ret); + argv[argc] = JS_UNDEFINED; + argv[0] = ab; + } + JS_FreeValue(ctx, ab); + js_free(ctx, buf); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +void private_symbols(void) +{ + JSRuntime *rt = new_runtime(); + JSContext *ctx = JS_NewContext(rt); + JSValue pub = JS_NewSymbol(ctx, "public", /*is_global*/false); + JSValue priv = JS_NewPrivateSymbol(ctx, "private"); + assert(JS_IsSymbol(pub)); + assert(JS_IsSymbol(priv)); + JSValue obj = JS_NewObject(ctx); + assert(JS_IsObject(obj)); + assert(true == JS_SetPropertyValue(ctx, obj, pub, JS_TRUE, JS_PROP_C_W_E)); + assert(true == JS_SetPropertyValue(ctx, obj, priv, JS_FALSE, JS_PROP_C_W_E)); + JSValue global_object = JS_GetGlobalObject(ctx); + assert(true == JS_SetPropertyStr(ctx, global_object, "o", JS_DupValue(ctx, obj))); + JS_FreeValue(ctx, global_object); + JSValue result = eval(ctx, "Object.getOwnPropertySymbols(o)"); + assert(JS_IsArray(result)); + int64_t length = -1; + assert(0 == JS_GetLength(ctx, result, &length)); + assert(length == 1); + JSValue item = JS_GetPropertyUint32(ctx, result, 0); + assert(JS_IsSymbol(item)); + assert(JS_IsSameValue(ctx, item, pub)); + JS_FreeValue(ctx, item); + JS_FreeValue(ctx, result); + result = JS_GetPropertyValue(ctx, obj, JS_DupValue(ctx, pub)); + assert(JS_IsBool(result)); + assert(JS_IsSameValue(ctx, result, JS_TRUE)); + result = JS_GetPropertyValue(ctx, obj, JS_DupValue(ctx, priv)); + assert(JS_IsBool(result)); + assert(JS_IsSameValue(ctx, result, JS_FALSE)); + JS_FreeValue(ctx, obj); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +// https://github.com/quickjs-ng/quickjs/issues/1181 +// JS_NewContext() must fail cleanly, not crash or leak, whichever of its +// allocations runs out of memory. +static void new_context_low_memory(void) +{ + JSMemoryUsage stats; + size_t base, headroom; + JSRuntime *rt; + JSContext *ctx; + int all, ok; + + all = ok = 0; + rt = new_runtime(); + JS_ComputeMemoryUsage(rt, &stats); + base = (size_t)stats.malloc_size; + // Small steps first, so that each of the first allocations gets its turn + // to fail, then bigger ones until a few contexts fit. + for (headroom = 0; ok < 4 && headroom < 4 * 1024 * 1024; + headroom += headroom < 8192 ? 8 : 1024) { + JS_SetMemoryLimit(rt, base + headroom); + ctx = JS_NewContext(rt); // expected to fail, not to crash + if (ctx) { + JS_FreeContext(ctx); + ok++; + } + all++; + } + JS_SetMemoryLimit(rt, 0); + JS_FreeRuntime(rt); + assert(ok > 0); // expect some successes... + assert(ok < all); // ...but not all +} + +// running out of memory in JSON.stringify must not leak the array element +// that was being converted +static void json_stringify_oom(void) +{ + static const char setup_code[] = + "globalThis.f = () => JSON.stringify([{}]);\n" + "f();\n"; // JSON.stringify is set up on first access, do it now + JSValue global_object, func, ret; + JSMemoryUsage stats; + uint32_t headroom; + JSRuntime *rt; + JSContext *ctx; + + rt = new_runtime(); + ctx = JS_NewContext(rt); + global_object = JS_GetGlobalObject(ctx); + + ret = eval(ctx, setup_code); + assert(!JS_IsException(ret)); + JS_FreeValue(ctx, ret); + + func = JS_GetPropertyStr(ctx, global_object, "f"); + assert(JS_IsFunction(ctx, func)); + + for (headroom = 0; headroom < 2048; headroom++) { + JS_ComputeMemoryUsage(rt, &stats); + JS_SetMemoryLimit(rt, (size_t)stats.malloc_size + headroom); + ret = JS_Call(ctx, func, JS_UNDEFINED, 0, NULL); + JS_SetMemoryLimit(rt, 0); + JS_FreeValue(ctx, ret); + JS_FreeValue(ctx, JS_GetException(ctx)); + } + + JS_FreeValue(ctx, func); + JS_FreeValue(ctx, global_object); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +struct dynamic_import_state { + int import_calls; + int attribute_calls; + bool defer; + char *basename; + char *filename; + JSValue token; + JSValue attributes; +}; + +static JSModuleDef *dynamic_import_loader(JSContext *ctx, const char *name, + void *opaque, JSValueConst attributes) +{ + struct dynamic_import_state *s = opaque; + if (!strcmp(name, "missing")) { + JS_ThrowReferenceError(ctx, "no such module"); + return NULL; + } + if (JS_IsObject(attributes)) { + JSValue type = JS_GetPropertyStr(ctx, attributes, "type"); + const char *str = JS_ToCString(ctx, type); + assert(str); + assert(!strcmp(str, "x")); + JS_FreeCString(ctx, str); + JS_FreeValue(ctx, type); + s->attribute_calls++; + } + static const char code[] = "export const v = 42"; + JSValue ret = JS_Eval(ctx, code, strlen(code), name, + JS_EVAL_TYPE_MODULE|JS_EVAL_FLAG_COMPILE_ONLY); + assert(!JS_IsException(ret)); + JSModuleDef *m = JS_VALUE_GET_PTR(ret); + JS_FreeValue(ctx, ret); + return m; +} + +static void dynamic_import_func(JSContext *ctx, const char *basename, + const char *filename, JSValue token, + JSValueConst attributes, void *opaque) +{ + struct dynamic_import_state *s = opaque; + s->import_calls++; + if (s->defer) { + s->basename = strdup(basename); + s->filename = strdup(filename); + assert(s->basename); + assert(s->filename); + s->token = token; + s->attributes = JS_DupValue(ctx, attributes); + return; + } + JSValue exception = JS_UNDEFINED; + JSValue promise = JS_LoadModule(ctx, basename, filename, attributes); + if (JS_IsException(promise)) + exception = JS_GetException(ctx); + assert(0 == JS_FinishDynamicImport(ctx, token, promise, exception)); +} + +static JSRuntime *dynamic_import_runtime(struct dynamic_import_state *s) +{ + JSRuntime *rt = new_runtime(); + JS_SetModuleLoaderFunc2(rt, NULL, dynamic_import_loader, NULL, s); + JS_SetDynamicImportFunc(rt, dynamic_import_func, s); + return rt; +} + +static void dynamic_import_drain_jobs(JSRuntime *rt) +{ + JSContext *ctx; + while (JS_ExecutePendingJob(rt, &ctx) > 0) + ; +} + +static void dynamic_import_assert_namespace(JSContext *ctx, JSValueConst promise) +{ + assert(JS_PROMISE_FULFILLED == JS_PromiseState(ctx, promise)); + JSValue ns = JS_PromiseResult(ctx, promise); + JSValue v = JS_GetPropertyStr(ctx, ns, "v"); + assert(JS_IsNumber(v)); + assert(42 == JS_VALUE_GET_INT(v)); + JS_FreeValue(ctx, v); + JS_FreeValue(ctx, ns); +} + +static void dynamic_import_sync_ok(void) +{ + struct dynamic_import_state s = {0}; + JSRuntime *rt = dynamic_import_runtime(&s); + JSContext *ctx = JS_NewContext(rt); + JSValue promise = eval(ctx, "import('dep', {with: {type: 'x'}})"); + assert(JS_PROMISE_PENDING == JS_PromiseState(ctx, promise)); + dynamic_import_drain_jobs(rt); + assert(1 == s.import_calls); + assert(1 == s.attribute_calls); + dynamic_import_assert_namespace(ctx, promise); + JS_FreeValue(ctx, promise); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void dynamic_import_sync_missing(void) +{ + struct dynamic_import_state s = {0}; + JSRuntime *rt = dynamic_import_runtime(&s); + JSContext *ctx = JS_NewContext(rt); + JSValue promise = eval(ctx, "import('missing')"); + dynamic_import_drain_jobs(rt); + assert(1 == s.import_calls); + assert(JS_PROMISE_REJECTED == JS_PromiseState(ctx, promise)); + JSValue reason = JS_PromiseResult(ctx, promise); + assert(JS_IsError(reason)); + JS_FreeValue(ctx, reason); + JS_FreeValue(ctx, promise); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void dynamic_import_deferred(void) +{ + struct dynamic_import_state s = {.defer = true}; + JSRuntime *rt = dynamic_import_runtime(&s); + JSContext *ctx = JS_NewContext(rt); + JSValue promise = eval(ctx, "import('dep', {with: {type: 'x'}})"); + dynamic_import_drain_jobs(rt); + assert(1 == s.import_calls); + assert(0 == s.attribute_calls); + assert(JS_PROMISE_PENDING == JS_PromiseState(ctx, promise)); + // token and attributes must survive a collection while the import is parked + JS_RunGC(rt); + JSValue module_promise = JS_LoadModule(ctx, s.basename, s.filename, + s.attributes); + assert(!JS_IsException(module_promise)); + assert(0 == JS_FinishDynamicImport(ctx, s.token, module_promise, + JS_UNDEFINED)); + JS_FreeValue(ctx, s.attributes); + free(s.basename); + free(s.filename); + dynamic_import_drain_jobs(rt); + assert(1 == s.attribute_calls); + dynamic_import_assert_namespace(ctx, promise); + JS_FreeValue(ctx, promise); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static void dynamic_import_deferred_reject(void) +{ + struct dynamic_import_state s = {.defer = true}; + JSRuntime *rt = dynamic_import_runtime(&s); + JSContext *ctx = JS_NewContext(rt); + JSValue promise = eval(ctx, "import('dep')"); + dynamic_import_drain_jobs(rt); + assert(JS_PROMISE_PENDING == JS_PromiseState(ctx, promise)); + JSValue error = JS_NewError(ctx); + assert(1 == JS_SetPropertyStr(ctx, error, "tag", JS_NewInt32(ctx, 7))); + assert(0 == JS_FinishDynamicImport(ctx, s.token, JS_EXCEPTION, error)); + JS_FreeValue(ctx, s.attributes); + free(s.basename); + free(s.filename); + dynamic_import_drain_jobs(rt); + assert(JS_PROMISE_REJECTED == JS_PromiseState(ctx, promise)); + JSValue reason = JS_PromiseResult(ctx, promise); + JSValue tag = JS_GetPropertyStr(ctx, reason, "tag"); + assert(7 == JS_VALUE_GET_INT(tag)); + JS_FreeValue(ctx, tag); + JS_FreeValue(ctx, reason); + JS_FreeValue(ctx, promise); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +int main(void) +{ + cfunctions(); + sync_call(); + async_call(); + async_call_stack_overflow(); + raw_context_global_var(); + is_array(); + module_serde(); + module_unhandled_rejection(); + dynamic_import_sync_ok(); + dynamic_import_sync_missing(); + dynamic_import_deferred(); + dynamic_import_deferred_reject(); + promise_mark_as_handled(); + promise_then(); + runtime_cstring_free(); + utf16_string(); + weak_map_gc_check(); + promise_hook(); + dump_memory_usage(); + new_errors(); + dom_exception_added_twice(); + large_allocation_accounting(); + backtrace_oom_current_exception(); + backtrace_oom_callsite_array(); + proxy_own_keys_huge_length(); + global_object_prototype(); + slice_string_tocstring(); + immutable_array_buffer(); + shared_array_buffer_growth(); + get_uint8array(); + new_symbol(); + bulk_free_macros(); + detach_array_buffer_free_once(); + typed_array_sort_index_overflow(); + transfer_external_array_buffer(); + resize_external_array_buffer(); + transfer_default_managed_array_buffer(); + get_class_name(); + object_from(); + add_intrinsic_bigint(); + new_typed_array(); + std_eval_interrupt_handler(); + private_symbols(); + new_context_low_memory(); + json_stringify_oom(); + return 0; +} diff --git a/userland/qjs/source/builtin-array-fromasync.h b/userland/qjs/source/builtin-array-fromasync.h new file mode 100644 index 0000000..5ff44ad --- /dev/null +++ b/userland/qjs/source/builtin-array-fromasync.h @@ -0,0 +1,121 @@ +/* File generated automatically by the QuickJS-ng compiler. */ + +#include + +const uint32_t qjsc_builtin_array_fromasync_size = 890; + +const uint8_t qjsc_builtin_array_fromasync[890] = { + 0x1d, 0xd5, 0x99, 0xb7, 0x67, 0x0e, 0x01, 0x28, + 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0xb7, 0x61, + 0x73, 0x79, 0x6e, 0x63, 0x49, 0x74, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x01, 0x2a, 0x4f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0xb7, 0x64, 0x65, 0x66, + 0x69, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x01, 0x1e, 0x53, 0x79, 0x6d, + 0x62, 0x6f, 0x6c, 0xb7, 0x69, 0x74, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x01, 0x08, 0x63, 0x61, + 0x6c, 0x6c, 0x01, 0x12, 0x61, 0x72, 0x72, 0x61, + 0x79, 0x4c, 0x69, 0x6b, 0x65, 0x01, 0x0a, 0x6d, + 0x61, 0x70, 0x46, 0x6e, 0x01, 0x0e, 0x74, 0x68, + 0x69, 0x73, 0x41, 0x72, 0x67, 0x01, 0x0c, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x01, 0x02, 0x69, + 0x01, 0x1a, 0x69, 0x73, 0x43, 0x6f, 0x6e, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x01, + 0x08, 0x73, 0x79, 0x6e, 0x63, 0x01, 0x0c, 0x6d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x01, 0x08, 0x69, + 0x74, 0x65, 0x72, 0x01, 0x1c, 0x6e, 0x6f, 0x74, + 0x20, 0x61, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x0c, 0x00, 0x02, 0x00, 0xa8, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, + 0x04, 0x01, 0xaa, 0x01, 0x00, 0x00, 0x00, 0x0c, + 0x43, 0x02, 0x01, 0x00, 0x06, 0x00, 0x06, 0x01, + 0x06, 0x00, 0x01, 0x03, 0x06, 0xbc, 0x02, 0x00, + 0x01, 0x40, 0x03, 0xb2, 0x03, 0x00, 0x01, 0x40, + 0x00, 0xe2, 0x03, 0x00, 0x01, 0x40, 0x01, 0xe4, + 0x03, 0x00, 0x01, 0x40, 0x05, 0xe6, 0x03, 0x00, + 0x01, 0x40, 0x02, 0xe8, 0x03, 0x00, 0x01, 0x40, + 0x04, 0x0c, 0x60, 0x02, 0x01, 0x86, 0x02, 0x03, + 0x0e, 0x01, 0x06, 0x00, 0x06, 0x00, 0x8b, 0x04, + 0x11, 0xea, 0x03, 0x00, 0x01, 0x00, 0xec, 0x03, + 0x00, 0x01, 0x00, 0xee, 0x03, 0x00, 0x01, 0x00, + 0xea, 0x03, 0x01, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0x20, 0xec, 0x03, 0x01, 0x01, 0x20, 0xee, 0x03, + 0x01, 0x02, 0x20, 0xf0, 0x03, 0x02, 0x00, 0x20, + 0xf2, 0x03, 0x02, 0x04, 0x20, 0xf4, 0x03, 0x02, + 0x05, 0x20, 0xf6, 0x03, 0x02, 0x06, 0x20, 0xf8, + 0x03, 0x02, 0x07, 0x20, 0x66, 0x06, 0x08, 0x20, + 0x88, 0x01, 0x07, 0x09, 0x20, 0xfa, 0x03, 0x0a, + 0x08, 0x30, 0x88, 0x01, 0x0d, 0x0b, 0x20, 0xe0, + 0x01, 0x0d, 0x0c, 0x20, 0x10, 0x00, 0x01, 0x00, + 0xb2, 0x03, 0x01, 0x01, 0xe2, 0x03, 0x02, 0x01, + 0xe6, 0x03, 0x04, 0x01, 0xbc, 0x02, 0x00, 0x01, + 0xe8, 0x03, 0x05, 0x01, 0xe4, 0x03, 0x03, 0x01, + 0x08, 0xc8, 0x0d, 0x60, 0x02, 0x00, 0x60, 0x01, + 0x00, 0x60, 0x00, 0x00, 0xd7, 0xcf, 0xd8, 0x11, + 0xf8, 0xf0, 0x08, 0x0e, 0x38, 0x49, 0x00, 0x00, + 0x00, 0xe0, 0xd0, 0xd9, 0x11, 0xf8, 0xf0, 0x08, + 0x0e, 0x38, 0x49, 0x00, 0x00, 0x00, 0xe1, 0xd1, + 0x60, 0x07, 0x00, 0x60, 0x06, 0x00, 0x60, 0x05, + 0x00, 0x60, 0x04, 0x00, 0x60, 0x03, 0x00, 0xd8, + 0x38, 0x49, 0x00, 0x00, 0x00, 0xae, 0xf0, 0x16, + 0xd8, 0x96, 0x04, 0x1b, 0x00, 0x00, 0x00, 0xae, + 0xf0, 0x0c, 0xe3, 0x11, 0x04, 0xfe, 0x00, 0x00, + 0x00, 0x21, 0x01, 0x00, 0x30, 0x06, 0xd2, 0xba, + 0xc8, 0x04, 0xc7, 0x0d, 0xfb, 0xc8, 0x05, 0x09, + 0xc8, 0x06, 0xd7, 0xe4, 0x46, 0xc8, 0x07, 0x61, + 0x07, 0x00, 0x07, 0xab, 0xf0, 0x0f, 0x0a, 0x11, + 0x62, 0x06, 0x00, 0x0e, 0xd7, 0xe5, 0x46, 0x11, + 0x62, 0x07, 0x00, 0x0e, 0x61, 0x07, 0x00, 0x07, + 0xab, 0x68, 0xaa, 0x00, 0x00, 0x00, 0x60, 0x08, + 0x00, 0x06, 0x11, 0xf8, 0xf1, 0x0c, 0x70, 0x41, + 0x33, 0x00, 0x00, 0x00, 0xc8, 0x08, 0x0e, 0xf2, + 0x05, 0x0e, 0xd7, 0xf2, 0xf2, 0x61, 0x08, 0x00, + 0x8c, 0x11, 0xf1, 0x03, 0x0e, 0xba, 0x11, 0x62, + 0x08, 0x00, 0x0e, 0x61, 0x05, 0x00, 0xf0, 0x0c, + 0xc7, 0x0d, 0x11, 0x61, 0x08, 0x00, 0x21, 0x01, + 0x00, 0xf2, 0x06, 0xe6, 0x61, 0x08, 0x00, 0xf5, + 0x11, 0x62, 0x03, 0x00, 0x0e, 0x61, 0x04, 0x00, + 0x61, 0x08, 0x00, 0xa5, 0x68, 0x2f, 0x01, 0x00, + 0x00, 0x60, 0x09, 0x00, 0xd7, 0x61, 0x04, 0x00, + 0x46, 0xc8, 0x09, 0x61, 0x06, 0x00, 0xf0, 0x0a, + 0x61, 0x09, 0x00, 0x8a, 0x11, 0x62, 0x09, 0x00, + 0x0e, 0xd8, 0xf0, 0x15, 0x5d, 0x04, 0x00, 0xd9, + 0xd8, 0x61, 0x09, 0x00, 0x61, 0x04, 0x00, 0x22, + 0x04, 0x00, 0x8a, 0x11, 0x62, 0x09, 0x00, 0x0e, + 0x5d, 0x05, 0x00, 0x61, 0x03, 0x00, 0x61, 0x04, + 0x00, 0x90, 0x62, 0x04, 0x00, 0x0b, 0x61, 0x09, + 0x00, 0x4b, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x4b, + 0x41, 0x00, 0x00, 0x00, 0x0a, 0x4b, 0x42, 0x00, + 0x00, 0x00, 0x0a, 0x4b, 0x43, 0x00, 0x00, 0x00, + 0xf7, 0x0e, 0xf2, 0x9a, 0x60, 0x0a, 0x00, 0x5d, + 0x04, 0x00, 0xd7, 0x61, 0x07, 0x00, 0xf6, 0xc8, + 0x0a, 0x61, 0x05, 0x00, 0xf0, 0x09, 0xc7, 0x0d, + 0x11, 0x21, 0x00, 0x00, 0xf2, 0x03, 0xe6, 0xf4, + 0x11, 0x62, 0x03, 0x00, 0x0e, 0x6b, 0x91, 0x00, + 0x00, 0x00, 0x60, 0x0c, 0x00, 0x60, 0x0b, 0x00, + 0x06, 0x11, 0xf8, 0xf1, 0x13, 0x70, 0x41, 0x44, + 0x00, 0x00, 0x00, 0xc8, 0x0b, 0x41, 0x70, 0x00, + 0x00, 0x00, 0xc8, 0x0c, 0x0e, 0xf2, 0x10, 0x0e, + 0x61, 0x0a, 0x00, 0x41, 0x71, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x8a, 0xf2, 0xe0, 0x61, 0x0c, + 0x00, 0xf1, 0x53, 0x61, 0x06, 0x00, 0xf0, 0x0a, + 0x61, 0x0b, 0x00, 0x8a, 0x11, 0x62, 0x0b, 0x00, + 0x0e, 0xd8, 0xf0, 0x15, 0x5d, 0x04, 0x00, 0xd9, + 0xd8, 0x61, 0x0b, 0x00, 0x61, 0x04, 0x00, 0x22, + 0x04, 0x00, 0x8a, 0x11, 0x62, 0x0b, 0x00, 0x0e, + 0x5d, 0x05, 0x00, 0x61, 0x03, 0x00, 0x61, 0x04, + 0x00, 0x90, 0x62, 0x04, 0x00, 0x0b, 0x61, 0x0b, + 0x00, 0x4b, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x4b, + 0x41, 0x00, 0x00, 0x00, 0x0a, 0x4b, 0x42, 0x00, + 0x00, 0x00, 0x0a, 0x4b, 0x43, 0x00, 0x00, 0x00, + 0xf7, 0x0e, 0xf3, 0x7f, 0xff, 0x0e, 0x06, 0x6c, + 0x0d, 0x00, 0x00, 0x00, 0x0e, 0xf2, 0x1e, 0x6c, + 0x05, 0x00, 0x00, 0x00, 0x30, 0x61, 0x0a, 0x00, + 0x40, 0x06, 0x00, 0x00, 0x00, 0xf0, 0x0d, 0x61, + 0x0a, 0x00, 0x41, 0x06, 0x00, 0x00, 0x00, 0x24, + 0x00, 0x00, 0x0e, 0x6d, 0x61, 0x03, 0x00, 0x61, + 0x04, 0x00, 0x42, 0x33, 0x00, 0x00, 0x00, 0x61, + 0x03, 0x00, 0x2f, 0xc5, 0x00, 0x28, 0xc5, 0x00, + 0xd3, 0x28, +}; + diff --git a/userland/qjs/source/builtin-array-fromasync.js b/userland/qjs/source/builtin-array-fromasync.js new file mode 100644 index 0000000..49c0e1b --- /dev/null +++ b/userland/qjs/source/builtin-array-fromasync.js @@ -0,0 +1,36 @@ +;(function(Array, TypeError, Symbol·asyncIterator, Object·defineProperty, Symbol·iterator, call) { + "use strict" // result.length=i should throw if .length is not writable + return async function fromAsync(arrayLike, mapFn=undefined, thisArg=undefined) { + if (mapFn !== undefined && typeof mapFn !== "function") throw new TypeError("not a function") + let result, i = 0, isConstructor = typeof this === "function" + let sync = false, method = arrayLike[Symbol·asyncIterator] + if (method == null) sync = true, method = arrayLike[Symbol·iterator] + if (method == null) { + let {length} = arrayLike + length = +length || 0 + result = isConstructor ? new this(length) : Array(length) + while (i < length) { + let value = arrayLike[i] + if (sync) value = await value + if (mapFn) value = await call(thisArg, mapFn, value, i) + Object·defineProperty(result, i++, {value, configurable: true, writable: true, enumerable: true}) + } + } else { + const iter = call(arrayLike, method) + result = isConstructor ? new this() : Array() + try { + for (;;) { + let {value, done} = await iter.next() + if (done) break + if (sync) value = await value + if (mapFn) value = await call(thisArg, mapFn, value, i) + Object·defineProperty(result, i++, {value, configurable: true, writable: true, enumerable: true}) + } + } finally { + if (iter.return) iter.return() + } + } + result.length = i + return result + } +}) diff --git a/userland/qjs/source/builtin-iterator-zip-keyed.h b/userland/qjs/source/builtin-iterator-zip-keyed.h new file mode 100644 index 0000000..13fcabd --- /dev/null +++ b/userland/qjs/source/builtin-iterator-zip-keyed.h @@ -0,0 +1,313 @@ +/* File generated automatically by the QuickJS-ng compiler. */ + +#include + +const uint32_t qjsc_builtin_iterator_zip_keyed_size = 2427; + +const uint8_t qjsc_builtin_iterator_zip_keyed[2427] = { + 0x1d, 0x79, 0x0d, 0xf1, 0x8b, 0x2b, 0x01, 0x1c, + 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x48, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x01, 0x08, + 0x63, 0x61, 0x6c, 0x6c, 0x01, 0x24, 0x68, 0x61, + 0x73, 0x4f, 0x77, 0x6e, 0x45, 0x6e, 0x75, 0x6d, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x01, 0x24, 0x67, 0x65, 0x74, 0x4f, 0x77, 0x6e, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x4b, 0x65, 0x79, 0x73, 0x01, 0x1e, 0x53, 0x79, + 0x6d, 0x62, 0x6f, 0x6c, 0xb7, 0x69, 0x74, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x01, 0x0a, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x01, 0x0a, 0x63, 0x6c, + 0x6f, 0x73, 0x65, 0x01, 0x10, 0x63, 0x6c, 0x6f, + 0x73, 0x65, 0x61, 0x6c, 0x6c, 0x01, 0x02, 0x76, + 0x01, 0x02, 0x73, 0x01, 0x08, 0x69, 0x74, 0x65, + 0x72, 0x01, 0x0c, 0x6d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x01, 0x02, 0x65, 0x01, 0x0a, 0x69, 0x74, + 0x65, 0x72, 0x73, 0x01, 0x0a, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x01, 0x04, 0x65, 0x78, 0x01, 0x02, + 0x69, 0x01, 0x12, 0x69, 0x74, 0x65, 0x72, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x01, 0x0e, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x01, 0x08, 0x6d, + 0x6f, 0x64, 0x65, 0x01, 0x0e, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x01, 0x0a, 0x6e, 0x65, + 0x78, 0x74, 0x73, 0x01, 0x08, 0x70, 0x61, 0x64, + 0x73, 0x01, 0x06, 0x6b, 0x65, 0x79, 0x01, 0x06, + 0x64, 0x65, 0x6c, 0x01, 0x02, 0x6a, 0x01, 0x0a, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x01, 0x0a, 0x61, + 0x6c, 0x69, 0x76, 0x65, 0x01, 0x0a, 0x64, 0x6f, + 0x6e, 0x65, 0x73, 0x01, 0x0e, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x01, 0x0c, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x01, 0x1c, 0x72, 0x75, + 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x7a, 0x69, + 0x70, 0x70, 0x65, 0x72, 0x01, 0x06, 0x62, 0x75, + 0x67, 0x01, 0x0e, 0x6c, 0x6f, 0x6e, 0x67, 0x65, + 0x73, 0x74, 0x01, 0x0c, 0x73, 0x74, 0x72, 0x69, + 0x63, 0x74, 0x01, 0x22, 0x6d, 0x69, 0x73, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x20, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x73, 0x01, 0x10, 0x73, + 0x68, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, 0x01, + 0x16, 0x62, 0x75, 0x67, 0x3a, 0x20, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x3d, 0x01, 0x1a, 0x62, 0x61, + 0x64, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x01, 0x16, 0x62, 0x61, 0x64, + 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x01, 0x10, 0x62, 0x61, 0x64, 0x20, 0x6d, 0x6f, + 0x64, 0x65, 0x01, 0x16, 0x62, 0x61, 0x64, 0x20, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x01, + 0x18, 0x62, 0x61, 0x64, 0x20, 0x69, 0x74, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x0c, 0x00, 0x02, + 0x00, 0xa8, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x01, 0x04, 0x01, 0xaa, 0x01, 0x00, 0x00, + 0x00, 0x0c, 0x43, 0x02, 0x00, 0x00, 0x07, 0x03, + 0x07, 0x01, 0x0a, 0x00, 0x04, 0x0c, 0x0a, 0xe2, + 0x03, 0x00, 0x01, 0x40, 0x09, 0xb6, 0x03, 0x00, + 0x01, 0x40, 0x03, 0xb2, 0x03, 0x00, 0x01, 0x40, + 0x00, 0xe4, 0x03, 0x00, 0x01, 0x40, 0x01, 0xe6, + 0x03, 0x00, 0x01, 0x40, 0x07, 0xe8, 0x03, 0x00, + 0x01, 0x40, 0x06, 0xea, 0x03, 0x00, 0x01, 0x40, + 0x08, 0xec, 0x03, 0x00, 0x00, 0x40, 0x05, 0xee, + 0x03, 0x00, 0x01, 0x40, 0x02, 0xf0, 0x03, 0x00, + 0x02, 0x40, 0x04, 0x0c, 0x43, 0x02, 0x00, 0xec, + 0x03, 0x02, 0x00, 0x02, 0x03, 0x00, 0x01, 0x00, + 0x17, 0x02, 0xf2, 0x03, 0x00, 0x01, 0x00, 0xf4, + 0x03, 0x00, 0x01, 0x00, 0xb2, 0x03, 0x02, 0x01, + 0xd7, 0x96, 0x04, 0x4d, 0x00, 0x00, 0x00, 0xad, + 0xf0, 0x07, 0xd7, 0x07, 0xae, 0xf0, 0x02, 0x29, + 0xe3, 0x11, 0xd8, 0x21, 0x01, 0x00, 0x30, 0x0c, + 0x43, 0x02, 0x00, 0xee, 0x03, 0x01, 0x02, 0x01, + 0x04, 0x00, 0x01, 0x00, 0x2d, 0x03, 0xf6, 0x03, + 0x00, 0x01, 0x00, 0xf8, 0x03, 0x02, 0x00, 0x20, + 0xfa, 0x03, 0x05, 0x00, 0x03, 0xe4, 0x03, 0x03, + 0x01, 0x6b, 0x22, 0x00, 0x00, 0x00, 0x60, 0x00, + 0x00, 0xd7, 0xf1, 0x04, 0x06, 0x6e, 0x28, 0xd7, + 0x40, 0x06, 0x00, 0x00, 0x00, 0xcf, 0x61, 0x00, + 0x00, 0xf0, 0x08, 0xe3, 0xd7, 0x61, 0x00, 0x00, + 0xf6, 0x0e, 0x0e, 0x29, 0xd0, 0x6b, 0x07, 0x00, + 0x00, 0x00, 0xcc, 0x6e, 0x28, 0x30, 0x0c, 0x43, + 0x02, 0x00, 0xf0, 0x03, 0x02, 0x04, 0x02, 0x03, + 0x00, 0x01, 0x00, 0x48, 0x06, 0xfc, 0x03, 0x00, + 0x01, 0x00, 0xfe, 0x03, 0x00, 0x01, 0x00, 0x80, + 0x04, 0x01, 0x00, 0x20, 0x82, 0x04, 0x02, 0x01, + 0x20, 0xf6, 0x03, 0x03, 0x02, 0x20, 0xfa, 0x03, + 0x03, 0x03, 0x20, 0xee, 0x03, 0x01, 0x00, 0x60, + 0x00, 0x00, 0x38, 0x49, 0x00, 0x00, 0x00, 0xcf, + 0x60, 0x01, 0x00, 0xd8, 0xd0, 0x61, 0x01, 0x00, + 0x8f, 0x62, 0x01, 0x00, 0xba, 0xa7, 0xf0, 0x2c, + 0x60, 0x03, 0x00, 0x60, 0x02, 0x00, 0xd7, 0x61, + 0x01, 0x00, 0x46, 0xd1, 0xd7, 0x61, 0x01, 0x00, + 0x38, 0x49, 0x00, 0x00, 0x00, 0x48, 0xe3, 0x61, + 0x02, 0x00, 0xf5, 0xd2, 0x61, 0x00, 0x00, 0xf1, + 0xd5, 0x61, 0x03, 0x00, 0x11, 0x62, 0x00, 0x00, + 0x0e, 0xf2, 0xcb, 0x61, 0x00, 0x00, 0x28, 0x0c, + 0x41, 0x02, 0x00, 0xb8, 0x02, 0x02, 0x15, 0x01, + 0x06, 0x08, 0x09, 0x02, 0x80, 0x05, 0x17, 0x84, + 0x04, 0x00, 0x01, 0x00, 0x86, 0x04, 0x00, 0x01, + 0x00, 0x84, 0x04, 0x01, 0xff, 0xff, 0xff, 0xff, + 0x0f, 0x20, 0x86, 0x04, 0x01, 0x01, 0x20, 0x88, + 0x04, 0x02, 0x00, 0x60, 0x04, 0x8a, 0x04, 0x02, + 0x03, 0x20, 0x62, 0x02, 0x04, 0x60, 0x02, 0xfe, + 0x03, 0x02, 0x05, 0x60, 0x01, 0xfc, 0x03, 0x02, + 0x06, 0x60, 0x03, 0x8c, 0x04, 0x02, 0x07, 0x60, + 0x06, 0x8e, 0x04, 0x02, 0x08, 0x60, 0x05, 0x90, + 0x04, 0x09, 0x15, 0x20, 0x82, 0x04, 0x0b, 0x15, + 0x20, 0x92, 0x04, 0x0c, 0x0b, 0x20, 0x90, 0x04, + 0x0c, 0x0c, 0x20, 0xf6, 0x03, 0x0e, 0x0d, 0x20, + 0xf8, 0x03, 0x10, 0x0e, 0x20, 0x94, 0x04, 0x14, + 0x0d, 0x20, 0x82, 0x04, 0x19, 0x15, 0x20, 0x82, + 0x04, 0x1b, 0x15, 0x20, 0xfa, 0x03, 0x1c, 0x15, + 0x03, 0x96, 0x04, 0x02, 0x09, 0x60, 0x00, 0x98, + 0x04, 0x02, 0x14, 0x60, 0x07, 0xb2, 0x03, 0x02, + 0x01, 0xb6, 0x03, 0x01, 0x01, 0xe4, 0x03, 0x03, + 0x01, 0xf0, 0x03, 0x02, 0x00, 0xec, 0x03, 0x00, + 0x00, 0xe8, 0x03, 0x05, 0x01, 0xe6, 0x03, 0x04, + 0x01, 0xea, 0x03, 0x06, 0x01, 0xe2, 0x03, 0x00, + 0x01, 0x0c, 0x42, 0x03, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x05, 0x00, 0x0c, 0x00, 0xb9, 0x04, 0x09, + 0x9a, 0x04, 0x01, 0x00, 0x20, 0xe4, 0x01, 0x01, + 0x01, 0x20, 0x9c, 0x04, 0x01, 0x02, 0x20, 0x82, + 0x04, 0x03, 0x03, 0x20, 0x90, 0x04, 0x04, 0x04, + 0x20, 0xf6, 0x03, 0x04, 0x05, 0x20, 0x9e, 0x04, + 0x04, 0x06, 0x20, 0xfa, 0x03, 0x09, 0x07, 0x03, + 0x80, 0x04, 0x10, 0x07, 0x20, 0x96, 0x04, 0x13, + 0x10, 0xb2, 0x03, 0x00, 0x02, 0xb6, 0x03, 0x01, + 0x02, 0xfe, 0x03, 0x05, 0x10, 0x62, 0x04, 0x10, + 0xfc, 0x03, 0x06, 0x10, 0x88, 0x04, 0x02, 0x10, + 0x8e, 0x04, 0x08, 0x10, 0xe4, 0x03, 0x02, 0x02, + 0x8c, 0x04, 0x07, 0x10, 0x98, 0x04, 0x14, 0x10, + 0xf0, 0x03, 0x03, 0x02, 0x60, 0x02, 0x00, 0x60, + 0x01, 0x00, 0x60, 0x00, 0x00, 0x64, 0x00, 0x00, + 0x11, 0xba, 0xad, 0xf1, 0x06, 0x11, 0xbb, 0xad, + 0xf0, 0x09, 0xbc, 0x11, 0x65, 0x00, 0x00, 0x0e, + 0xf2, 0x33, 0x11, 0xbc, 0xad, 0xf0, 0x0c, 0xe4, + 0x11, 0x04, 0x10, 0x01, 0x00, 0x00, 0x21, 0x01, + 0x00, 0x30, 0x11, 0xbd, 0xad, 0xf0, 0x13, 0x0b, + 0x38, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x44, 0x00, + 0x00, 0x00, 0x0a, 0x4b, 0x70, 0x00, 0x00, 0x00, + 0x28, 0xe5, 0x11, 0x04, 0x11, 0x01, 0x00, 0x00, + 0x21, 0x01, 0x00, 0x30, 0x0e, 0xba, 0xcf, 0xba, + 0xd0, 0x0c, 0x07, 0xd1, 0x60, 0x03, 0x00, 0xba, + 0xd2, 0x61, 0x03, 0x00, 0x64, 0x03, 0x00, 0xa5, + 0x68, 0x9f, 0x01, 0x00, 0x00, 0x60, 0x06, 0x00, + 0x60, 0x05, 0x00, 0x60, 0x04, 0x00, 0x64, 0x04, + 0x00, 0x61, 0x03, 0x00, 0x46, 0xc8, 0x04, 0x64, + 0x05, 0x00, 0x61, 0x03, 0x00, 0x46, 0xc8, 0x05, + 0x61, 0x05, 0x00, 0xf1, 0x28, 0x64, 0x06, 0x00, + 0x04, 0x12, 0x01, 0x00, 0x00, 0xae, 0xf0, 0x0c, + 0xe5, 0x11, 0x04, 0x11, 0x01, 0x00, 0x00, 0x21, + 0x01, 0x00, 0x30, 0x61, 0x02, 0x00, 0x61, 0x04, + 0x00, 0x64, 0x07, 0x00, 0x61, 0x03, 0x00, 0x46, + 0x48, 0xf3, 0x4b, 0x01, 0x06, 0xc8, 0x06, 0x6b, + 0x1a, 0x00, 0x00, 0x00, 0x5d, 0x08, 0x00, 0x61, + 0x05, 0x00, 0x64, 0x09, 0x00, 0x61, 0x03, 0x00, + 0x46, 0xf6, 0x11, 0x62, 0x06, 0x00, 0x0e, 0x0e, + 0xf2, 0x29, 0xc8, 0x07, 0x6b, 0x24, 0x00, 0x00, + 0x00, 0xba, 0x11, 0x65, 0x0a, 0x00, 0x0e, 0x64, + 0x05, 0x00, 0x61, 0x03, 0x00, 0x38, 0x49, 0x00, + 0x00, 0x00, 0x48, 0x5d, 0x0b, 0x00, 0x64, 0x05, + 0x00, 0x64, 0x03, 0x00, 0xf6, 0x0e, 0xc7, 0x07, + 0x30, 0x30, 0x61, 0x06, 0x00, 0x40, 0x70, 0x00, + 0x00, 0x00, 0xf1, 0x43, 0x64, 0x06, 0x00, 0x04, + 0x13, 0x01, 0x00, 0x00, 0xad, 0xf0, 0x1e, 0x61, + 0x00, 0x00, 0xba, 0xa7, 0xf0, 0x17, 0x5d, 0x0b, + 0x00, 0x64, 0x05, 0x00, 0x64, 0x03, 0x00, 0xf6, + 0x0e, 0xe4, 0x11, 0x04, 0x14, 0x01, 0x00, 0x00, + 0x21, 0x01, 0x00, 0x30, 0x61, 0x02, 0x00, 0x61, + 0x04, 0x00, 0x61, 0x06, 0x00, 0x40, 0x44, 0x00, + 0x00, 0x00, 0x48, 0x61, 0x01, 0x00, 0x90, 0x62, + 0x01, 0x00, 0x0e, 0xf3, 0xb9, 0x00, 0x64, 0x0a, + 0x00, 0x8f, 0x65, 0x0a, 0x00, 0x0e, 0x61, 0x00, + 0x00, 0x90, 0x62, 0x00, 0x00, 0x0e, 0x64, 0x05, + 0x00, 0x61, 0x03, 0x00, 0x38, 0x49, 0x00, 0x00, + 0x00, 0x48, 0x64, 0x06, 0x00, 0x60, 0x08, 0x00, + 0x11, 0x04, 0x15, 0x01, 0x00, 0x00, 0xad, 0xf0, + 0x2e, 0x5d, 0x0b, 0x00, 0x64, 0x05, 0x00, 0x64, + 0x03, 0x00, 0xf6, 0xc8, 0x08, 0x61, 0x08, 0x00, + 0xf0, 0x05, 0x61, 0x08, 0x00, 0x30, 0xbd, 0x11, + 0x65, 0x00, 0x00, 0x0e, 0x0b, 0x38, 0x49, 0x00, + 0x00, 0x00, 0x4b, 0x44, 0x00, 0x00, 0x00, 0x0a, + 0x4b, 0x70, 0x00, 0x00, 0x00, 0x28, 0x11, 0x04, + 0x12, 0x01, 0x00, 0x00, 0xad, 0xf0, 0x30, 0x64, + 0x0a, 0x00, 0xbb, 0xa5, 0xf0, 0x19, 0xbd, 0x11, + 0x65, 0x00, 0x00, 0x0e, 0x0b, 0x38, 0x49, 0x00, + 0x00, 0x00, 0x4b, 0x44, 0x00, 0x00, 0x00, 0x0a, + 0x4b, 0x70, 0x00, 0x00, 0x00, 0x28, 0x61, 0x02, + 0x00, 0x61, 0x04, 0x00, 0x64, 0x07, 0x00, 0x61, + 0x03, 0x00, 0x46, 0x48, 0xf2, 0x27, 0x11, 0x04, + 0x13, 0x01, 0x00, 0x00, 0xad, 0xf0, 0x1e, 0x61, + 0x01, 0x00, 0xba, 0xa7, 0xf0, 0x17, 0x5d, 0x0b, + 0x00, 0x64, 0x05, 0x00, 0x64, 0x03, 0x00, 0xf6, + 0x0e, 0xe4, 0x11, 0x04, 0x14, 0x01, 0x00, 0x00, + 0x21, 0x01, 0x00, 0x30, 0x0e, 0x61, 0x03, 0x00, + 0x90, 0x62, 0x03, 0x00, 0x0e, 0xf3, 0x5b, 0xfe, + 0x61, 0x01, 0x00, 0xba, 0xad, 0xf0, 0x19, 0xbd, + 0x11, 0x65, 0x00, 0x00, 0x0e, 0x0b, 0x38, 0x49, + 0x00, 0x00, 0x00, 0x4b, 0x44, 0x00, 0x00, 0x00, + 0x0a, 0x4b, 0x70, 0x00, 0x00, 0x00, 0x28, 0xbb, + 0x11, 0x65, 0x00, 0x00, 0x0e, 0x0b, 0x61, 0x02, + 0x00, 0x4b, 0x44, 0x00, 0x00, 0x00, 0x09, 0x4b, + 0x70, 0x00, 0x00, 0x00, 0x28, 0x0c, 0x42, 0x03, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x06, + 0x00, 0x82, 0x01, 0x01, 0x80, 0x04, 0x01, 0x00, + 0x20, 0x96, 0x04, 0x13, 0x10, 0xb2, 0x03, 0x00, + 0x02, 0xb6, 0x03, 0x01, 0x02, 0xf0, 0x03, 0x03, + 0x02, 0xfc, 0x03, 0x06, 0x10, 0xfe, 0x03, 0x05, + 0x10, 0x60, 0x00, 0x00, 0x64, 0x00, 0x00, 0x11, + 0xba, 0xad, 0xf0, 0x09, 0xbd, 0x11, 0x65, 0x00, + 0x00, 0x0e, 0xf2, 0x45, 0x11, 0xbb, 0xad, 0xf0, + 0x09, 0xbc, 0x11, 0x65, 0x00, 0x00, 0x0e, 0xf2, + 0x38, 0x11, 0xbc, 0xad, 0xf0, 0x0c, 0xe4, 0x11, + 0x04, 0x10, 0x01, 0x00, 0x00, 0x21, 0x01, 0x00, + 0x30, 0x11, 0xbd, 0xad, 0xf0, 0x13, 0x0b, 0x38, + 0x49, 0x00, 0x00, 0x00, 0x4b, 0x44, 0x00, 0x00, + 0x00, 0x0a, 0x4b, 0x70, 0x00, 0x00, 0x00, 0x28, + 0xe5, 0x11, 0x04, 0x16, 0x01, 0x00, 0x00, 0x64, + 0x00, 0x00, 0x71, 0x9c, 0x21, 0x01, 0x00, 0x30, + 0x0e, 0xe6, 0x64, 0x04, 0x00, 0x64, 0x05, 0x00, + 0xf6, 0xcf, 0x61, 0x00, 0x00, 0xf0, 0x05, 0x61, + 0x00, 0x00, 0x30, 0xbd, 0x11, 0x65, 0x00, 0x00, + 0x0e, 0x0b, 0x38, 0x49, 0x00, 0x00, 0x00, 0x4b, + 0x44, 0x00, 0x00, 0x00, 0x0a, 0x4b, 0x70, 0x00, + 0x00, 0x00, 0x28, 0x60, 0x01, 0x00, 0x60, 0x00, + 0x00, 0xd7, 0xcf, 0xd8, 0x11, 0xf8, 0xf0, 0x08, + 0x0e, 0x38, 0x49, 0x00, 0x00, 0x00, 0xe0, 0xd0, + 0x60, 0x14, 0x00, 0x60, 0x13, 0x00, 0x60, 0x08, + 0x00, 0x60, 0x07, 0x00, 0x60, 0x06, 0x00, 0x60, + 0x05, 0x00, 0x60, 0x04, 0x00, 0x60, 0x03, 0x00, + 0x60, 0x02, 0x00, 0x5d, 0x04, 0x00, 0xd7, 0x04, + 0x17, 0x01, 0x00, 0x00, 0xf6, 0x0e, 0xd8, 0x38, + 0x49, 0x00, 0x00, 0x00, 0xad, 0xf0, 0x06, 0x0c, + 0x07, 0xdc, 0xf2, 0x0c, 0x5d, 0x04, 0x00, 0xd8, + 0x04, 0x18, 0x01, 0x00, 0x00, 0xf6, 0x0e, 0xd8, + 0x40, 0x04, 0x01, 0x00, 0x00, 0xd1, 0x61, 0x02, + 0x00, 0x38, 0x49, 0x00, 0x00, 0x00, 0xad, 0xf0, + 0x0b, 0x04, 0x15, 0x01, 0x00, 0x00, 0x11, 0x62, + 0x02, 0x00, 0x0e, 0x61, 0x02, 0x00, 0x04, 0x13, + 0x01, 0x00, 0x00, 0xad, 0x11, 0xf1, 0x18, 0x0e, + 0x61, 0x02, 0x00, 0x04, 0x12, 0x01, 0x00, 0x00, + 0xad, 0x11, 0xf1, 0x0b, 0x0e, 0x61, 0x02, 0x00, + 0x04, 0x15, 0x01, 0x00, 0x00, 0xad, 0xf1, 0x0c, + 0xe3, 0x11, 0x04, 0x19, 0x01, 0x00, 0x00, 0x21, + 0x01, 0x00, 0x30, 0x38, 0x49, 0x00, 0x00, 0x00, + 0xd2, 0x61, 0x02, 0x00, 0x04, 0x12, 0x01, 0x00, + 0x00, 0xad, 0xf0, 0x24, 0xd8, 0x40, 0x05, 0x01, + 0x00, 0x00, 0x11, 0x62, 0x03, 0x00, 0x0e, 0x61, + 0x03, 0x00, 0x38, 0x49, 0x00, 0x00, 0x00, 0xae, + 0xf0, 0x0e, 0x5d, 0x04, 0x00, 0x61, 0x03, 0x00, + 0x04, 0x1a, 0x01, 0x00, 0x00, 0xf6, 0x0e, 0x26, + 0x00, 0x00, 0xc8, 0x04, 0xba, 0xc8, 0x05, 0x26, + 0x00, 0x00, 0xc8, 0x06, 0x26, 0x00, 0x00, 0xc8, + 0x07, 0x26, 0x00, 0x00, 0xc8, 0x08, 0x60, 0x09, + 0x00, 0x5d, 0x05, 0x00, 0xd7, 0xf5, 0x7e, 0xf2, + 0x11, 0xc8, 0x09, 0x61, 0x04, 0x00, 0x61, 0x05, + 0x00, 0x90, 0x62, 0x05, 0x00, 0x61, 0x09, 0x00, + 0x48, 0x81, 0x00, 0xf0, 0xed, 0x0e, 0x83, 0x6b, + 0x41, 0x01, 0x00, 0x00, 0x60, 0x0a, 0x00, 0xba, + 0xc8, 0x0a, 0x61, 0x0a, 0x00, 0x61, 0x05, 0x00, + 0xa5, 0x68, 0xcc, 0x00, 0x00, 0x00, 0x60, 0x0c, + 0x00, 0x60, 0x0b, 0x00, 0x0a, 0xc8, 0x0b, 0x61, + 0x04, 0x00, 0x61, 0x0a, 0x00, 0x46, 0xc8, 0x0c, + 0x5d, 0x06, 0x00, 0xd7, 0x61, 0x0c, 0x00, 0xf6, + 0xf0, 0x60, 0x60, 0x0d, 0x00, 0xd7, 0x61, 0x0c, + 0x00, 0x46, 0xc8, 0x0d, 0x61, 0x0d, 0x00, 0x38, + 0x49, 0x00, 0x00, 0x00, 0xae, 0xf0, 0x4b, 0x60, + 0x0e, 0x00, 0x5d, 0x04, 0x00, 0x61, 0x0d, 0x00, + 0x04, 0x1b, 0x01, 0x00, 0x00, 0xf6, 0x0e, 0x61, + 0x0d, 0x00, 0x5d, 0x07, 0x00, 0x46, 0xc8, 0x0e, + 0x61, 0x0e, 0x00, 0xf0, 0x0e, 0xe5, 0x61, 0x0d, + 0x00, 0x61, 0x0e, 0x00, 0xf6, 0x11, 0x62, 0x0d, + 0x00, 0x0e, 0x61, 0x06, 0x00, 0x61, 0x0a, 0x00, + 0x61, 0x0d, 0x00, 0x48, 0x61, 0x07, 0x00, 0x61, + 0x0a, 0x00, 0x61, 0x0d, 0x00, 0x40, 0x71, 0x00, + 0x00, 0x00, 0x48, 0x09, 0x11, 0x62, 0x0b, 0x00, + 0x0e, 0x61, 0x0b, 0x00, 0xf0, 0x3e, 0x60, 0x0f, + 0x00, 0x61, 0x0a, 0x00, 0xbb, 0x9c, 0xc8, 0x0f, + 0x61, 0x0f, 0x00, 0x61, 0x05, 0x00, 0xa5, 0xf0, + 0x1b, 0x61, 0x04, 0x00, 0x61, 0x0f, 0x00, 0xbb, + 0x9d, 0x61, 0x04, 0x00, 0x61, 0x0f, 0x00, 0x46, + 0x48, 0x61, 0x0f, 0x00, 0x90, 0x62, 0x0f, 0x00, + 0x0e, 0xf2, 0xde, 0x61, 0x05, 0x00, 0x8f, 0x62, + 0x05, 0x00, 0x0e, 0x61, 0x0a, 0x00, 0x8f, 0x62, + 0x0a, 0x00, 0x0e, 0x61, 0x0a, 0x00, 0x90, 0x62, + 0x0a, 0x00, 0x0e, 0xf3, 0x2e, 0xff, 0x61, 0x02, + 0x00, 0x04, 0x12, 0x01, 0x00, 0x00, 0xad, 0xf0, + 0x56, 0x61, 0x03, 0x00, 0xf0, 0x2c, 0x60, 0x10, + 0x00, 0xba, 0xc8, 0x10, 0x61, 0x10, 0x00, 0x61, + 0x05, 0x00, 0xa5, 0xf0, 0x42, 0x61, 0x08, 0x00, + 0x61, 0x10, 0x00, 0x61, 0x03, 0x00, 0x61, 0x04, + 0x00, 0x61, 0x10, 0x00, 0x46, 0x46, 0x48, 0x61, + 0x10, 0x00, 0x90, 0x62, 0x10, 0x00, 0x0e, 0xf2, + 0xdc, 0x60, 0x11, 0x00, 0xba, 0xc8, 0x11, 0x61, + 0x11, 0x00, 0x61, 0x05, 0x00, 0xa5, 0xf0, 0x17, + 0x61, 0x08, 0x00, 0x61, 0x11, 0x00, 0x38, 0x49, + 0x00, 0x00, 0x00, 0x48, 0x61, 0x11, 0x00, 0x90, + 0x62, 0x11, 0x00, 0x0e, 0xf2, 0xe2, 0x0e, 0xf2, + 0x15, 0xc8, 0x12, 0x6b, 0x10, 0x00, 0x00, 0x00, + 0xe6, 0x61, 0x06, 0x00, 0x61, 0x05, 0x00, 0xf6, + 0x0e, 0xc7, 0x12, 0x30, 0x30, 0xba, 0xc8, 0x13, + 0x61, 0x05, 0x00, 0xc8, 0x14, 0x0b, 0x5d, 0x08, + 0x00, 0x4e, 0xc5, 0x00, 0x53, 0x71, 0x00, 0x00, + 0x00, 0x04, 0xc5, 0x01, 0x53, 0x06, 0x00, 0x00, + 0x00, 0x04, 0x28, 0xc5, 0x00, 0xcf, 0xc5, 0x01, + 0xd0, 0xc5, 0x02, 0xd1, 0xc5, 0x03, 0x28, 0xc5, + 0x00, 0xd3, 0x28, +}; + diff --git a/userland/qjs/source/builtin-iterator-zip-keyed.js b/userland/qjs/source/builtin-iterator-zip-keyed.js new file mode 100644 index 0000000..10aedf3 --- /dev/null +++ b/userland/qjs/source/builtin-iterator-zip-keyed.js @@ -0,0 +1,194 @@ +;(function(IteratorHelper, InternalError, TypeError, call, + hasOwnEnumProperty, getOwnPropertyKeys, Symbol·iterator) { + function check(v, s) { + if (typeof v === "object" && v !== null) return + throw new TypeError(s) + } + function close(iter) { + try { + if (!iter) return + let method = iter.return + if (method) call(iter, method) + } catch (e) { + return e + } + } + function closeall(iters, count) { + let ex = undefined + for (let i = count; i-- > 0;) { + let iter = iters[i] + iters[i] = undefined + let e = close(iter) + if (!ex) ex = e + } + return ex + } + return function zipKeyed(iterables, options = undefined) { + check(iterables, "bad iterables") + if (options === undefined) options = {__proto__: null} + else check(options, "bad options") + let mode = options.mode + if (mode === undefined) mode = "shortest" + if (!(mode === "strict" || mode === "longest" || mode === "shortest")) + throw new TypeError("bad mode") + let padding = undefined + if (mode === "longest") { + padding = options.padding + if (padding !== undefined) check(padding, "bad padding") + } + let keys = [] + let count = 0 + let iters = [] + let nexts = [] + let pads = [] + for (let key of getOwnPropertyKeys(iterables)) keys[count++] = key + try { + for (let i = 0; i < count; i++) { + let del = true + let key = keys[i] + // test262 goes out of its way to destroy performance here: + // we must only add enumerable properties but because evil + // getters can flip the visibility of subsequent properties, + // we have to first collect *all* properties, enumerable and + // non-enumerable, then check each one when we add it to the + // final list + // TODO(bnoordhuis) optimize by introducing some kind of + // mutation observer; mutation is the uncommon case + if (hasOwnEnumProperty(iterables, key)) { + let iter = iterables[key] + if (iter !== undefined) { + check(iter, "bad iterator") + let method = iter[Symbol·iterator] + if (method) iter = call(iter, method) // iterable -> iterator + iters[i] = iter + nexts[i] = iter.next + del = false + } + } + if (del) { + // splice out property; the assumption here is that the + // vast majority of objects don't have non-enumerable + // properties, or properties whose value is undefined + for (let j = i+1; j < count; j++) keys[j-1] = keys[j] + count-- + i-- + } + } + if (mode === "longest") { + if (padding) { + for (let i = 0; i < count; i++) pads[i] = padding[keys[i]] + } else { + for (let i = 0; i < count; i++) pads[i] = undefined + } + } + } catch (e) { + closeall(iters, count) + throw e + } + // note: uses plain numbers for |state|, using + // constants grows the bytecode by about 200 bytes + let state = 0 // new, suspend, execute, complete + let alive = count + return { + __proto__: IteratorHelper, + // TODO(bnoordhuis) shows up as "at next (:0:1)" in stack + // traces when iterator throws, should be "at next (native)" + next() { + switch (state) { + case 0: // new + case 1: // suspend + state = 2 // execute + break + case 2: // execute + throw new TypeError("running zipper") + case 3: // complete + return {value:undefined, done:true} + default: + throw new InternalError("bug") + } + let dones = 0 + let values = 0 + let results = {__proto__: null} + for (let i = 0; i < count; i++) { + let key = keys[i] + let iter = iters[i] + if (!iter) { + if (mode !== "longest") throw new InternalError("bug") + results[key] = pads[i] + continue + } + let result + try { + result = call(iter, nexts[i]) + } catch (e) { + alive = 0 + iters[i] = undefined + closeall(iters, count) + throw e + } + // order of .done and .value property + // access is observable and matters + if (!result.done) { + if (mode === "strict" && dones > 0) { + closeall(iters, count) + throw new TypeError("mismatched inputs") + } + results[key] = result.value + values++ + continue + } + alive-- + dones++ + iters[i] = undefined + switch (mode) { + case "shortest": + let ex = closeall(iters, count) + if (ex) throw ex + state = 3 // complete + return {value:undefined, done:true} + case "longest": + if (alive < 1) { + state = 3 // complete + return {value:undefined, done:true} + } + results[key] = pads[i] + break + case "strict": + if (values > 0) { + closeall(iters, count) + throw new TypeError("mismatched inputs") + } + break + } + } + if (values === 0) { + state = 3 // complete + return {value:undefined, done:true} + } + state = 1 // suspend + return {value:results, done:false} + }, + return() { + switch (state) { + case 0: // new + state = 3 // complete + break + case 1: // suspend + state = 2 // execute + break + case 2: // execute + throw new TypeError("running zipper") + case 3: // complete + return {value:undefined, done:true} + default: + throw new InternalError(`bug: state=${state}`) + } + // TODO skip when already closed because of earlier exception + let ex = closeall(iters, count) + if (ex) throw ex + state = 3 // complete + return {value:undefined, done:true} + }, + } + } +}) diff --git a/userland/qjs/source/builtin-iterator-zip.h b/userland/qjs/source/builtin-iterator-zip.h new file mode 100644 index 0000000..6f7ec11 --- /dev/null +++ b/userland/qjs/source/builtin-iterator-zip.h @@ -0,0 +1,321 @@ +/* File generated automatically by the QuickJS-ng compiler. */ + +#include + +const uint32_t qjsc_builtin_iterator_zip_size = 2489; + +const uint8_t qjsc_builtin_iterator_zip[2489] = { + 0x1d, 0x5f, 0x6a, 0xc3, 0x65, 0x2a, 0x01, 0x1c, + 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x48, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x01, 0x08, + 0x63, 0x61, 0x6c, 0x6c, 0x01, 0x1e, 0x53, 0x79, + 0x6d, 0x62, 0x6f, 0x6c, 0xb7, 0x69, 0x74, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x01, 0x0a, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x01, 0x0a, 0x63, 0x6c, + 0x6f, 0x73, 0x65, 0x01, 0x10, 0x63, 0x6c, 0x6f, + 0x73, 0x65, 0x61, 0x6c, 0x6c, 0x01, 0x02, 0x76, + 0x01, 0x02, 0x73, 0x01, 0x08, 0x69, 0x74, 0x65, + 0x72, 0x01, 0x0c, 0x6d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x01, 0x02, 0x65, 0x01, 0x0a, 0x69, 0x74, + 0x65, 0x72, 0x73, 0x01, 0x0a, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x01, 0x04, 0x65, 0x78, 0x01, 0x02, + 0x69, 0x01, 0x12, 0x69, 0x74, 0x65, 0x72, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x01, 0x0e, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x01, 0x08, 0x6d, + 0x6f, 0x64, 0x65, 0x01, 0x0e, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x01, 0x08, 0x70, 0x61, + 0x64, 0x73, 0x01, 0x0a, 0x6e, 0x65, 0x78, 0x74, + 0x73, 0x01, 0x16, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x69, 0x74, 0x65, 0x72, 0x01, 0x1a, + 0x69, 0x74, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x69, 0x74, 0x65, 0x72, 0x01, 0x08, 0x69, + 0x74, 0x65, 0x6d, 0x01, 0x02, 0x74, 0x01, 0x0a, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x01, 0x0a, 0x61, + 0x6c, 0x69, 0x76, 0x65, 0x01, 0x0a, 0x64, 0x6f, + 0x6e, 0x65, 0x73, 0x01, 0x0e, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x01, 0x0c, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x01, 0x1c, 0x72, 0x75, + 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x7a, 0x69, + 0x70, 0x70, 0x65, 0x72, 0x01, 0x06, 0x62, 0x75, + 0x67, 0x01, 0x0e, 0x6c, 0x6f, 0x6e, 0x67, 0x65, + 0x73, 0x74, 0x01, 0x0c, 0x73, 0x74, 0x72, 0x69, + 0x63, 0x74, 0x01, 0x22, 0x6d, 0x69, 0x73, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x20, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x73, 0x01, 0x10, 0x73, + 0x68, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, 0x01, + 0x16, 0x62, 0x75, 0x67, 0x3a, 0x20, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x3d, 0x01, 0x1a, 0x62, 0x61, + 0x64, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x01, 0x16, 0x62, 0x61, 0x64, + 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x01, 0x10, 0x62, 0x61, 0x64, 0x20, 0x6d, 0x6f, + 0x64, 0x65, 0x01, 0x16, 0x62, 0x61, 0x64, 0x20, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x01, + 0x18, 0x62, 0x61, 0x64, 0x20, 0x69, 0x74, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x0c, 0x00, 0x02, + 0x00, 0xa8, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x01, 0x04, 0x01, 0xaa, 0x01, 0x00, 0x00, + 0x00, 0x0c, 0x43, 0x02, 0x00, 0x00, 0x05, 0x03, + 0x05, 0x01, 0x08, 0x00, 0x04, 0x0c, 0x08, 0xe2, + 0x03, 0x00, 0x01, 0x40, 0x07, 0xb6, 0x03, 0x00, + 0x01, 0x40, 0x03, 0xb2, 0x03, 0x00, 0x01, 0x40, + 0x00, 0xe4, 0x03, 0x00, 0x01, 0x40, 0x01, 0xe6, + 0x03, 0x00, 0x01, 0x40, 0x06, 0xe8, 0x03, 0x00, + 0x00, 0x40, 0x05, 0xea, 0x03, 0x00, 0x01, 0x40, + 0x02, 0xec, 0x03, 0x00, 0x02, 0x40, 0x04, 0x0c, + 0x43, 0x02, 0x00, 0xe8, 0x03, 0x02, 0x00, 0x02, + 0x03, 0x00, 0x01, 0x00, 0x17, 0x02, 0xee, 0x03, + 0x00, 0x01, 0x00, 0xf0, 0x03, 0x00, 0x01, 0x00, + 0xb2, 0x03, 0x02, 0x01, 0xd7, 0x96, 0x04, 0x4d, + 0x00, 0x00, 0x00, 0xad, 0xf0, 0x07, 0xd7, 0x07, + 0xae, 0xf0, 0x02, 0x29, 0xe3, 0x11, 0xd8, 0x21, + 0x01, 0x00, 0x30, 0x0c, 0x43, 0x02, 0x00, 0xea, + 0x03, 0x01, 0x02, 0x01, 0x04, 0x00, 0x01, 0x00, + 0x2d, 0x03, 0xf2, 0x03, 0x00, 0x01, 0x00, 0xf4, + 0x03, 0x02, 0x00, 0x20, 0xf6, 0x03, 0x05, 0x00, + 0x03, 0xe4, 0x03, 0x03, 0x01, 0x6b, 0x22, 0x00, + 0x00, 0x00, 0x60, 0x00, 0x00, 0xd7, 0xf1, 0x04, + 0x06, 0x6e, 0x28, 0xd7, 0x40, 0x06, 0x00, 0x00, + 0x00, 0xcf, 0x61, 0x00, 0x00, 0xf0, 0x08, 0xe3, + 0xd7, 0x61, 0x00, 0x00, 0xf6, 0x0e, 0x0e, 0x29, + 0xd0, 0x6b, 0x07, 0x00, 0x00, 0x00, 0xcc, 0x6e, + 0x28, 0x30, 0x0c, 0x43, 0x02, 0x00, 0xec, 0x03, + 0x02, 0x04, 0x02, 0x03, 0x00, 0x01, 0x00, 0x48, + 0x06, 0xf8, 0x03, 0x00, 0x01, 0x00, 0xfa, 0x03, + 0x00, 0x01, 0x00, 0xfc, 0x03, 0x01, 0x00, 0x20, + 0xfe, 0x03, 0x02, 0x01, 0x20, 0xf2, 0x03, 0x03, + 0x02, 0x20, 0xf6, 0x03, 0x03, 0x03, 0x20, 0xea, + 0x03, 0x01, 0x00, 0x60, 0x00, 0x00, 0x38, 0x49, + 0x00, 0x00, 0x00, 0xcf, 0x60, 0x01, 0x00, 0xd8, + 0xd0, 0x61, 0x01, 0x00, 0x8f, 0x62, 0x01, 0x00, + 0xba, 0xa7, 0xf0, 0x2c, 0x60, 0x03, 0x00, 0x60, + 0x02, 0x00, 0xd7, 0x61, 0x01, 0x00, 0x46, 0xd1, + 0xd7, 0x61, 0x01, 0x00, 0x38, 0x49, 0x00, 0x00, + 0x00, 0x48, 0xe3, 0x61, 0x02, 0x00, 0xf5, 0xd2, + 0x61, 0x00, 0x00, 0xf1, 0xd5, 0x61, 0x03, 0x00, + 0x11, 0x62, 0x00, 0x00, 0x0e, 0xf2, 0xcb, 0x61, + 0x00, 0x00, 0x28, 0x0c, 0x41, 0x02, 0x00, 0xb6, + 0x02, 0x02, 0x1a, 0x01, 0x05, 0x07, 0x08, 0x02, + 0xd8, 0x05, 0x1c, 0x80, 0x04, 0x00, 0x01, 0x00, + 0x82, 0x04, 0x00, 0x01, 0x00, 0x80, 0x04, 0x01, + 0xff, 0xff, 0xff, 0xff, 0x0f, 0x20, 0x82, 0x04, + 0x01, 0x01, 0x20, 0x84, 0x04, 0x02, 0x00, 0x60, + 0x03, 0x86, 0x04, 0x02, 0x03, 0x20, 0x88, 0x04, + 0x02, 0x04, 0x60, 0x04, 0xf8, 0x03, 0x02, 0x05, + 0x60, 0x02, 0x8a, 0x04, 0x02, 0x06, 0x60, 0x05, + 0xfa, 0x03, 0x02, 0x07, 0x60, 0x01, 0x8c, 0x04, + 0x02, 0x08, 0x20, 0x8e, 0x04, 0x02, 0x09, 0x20, + 0xe2, 0x01, 0x09, 0x1a, 0x20, 0x90, 0x04, 0x0b, + 0x0b, 0x20, 0xf6, 0x03, 0x0d, 0x0f, 0x03, 0xf2, + 0x03, 0x0b, 0x0c, 0x20, 0xf4, 0x03, 0x0b, 0x0e, + 0x20, 0xe2, 0x01, 0x13, 0x0b, 0x20, 0xfe, 0x03, + 0x13, 0x10, 0x20, 0xe0, 0x01, 0x13, 0x11, 0x20, + 0x88, 0x01, 0x15, 0x16, 0x20, 0x90, 0x04, 0x16, + 0x13, 0x20, 0xf6, 0x03, 0x17, 0x13, 0x03, 0x92, + 0x04, 0x13, 0x12, 0x20, 0xfc, 0x03, 0x1c, 0x16, + 0x20, 0xf6, 0x03, 0x1f, 0x1a, 0x03, 0x94, 0x04, + 0x02, 0x0a, 0x60, 0x00, 0x96, 0x04, 0x02, 0x19, + 0x60, 0x06, 0xb2, 0x03, 0x02, 0x01, 0xb6, 0x03, + 0x01, 0x01, 0xe4, 0x03, 0x03, 0x01, 0xec, 0x03, + 0x02, 0x00, 0xe8, 0x03, 0x00, 0x00, 0xe6, 0x03, + 0x04, 0x01, 0xea, 0x03, 0x01, 0x00, 0xe2, 0x03, + 0x00, 0x01, 0x0c, 0x42, 0x03, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x05, 0x00, 0x0b, 0x00, 0xae, 0x04, + 0x08, 0x98, 0x04, 0x01, 0x00, 0x20, 0xe4, 0x01, + 0x01, 0x01, 0x20, 0x9a, 0x04, 0x01, 0x02, 0x20, + 0xfe, 0x03, 0x03, 0x03, 0x20, 0xf2, 0x03, 0x04, + 0x04, 0x20, 0x9c, 0x04, 0x04, 0x05, 0x20, 0xf6, + 0x03, 0x09, 0x06, 0x03, 0xfc, 0x03, 0x10, 0x06, + 0x20, 0x94, 0x04, 0x18, 0x10, 0xb2, 0x03, 0x00, + 0x02, 0xb6, 0x03, 0x01, 0x02, 0xfa, 0x03, 0x07, + 0x10, 0xf8, 0x03, 0x05, 0x10, 0x84, 0x04, 0x02, + 0x10, 0x88, 0x04, 0x04, 0x10, 0xe4, 0x03, 0x02, + 0x02, 0x8a, 0x04, 0x06, 0x10, 0x96, 0x04, 0x19, + 0x10, 0xec, 0x03, 0x03, 0x02, 0x60, 0x02, 0x00, + 0x60, 0x01, 0x00, 0x60, 0x00, 0x00, 0x64, 0x00, + 0x00, 0x11, 0xba, 0xad, 0xf1, 0x06, 0x11, 0xbb, + 0xad, 0xf0, 0x09, 0xbc, 0x11, 0x65, 0x00, 0x00, + 0x0e, 0xf2, 0x33, 0x11, 0xbc, 0xad, 0xf0, 0x0c, + 0xe4, 0x11, 0x04, 0x0f, 0x01, 0x00, 0x00, 0x21, + 0x01, 0x00, 0x30, 0x11, 0xbd, 0xad, 0xf0, 0x13, + 0x0b, 0x38, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x44, + 0x00, 0x00, 0x00, 0x0a, 0x4b, 0x70, 0x00, 0x00, + 0x00, 0x28, 0xe5, 0x11, 0x04, 0x10, 0x01, 0x00, + 0x00, 0x21, 0x01, 0x00, 0x30, 0x0e, 0xba, 0xcf, + 0xba, 0xd0, 0x26, 0x00, 0x00, 0xd1, 0x60, 0x03, + 0x00, 0xba, 0xd2, 0x61, 0x03, 0x00, 0x64, 0x03, + 0x00, 0xa5, 0x68, 0x93, 0x01, 0x00, 0x00, 0x60, + 0x05, 0x00, 0x60, 0x04, 0x00, 0x64, 0x04, 0x00, + 0x61, 0x03, 0x00, 0x46, 0xc8, 0x04, 0x61, 0x04, + 0x00, 0xf1, 0x28, 0x64, 0x05, 0x00, 0x04, 0x11, + 0x01, 0x00, 0x00, 0xae, 0xf0, 0x0c, 0xe5, 0x11, + 0x04, 0x10, 0x01, 0x00, 0x00, 0x21, 0x01, 0x00, + 0x30, 0x61, 0x02, 0x00, 0x61, 0x03, 0x00, 0x64, + 0x06, 0x00, 0x61, 0x03, 0x00, 0x46, 0x48, 0xf3, + 0x4b, 0x01, 0x06, 0xc8, 0x05, 0x6b, 0x1a, 0x00, + 0x00, 0x00, 0x5d, 0x07, 0x00, 0x61, 0x04, 0x00, + 0x64, 0x08, 0x00, 0x61, 0x03, 0x00, 0x46, 0xf6, + 0x11, 0x62, 0x05, 0x00, 0x0e, 0x0e, 0xf2, 0x29, + 0xc8, 0x06, 0x6b, 0x24, 0x00, 0x00, 0x00, 0xba, + 0x11, 0x65, 0x09, 0x00, 0x0e, 0x64, 0x04, 0x00, + 0x61, 0x03, 0x00, 0x38, 0x49, 0x00, 0x00, 0x00, + 0x48, 0x5d, 0x0a, 0x00, 0x64, 0x04, 0x00, 0x64, + 0x03, 0x00, 0xf6, 0x0e, 0xc7, 0x06, 0x30, 0x30, + 0x61, 0x05, 0x00, 0x40, 0x70, 0x00, 0x00, 0x00, + 0xf1, 0x43, 0x64, 0x05, 0x00, 0x04, 0x12, 0x01, + 0x00, 0x00, 0xad, 0xf0, 0x1e, 0x61, 0x00, 0x00, + 0xba, 0xa7, 0xf0, 0x17, 0x5d, 0x0a, 0x00, 0x64, + 0x04, 0x00, 0x64, 0x03, 0x00, 0xf6, 0x0e, 0xe4, + 0x11, 0x04, 0x13, 0x01, 0x00, 0x00, 0x21, 0x01, + 0x00, 0x30, 0x61, 0x02, 0x00, 0x61, 0x03, 0x00, + 0x61, 0x05, 0x00, 0x40, 0x44, 0x00, 0x00, 0x00, + 0x48, 0x61, 0x01, 0x00, 0x90, 0x62, 0x01, 0x00, + 0x0e, 0xf3, 0xb9, 0x00, 0x64, 0x09, 0x00, 0x8f, + 0x65, 0x09, 0x00, 0x0e, 0x61, 0x00, 0x00, 0x90, + 0x62, 0x00, 0x00, 0x0e, 0x64, 0x04, 0x00, 0x61, + 0x03, 0x00, 0x38, 0x49, 0x00, 0x00, 0x00, 0x48, + 0x64, 0x05, 0x00, 0x60, 0x07, 0x00, 0x11, 0x04, + 0x14, 0x01, 0x00, 0x00, 0xad, 0xf0, 0x2e, 0x5d, + 0x0a, 0x00, 0x64, 0x04, 0x00, 0x64, 0x03, 0x00, + 0xf6, 0xc8, 0x07, 0x61, 0x07, 0x00, 0xf0, 0x05, + 0x61, 0x07, 0x00, 0x30, 0xbd, 0x11, 0x65, 0x00, + 0x00, 0x0e, 0x0b, 0x38, 0x49, 0x00, 0x00, 0x00, + 0x4b, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x4b, 0x70, + 0x00, 0x00, 0x00, 0x28, 0x11, 0x04, 0x11, 0x01, + 0x00, 0x00, 0xad, 0xf0, 0x30, 0x64, 0x09, 0x00, + 0xbb, 0xa5, 0xf0, 0x19, 0xbd, 0x11, 0x65, 0x00, + 0x00, 0x0e, 0x0b, 0x38, 0x49, 0x00, 0x00, 0x00, + 0x4b, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x4b, 0x70, + 0x00, 0x00, 0x00, 0x28, 0x61, 0x02, 0x00, 0x61, + 0x03, 0x00, 0x64, 0x06, 0x00, 0x61, 0x03, 0x00, + 0x46, 0x48, 0xf2, 0x27, 0x11, 0x04, 0x12, 0x01, + 0x00, 0x00, 0xad, 0xf0, 0x1e, 0x61, 0x01, 0x00, + 0xba, 0xa7, 0xf0, 0x17, 0x5d, 0x0a, 0x00, 0x64, + 0x04, 0x00, 0x64, 0x03, 0x00, 0xf6, 0x0e, 0xe4, + 0x11, 0x04, 0x13, 0x01, 0x00, 0x00, 0x21, 0x01, + 0x00, 0x30, 0x0e, 0x61, 0x03, 0x00, 0x90, 0x62, + 0x03, 0x00, 0x0e, 0xf3, 0x67, 0xfe, 0x61, 0x01, + 0x00, 0xba, 0xad, 0xf0, 0x19, 0xbd, 0x11, 0x65, + 0x00, 0x00, 0x0e, 0x0b, 0x38, 0x49, 0x00, 0x00, + 0x00, 0x4b, 0x44, 0x00, 0x00, 0x00, 0x0a, 0x4b, + 0x70, 0x00, 0x00, 0x00, 0x28, 0xbb, 0x11, 0x65, + 0x00, 0x00, 0x0e, 0x0b, 0x61, 0x02, 0x00, 0x4b, + 0x44, 0x00, 0x00, 0x00, 0x09, 0x4b, 0x70, 0x00, + 0x00, 0x00, 0x28, 0x0c, 0x42, 0x03, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x05, 0x00, 0x06, 0x00, 0x82, + 0x01, 0x01, 0xfc, 0x03, 0x01, 0x00, 0x20, 0x94, + 0x04, 0x18, 0x10, 0xb2, 0x03, 0x00, 0x02, 0xb6, + 0x03, 0x01, 0x02, 0xec, 0x03, 0x03, 0x02, 0xf8, + 0x03, 0x05, 0x10, 0xfa, 0x03, 0x07, 0x10, 0x60, + 0x00, 0x00, 0x64, 0x00, 0x00, 0x11, 0xba, 0xad, + 0xf0, 0x09, 0xbd, 0x11, 0x65, 0x00, 0x00, 0x0e, + 0xf2, 0x45, 0x11, 0xbb, 0xad, 0xf0, 0x09, 0xbc, + 0x11, 0x65, 0x00, 0x00, 0x0e, 0xf2, 0x38, 0x11, + 0xbc, 0xad, 0xf0, 0x0c, 0xe4, 0x11, 0x04, 0x0f, + 0x01, 0x00, 0x00, 0x21, 0x01, 0x00, 0x30, 0x11, + 0xbd, 0xad, 0xf0, 0x13, 0x0b, 0x38, 0x49, 0x00, + 0x00, 0x00, 0x4b, 0x44, 0x00, 0x00, 0x00, 0x0a, + 0x4b, 0x70, 0x00, 0x00, 0x00, 0x28, 0xe5, 0x11, + 0x04, 0x15, 0x01, 0x00, 0x00, 0x64, 0x00, 0x00, + 0x71, 0x9c, 0x21, 0x01, 0x00, 0x30, 0x0e, 0xe6, + 0x64, 0x04, 0x00, 0x64, 0x05, 0x00, 0xf6, 0xcf, + 0x61, 0x00, 0x00, 0xf0, 0x05, 0x61, 0x00, 0x00, + 0x30, 0xbd, 0x11, 0x65, 0x00, 0x00, 0x0e, 0x0b, + 0x38, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x44, 0x00, + 0x00, 0x00, 0x0a, 0x4b, 0x70, 0x00, 0x00, 0x00, + 0x28, 0x60, 0x01, 0x00, 0x60, 0x00, 0x00, 0xd7, + 0xcf, 0xd8, 0x11, 0xf8, 0xf0, 0x08, 0x0e, 0x38, + 0x49, 0x00, 0x00, 0x00, 0xe0, 0xd0, 0x60, 0x19, + 0x00, 0x60, 0x18, 0x00, 0x60, 0x09, 0x00, 0x60, + 0x08, 0x00, 0x60, 0x07, 0x00, 0x60, 0x06, 0x00, + 0x60, 0x05, 0x00, 0x60, 0x04, 0x00, 0x60, 0x03, + 0x00, 0x60, 0x02, 0x00, 0x5d, 0x04, 0x00, 0xd7, + 0x04, 0x16, 0x01, 0x00, 0x00, 0xf6, 0x0e, 0xd8, + 0x38, 0x49, 0x00, 0x00, 0x00, 0xad, 0xf0, 0x06, + 0x0c, 0x07, 0xdc, 0xf2, 0x0c, 0x5d, 0x04, 0x00, + 0xd8, 0x04, 0x17, 0x01, 0x00, 0x00, 0xf6, 0x0e, + 0xd8, 0x40, 0x02, 0x01, 0x00, 0x00, 0xd1, 0x61, + 0x02, 0x00, 0x38, 0x49, 0x00, 0x00, 0x00, 0xad, + 0xf0, 0x0b, 0x04, 0x14, 0x01, 0x00, 0x00, 0x11, + 0x62, 0x02, 0x00, 0x0e, 0x61, 0x02, 0x00, 0x04, + 0x12, 0x01, 0x00, 0x00, 0xad, 0x11, 0xf1, 0x18, + 0x0e, 0x61, 0x02, 0x00, 0x04, 0x11, 0x01, 0x00, + 0x00, 0xad, 0x11, 0xf1, 0x0b, 0x0e, 0x61, 0x02, + 0x00, 0x04, 0x14, 0x01, 0x00, 0x00, 0xad, 0xf1, + 0x0c, 0xe3, 0x11, 0x04, 0x18, 0x01, 0x00, 0x00, + 0x21, 0x01, 0x00, 0x30, 0x38, 0x49, 0x00, 0x00, + 0x00, 0xd2, 0x61, 0x02, 0x00, 0x04, 0x11, 0x01, + 0x00, 0x00, 0xad, 0xf0, 0x24, 0xd8, 0x40, 0x03, + 0x01, 0x00, 0x00, 0x11, 0x62, 0x03, 0x00, 0x0e, + 0x61, 0x03, 0x00, 0x38, 0x49, 0x00, 0x00, 0x00, + 0xae, 0xf0, 0x0e, 0x5d, 0x04, 0x00, 0x61, 0x03, + 0x00, 0x04, 0x19, 0x01, 0x00, 0x00, 0xf6, 0x0e, + 0x26, 0x00, 0x00, 0xc8, 0x04, 0x26, 0x00, 0x00, + 0xc8, 0x05, 0x26, 0x00, 0x00, 0xc8, 0x06, 0xba, + 0xc8, 0x07, 0x38, 0x49, 0x00, 0x00, 0x00, 0xc8, + 0x08, 0xd7, 0x5d, 0x05, 0x00, 0x47, 0x24, 0x00, + 0x00, 0xc8, 0x09, 0x6b, 0x9b, 0x01, 0x00, 0x00, + 0x60, 0x0a, 0x00, 0x61, 0x09, 0x00, 0x40, 0x71, + 0x00, 0x00, 0x00, 0xc8, 0x0a, 0x60, 0x0e, 0x00, + 0x60, 0x0d, 0x00, 0x60, 0x0b, 0x00, 0x06, 0xc8, + 0x0b, 0x6b, 0x14, 0x00, 0x00, 0x00, 0xe5, 0x61, + 0x09, 0x00, 0x61, 0x0a, 0x00, 0xf6, 0x11, 0x62, + 0x0b, 0x00, 0x0e, 0x0e, 0xf2, 0x16, 0xc8, 0x0c, + 0x6b, 0x11, 0x00, 0x00, 0x00, 0x38, 0x49, 0x00, + 0x00, 0x00, 0x11, 0x62, 0x09, 0x00, 0x0e, 0xc7, + 0x0c, 0x30, 0x30, 0x61, 0x0b, 0x00, 0x40, 0x70, + 0x00, 0x00, 0x00, 0xf1, 0x57, 0x61, 0x0b, 0x00, + 0x40, 0x44, 0x00, 0x00, 0x00, 0xc8, 0x0d, 0x5d, + 0x04, 0x00, 0x61, 0x0d, 0x00, 0x04, 0x1a, 0x01, + 0x00, 0x00, 0xf6, 0x0e, 0x61, 0x0d, 0x00, 0x5d, + 0x05, 0x00, 0x46, 0xc8, 0x0e, 0x61, 0x0e, 0x00, + 0xf0, 0x0e, 0xe5, 0x61, 0x0d, 0x00, 0x61, 0x0e, + 0x00, 0xf6, 0x11, 0x62, 0x0d, 0x00, 0x0e, 0x61, + 0x05, 0x00, 0x61, 0x07, 0x00, 0x61, 0x0d, 0x00, + 0x48, 0x61, 0x06, 0x00, 0x61, 0x07, 0x00, 0x61, + 0x0d, 0x00, 0x40, 0x71, 0x00, 0x00, 0x00, 0x48, + 0x61, 0x07, 0x00, 0x90, 0x62, 0x07, 0x00, 0x0e, + 0xf3, 0x6c, 0xff, 0x38, 0x49, 0x00, 0x00, 0x00, + 0x11, 0x62, 0x09, 0x00, 0x0e, 0x61, 0x03, 0x00, + 0x68, 0xe3, 0x00, 0x00, 0x00, 0x60, 0x15, 0x00, + 0x60, 0x11, 0x00, 0x60, 0x10, 0x00, 0x60, 0x0f, + 0x00, 0x61, 0x03, 0x00, 0x5d, 0x05, 0x00, 0x47, + 0x24, 0x00, 0x00, 0x11, 0x62, 0x08, 0x00, 0x0e, + 0x61, 0x08, 0x00, 0x40, 0x71, 0x00, 0x00, 0x00, + 0xc8, 0x0f, 0xba, 0xc8, 0x10, 0x09, 0xc8, 0x11, + 0x61, 0x10, 0x00, 0x61, 0x07, 0x00, 0xa5, 0xf0, + 0x64, 0x60, 0x12, 0x00, 0x06, 0xc8, 0x12, 0x6b, + 0x2e, 0x00, 0x00, 0x00, 0x60, 0x13, 0x00, 0xe5, + 0x61, 0x08, 0x00, 0x61, 0x0f, 0x00, 0xf6, 0xc8, + 0x13, 0x61, 0x13, 0x00, 0x40, 0x70, 0x00, 0x00, + 0x00, 0x11, 0x62, 0x11, 0x00, 0x0e, 0x61, 0x13, + 0x00, 0x40, 0x44, 0x00, 0x00, 0x00, 0x11, 0x62, + 0x12, 0x00, 0x0e, 0x0e, 0xf2, 0x16, 0xc8, 0x14, + 0x6b, 0x11, 0x00, 0x00, 0x00, 0x38, 0x49, 0x00, + 0x00, 0x00, 0x11, 0x62, 0x08, 0x00, 0x0e, 0xc7, + 0x14, 0x30, 0x30, 0x61, 0x11, 0x00, 0xf1, 0x15, + 0x61, 0x04, 0x00, 0x61, 0x10, 0x00, 0x61, 0x12, + 0x00, 0x48, 0x61, 0x10, 0x00, 0x90, 0x62, 0x10, + 0x00, 0x0e, 0xf2, 0x95, 0x61, 0x08, 0x00, 0xc8, + 0x15, 0x38, 0x49, 0x00, 0x00, 0x00, 0x11, 0x62, + 0x08, 0x00, 0x0e, 0x61, 0x11, 0x00, 0xf1, 0x16, + 0x60, 0x16, 0x00, 0x5d, 0x06, 0x00, 0x61, 0x15, + 0x00, 0xf5, 0xc8, 0x16, 0x61, 0x16, 0x00, 0xf0, + 0x05, 0x61, 0x16, 0x00, 0x30, 0x61, 0x10, 0x00, + 0x61, 0x07, 0x00, 0xa5, 0xf0, 0x17, 0x61, 0x04, + 0x00, 0x61, 0x10, 0x00, 0x38, 0x49, 0x00, 0x00, + 0x00, 0x48, 0x61, 0x10, 0x00, 0x90, 0x62, 0x10, + 0x00, 0x0e, 0xf2, 0xe2, 0x0e, 0xf2, 0x25, 0xc8, + 0x17, 0x6b, 0x20, 0x00, 0x00, 0x00, 0xe6, 0x61, + 0x05, 0x00, 0x61, 0x07, 0x00, 0xf6, 0x0e, 0x5d, + 0x06, 0x00, 0x61, 0x09, 0x00, 0xf5, 0x0e, 0x5d, + 0x06, 0x00, 0x61, 0x08, 0x00, 0xf5, 0x0e, 0xc7, + 0x17, 0x30, 0x30, 0xba, 0xc8, 0x18, 0x61, 0x07, + 0x00, 0xc8, 0x19, 0x0b, 0x5d, 0x07, 0x00, 0x4e, + 0xc5, 0x00, 0x53, 0x71, 0x00, 0x00, 0x00, 0x04, + 0xc5, 0x01, 0x53, 0x06, 0x00, 0x00, 0x00, 0x04, + 0x28, 0xc5, 0x00, 0xcf, 0xc5, 0x01, 0xd0, 0xc5, + 0x02, 0xd1, 0xc5, 0x03, 0x28, 0xc5, 0x00, 0xd3, + 0x28, +}; + diff --git a/userland/qjs/source/builtin-iterator-zip.js b/userland/qjs/source/builtin-iterator-zip.js new file mode 100644 index 0000000..8d2707e --- /dev/null +++ b/userland/qjs/source/builtin-iterator-zip.js @@ -0,0 +1,210 @@ +;(function(IteratorHelper, InternalError, TypeError, call, Symbol·iterator) { + function check(v, s) { + if (typeof v === "object" && v !== null) return + throw new TypeError(s) + } + function close(iter) { + try { + if (!iter) return + let method = iter.return + if (method) call(iter, method) + } catch (e) { + return e + } + } + function closeall(iters, count) { + let ex = undefined + for (let i = count; i-- > 0;) { + let iter = iters[i] + iters[i] = undefined + let e = close(iter) + if (!ex) ex = e + } + return ex + } + return function zip(iterables, options = undefined) { + check(iterables, "bad iterables") + if (options === undefined) options = {__proto__: null} + else check(options, "bad options") + let mode = options.mode + if (mode === undefined) mode = "shortest" + if (!(mode === "strict" || mode === "longest" || mode === "shortest")) + throw new TypeError("bad mode") + let padding = undefined + if (mode === "longest") { + padding = options.padding + if (padding !== undefined) check(padding, "bad padding") + } + let pads = [] + let iters = [] + let nexts = [] + let count = 0 + let paddingiter = undefined + let iterablesiter = iterables[Symbol·iterator]() + try { + let next = iterablesiter.next + for (;;) { + let item + try { + item = call(iterablesiter, next) + } catch (e) { + // *don't* close |iterablesiter| when .next() throws + iterablesiter = undefined + throw e + } + // order of .done and .value property + // access is observable and matters + if (item.done) break + let iter = item.value + check(iter, "bad iterator") + let method = iter[Symbol·iterator] + if (method) iter = call(iter, method) // iterable -> iterator + iters[count] = iter + nexts[count] = iter.next + count++ + } + iterablesiter = undefined + if (padding) { + paddingiter = padding[Symbol·iterator]() + let next = paddingiter.next + let i = 0 + let done = false + for (; i < count; i++) { + let value + try { + let item = call(paddingiter, next) + // order of .done and .value property + // access is observable and matters + done = item.done + value = item.value + } catch (e) { + // *don't* close |paddingiter| when .next() + // or .done or .value property access throws + paddingiter = undefined + throw e + } + if (done) break + pads[i] = value + } + // have to be careful to not double-close on exception + // exceptions from .return() should still bubble up though + let t = paddingiter + paddingiter = undefined + if (!done) { + let ex = close(t) + if (ex) throw ex + } + for (; i < count; i++) pads[i] = undefined + } + } catch (e) { + closeall(iters, count) + close(iterablesiter) + close(paddingiter) + throw e + } + // note: uses plain numbers for |state|, using + // constants grows the bytecode by about 200 bytes + let state = 0 // new, suspend, execute, complete + let alive = count + return { + __proto__: IteratorHelper, + // TODO(bnoordhuis) shows up as "at next (:0:1)" in stack + // traces when iterator throws, should be "at next (native)" + next() { + switch (state) { + case 0: // new + case 1: // suspend + state = 2 // execute + break + case 2: // execute + throw new TypeError("running zipper") + case 3: // complete + return {value:undefined, done:true} + default: + throw new InternalError("bug") + } + let dones = 0 + let values = 0 + let results = [] + for (let i = 0; i < count; i++) { + let iter = iters[i] + if (!iter) { + if (mode !== "longest") throw new InternalError("bug") + results[i] = pads[i] + continue + } + let result + try { + result = call(iter, nexts[i]) + } catch (e) { + alive = 0 + iters[i] = undefined + closeall(iters, count) + throw e + } + // order of .done and .value property + // access is observable and matters + if (!result.done) { + if (mode === "strict" && dones > 0) { + closeall(iters, count) + throw new TypeError("mismatched inputs") + } + results[i] = result.value + values++ + continue + } + alive-- + dones++ + iters[i] = undefined + switch (mode) { + case "shortest": + let ex = closeall(iters, count) + if (ex) throw ex + state = 3 // complete + return {value:undefined, done:true} + case "longest": + if (alive < 1) { + state = 3 // complete + return {value:undefined, done:true} + } + results[i] = pads[i] + break + case "strict": + if (values > 0) { + closeall(iters, count) + throw new TypeError("mismatched inputs") + } + break + } + } + if (values === 0) { + state = 3 // complete + return {value:undefined, done:true} + } + state = 1 // suspend + return {value:results, done:false} + }, + return() { + switch (state) { + case 0: // new + state = 3 // complete + break + case 1: // suspend + state = 2 // execute + break + case 2: // execute + throw new TypeError("running zipper") + case 3: // complete + return {value:undefined, done:true} + default: + throw new InternalError(`bug: state=${state}`) + } + // TODO skip when already closed because of earlier exception + let ex = closeall(iters, count) + if (ex) throw ex + state = 3 // complete + return {value:undefined, done:true} + }, + } + } +}) diff --git a/userland/qjs/source/ctest.c b/userland/qjs/source/ctest.c new file mode 100644 index 0000000..eeb03e8 --- /dev/null +++ b/userland/qjs/source/ctest.c @@ -0,0 +1,17 @@ +// note: file is not actually compiled, only checked for C syntax errors +#include "quickjs.h" + +int main(void) +{ + JSRuntime *rt = JS_NewRuntime(); + JSContext *ctx = JS_NewContext(rt); + JS_FreeValue(ctx, JS_NAN); + JS_FreeValue(ctx, JS_UNDEFINED); + JS_FreeValue(ctx, JS_NewFloat64(ctx, 42)); + // not a legal way of using JS_MKPTR but this is here + // to have the compiler syntax-check its definition + JS_FreeValue(ctx, JS_MKPTR(JS_TAG_UNINITIALIZED, 0)); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + return 0; +} diff --git a/userland/qjs/source/cutils.h b/userland/qjs/source/cutils.h new file mode 100644 index 0000000..d441bba --- /dev/null +++ b/userland/qjs/source/cutils.h @@ -0,0 +1,2021 @@ +/* + * C utilities + * + * Copyright (c) 2017 Fabrice Bellard + * Copyright (c) 2018 Charlie Gordon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef CUTILS_H +#define CUTILS_H + +#include +#include +#include +#include +#if !defined(_MSC_VER) +#include +#endif +#if defined(__APPLE__) +#include +#endif +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_MSC_VER) +#include +#define alloca _alloca +#define ssize_t ptrdiff_t +#endif +#if defined(__APPLE__) +#include +#elif defined(__linux__) || defined(__ANDROID__) || defined(__CYGWIN__) || defined(__GLIBC__) || defined(__wasi__) +#include +#elif defined(__FreeBSD__) +#include +#elif defined(_WIN32) +#include +#include +#include // _beginthread +#endif +#if !defined(_WIN32) && !defined(EMSCRIPTEN) && !defined(__wasi__) && !defined(__DJGPP) +#include +#include +#endif +#if !defined(_WIN32) +#include +#include +#endif + +#if defined(__sun) +#undef __maybe_unused +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +# define likely(x) (x) +# define unlikely(x) (x) +# define no_inline __declspec(noinline) +# define __maybe_unused +# define __attribute__(x) +# define __attribute(x) +#else +# define likely(x) __builtin_expect(!!(x), 1) +# define unlikely(x) __builtin_expect(!!(x), 0) +# define no_inline __attribute__((noinline)) +# define __maybe_unused __attribute__((unused)) +#endif + +#ifndef offsetof +#define offsetof(type, field) ((size_t) &((type *)0)->field) +#endif +#ifndef countof +#define countof(x) (sizeof(x) / sizeof((x)[0])) +#ifndef endof +#define endof(x) ((x) + countof(x)) +#endif +#endif +#ifndef container_of +/* return the pointer of type 'type *' containing 'ptr' as field 'member' */ +#define container_of(ptr, type, member) ((type *)((uint8_t *)(ptr) - offsetof(type, member))) +#endif + +#if defined(_MSC_VER) || defined(__cplusplus) +#define minimum_length(n) n +#else +#define minimum_length(n) static n +#endif + +/* Borrowed from Folly */ +#ifndef JS_PRINTF_FORMAT +/* Clang on Windows doesn't seem to support _Printf_format_string_ */ +#if defined(_MSC_VER) && !defined(__clang__) +#include +#define JS_PRINTF_FORMAT _Printf_format_string_ +#define JS_PRINTF_FORMAT_ATTR(format_param, dots_param) +#else +#define JS_PRINTF_FORMAT +#if !defined(__clang__) && defined(__GNUC__) +#define JS_PRINTF_FORMAT_ATTR(format_param, dots_param) \ + __attribute__((format(gnu_printf, format_param, dots_param))) +#else +#define JS_PRINTF_FORMAT_ATTR(format_param, dots_param) \ + __attribute__((format(printf, format_param, dots_param))) +#endif +#endif +#endif + +#if defined(PATH_MAX) +# define JS__PATH_MAX PATH_MAX +#elif defined(_WIN32) +# define JS__PATH_MAX 32767 +#else +# define JS__PATH_MAX 8192 +#endif + +static inline void js__pstrcpy(char *buf, int buf_size, const char *str); +static inline char *js__pstrcat(char *buf, int buf_size, const char *s); +static inline int js__strstart(const char *str, const char *val, const char **ptr); +static inline int js__has_suffix(const char *str, const char *suffix); + +static inline uint8_t is_be(void) { + union { + uint16_t a; + uint8_t b; + } u = { 0x100 }; + return u.b; +} + +static inline int max_int(int a, int b) +{ + if (a > b) + return a; + else + return b; +} + +static inline int min_int(int a, int b) +{ + if (a < b) + return a; + else + return b; +} + +static inline uint32_t max_uint32(uint32_t a, uint32_t b) +{ + if (a > b) + return a; + else + return b; +} + +static inline uint32_t min_uint32(uint32_t a, uint32_t b) +{ + if (a < b) + return a; + else + return b; +} + +static inline int64_t max_int64(int64_t a, int64_t b) +{ + if (a > b) + return a; + else + return b; +} + +static inline int64_t min_int64(int64_t a, int64_t b) +{ + if (a < b) + return a; + else + return b; +} + +static inline uint32_t hash32(uint32_t a) +{ + // use the negative of the golden ratio, it spreads out the bits nicely + // and is what the linux kernel does + // + // the golden ratio phi is defined as (1+sqrt(5))/2 or 1 + (sqrt(5)-1)/2 + // (approx. 1.618033988), and negated is round(2**32/phi**2) = 0x61c88647 + return a * 0x61c88647; +} + +static inline uint64_t hash64(uint64_t a) +{ + return a * 0x61c8864680b583ebULL; +} + +static inline uintptr_t hash_uintptr(uintptr_t a) +{ + if (sizeof(uintptr_t) == sizeof(uint32_t)) { + return hash32(a); + } else { + return hash64(a); + } +} + +/* WARNING: undefined if a = 0 */ +static inline int clz32(unsigned int a) +{ +#if defined(_MSC_VER) && !defined(__clang__) + unsigned long index; + _BitScanReverse(&index, a); + return 31 - index; +#else + return __builtin_clz(a); +#endif +} + +/* WARNING: undefined if a = 0 */ +static inline int clz64(uint64_t a) +{ +#if defined(_MSC_VER) && !defined(__clang__) +#if INTPTR_MAX == INT64_MAX + unsigned long index; + _BitScanReverse64(&index, a); + return 63 - index; +#else + if (a >> 32) + return clz32((unsigned)(a >> 32)); + else + return clz32((unsigned)a) + 32; +#endif +#else + return __builtin_clzll(a); +#endif +} + +static inline uintptr_t clz_uintptr(uintptr_t a) +{ + if (sizeof(uintptr_t) == sizeof(uint32_t)) { + return clz32(a); + } else { + return clz64(a); + } +} + +/* WARNING: undefined if a = 0 */ +static inline int ctz32(unsigned int a) +{ +#if defined(_MSC_VER) && !defined(__clang__) + unsigned long index; + _BitScanForward(&index, a); + return index; +#else + return __builtin_ctz(a); +#endif +} + +/* WARNING: undefined if a = 0 */ +static inline int ctz64(uint64_t a) +{ +#if defined(_MSC_VER) && !defined(__clang__) + unsigned long index; + _BitScanForward64(&index, a); + return index; +#else + return __builtin_ctzll(a); +#endif +} + +static inline uint64_t get_u64(const uint8_t *tab) +{ + uint64_t v; + memcpy(&v, tab, sizeof(v)); + return v; +} + +static inline int64_t get_i64(const uint8_t *tab) +{ + int64_t v; + memcpy(&v, tab, sizeof(v)); + return v; +} + +static inline void put_u64(uint8_t *tab, uint64_t val) +{ + memcpy(tab, &val, sizeof(val)); +} + +static inline uint32_t get_u32(const uint8_t *tab) +{ + uint32_t v; + memcpy(&v, tab, sizeof(v)); + return v; +} + +static inline int32_t get_i32(const uint8_t *tab) +{ + int32_t v; + memcpy(&v, tab, sizeof(v)); + return v; +} + +static inline void put_u32(uint8_t *tab, uint32_t val) +{ + memcpy(tab, &val, sizeof(val)); +} + +static inline uint32_t get_u16(const uint8_t *tab) +{ + uint16_t v; + memcpy(&v, tab, sizeof(v)); + return v; +} + +static inline int32_t get_i16(const uint8_t *tab) +{ + int16_t v; + memcpy(&v, tab, sizeof(v)); + return v; +} + +static inline void put_u16(uint8_t *tab, uint16_t val) +{ + memcpy(tab, &val, sizeof(val)); +} + +static inline uint32_t get_u8(const uint8_t *tab) +{ + return *tab; +} + +static inline int32_t get_i8(const uint8_t *tab) +{ + return (int8_t)*tab; +} + +static inline void put_u8(uint8_t *tab, uint8_t val) +{ + *tab = val; +} + +#ifndef bswap16 +static inline uint16_t bswap16(uint16_t x) +{ + return (x >> 8) | (x << 8); +} +#endif + +#ifndef bswap32 +static inline uint32_t bswap32(uint32_t v) +{ + return ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) | + ((v & 0x0000ff00) << 8) | ((v & 0x000000ff) << 24); +} +#endif + +#ifndef bswap64 +static inline uint64_t bswap64(uint64_t v) +{ + return ((v & ((uint64_t)0xff << (7 * 8))) >> (7 * 8)) | + ((v & ((uint64_t)0xff << (6 * 8))) >> (5 * 8)) | + ((v & ((uint64_t)0xff << (5 * 8))) >> (3 * 8)) | + ((v & ((uint64_t)0xff << (4 * 8))) >> (1 * 8)) | + ((v & ((uint64_t)0xff << (3 * 8))) << (1 * 8)) | + ((v & ((uint64_t)0xff << (2 * 8))) << (3 * 8)) | + ((v & ((uint64_t)0xff << (1 * 8))) << (5 * 8)) | + ((v & ((uint64_t)0xff << (0 * 8))) << (7 * 8)); +} +#endif + +static inline double fromfp16(uint16_t v) { + double d, s; + int e; + if ((v & 0x7C00) == 0x7C00) { + d = (v & 0x3FF) ? NAN : INFINITY; + } else { + d = (v & 0x3FF) / 1024.; + e = (v & 0x7C00) >> 10; + if (e == 0) { + e = -14; + } else { + d += 1; + e -= 15; + } + d = scalbn(d, e); + } + s = (v & 0x8000) ? -1.0 : 1.0; + return d * s; +} + +static inline uint16_t tofp16(double d) { + uint16_t f, s; + double t; + int e; + s = 0; + if (copysign(1, d) < 0) { // preserve sign when |d| is negative zero + d = -d; + s = 0x8000; + } + if (isinf(d)) + return s | 0x7C00; + if (isnan(d)) + return s | 0x7C01; + if (d == 0) + return s | 0; + d = 2 * frexp(d, &e); + e--; + if (e > 15) + return s | 0x7C00; // out of range, return +/-infinity + if (e < -25) { + d = 0; + e = 0; + } else if (e < -14) { + d = scalbn(d, e + 14); + e = 0; + } else { + d -= 1; + e += 15; + } + d *= 1024.; + f = (uint16_t)d; + t = d - f; + if (t < 0.5) + goto done; + if (t == 0.5) + if ((f & 1) == 0) + goto done; + // adjust for rounding + if (++f == 1024) { + f = 0; + if (++e == 31) + return s | 0x7C00; // out of range, return +/-infinity + } +done: + return s | (e << 10) | f; +} + +static inline int isfp16nan(uint16_t v) { + return (v & 0x7FFF) > 0x7C00; +} + +static inline int isfp16zero(uint16_t v) { + return (v & 0x7FFF) == 0; +} + +/* XXX: should take an extra argument to pass slack information to the caller */ +typedef void *DynBufReallocFunc(void *opaque, void *ptr, size_t size); + +typedef struct DynBuf { + uint8_t *buf; + size_t size; + size_t allocated_size; + bool error; /* true if a memory allocation error occurred */ + DynBufReallocFunc *realloc_func; + void *opaque; /* for realloc_func */ +} DynBuf; + +static inline void dbuf_init(DynBuf *s); +static inline void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func); +static inline int dbuf_claim(DynBuf *s, size_t len); +static inline int dbuf_put(DynBuf *s, const void *data, size_t len); +static inline int dbuf_put_self(DynBuf *s, size_t offset, size_t len); +static inline int __dbuf_putc(DynBuf *s, uint8_t c); +static inline int __dbuf_put_u16(DynBuf *s, uint16_t val); +static inline int __dbuf_put_u32(DynBuf *s, uint32_t val); +static inline int __dbuf_put_u64(DynBuf *s, uint64_t val); +static inline int dbuf_putstr(DynBuf *s, const char *str); +static inline int dbuf_putc(DynBuf *s, uint8_t val) +{ + if (unlikely((s->allocated_size - s->size) < 1)) + return __dbuf_putc(s, val); + s->buf[s->size++] = val; + return 0; +} +static inline int dbuf_put_u16(DynBuf *s, uint16_t val) +{ + if (unlikely((s->allocated_size - s->size) < 2)) + return __dbuf_put_u16(s, val); + put_u16(s->buf + s->size, val); + s->size += 2; + return 0; +} +static inline int dbuf_put_u32(DynBuf *s, uint32_t val) +{ + if (unlikely((s->allocated_size - s->size) < 4)) + return __dbuf_put_u32(s, val); + put_u32(s->buf + s->size, val); + s->size += 4; + return 0; +} +static inline int dbuf_put_u64(DynBuf *s, uint64_t val) +{ + if (unlikely((s->allocated_size - s->size) < 8)) + return __dbuf_put_u64(s, val); + put_u64(s->buf + s->size, val); + s->size += 8; + return 0; +} +static inline int JS_PRINTF_FORMAT_ATTR(2, 3) dbuf_printf(DynBuf *s, JS_PRINTF_FORMAT const char *fmt, ...); +static inline void dbuf_free(DynBuf *s); +static inline bool dbuf_error(DynBuf *s) { + return s->error; +} +static inline void dbuf_set_error(DynBuf *s) +{ + s->error = true; +} + +/*---- UTF-8 and UTF-16 handling ----*/ + +#define UTF8_CHAR_LEN_MAX 4 + +enum { + UTF8_PLAIN_ASCII = 0, // 7-bit ASCII plain text + UTF8_NON_ASCII = 1, // has non ASCII code points (8-bit or more) + UTF8_HAS_16BIT = 2, // has 16-bit code points + UTF8_HAS_NON_BMP1 = 4, // has non-BMP1 code points, needs UTF-16 surrogate pairs + UTF8_HAS_ERRORS = 8, // has encoding errors +}; +static inline int utf8_scan(const char *buf, size_t len, size_t *plen); +static inline size_t utf8_encode_len(uint32_t c); +static inline size_t utf8_encode(uint8_t buf[minimum_length(UTF8_CHAR_LEN_MAX)], uint32_t c); +static inline uint32_t utf8_decode_len(const uint8_t *p, size_t max_len, const uint8_t **pp); +static inline uint32_t utf8_decode(const uint8_t *p, const uint8_t **pp); +static inline size_t utf8_decode_buf8(uint8_t *dest, size_t dest_len, const char *src, size_t src_len); +static inline size_t utf8_decode_buf16(uint16_t *dest, size_t dest_len, const char *src, size_t src_len); +static inline size_t utf8_encode_buf8(char *dest, size_t dest_len, const uint8_t *src, size_t src_len); +static inline size_t utf8_encode_buf16(char *dest, size_t dest_len, const uint16_t *src, size_t src_len); + +static inline bool is_surrogate(uint32_t c) +{ + return (c >> 11) == (0xD800 >> 11); // 0xD800-0xDFFF +} + +static inline bool is_hi_surrogate(uint32_t c) +{ + return (c >> 10) == (0xD800 >> 10); // 0xD800-0xDBFF +} + +static inline bool is_lo_surrogate(uint32_t c) +{ + return (c >> 10) == (0xDC00 >> 10); // 0xDC00-0xDFFF +} + +static inline uint32_t get_hi_surrogate(uint32_t c) +{ + return (c >> 10) - (0x10000 >> 10) + 0xD800; +} + +static inline uint32_t get_lo_surrogate(uint32_t c) +{ + return (c & 0x3FF) | 0xDC00; +} + +static inline uint32_t from_surrogate(uint32_t hi, uint32_t lo) +{ + return 65536 + 1024 * (hi & 1023) + (lo & 1023); +} + +static inline int from_hex(int c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + else if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + else if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + else + return -1; +} + +static inline uint8_t is_upper_ascii(uint8_t c) { + return c >= 'A' && c <= 'Z'; +} + +static inline uint8_t to_upper_ascii(uint8_t c) { + return c >= 'a' && c <= 'z' ? c - 'a' + 'A' : c; +} + +static inline void rqsort(void *base, size_t nmemb, size_t size, + int (*cmp)(const void *, const void *, void *), + void *arg); + +static inline uint64_t float64_as_uint64(double d) +{ + union { + double d; + uint64_t u64; + } u; + u.d = d; + return u.u64; +} + +static inline double uint64_as_float64(uint64_t u64) +{ + union { + double d; + uint64_t u64; + } u; + u.u64 = u64; + return u.d; +} + +static inline int64_t js__gettimeofday_us(void); +static inline uint64_t js__hrtime_ns(void); + +static inline size_t js__malloc_usable_size(const void *ptr) +{ +#if defined(__APPLE__) + return malloc_size(ptr); +#elif defined(_WIN32) + return _msize((void *)ptr); +#elif defined(__linux__) || defined(__ANDROID__) || defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__GLIBC__) || defined(__wasi__) + return malloc_usable_size((void *)ptr); +#else + return 0; +#endif +} + +static inline int js_exepath(char* buffer, size_t* size); + +/* Cross-platform threading APIs. */ + +#if defined(EMSCRIPTEN) || defined(__wasi__) || defined(__DJGPP) + +#define JS_HAVE_THREADS 0 + +#else + +#define JS_HAVE_THREADS 1 + +#if defined(_WIN32) +#define JS_ONCE_INIT INIT_ONCE_STATIC_INIT +typedef INIT_ONCE js_once_t; +typedef CRITICAL_SECTION js_mutex_t; +typedef CONDITION_VARIABLE js_cond_t; +typedef HANDLE js_thread_t; +#else +#define JS_ONCE_INIT PTHREAD_ONCE_INIT +typedef pthread_once_t js_once_t; +typedef pthread_mutex_t js_mutex_t; +typedef pthread_cond_t js_cond_t; +typedef pthread_t js_thread_t; +#endif + +static inline void js_once(js_once_t *guard, void (*callback)(void)); + +static inline void js_mutex_init(js_mutex_t *mutex); +static inline void js_mutex_destroy(js_mutex_t *mutex); +static inline void js_mutex_lock(js_mutex_t *mutex); +static inline void js_mutex_unlock(js_mutex_t *mutex); + +static inline void js_cond_init(js_cond_t *cond); +static inline void js_cond_destroy(js_cond_t *cond); +static inline void js_cond_signal(js_cond_t *cond); +static inline void js_cond_broadcast(js_cond_t *cond); +static inline void js_cond_wait(js_cond_t *cond, js_mutex_t *mutex); +static inline int js_cond_timedwait(js_cond_t *cond, js_mutex_t *mutex, uint64_t timeout); + +enum { + JS_THREAD_CREATE_DETACHED = 1, +}; + +// creates threads with 2 MB stacks (glibc default) +static inline int js_thread_create(js_thread_t *thrd, void (*start)(void *), void *arg, + int flags); +static inline int js_thread_join(js_thread_t thrd); + +#endif /* !defined(EMSCRIPTEN) && !defined(__wasi__) */ + +// JS requires strict rounding behavior. Turn on 64-bits double precision +// and disable x87 80-bits extended precision for intermediate floating-point +// results. 0x300 is extended precision, 0x200 is double precision. +// Note that `*&cw` in the asm constraints looks redundant but isn't. +#if defined(__i386__) && !defined(_MSC_VER) +#define JS_X87_FPCW_SAVE_AND_ADJUST(cw) \ + (void)0; \ + unsigned short cw; \ + __asm__ __volatile__("fnstcw %0" : "=m"(*&cw)); \ + do { \ + unsigned short t = 0x200 | (cw & ~0x300); \ + __asm__ __volatile__("fldcw %0" : /*empty*/ : "m"(*&t)); \ + } while (0) +#define JS_X87_FPCW_RESTORE(cw) \ + __asm__ __volatile__("fldcw %0" : /*empty*/ : "m"(*&cw)) +#else +#define JS_X87_FPCW_SAVE_AND_ADJUST(cw) +#define JS_X87_FPCW_RESTORE(cw) +#endif + +#undef NANOSEC +#define NANOSEC ((uint64_t) 1e9) + +static inline void js__pstrcpy(char *buf, int buf_size, const char *str) +{ + int c; + char *q = buf; + + if (buf_size <= 0) + return; + + for(;;) { + c = *str++; + if (c == 0 || q >= buf + buf_size - 1) + break; + *q++ = c; + } + *q = '\0'; +} + +/* strcat and truncate. */ +static inline char *js__pstrcat(char *buf, int buf_size, const char *s) +{ + int len; + len = strlen(buf); + if (len < buf_size) + js__pstrcpy(buf + len, buf_size - len, s); + return buf; +} + +static inline int js__strstart(const char *str, const char *val, const char **ptr) +{ + const char *p, *q; + p = str; + q = val; + while (*q != '\0') { + if (*p != *q) + return 0; + p++; + q++; + } + if (ptr) + *ptr = p; + return 1; +} + +static inline int js__has_suffix(const char *str, const char *suffix) +{ + size_t len = strlen(str); + size_t slen = strlen(suffix); + return (len >= slen && !memcmp(str + len - slen, suffix, slen)); +} + +/* Dynamic buffer package */ + +static void *dbuf_default_realloc(void *opaque, void *ptr, size_t size) +{ + if (unlikely(size == 0)) { + free(ptr); + return NULL; + } + return realloc(ptr, size); +} + +static inline void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func) +{ + memset(s, 0, sizeof(*s)); + if (!realloc_func) + realloc_func = dbuf_default_realloc; + s->opaque = opaque; + s->realloc_func = realloc_func; +} + +static inline void dbuf_init(DynBuf *s) +{ + dbuf_init2(s, NULL, NULL); +} + +/* Try to allocate 'len' more bytes. return < 0 if error */ +static inline int dbuf_claim(DynBuf *s, size_t len) +{ + size_t new_size, size, new_allocated_size; + uint8_t *new_buf; + new_size = s->size + len; + if (new_size < len) + return -1; /* overflow */ + if (new_size > s->allocated_size) { + if (s->error) + return -1; + size = s->allocated_size + (s->allocated_size / 2); + if (size < new_size || size < s->allocated_size) /* overflow test */ + new_allocated_size = new_size; + else + new_allocated_size = size; + new_buf = s->realloc_func(s->opaque, s->buf, new_allocated_size); + if (!new_buf) { + s->error = true; + return -1; + } + s->buf = new_buf; + s->allocated_size = new_allocated_size; + } + return 0; +} + +static inline int dbuf_put(DynBuf *s, const void *data, size_t len) +{ + if (unlikely((s->size + len) > s->allocated_size)) { + if (dbuf_claim(s, len)) + return -1; + } + if (len > 0) { + memcpy(s->buf + s->size, data, len); + s->size += len; + } + return 0; +} + +static inline int dbuf_put_self(DynBuf *s, size_t offset, size_t len) +{ + if (unlikely((s->size + len) > s->allocated_size)) { + if (dbuf_claim(s, len)) + return -1; + } + if (len > 0) { + memcpy(s->buf + s->size, s->buf + offset, len); + s->size += len; + } + return 0; +} + +static inline int __dbuf_putc(DynBuf *s, uint8_t c) +{ + return dbuf_put(s, &c, 1); +} + +static inline int __dbuf_put_u16(DynBuf *s, uint16_t val) +{ + return dbuf_put(s, (uint8_t *)&val, 2); +} + +static inline int __dbuf_put_u32(DynBuf *s, uint32_t val) +{ + return dbuf_put(s, (uint8_t *)&val, 4); +} + +static inline int __dbuf_put_u64(DynBuf *s, uint64_t val) +{ + return dbuf_put(s, (uint8_t *)&val, 8); +} + +static inline int dbuf_putstr(DynBuf *s, const char *str) +{ + return dbuf_put(s, (const uint8_t *)str, strlen(str)); +} + +static inline int JS_PRINTF_FORMAT_ATTR(2, 3) dbuf_printf(DynBuf *s, JS_PRINTF_FORMAT const char *fmt, ...) +{ + va_list ap; + char buf[128]; + int len; + + va_start(ap, fmt); + len = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + if (len < (int)sizeof(buf)) { + /* fast case */ + return dbuf_put(s, (uint8_t *)buf, len); + } else { + if (dbuf_claim(s, len + 1)) + return -1; + va_start(ap, fmt); + vsnprintf((char *)(s->buf + s->size), s->allocated_size - s->size, + fmt, ap); + va_end(ap); + s->size += len; + } + return 0; +} + +static inline void dbuf_free(DynBuf *s) +{ + /* we test s->buf as a fail safe to avoid crashing if dbuf_free() + is called twice */ + if (s->buf) { + s->realloc_func(s->opaque, s->buf, 0); + } + memset(s, 0, sizeof(*s)); +} + +/*--- UTF-8 utility functions --*/ + +/* Note: only encode valid codepoints (0x0000..0x10FFFF). + At most UTF8_CHAR_LEN_MAX bytes are output. */ + +/* Compute the number of bytes of the UTF-8 encoding for a codepoint + `c` is a code-point. + Returns the number of bytes. If a codepoint is beyond 0x10FFFF the + return value is 3 as the codepoint would be encoded as 0xFFFD. + */ +static inline size_t utf8_encode_len(uint32_t c) +{ + if (c < 0x80) + return 1; + if (c < 0x800) + return 2; + if (c < 0x10000) + return 3; + if (c < 0x110000) + return 4; + return 3; +} + +/* Encode a codepoint in UTF-8 + `buf` points to an array of at least `UTF8_CHAR_LEN_MAX` bytes + `c` is a code-point. + Returns the number of bytes. If a codepoint is beyond 0x10FFFF the + return value is 3 and the codepoint is encoded as 0xFFFD. + No null byte is stored after the encoded bytes. + Return value is in range 1..4 + */ +static inline size_t utf8_encode(uint8_t buf[minimum_length(UTF8_CHAR_LEN_MAX)], uint32_t c) +{ + if (c < 0x80) { + buf[0] = c; + return 1; + } + if (c < 0x800) { + buf[0] = (c >> 6) | 0xC0; + buf[1] = (c & 0x3F) | 0x80; + return 2; + } + if (c < 0x10000) { + buf[0] = (c >> 12) | 0xE0; + buf[1] = ((c >> 6) & 0x3F) | 0x80; + buf[2] = (c & 0x3F) | 0x80; + return 3; + } + if (c < 0x110000) { + buf[0] = (c >> 18) | 0xF0; + buf[1] = ((c >> 12) & 0x3F) | 0x80; + buf[2] = ((c >> 6) & 0x3F) | 0x80; + buf[3] = (c & 0x3F) | 0x80; + return 4; + } + buf[0] = (0xFFFD >> 12) | 0xE0; + buf[1] = ((0xFFFD >> 6) & 0x3F) | 0x80; + buf[2] = (0xFFFD & 0x3F) | 0x80; + return 3; +} + +/* Decode a single code point from a UTF-8 encoded array of bytes + `p` is a valid pointer to an array of bytes + `pp` is a valid pointer to a `const uint8_t *` to store a pointer + to the byte following the current sequence. + Return the code point at `p`, in the range `0..0x10FFFF` + Return 0xFFFD on error. Only a single byte is consumed in this case + The maximum length for a UTF-8 byte sequence is 4 bytes. + This implements the algorithm specified in whatwg.org, except it accepts + UTF-8 encoded surrogates as JavaScript allows them in strings. + The source string is assumed to have at least UTF8_CHAR_LEN_MAX bytes + or be null terminated. + If `p[0]` is '\0', the return value is `0` and the byte is consumed. + cf: https://encoding.spec.whatwg.org/#utf-8-encoder + */ +static inline uint32_t utf8_decode(const uint8_t *p, const uint8_t **pp) +{ + uint32_t c; + uint8_t lower, upper; + + c = *p++; + if (c < 0x80) { + *pp = p; + return c; + } + switch(c) { + case 0xC2: case 0xC3: + case 0xC4: case 0xC5: case 0xC6: case 0xC7: + case 0xC8: case 0xC9: case 0xCA: case 0xCB: + case 0xCC: case 0xCD: case 0xCE: case 0xCF: + case 0xD0: case 0xD1: case 0xD2: case 0xD3: + case 0xD4: case 0xD5: case 0xD6: case 0xD7: + case 0xD8: case 0xD9: case 0xDA: case 0xDB: + case 0xDC: case 0xDD: case 0xDE: case 0xDF: + if (*p >= 0x80 && *p <= 0xBF) { + *pp = p + 1; + return ((c - 0xC0) << 6) + (*p - 0x80); + } + // otherwise encoding error + break; + case 0xE0: + lower = 0xA0; /* reject invalid encoding */ + goto need2; + case 0xE1: case 0xE2: case 0xE3: + case 0xE4: case 0xE5: case 0xE6: case 0xE7: + case 0xE8: case 0xE9: case 0xEA: case 0xEB: + case 0xEC: case 0xED: case 0xEE: case 0xEF: + lower = 0x80; + need2: + if (*p >= lower && *p <= 0xBF && p[1] >= 0x80 && p[1] <= 0xBF) { + *pp = p + 2; + return ((c - 0xE0) << 12) + ((*p - 0x80) << 6) + (p[1] - 0x80); + } + // otherwise encoding error + break; + case 0xF0: + lower = 0x90; /* reject invalid encoding */ + upper = 0xBF; + goto need3; + case 0xF4: + lower = 0x80; + upper = 0x8F; /* reject values above 0x10FFFF */ + goto need3; + case 0xF1: case 0xF2: case 0xF3: + lower = 0x80; + upper = 0xBF; + need3: + if (*p >= lower && *p <= upper && p[1] >= 0x80 && p[1] <= 0xBF + && p[2] >= 0x80 && p[2] <= 0xBF) { + *pp = p + 3; + return ((c - 0xF0) << 18) + ((*p - 0x80) << 12) + + ((p[1] - 0x80) << 6) + (p[2] - 0x80); + } + // otherwise encoding error + break; + default: + // invalid lead byte + break; + } + *pp = p; + return 0xFFFD; +} + +static inline uint32_t utf8_decode_len(const uint8_t *p, size_t max_len, const uint8_t **pp) { + switch (max_len) { + case 0: + *pp = p; + return 0xFFFD; + case 1: + if (*p < 0x80) + goto good; + break; + case 2: + if (*p < 0xE0) + goto good; + break; + case 3: + if (*p < 0xF0) + goto good; + break; + default: + good: + return utf8_decode(p, pp); + } + *pp = p + 1; + return 0xFFFD; +} + +/* Scan a UTF-8 encoded buffer for content type + `buf` is a valid pointer to a UTF-8 encoded string + `len` is the number of bytes to scan + `plen` points to a `size_t` variable to receive the number of units + Return value is a mask of bits. + - `UTF8_PLAIN_ASCII`: return value for 7-bit ASCII plain text + - `UTF8_NON_ASCII`: bit for non ASCII code points (8-bit or more) + - `UTF8_HAS_16BIT`: bit for 16-bit code points + - `UTF8_HAS_NON_BMP1`: bit for non-BMP1 code points, needs UTF-16 surrogate pairs + - `UTF8_HAS_ERRORS`: bit for encoding errors + */ +static inline int utf8_scan(const char *buf, size_t buf_len, size_t *plen) +{ + const uint8_t *p, *p_end, *p_next; + size_t i, len; + int kind; + uint8_t cbits; + + kind = UTF8_PLAIN_ASCII; + cbits = 0; + len = buf_len; + // TODO: handle more than 1 byte at a time + for (i = 0; i < buf_len; i++) + cbits |= buf[i]; + if (cbits >= 0x80) { + p = (const uint8_t *)buf; + p_end = p + buf_len; + kind = UTF8_NON_ASCII; + len = 0; + while (p < p_end) { + len++; + if (*p++ >= 0x80) { + /* parse UTF-8 sequence, check for encoding error */ + uint32_t c = utf8_decode_len(p - 1, p_end - (p - 1), &p_next); + if (p_next == p) + kind |= UTF8_HAS_ERRORS; + p = p_next; + if (c > 0xFF) { + kind |= UTF8_HAS_16BIT; + if (c > 0xFFFF) { + len++; + kind |= UTF8_HAS_NON_BMP1; + } + } + } + } + } + *plen = len; + return kind; +} + +/* Decode a string encoded in UTF-8 into an array of bytes + `src` points to the source string. It is assumed to be correctly encoded + and only contains code points below 0x800 + `src_len` is the length of the source string + `dest` points to the destination array, it can be null if `dest_len` is `0` + `dest_len` is the length of the destination array. A null + terminator is stored at the end of the array unless `dest_len` is `0`. + */ +static inline size_t utf8_decode_buf8(uint8_t *dest, size_t dest_len, const char *src, size_t src_len) +{ + const uint8_t *p, *p_end; + size_t i; + + p = (const uint8_t *)src; + p_end = p + src_len; + for (i = 0; p < p_end; i++) { + uint32_t c = *p++; + if (c >= 0xC0) + c = (c << 6) + *p++ - ((0xC0 << 6) + 0x80); + if (i < dest_len) + dest[i] = c; + } + if (i < dest_len) + dest[i] = '\0'; + else if (dest_len > 0) + dest[dest_len - 1] = '\0'; + return i; +} + +/* Decode a string encoded in UTF-8 into an array of 16-bit words + `src` points to the source string. It is assumed to be correctly encoded. + `src_len` is the length of the source string + `dest` points to the destination array, it can be null if `dest_len` is `0` + `dest_len` is the length of the destination array. No null terminator is + stored at the end of the array. + */ +static inline size_t utf8_decode_buf16(uint16_t *dest, size_t dest_len, const char *src, size_t src_len) +{ + const uint8_t *p, *p_end; + size_t i; + + p = (const uint8_t *)src; + p_end = p + src_len; + for (i = 0; p < p_end; i++) { + uint32_t c = *p++; + if (c >= 0x80) { + /* parse utf-8 sequence */ + c = utf8_decode_len(p - 1, p_end - (p - 1), &p); + /* encoding errors are converted as 0xFFFD and use a single byte */ + if (c > 0xFFFF) { + if (i < dest_len) + dest[i] = get_hi_surrogate(c); + i++; + c = get_lo_surrogate(c); + } + } + if (i < dest_len) + dest[i] = c; + } + return i; +} + +/* Encode a buffer of 8-bit bytes as a UTF-8 encoded string + `src` points to the source buffer. + `src_len` is the length of the source buffer + `dest` points to the destination array, it can be null if `dest_len` is `0` + `dest_len` is the length in bytes of the destination array. A null + terminator is stored at the end of the array unless `dest_len` is `0`. + */ +static inline size_t utf8_encode_buf8(char *dest, size_t dest_len, const uint8_t *src, size_t src_len) +{ + size_t i, j; + uint32_t c; + + for (i = j = 0; i < src_len; i++) { + c = src[i]; + if (c < 0x80) { + if (j + 1 >= dest_len) + goto overflow; + dest[j++] = c; + } else { + if (j + 2 >= dest_len) + goto overflow; + dest[j++] = (c >> 6) | 0xC0; + dest[j++] = (c & 0x3F) | 0x80; + } + } + if (j < dest_len) + dest[j] = '\0'; + return j; + +overflow: + if (j < dest_len) + dest[j] = '\0'; + while (i < src_len) + j += 1 + (src[i++] >= 0x80); + return j; +} + +/* Encode a buffer of 16-bit code points as a UTF-8 encoded string + `src` points to the source buffer. + `src_len` is the length of the source buffer + `dest` points to the destination array, it can be null if `dest_len` is `0` + `dest_len` is the length in bytes of the destination array. A null + terminator is stored at the end of the array unless `dest_len` is `0`. + */ +static inline size_t utf8_encode_buf16(char *dest, size_t dest_len, const uint16_t *src, size_t src_len) +{ + size_t i, j; + uint32_t c; + + for (i = j = 0; i < src_len;) { + c = src[i++]; + if (c < 0x80) { + if (j + 1 >= dest_len) + goto overflow; + dest[j++] = c; + } else { + if (is_hi_surrogate(c) && i < src_len && is_lo_surrogate(src[i])) + c = from_surrogate(c, src[i++]); + if (j + utf8_encode_len(c) >= dest_len) + goto overflow; + j += utf8_encode((uint8_t *)dest + j, c); + } + } + if (j < dest_len) + dest[j] = '\0'; + return j; + +overflow: + i -= 1 + (c > 0xFFFF); + if (j < dest_len) + dest[j] = '\0'; + while (i < src_len) { + c = src[i++]; + if (c < 0x80) { + j++; + } else { + if (is_hi_surrogate(c) && i < src_len && is_lo_surrogate(src[i])) + c = from_surrogate(c, src[i++]); + j += utf8_encode_len(c); + } + } + return j; +} + +/*---- sorting with opaque argument ----*/ + +typedef void (*exchange_f)(void *a, void *b, size_t size); +typedef int (*cmp_f)(const void *, const void *, void *opaque); + +static void exchange_bytes(void *a, void *b, size_t size) { + uint8_t *ap = (uint8_t *)a; + uint8_t *bp = (uint8_t *)b; + + while (size-- != 0) { + uint8_t t = *ap; + *ap++ = *bp; + *bp++ = t; + } +} + +static void exchange_one_byte(void *a, void *b, size_t size) { + uint8_t *ap = (uint8_t *)a; + uint8_t *bp = (uint8_t *)b; + uint8_t t = *ap; + *ap = *bp; + *bp = t; +} + +static void exchange_int16s(void *a, void *b, size_t size) { + uint16_t *ap = (uint16_t *)a; + uint16_t *bp = (uint16_t *)b; + + for (size /= sizeof(uint16_t); size-- != 0;) { + uint16_t t = *ap; + *ap++ = *bp; + *bp++ = t; + } +} + +static void exchange_one_int16(void *a, void *b, size_t size) { + uint16_t *ap = (uint16_t *)a; + uint16_t *bp = (uint16_t *)b; + uint16_t t = *ap; + *ap = *bp; + *bp = t; +} + +static void exchange_int32s(void *a, void *b, size_t size) { + uint32_t *ap = (uint32_t *)a; + uint32_t *bp = (uint32_t *)b; + + for (size /= sizeof(uint32_t); size-- != 0;) { + uint32_t t = *ap; + *ap++ = *bp; + *bp++ = t; + } +} + +static void exchange_one_int32(void *a, void *b, size_t size) { + uint32_t *ap = (uint32_t *)a; + uint32_t *bp = (uint32_t *)b; + uint32_t t = *ap; + *ap = *bp; + *bp = t; +} + +static void exchange_int64s(void *a, void *b, size_t size) { + uint64_t *ap = (uint64_t *)a; + uint64_t *bp = (uint64_t *)b; + + for (size /= sizeof(uint64_t); size-- != 0;) { + uint64_t t = *ap; + *ap++ = *bp; + *bp++ = t; + } +} + +static void exchange_one_int64(void *a, void *b, size_t size) { + uint64_t *ap = (uint64_t *)a; + uint64_t *bp = (uint64_t *)b; + uint64_t t = *ap; + *ap = *bp; + *bp = t; +} + +static void exchange_int128s(void *a, void *b, size_t size) { + uint64_t *ap = (uint64_t *)a; + uint64_t *bp = (uint64_t *)b; + + for (size /= sizeof(uint64_t) * 2; size-- != 0; ap += 2, bp += 2) { + uint64_t t = ap[0]; + uint64_t u = ap[1]; + ap[0] = bp[0]; + ap[1] = bp[1]; + bp[0] = t; + bp[1] = u; + } +} + +static void exchange_one_int128(void *a, void *b, size_t size) { + uint64_t *ap = (uint64_t *)a; + uint64_t *bp = (uint64_t *)b; + uint64_t t = ap[0]; + uint64_t u = ap[1]; + ap[0] = bp[0]; + ap[1] = bp[1]; + bp[0] = t; + bp[1] = u; +} + +static inline exchange_f exchange_func(const void *base, size_t size) { + switch (((uintptr_t)base | (uintptr_t)size) & 15) { + case 0: + if (size == sizeof(uint64_t) * 2) + return exchange_one_int128; + else + return exchange_int128s; + case 8: + if (size == sizeof(uint64_t)) + return exchange_one_int64; + else + return exchange_int64s; + case 4: + case 12: + if (size == sizeof(uint32_t)) + return exchange_one_int32; + else + return exchange_int32s; + case 2: + case 6: + case 10: + case 14: + if (size == sizeof(uint16_t)) + return exchange_one_int16; + else + return exchange_int16s; + default: + if (size == 1) + return exchange_one_byte; + else + return exchange_bytes; + } +} + +static void heapsortx(void *base, size_t nmemb, size_t size, cmp_f cmp, void *opaque) +{ + uint8_t *basep = (uint8_t *)base; + size_t i, n, c, r; + exchange_f swap = exchange_func(base, size); + + if (nmemb > 1) { + i = (nmemb / 2) * size; + n = nmemb * size; + + while (i > 0) { + i -= size; + for (r = i; (c = r * 2 + size) < n; r = c) { + if (c < n - size && cmp(basep + c, basep + c + size, opaque) <= 0) + c += size; + if (cmp(basep + r, basep + c, opaque) > 0) + break; + swap(basep + r, basep + c, size); + } + } + for (i = n - size; i > 0; i -= size) { + swap(basep, basep + i, size); + + for (r = 0; (c = r * 2 + size) < i; r = c) { + if (c < i - size && cmp(basep + c, basep + c + size, opaque) <= 0) + c += size; + if (cmp(basep + r, basep + c, opaque) > 0) + break; + swap(basep + r, basep + c, size); + } + } + } +} + +static inline void *med3(void *a, void *b, void *c, cmp_f cmp, void *opaque) +{ + return cmp(a, b, opaque) < 0 ? + (cmp(b, c, opaque) < 0 ? b : (cmp(a, c, opaque) < 0 ? c : a )) : + (cmp(b, c, opaque) > 0 ? b : (cmp(a, c, opaque) < 0 ? a : c )); +} + +/* pointer based version with local stack and insertion sort threshhold */ +static inline void rqsort(void *base, size_t nmemb, size_t size, cmp_f cmp, void *opaque) +{ + struct { uint8_t *base; size_t count; int depth; } stack[50], *sp = stack; + uint8_t *ptr, *pi, *pj, *plt, *pgt, *top, *m; + size_t m4, i, lt, gt, span, span2; + int c, depth; + exchange_f swap = exchange_func(base, size); + exchange_f swap_block = exchange_func(base, size | 128); + + if (nmemb < 2 || size <= 0) + return; + + sp->base = (uint8_t *)base; + sp->count = nmemb; + sp->depth = 0; + sp++; + + while (sp > stack) { + sp--; + ptr = sp->base; + nmemb = sp->count; + depth = sp->depth; + + while (nmemb > 6) { + if (++depth > 50) { + /* depth check to ensure worst case logarithmic time */ + heapsortx(ptr, nmemb, size, cmp, opaque); + nmemb = 0; + break; + } + /* select median of 3 from 1/4, 1/2, 3/4 positions */ + /* should use median of 5 or 9? */ + m4 = (nmemb >> 2) * size; + m = med3(ptr + m4, ptr + 2 * m4, ptr + 3 * m4, cmp, opaque); + swap(ptr, m, size); /* move the pivot to the start or the array */ + i = lt = 1; + pi = plt = ptr + size; + gt = nmemb; + pj = pgt = top = ptr + nmemb * size; + for (;;) { + while (pi < pj && (c = cmp(ptr, pi, opaque)) >= 0) { + if (c == 0) { + swap(plt, pi, size); + lt++; + plt += size; + } + i++; + pi += size; + } + while (pi < (pj -= size) && (c = cmp(ptr, pj, opaque)) <= 0) { + if (c == 0) { + gt--; + pgt -= size; + swap(pgt, pj, size); + } + } + if (pi >= pj) + break; + swap(pi, pj, size); + i++; + pi += size; + } + /* array has 4 parts: + * from 0 to lt excluded: elements identical to pivot + * from lt to pi excluded: elements smaller than pivot + * from pi to gt excluded: elements greater than pivot + * from gt to n excluded: elements identical to pivot + */ + /* move elements identical to pivot in the middle of the array: */ + /* swap values in ranges [0..lt[ and [i-lt..i[ + swapping the smallest span between lt and i-lt is sufficient + */ + span = plt - ptr; + span2 = pi - plt; + lt = i - lt; + if (span > span2) + span = span2; + swap_block(ptr, pi - span, span); + /* swap values in ranges [gt..top[ and [i..top-(top-gt)[ + swapping the smallest span between top-gt and gt-i is sufficient + */ + span = top - pgt; + span2 = pgt - pi; + pgt = top - span2; + gt = nmemb - (gt - i); + if (span > span2) + span = span2; + swap_block(pi, top - span, span); + + /* now array has 3 parts: + * from 0 to lt excluded: elements smaller than pivot + * from lt to gt excluded: elements identical to pivot + * from gt to n excluded: elements greater than pivot + */ + /* stack the larger segment and keep processing the smaller one + to minimize stack use for pathological distributions */ + if (lt > nmemb - gt) { + sp->base = ptr; + sp->count = lt; + sp->depth = depth; + sp++; + ptr = pgt; + nmemb -= gt; + } else { + sp->base = pgt; + sp->count = nmemb - gt; + sp->depth = depth; + sp++; + nmemb = lt; + } + } + /* Use insertion sort for small fragments */ + for (pi = ptr + size, top = ptr + nmemb * size; pi < top; pi += size) { + for (pj = pi; pj > ptr && cmp(pj - size, pj, opaque) > 0; pj -= size) + swap(pj, pj - size, size); + } + } +} + +/*---- Portable time functions ----*/ + +#ifdef _WIN32 + // From: https://stackoverflow.com/a/26085827 +static int gettimeofday_msvc(struct timeval *tp) +{ + static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL); + + SYSTEMTIME system_time; + FILETIME file_time; + uint64_t time; + + GetSystemTime(&system_time); + SystemTimeToFileTime(&system_time, &file_time); + time = ((uint64_t)file_time.dwLowDateTime); + time += ((uint64_t)file_time.dwHighDateTime) << 32; + + tp->tv_sec = (long)((time - EPOCH) / 10000000L); + tp->tv_usec = (long)(system_time.wMilliseconds * 1000); + + return 0; +} + +static inline uint64_t js__hrtime_ns(void) { + LARGE_INTEGER counter, frequency; + double scaled_freq; + double result; + + if (!QueryPerformanceFrequency(&frequency)) + abort(); + assert(frequency.QuadPart != 0); + + if (!QueryPerformanceCounter(&counter)) + abort(); + assert(counter.QuadPart != 0); + + /* Because we have no guarantee about the order of magnitude of the + * performance counter interval, integer math could cause this computation + * to overflow. Therefore we resort to floating point math. + */ + scaled_freq = (double) frequency.QuadPart / NANOSEC; + result = (double) counter.QuadPart / scaled_freq; + return (uint64_t) result; +} +#else +static inline uint64_t js__hrtime_ns(void) { +#ifdef __DJGPP + struct timeval tv; + if (gettimeofday(&tv, NULL)) + abort(); + return tv.tv_sec * NANOSEC + tv.tv_usec * 1000; +#else + struct timespec t; + + if (clock_gettime(CLOCK_MONOTONIC, &t)) + abort(); + + return t.tv_sec * NANOSEC + t.tv_nsec; +#endif +} +#endif + +static inline int64_t js__gettimeofday_us(void) { + struct timeval tv; +#ifdef _WIN32 + gettimeofday_msvc(&tv); +#else + gettimeofday(&tv, NULL); +#endif + return ((int64_t)tv.tv_sec * 1000000) + tv.tv_usec; +} + +#if defined(_WIN32) +static inline int js_exepath(char *buffer, size_t *size_ptr) { + int utf8_len, utf16_buffer_len, utf16_len; + WCHAR* utf16_buffer; + + if (buffer == NULL || size_ptr == NULL || *size_ptr == 0) + return -1; + + if (*size_ptr > 32768) { + /* Windows paths can never be longer than this. */ + utf16_buffer_len = 32768; + } else { + utf16_buffer_len = (int)*size_ptr; + } + + utf16_buffer = malloc(sizeof(WCHAR) * utf16_buffer_len); + if (!utf16_buffer) + return -1; + + /* Get the path as UTF-16. */ + utf16_len = GetModuleFileNameW(NULL, utf16_buffer, utf16_buffer_len); + if (utf16_len <= 0) + goto error; + + /* Convert to UTF-8 */ + utf8_len = WideCharToMultiByte(CP_UTF8, + 0, + utf16_buffer, + -1, + buffer, + (int)*size_ptr, + NULL, + NULL); + if (utf8_len == 0) + goto error; + + free(utf16_buffer); + + /* utf8_len *does* include the terminating null at this point, but the + * returned size shouldn't. */ + *size_ptr = utf8_len - 1; + return 0; + +error: + free(utf16_buffer); + return -1; +} +#elif defined(__APPLE__) +static inline int js_exepath(char *buffer, size_t *size) { + /* realpath(exepath) may be > PATH_MAX so double it to be on the safe side. */ + char abspath[PATH_MAX * 2 + 1]; + char exepath[PATH_MAX + 1]; + uint32_t exepath_size; + size_t abspath_size; + + if (buffer == NULL || size == NULL || *size == 0) + return -1; + + exepath_size = sizeof(exepath); + if (_NSGetExecutablePath(exepath, &exepath_size)) + return -1; + + if (realpath(exepath, abspath) != abspath) + return -1; + + abspath_size = strlen(abspath); + if (abspath_size == 0) + return -1; + + *size -= 1; + if (*size > abspath_size) + *size = abspath_size; + + memcpy(buffer, abspath, *size); + buffer[*size] = '\0'; + + return 0; +} +#elif defined(__linux__) || defined(__GNU__) +static inline int js_exepath(char *buffer, size_t *size) { + ssize_t n; + + if (buffer == NULL || size == NULL || *size == 0) + return -1; + + n = *size - 1; + if (n > 0) + n = readlink("/proc/self/exe", buffer, n); + + if (n == -1) + return n; + + buffer[n] = '\0'; + *size = n; + + return 0; +} +#else +static inline int js_exepath(char* buffer, size_t* size_ptr) { + return -1; +} +#endif + +/*--- Cross-platform threading APIs. ----*/ + +#if JS_HAVE_THREADS +#if defined(_WIN32) +typedef void (*js__once_cb)(void); + +typedef struct { + js__once_cb callback; +} js__once_data_t; + +static int WINAPI js__once_inner(INIT_ONCE *once, void *param, void **context) { + js__once_data_t *data = param; + + data->callback(); + + return 1; +} + +static inline void js_once(js_once_t *guard, js__once_cb callback) { + js__once_data_t data = { .callback = callback }; + InitOnceExecuteOnce(guard, js__once_inner, (void*) &data, NULL); +} + +static inline void js_mutex_init(js_mutex_t *mutex) { + InitializeCriticalSection(mutex); +} + +static inline void js_mutex_destroy(js_mutex_t *mutex) { + DeleteCriticalSection(mutex); +} + +static inline void js_mutex_lock(js_mutex_t *mutex) { + EnterCriticalSection(mutex); +} + +static inline void js_mutex_unlock(js_mutex_t *mutex) { + LeaveCriticalSection(mutex); +} + +static inline void js_cond_init(js_cond_t *cond) { + InitializeConditionVariable(cond); +} + +static inline void js_cond_destroy(js_cond_t *cond) { + /* nothing to do */ + (void) cond; +} + +static inline void js_cond_signal(js_cond_t *cond) { + WakeConditionVariable(cond); +} + +static inline void js_cond_broadcast(js_cond_t *cond) { + WakeAllConditionVariable(cond); +} + +static inline void js_cond_wait(js_cond_t *cond, js_mutex_t *mutex) { + if (!SleepConditionVariableCS(cond, mutex, INFINITE)) + abort(); +} + +static inline int js_cond_timedwait(js_cond_t *cond, js_mutex_t *mutex, uint64_t timeout) { + if (SleepConditionVariableCS(cond, mutex, (DWORD)(timeout / 1e6))) + return 0; + if (GetLastError() != ERROR_TIMEOUT) + abort(); + return -1; +} + +static inline int js_thread_create(js_thread_t *thrd, void (*start)(void *), void *arg, + int flags) +{ + HANDLE h, cp; + + *thrd = INVALID_HANDLE_VALUE; + if (flags & ~JS_THREAD_CREATE_DETACHED) + return -1; + h = (HANDLE)_beginthread(start, /*stacksize*/2<<20, arg); + if (!h) + return -1; + if (flags & JS_THREAD_CREATE_DETACHED) + return 0; + // _endthread() automatically closes the handle but we want to wait on + // it so make a copy. Race-y for very short-lived threads. Can be solved + // by switching to _beginthreadex(CREATE_SUSPENDED) but means changing + // |start| from __cdecl to __stdcall. + cp = GetCurrentProcess(); + if (DuplicateHandle(cp, h, cp, thrd, 0, FALSE, DUPLICATE_SAME_ACCESS)) + return 0; + return -1; +} + +static inline int js_thread_join(js_thread_t thrd) +{ + if (WaitForSingleObject(thrd, INFINITE)) + return -1; + CloseHandle(thrd); + return 0; +} + +#else /* !defined(_WIN32) */ + +static inline void js_once(js_once_t *guard, void (*callback)(void)) { + if (pthread_once(guard, callback)) + abort(); +} + +static inline void js_mutex_init(js_mutex_t *mutex) { + if (pthread_mutex_init(mutex, NULL)) + abort(); +} + +static inline void js_mutex_destroy(js_mutex_t *mutex) { + if (pthread_mutex_destroy(mutex)) + abort(); +} + +static inline void js_mutex_lock(js_mutex_t *mutex) { + if (pthread_mutex_lock(mutex)) + abort(); +} + +static inline void js_mutex_unlock(js_mutex_t *mutex) { + if (pthread_mutex_unlock(mutex)) + abort(); +} + +static inline void js_cond_init(js_cond_t *cond) { +#if defined(__APPLE__) && defined(__MACH__) + if (pthread_cond_init(cond, NULL)) + abort(); +#else + pthread_condattr_t attr; + + if (pthread_condattr_init(&attr)) + abort(); + + if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) + abort(); + + if (pthread_cond_init(cond, &attr)) + abort(); + + if (pthread_condattr_destroy(&attr)) + abort(); +#endif +} + +static inline void js_cond_destroy(js_cond_t *cond) { +#if defined(__APPLE__) && defined(__MACH__) + /* It has been reported that destroying condition variables that have been + * signalled but not waited on can sometimes result in application crashes. + * See https://codereview.chromium.org/1323293005. + */ + pthread_mutex_t mutex; + struct timespec ts; + int err; + + if (pthread_mutex_init(&mutex, NULL)) + abort(); + + if (pthread_mutex_lock(&mutex)) + abort(); + + ts.tv_sec = 0; + ts.tv_nsec = 1; + + err = pthread_cond_timedwait_relative_np(cond, &mutex, &ts); + if (err != 0 && err != ETIMEDOUT) + abort(); + + if (pthread_mutex_unlock(&mutex)) + abort(); + + if (pthread_mutex_destroy(&mutex)) + abort(); +#endif /* defined(__APPLE__) && defined(__MACH__) */ + + if (pthread_cond_destroy(cond)) + abort(); +} + +static inline void js_cond_signal(js_cond_t *cond) { + if (pthread_cond_signal(cond)) + abort(); +} + +static inline void js_cond_broadcast(js_cond_t *cond) { + if (pthread_cond_broadcast(cond)) + abort(); +} + +static inline void js_cond_wait(js_cond_t *cond, js_mutex_t *mutex) { +#if defined(__APPLE__) && defined(__MACH__) + int r; + + errno = 0; + r = pthread_cond_wait(cond, mutex); + + /* Workaround for a bug in OS X at least up to 13.6 + * See https://github.com/libuv/libuv/issues/4165 + */ + if (r == EINVAL && errno == EBUSY) + return; + if (r) + abort(); +#else + if (pthread_cond_wait(cond, mutex)) + abort(); +#endif +} + +static inline int js_cond_timedwait(js_cond_t *cond, js_mutex_t *mutex, uint64_t timeout) { + int r; + struct timespec ts; + +#if !defined(__APPLE__) + timeout += js__hrtime_ns(); +#endif + + ts.tv_sec = timeout / NANOSEC; + ts.tv_nsec = timeout % NANOSEC; +#if defined(__APPLE__) && defined(__MACH__) + r = pthread_cond_timedwait_relative_np(cond, mutex, &ts); +#else + r = pthread_cond_timedwait(cond, mutex, &ts); +#endif + + if (r == 0) + return 0; + + if (r == ETIMEDOUT) + return -1; + + abort(); + + /* Pacify some compilers. */ + return -1; +} + +static inline int js_thread_create(js_thread_t *thrd, void (*start)(void *), void *arg, + int flags) +{ + union { + void (*x)(void *); + void *(*f)(void *); + } u = {start}; + pthread_attr_t attr; + int ret; + + if (flags & ~JS_THREAD_CREATE_DETACHED) + return -1; + if (pthread_attr_init(&attr)) + return -1; + ret = -1; + if (pthread_attr_setstacksize(&attr, 2<<20)) + goto fail; + if (flags & JS_THREAD_CREATE_DETACHED) + if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) + goto fail; + if (pthread_create(thrd, &attr, u.f, arg)) + goto fail; + ret = 0; +fail: + pthread_attr_destroy(&attr); + return ret; +} + +static inline int js_thread_join(js_thread_t thrd) +{ + if (pthread_join(thrd, NULL)) + return -1; + return 0; +} + +#endif /* !defined(_WIN32) */ +#endif /* JS_HAVE_THREADS */ + +#ifdef __cplusplus +} /* extern "C" { */ +#endif + +#endif /* CUTILS_H */ diff --git a/userland/qjs/source/cxxtest.cc b/userland/qjs/source/cxxtest.cc new file mode 100644 index 0000000..b615100 --- /dev/null +++ b/userland/qjs/source/cxxtest.cc @@ -0,0 +1,2 @@ +// note: file is not actually compiled, only checked for C++ syntax errors +#include "ctest.c" diff --git a/userland/qjs/source/docs/.gitignore b/userland/qjs/source/docs/.gitignore new file mode 100644 index 0000000..b2d6de3 --- /dev/null +++ b/userland/qjs/source/docs/.gitignore @@ -0,0 +1,20 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/userland/qjs/source/docs/.nvmrc b/userland/qjs/source/docs/.nvmrc new file mode 100644 index 0000000..3c03207 --- /dev/null +++ b/userland/qjs/source/docs/.nvmrc @@ -0,0 +1 @@ +18 diff --git a/userland/qjs/source/docs/babel.config.js b/userland/qjs/source/docs/babel.config.js new file mode 100644 index 0000000..e00595d --- /dev/null +++ b/userland/qjs/source/docs/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: [require.resolve('@docusaurus/core/lib/babel/preset')], +}; diff --git a/userland/qjs/source/docs/docs/building.md b/userland/qjs/source/docs/docs/building.md new file mode 100644 index 0000000..0ced0fe --- /dev/null +++ b/userland/qjs/source/docs/docs/building.md @@ -0,0 +1,74 @@ +--- +sidebar_position: 2 +--- + +# Building + +QuickJS uses [CMake] as its main build system, with an additional helper [Makefile]. + +:::note +Windows users will need to run the CMake commands manually. +::: + +## Getting the source + +```bash +git clone https://github.com/quickjs-ng/quickjs.git +cd quickjs +``` + +## Compiling everything + +```bash +make +``` + +This will build the `qjs` and `qjsc` executables and other test tools. Head over [here](./cli) for +instructions on how to use them. + +## Big Endian architecture support + +When compiling for a big endian target the bundled bytecode must be regenerated. The generated bytecode is endian dependent +and the currently shipped source builds have little endian bytecode. To regenerate it: + +```bash +make codegen +``` + +Then proceed with `make` as normal. + +## Amalgamated builds + +The amalgamated build rolls individual source files into a single big file. +It's a good choice for projects that want to use QuickJS without CMake. + +Download quickjs-amalgam.zip from [Releases](https://github.com/quickjs-ng/quickjs/releases) + +To enable the std, os and bjson modules, compile quickjs-amalgam.c with +`-DQJS_BUILD_LIBC`. + +## Debug builds + +```bash +make debug +``` + +This will produce a debug build without optimizations, suitable for developers. + +## Running test262 + +```bash +make test262 +``` + +This will run the test262 suite. + +```bash +make test262-update +``` + +This will run the test262 suite and update the error / pass report, useful after +implementing a new feature that would alter the result of the test suite. + +[CMake]: https://cmake.org +[Makefile]: https://www.gnu.org/software/make/ diff --git a/userland/qjs/source/docs/docs/cli.md b/userland/qjs/source/docs/docs/cli.md new file mode 100644 index 0000000..d859439 --- /dev/null +++ b/userland/qjs/source/docs/docs/cli.md @@ -0,0 +1,130 @@ +--- +sidebar_position: 4 +--- + +# The qjs and qjsc CLI tools + +## `qjs` - The QuickJS JavaScript interpreter + +The `qjs` executable runs the JavaScript interpreter. It includes a simple standard +library and REPL. + +``` +$ qjs +usage: qjs [options] [file [args]] +-h --help list options +-e --eval EXPR evaluate EXPR +-i --interactive go to interactive mode +-m --module load as ES6 module (default=autodetect) + --script load as ES6 script (default=autodetect) +-I --include file include an additional file + --std make 'std', 'os' and 'bjson' available to script +-T --trace trace memory allocation +-d --dump dump the memory usage stats +-D --dump-flags flags for dumping debug data (see DUMP_* defines) +-c --compile FILE compile the given JS file as a standalone executable +-o --out FILE output file for standalone executables + --exe select the executable to use as the base, defaults to the current one + --memory-limit n limit the memory usage to 'n' Kbytes + --stack-size n limit the stack size to 'n' Kbytes + --unhandled-rejection dump unhandled promise rejections +-q --quit just instantiate the interpreter and quit +``` + +The following dump flags are supported: + +``` +DUMP_BYTECODE_FINAL 0x01 /* dump pass 3 final byte code */ +DUMP_BYTECODE_PASS2 0x02 /* dump pass 2 code */ +DUMP_BYTECODE_PASS1 0x04 /* dump pass 1 code */ +DUMP_BYTECODE_HEX 0x10 /* dump bytecode in hex */ +DUMP_BYTECODE_PC2LINE 0x20 /* dump line number table */ +DUMP_BYTECODE_STACK 0x40 /* dump compute_stack_size */ +DUMP_BYTECODE_STEP 0x80 /* dump executed bytecode */ +DUMP_READ_OBJECT 0x100 /* dump the marshalled objects at load time */ +DUMP_FREE 0x200 /* dump every object free */ +DUMP_GC 0x400 /* dump the occurrence of the automatic GC */ +DUMP_GC_FREE 0x800 /* dump objects freed by the GC */ +DUMP_MODULE_RESOLVE 0x1000 /* dump module resolution steps */ +DUMP_PROMISE 0x2000 /* dump promise steps */ +DUMP_LEAKS 0x4000 /* dump leaked objects and strings in JS_FreeRuntime */ +DUMP_ATOM_LEAKS 0x8000 /* dump leaked atoms in JS_FreeRuntime */ +DUMP_MEM 0x10000 /* dump memory usage in JS_FreeRuntime */ +DUMP_OBJECTS 0x20000 /* dump objects in JS_FreeRuntime */ +DUMP_ATOMS 0x40000 /* dump atoms in JS_FreeRuntime */ +DUMP_SHAPES 0x80000 /* dump shapes in JS_FreeRuntime */ +``` + +### Creating standalone executables + +With the `qjs` CLI it's possible to create standalone executables that will bundle the given JavaScript file +alongside the binary. + +``` +$ qjs -c app.js -o app --exe qjs +``` + +The resulting `app` binary will have the same runtime dependencies as the `qjs` binary. This is acomplished +by compiling the target JavaScript file to bytecode and adding it a copy of the executable, with a little +trailer to help locate it. `--exe` expects the absolute path to `qjs`, e.g., `~/bin/qjs` or `$HOME/bin/qjs`. + +Rather than using the current executable, it's possible to use the `--exe` switch to create standalone +executables for other platforms. + +No JavaScript bundling is performed, the specified JS file cannot depend on other files. A bundler such +as `esbuild` can be used to generate an app bundle which can then be turned into the executable. + +``` +npx esbuild my-app/index.js \ + --bundle \ + --outfile=app.js \ + --external:qjs:* \ + --minify \ + --target=es2023 \ + --platform=neutral \ + --format=esm \ + --main-fields=main,module +``` + +## `qjsc` - The QuickJS JavaScript compiler + +The `qjsc` executable runs the JavaScript compiler, it can generate bytecode from +source files which can then be embedded in an executable, or it can generate the necessary +scaffolding to build a C application which embeds QuickJS. + +``` +$ qjsc +usage: qjsc [options] [files] + +options are: +-b output raw bytecode instead of C code +-e output main() and bytecode in a C file +-o output set the output filename +-n script_name set the script name (as used in stack traces) +-N cname set the C name of the generated data +-m compile as JavaScript module (default=autodetect) +-D module_name compile a dynamically loaded module or worker +-M module_name[,cname] add initialization code for an external C module +-p prefix set the prefix of the generated C names +-s strip the source code, specify twice to also strip debug info +-S n set the maximum stack size to 'n' bytes (default=262144) +``` + +Here is an example on how to create a standalone executable that embeds QuickJS +and the `examples/hello.js` JavaScript file: + +```bash +# Make sure you are in the QuickJS source directory. +$ cc hello.c dtoa.c libregexp.c libunicode.c quickjs.c quickjs-libc.c -I. -o hello +``` + +The resulting binary `hello` will be in the current directory. + +```bash +$ ./hello +Hello World +``` + +:::note +See the ["Creating standalone executables"](#creating-standalone-executables) section for a simpler way. +::: diff --git a/userland/qjs/source/docs/docs/developer-guide/_category_.json b/userland/qjs/source/docs/docs/developer-guide/_category_.json new file mode 100644 index 0000000..6050477 --- /dev/null +++ b/userland/qjs/source/docs/docs/developer-guide/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Developer Guide", + "position": 6, + "link": { + "type": "generated-index" + } +} diff --git a/userland/qjs/source/docs/docs/developer-guide/api.md b/userland/qjs/source/docs/docs/developer-guide/api.md new file mode 100644 index 0000000..78bec94 --- /dev/null +++ b/userland/qjs/source/docs/docs/developer-guide/api.md @@ -0,0 +1,3 @@ +# API Reference + +WIP. diff --git a/userland/qjs/source/docs/docs/developer-guide/internals.md b/userland/qjs/source/docs/docs/developer-guide/internals.md new file mode 100644 index 0000000..4c9afea --- /dev/null +++ b/userland/qjs/source/docs/docs/developer-guide/internals.md @@ -0,0 +1,117 @@ +# Internals + +## Bytecode + +The compiler generates bytecode directly with no intermediate +representation such as a parse tree, hence it is very fast. Several +optimizations passes are done over the generated bytecode. + +A stack-based bytecode was chosen because it is simple and generates +compact code. + +For each function, the maximum stack size is computed at compile time so that +no runtime stack overflow tests are needed. + +A separate compressed line number table is maintained for the debug +information. + +Access to closure variables is optimized and is almost as fast as local +variables. + +Direct `eval` in strict mode is optimized. + +## Runtime + +### Strings + +Strings are stored either as an 8 bit or a 16 bit array of +characters. Hence random access to characters is always fast. + +The C API provides functions to convert JavaScript Strings to C UTF-8 encoded +strings. The most common case where the JavaScript string contains +only ASCII characters involves no copying. + +### Objects + +The object shapes (object prototype, property names and flags) are shared +between objects to save memory. + +Arrays with no holes (except at the end of the array) are optimized. + +TypedArray accesses are optimized. + +### Atoms + +Object property names and some strings are stored as Atoms (unique +strings) to save memory and allow fast comparison. Atoms are +represented as a 32 bit integer. Half of the atom range is reserved for +immediate integer literals from 0 to 2^31-1. + +### Numbers + +Numbers are represented either as 32-bit signed integers or 64-bit IEEE-754 +floating point values. Most operations have fast paths for the 32-bit +integer case. + +### Garbage collection + +Reference counting is used to free objects automatically and +deterministically. A separate cycle removal pass is done when the allocated +memory becomes too large. The cycle removal algorithm only uses the +reference counts and the object content, so no explicit garbage +collection roots need to be manipulated in the C code. + +### JSValue + +It is a JavaScript value which can be a primitive type (such as +Number, String, ...) or an Object. NaN boxing is used in the 32-bit version +to store 64-bit floating point numbers. The representation is +optimized so that 32-bit integers and reference counted values can be +efficiently tested. + +In 64-bit code, JSValue are 128-bit large and no NaN boxing is used. The +rationale is that in 64-bit code memory usage is less critical. + +In both cases (32 or 64 bits), JSValue exactly fits two CPU registers, +so it can be efficiently returned by C functions. + +### Function call + +The engine is optimized so that function calls are fast. The system +stack holds the JavaScript parameters and local variables. + +### RegExp + +A specific regular expression engine was developed. It is both small +and efficient and supports all the ES2020+ features including the +Unicode properties. As the JavaScript compiler, it directly generates +bytecode without a parse tree. + +Backtracking with an explicit stack is used so that there is no +recursion on the system stack. Simple quantifiers are specifically +optimized to avoid recursions. + +Infinite recursions coming from quantifiers with empty terms are +avoided. + +The full regexp library weighs about 15 KiB (x86 code), excluding the +Unicode library. + +### Unicode + +A specific Unicode library was developed so that there is no +dependency on an external large Unicode library such as ICU. All the +Unicode tables are compressed while keeping a reasonable access +speed. + +The library supports case conversion, Unicode normalization, Unicode +script queries, Unicode general category queries and all Unicode +binary properties. + +The full Unicode library weighs about 45 KiB (x86 code). + +### BigInt + +BigInt is implemented with the [libbf](https://bellard.org/libbf) library. +It weights about 90 KiB (x86 code) and provides arbitrary precision IEEE 754 floating +point operations and transcendental functions with exact rounding. diff --git a/userland/qjs/source/docs/docs/developer-guide/intro.md b/userland/qjs/source/docs/docs/developer-guide/intro.md new file mode 100644 index 0000000..551bb37 --- /dev/null +++ b/userland/qjs/source/docs/docs/developer-guide/intro.md @@ -0,0 +1,111 @@ +--- +sidebar_position: 1 +--- + +# The QuickJS C API + +The C API was designed to be simple and efficient. The C API is +defined in the header `quickjs.h`. + +## Runtime and contexts + +`JSRuntime` represents a JavaScript runtime corresponding to an +object heap. Several runtimes can exist at the same time but they +cannot exchange objects. Inside a given runtime, no multi-threading is +supported. + +`JSContext` represents a JavaScript context (or Realm). Each +JSContext has its own global objects and system objects. There can be +several JSContexts per JSRuntime and they can share objects, similar +to frames of the same origin sharing JavaScript objects in a +web browser. + +## JSValue + +`JSValue` represents a JavaScript value which can be a primitive +type or an object. Reference counting is used, so it is important to +explicitly duplicate (`JS_DupValue()`, increment the reference +count) or free (`JS_FreeValue()`, decrement the reference count) +JSValues. + +## C functions + +C functions can be created with +`JS_NewCFunction()`. `JS_SetPropertyFunctionList()` is a +shortcut to easily add functions, setters and getters properties to a +given object. + +Unlike other embedded JavaScript engines, there is no implicit stack, +so C functions get their parameters as normal C parameters. As a +general rule, C functions take constant `JSValue`s as parameters +(so they don't need to free them) and return a newly allocated (=live) +`JSValue`. + +## Exceptions + +Most C functions can return a JavaScript exception. It +must be explicitly tested and handled by the C code. The specific +`JSValue` `JS_EXCEPTION` indicates that an exception +occurred. The actual exception object is stored in the +`JSContext` and can be retrieved with `JS_GetException()`. + +## Script evaluation + +Use `JS_Eval()` to evaluate a script or module source. + +If the script or module was compiled to bytecode with `qjsc`, it +can be evaluated by calling `js_std_eval_binary()`. The advantage +is that no compilation is needed so it is faster and smaller because +the compiler can be removed from the executable if no `eval` is +required. + +Note: the bytecode format is linked to a given QuickJS +version. Moreover, no security check is done before its +execution. Hence the bytecode should not be loaded from untrusted +sources. + +## JS Classes + +C opaque data can be attached to a JavaScript object. The type of the +C opaque data is determined with the class ID (`JSClassID`) of +the object. Hence the first step is to register a new class ID and JS +class (`JS_NewClassID()`, `JS_NewClass()`). Then you can +create objects of this class with `JS_NewObjectClass()` and get or +set the C opaque point with `JS_GetOpaque()` / `JS_SetOpaque()`. + +When defining a new JS class, it is possible to declare a finalizer +which is called when the object is destroyed. The finalizer should be +used to release C resources. It is invalid to execute JS code from +it. A `gc_mark` method can be provided so that the cycle removal +algorithm can find the other objects referenced by this object. Other +methods are available to define exotic object behaviors. + +The class and class ID are allocated per-runtime. `JS_SetClassProto()` +is used to define a prototype for a given class in a given `JSContext`. +`JS_NewObjectClass()` sets this prototype in the created object. + +Examples are available in `quickjs-libc.c`. + +## C Modules + +Native ES6 modules are supported and can be dynamically or statically +linked. The standard library `quickjs-libc.c` is a good example +of a native module. + +## Memory handling + +Use `JS_SetMemoryLimit()` to set a global memory allocation limit +to a given `JSRuntime`. + +Custom memory allocation functions can be provided with `JS_NewRuntime2()`. + +The maximum system stack size can be set with `JS_SetMaxStackSize()`. + +## Execution timeout and interrupts + +Use `JS_SetInterruptHandler()` to set a callback which is +regularly called by the engine when it is executing code. This +callback can be used to implement an execution timeout. + +It is used by the command line interpreter to implement a +`Ctrl-C` handler. diff --git a/userland/qjs/source/docs/docs/diff.md b/userland/qjs/source/docs/docs/diff.md new file mode 100644 index 0000000..adf81ee --- /dev/null +++ b/userland/qjs/source/docs/docs/diff.md @@ -0,0 +1,68 @@ +# Differences with bellard/quickjs + +This project aims to be a drop-in replacement for those already using QuickJS. +Minimal API changes might be necessary. + +## Community development + +NG is developed in the open, interacting with the wider community and through +these interactions many improvements have already been made, including the incorporation +of patches previously maintained in other forks. + +Each PR is reviewed, iterated on, and merged in GitHub. + +To date, NG has had over 40 distinct contributors and over 400 PRs. + +## Consistent release cadence + +As the project moves forward, a steady cadence of releases has been maintained, with an +average of a new release every 2 months. + +## Testing + +Since its inception testing has been a focus. Each PR is tested in over 50 configurations, +involving different operating systems, build types and sanitizers. + +The `test262` suite is also run for every change. + +## Cross-platform support + +In order to better support other platforms such as Windows the build system was +changed to use [CMake]. + +In addition, Windows is treated as a first class citizen, with the addition of support +for the MSVC compiler. + +[CMake]: https://cmake.org/ + +## Performance + +While being an interpreter limits the performance in comparison with other engines which +use a JIT, several significant performance improvements have been made: + +- Opcode fusion +- Polymorphic inline caching +- Memory allocation improvements +- Improved parse speeds + +## New ECMAScript APIs + +The main focus of NG is to deliver state-of-the-art JavaScript features. Typically once they +are stable (stage 4) but sometimes even at earlier stages. Here is a non-exhaustive list +of ES features present in NG: + +- Resizable ArrayBuffer +- Float16Array +- WeakRef +- FinalizationRegistry +- Iterator Helpers +- Promise.try +- Error.isError +- Set operations + +Some non-standard but widely used APIs have also been added: + +- V8's [stack trace API](https://v8.dev/docs/stack-trace-api) + - `Error.captureStackTrace` + - `Error.prepareStackTrace` + - `Error.stackTraceLimit` diff --git a/userland/qjs/source/docs/docs/es_features.md b/userland/qjs/source/docs/docs/es_features.md new file mode 100644 index 0000000..d57754c --- /dev/null +++ b/userland/qjs/source/docs/docs/es_features.md @@ -0,0 +1,11 @@ +--- +sidebar_position: 7 +--- + +# ECMAScript Features + +QuickJS aims to support the latest available ECMAScript features once they hit the spec. + +Progress on _test262_ compliance can be checked [here](https://test262.fyi/#|qjs_ng). + +Due to size constraints it is unlikely QuickJS will ever support the [Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl) APIs. diff --git a/userland/qjs/source/docs/docs/installation.md b/userland/qjs/source/docs/docs/installation.md new file mode 100644 index 0000000..5df467c --- /dev/null +++ b/userland/qjs/source/docs/docs/installation.md @@ -0,0 +1,34 @@ +--- +sidebar_position: 3 +--- + +# Installation + +Installing QuickJS is simple, and we provide several ways to do so. + + +## Build from source + +If you built it from source as outlined in [building](./building) you can just run: + +```bash +make install +``` + +and it will be installed in your system. The default installation path is `/usr/local`. + + +## Using a prebuilt binary + +Each [release on GitHub] includes binaries for several systems and architectures. + + +## Using jsvu + +As of version 2.2.0 of `jsvu`, QuickJS-ng will be installed when the `quickjs` engine is requested. + +```bash +npm install jsvu -g +``` + +[release on GitHub]: https://github.com/quickjs-ng/quickjs/releases diff --git a/userland/qjs/source/docs/docs/intro.md b/userland/qjs/source/docs/docs/intro.md new file mode 100644 index 0000000..cb63ed5 --- /dev/null +++ b/userland/qjs/source/docs/docs/intro.md @@ -0,0 +1,33 @@ +--- +slug: / +sidebar_position: 1 +sidebar_label: Welcome +--- + +# Welcome to QuickJS-NG + +QuickJS is a small and embeddable JavaScript engine. It aims to support the latest +[ECMAScript] specification. + +This project is a _fork_ of the [original QuickJS project] by Fabrice Bellard and Charlie Gordon, after it went dormant, with the intent of reigniting its development. + +This project is focused on (but not limited to): + +- Community development +- Testing +- Cross-platform support +- ES features + +You can check the differences with the original project [here.](./diff) + +:::note +This site is under construction, the entire API is not yet documented. +::: + +## Getting Started + +Head over to [building](./building) if you want to build QuickJS from source or [installation](./installation) +for installing it from prebuilt binaries. + +[ECMAScript]: https://tc39.es/ecma262/ +[original QuickJS project]: https://bellard.org/quickjs diff --git a/userland/qjs/source/docs/docs/projects.md b/userland/qjs/source/docs/docs/projects.md new file mode 100644 index 0000000..eb17f3a --- /dev/null +++ b/userland/qjs/source/docs/docs/projects.md @@ -0,0 +1,116 @@ +# Projects using NG + +Here is a list of projects currently using, supporting or migrating to QuickJS-NG. +If you want yours to be listed here, please open a PR! + +## [txiki.js](https://github.com/saghul/txiki.js) + +A tiny JavaScript runtime. + +## [radare2](https://github.com/radareorg/radare2) + +Reverse engineering framework. + +## [rquickjs](https://github.com/DelSkayn/rquickjs) + +High level Rust bindings. + +## [llrt](https://github.com/awslabs/llrt) + +Lightweight JS runtime for serverless applications. + +## [nx.js](https://github.com/TooTallNate/nx.js) + +JavaScript runtime for Nintendo Switch homebrew applications. + +## [quickjs-rusty](https://github.com/Icemic/quickjs-rusty) + +Rust wrapper focus on embedding-ready and no-pain type conversion and interoperability. + +## [CSPro](https://github.com/csprousers/cspro) + +CSPro incorporates the QuickJS-NG engine as its embedded JavaScript runtime for executing logic, complementing its own domain-specific language, CSPro Logic. + +## [GodotJS](https://github.com/godotjs/GodotJS) + +This project adds TypeScript/JavaScript support for Godot 4.x. It supports multiple javascript runtimes, including QuickJS-NG. + +## [quickjs_es_runtime](https://github.com/HiRoFa/quickjs_es_runtime) + +Rust wrapper with typescript, modules, promises, async/await and much more. + +## [Lua jsregexp](https://github.com/kmarius/jsregexp) + +JavaScript regular expressions for Lua. + +## [Edbrowse](https://edbrowse.org) + +A combination editor, web-browser, and mail client that is 100% text based. + +## [go-quickjs-wasi-reactor](https://github.com/aperturerobotics/go-quickjs-wasi-reactor) + +Go module that embeds QuickJS-NG compiled to WebAssembly using the WASI reactor model. Provides re-entrant execution via exported C API functions, a high-level Go API with wazero, non-blocking event loop control, and a command-line REPL. + +## [js-quickjs-wasi-reactor](https://github.com/aperturerobotics/js-quickjs-wasi-reactor) + +JavaScript/TypeScript harness for running QuickJS-NG in WASI reactor mode. Includes a browser-compatible WASI shim, virtual filesystem, custom I/O handlers, and non-blocking event loop integration for browser and Node.js/Bun environments. + +## [quickjs.ml](https://github.com/ml-in-barcelona/quickjs.ml) + +OCaml bindings to quickjs-ng. Exposing both low-level C library access (libregexp, libunicode, js_dtoa, js_atod, and cutils) and a high-level API mirroring JavaScript built-ins like RegExp, String, and Number. + +## [Python quickjs-ng](https://github.com/genotrance/quickjs-ng) + +Python bindings for quickjs-ng based on https://github.com/PetterS/quickjs. + +## [Px](https://github.com/genotrance/px) + +Proxy server using quickjs-ng for PAC file processing. + +## [std::slop](https://github.com/hsaliak/std_slop) + +A C++/SQL based Coding agent. It exposes a QuickJS-ng environment to the LLM. The Agent accomplishes all it's work through this QuickJS-NG based "control plane". + +## [QuickBEAM](https://github.com/elixir-volt/quickbeam) + +JavaScript runtime for the BEAM - Web APIs backed by OTP, native DOM, and a built-in TypeScript toolchain. + +## [quickjs-go](https://github.com/buke/quickjs-go) + +Golang bindings for QuickJS-NG using cgo + +## [Nordstjernen](https://github.com/nordstjernen-web/nordstjernen) + +Nordstjernen web browser. + +## [quickjs-cpp](https://github.com/qr243vbi/quickjs-cpp) + +Header only library for quickjs-ng with modern C++ interface (Archived). + +## [NekoBox](https://github.com/qr243vbi/nekobox) + +A lightweight proxy client, empowered by sing-box and thrift. + +## [RongJS](https://github.com/LingXia-Dev/Rong) + +A multi-engine JavaScript runtime and Rust embedding API with first-class QuickJS-NG support. + +## [scriptc](https://github.com/vercel-labs/scriptc) + +TypeScript-to-Native Compiler + +## [Qbs](https://github.com/qbs/qbs) + +Cross-platform build system. Uses QuickJS-NG as its JavaScript backend for evaluating project files. + +## [Vayu](https://github.com/athrvk/vayu) + +Open-source API client with a native C++ load-testing engine. Embeds QuickJS-NG to enable in-app scripting: pre-request and test scripts with a Postman-compatible `pm.*` API. + +## [react-native-quickjs](https://github.com/react-native-quickjs/quickjs) + +JSI runtime for React Native using QuickJS-NG. Replaces Hermes / JSC. + +## [DuckDB QuickJS Extension](https://query.farm/products/extensions/quickjs/) + +DuckDB extension by Query.Farm that embeds QuickJS-NG, allowing JavaScript to be executed directly inside SQL queries as scalar and table functions. diff --git a/userland/qjs/source/docs/docs/stdlib.md b/userland/qjs/source/docs/docs/stdlib.md new file mode 100644 index 0000000..f579760 --- /dev/null +++ b/userland/qjs/source/docs/docs/stdlib.md @@ -0,0 +1,605 @@ +--- +sidebar_position: 5 +--- + +# Standard library + +The standard libary is provided as part of the `qjs` executable and the `quickjs-libc.c` source file +and it's not part of the core engine. + +## Globals + +### `argv0` + +Provides the executable path. + +### `scriptArgs` + +Provides the command line arguments. The first argument is the script name. + +### `print(...args)` + +Print the arguments separated by spaces and a trailing newline. + +### `console.log(...args)` + +Same as `print()`. + +### `navigator.userAgent` + +Returns `quickjs-ng/`. + +### `gc()` + +Shorthand for `std.gc()`. + +## `qjs:bjson` module + +### `bjson.write(obj, [flags])` + +Serializes the given object into the QuickJS internal serialization format. +Returns an ArrayBuffer with the serialized data. + +Supported flags: + +- `WRITE_OBJ_BYTECODE`: allow serializing functions and modules +- `WRITE_OBJ_REFERENCE`: allow serializing object references +- `WRITE_OBJ_SAB`: allow serializing SharedArrayBuffer instances +- `WRITE_OBJ_STRIP_DEBUG`: strip debugging information when serializing +- `WRITE_OBJ_STRIP_SOURCE`: strip the source information when serializing + +### `bjson.read(buf, [pos], [len], [flags])` + +De-serialize the given ArrayBuffer (in QuickJS internal serialization format) back into a JavaScript value. + +Supported flags: + +- `READ_OBJ_BYTECODE`: allow de-serializing functions and modules +- `READ_OBJ_REFERENCE`: allow de-serializing object references + +Security caveat: `bjson.read()` is resilient against malformed input (the wire +format is checksummed) but is not designed to withstand adversarial attacks. +Don't feed it untrusted input. + +## `qjs:os` module + +The `os` module provides Operating System specific functions: + +- low level file access +- signals +- timers +- basic asynchronous I/O +- workers (threads) + +The OS functions usually return 0 if OK or an OS specific negative +error code. + +### `open(filename, flags, mode = 0o666)` + +Open a file. Return a handle or < 0 if error. + +Supported flags: + +- `O_RDONLY` +- `O_WRONLY` +- `O_RDWR` +- `O_APPEND` +- `O_CREAT` +- `O_EXCL` +- `O_TRUNC` + +POSIX open flags. + +- `O_TEXT` + +(Windows specific). Open the file in text mode. The default is binary mode. + +### `close(fd)` + +Close the file handle `fd`. + +### `seek(fd, offset, whence)` + +Seek in the file. Use `std.SEEK_*` for +`whence`. `offset` is either a number or a BigInt. If +`offset` is a BigInt, a BigInt is returned too. + +### `read(fd, buffer, offset, length)` + +Read `length` bytes from the file handle `fd` to the +ArrayBuffer `buffer` at byte position `offset`. +Return the number of read bytes or < 0 if error. + +### `write(fd, buffer, offset, length)` + +Write `length` bytes to the file handle `fd` from the +ArrayBuffer `buffer` at byte position `offset`. +Return the number of written bytes or < 0 if error. + +### `isatty(fd)` + +Return `true` is `fd` is a TTY (terminal) handle. + +### `ttyGetWinSize(fd)` + +Return the TTY size as `[width, height]` or `null` if not available. + +### `ttySetRaw(fd)` + +Set the TTY in raw mode. + +### `remove(filename)` + +Remove a file. Return 0 if OK or `-errno`. + +### `rename(oldname, newname)` + +Rename a file. Return 0 if OK or `-errno`. + +### `realpath(path)` + +Return `[str, err]` where `str` is the canonicalized absolute +pathname of `path` and `err` the error code. + +### `getcwd()` + +Return `[str, err]` where `str` is the current working directory +and `err` the error code. + +### `exePath()` + +Returns the full path of the current executable or `undefined` if not available / supported. + +### `chdir(path)` + +Change the current directory. Return 0 if OK or `-errno`. + +### `mkdir(path, mode = 0o777)` + +Create a directory at `path`. Return 0 if OK or `-errno`. + +### `mkdtemp(pattern = "tmpXXXXXX")` + +Create a temporary directory. `XXXXXX` must be at the end of the pattern +string and is replaced with a random name. The directory is created with +file mode `0o700`. + +Return `[path, err]` where `path` is a string and `err` is 0 or `-errno`. + +Not available on Windows and WASI. + +### `mkstemp(pattern = "tmpXXXXXX")` + +Create a temporary file and open it. `XXXXXX` must be at the end of the +pattern string and is replaced with a random name. The file is created with +file mode `0o600` and opened in read/write mode. + +Return `[path, fd]` where `path` is a string and `fd` is the file descriptor +or `-errno`, i.e., the error code if less than zero. + +Unlike `std.tmpfile()`, the file is not automatically deleted on close. + +See also `std.fdopen()`. + +Not available on Windows and WASI. + +### `stat(path)` / `lstat(path)` + +Return `[obj, err]` where `obj` is an object containing the +file status of `path`. `err` is the error code. The +following fields are defined in `obj`: `dev`, `ino`, `mode`, `nlink`, +`uid`, `gid`, `rdev`, `size`, `blocks`, `atime`, `mtime`, `ctime`. The times are +specified in milliseconds since 1970. `lstat()` is the same as +`stat()` excepts that it returns information about the link +itself. + +- `S_IFMT` +- `S_IFIFO` +- `S_IFCHR` +- `S_IFDIR` +- `S_IFBLK` +- `S_IFREG` +- `S_IFSOCK` +- `S_IFLNK` +- `S_ISGID` +- `S_ISUID` + +Constants to interpret the `mode` property returned by +`stat()`. They have the same value as in the C system header +`sys/stat.h`. + +### `utimes(path, atime, mtime)` + +Change the access and modification times of the file `path`. The +times are specified in milliseconds since 1970. Return 0 if OK or `-errno`. + +### `symlink(target, linkpath)` + +Create a link at `linkpath` containing the string `target`. Return 0 if OK or `-errno`. + +### `readlink(path)` + +Return `[str, err]` where `str` is the link target and `err` +the error code. + +### `readdir(path)` + +Return `[array, err]` where `array` is an array of strings +containing the filenames of the directory `path`. `err` is +the error code. `array` contains at least `"."` and `".."` +if successful. + +### `setReadHandler(fd, func)` + +Add a read handler to the file handle `fd`. `func` is called +each time there is data pending for `fd`. A single read handler +per file handle is supported. Use `func = null` to remove the +handler. + +### `setWriteHandler(fd, func)` + +Add a write handler to the file handle `fd`. `func` is +called each time data can be written to `fd`. A single write +handler per file handle is supported. Use `func = null` to remove +the handler. + +### `signal(signal, func)` + +Call the function `func` when the signal `signal` +happens. Only a single handler per signal number is supported. Use +`null` to set the default handler or `undefined` to ignore +the signal. Signal handlers can only be defined in the main thread. + +- `SIGINT` +- `SIGABRT` +- `SIGFPE` +- `SIGILL` +- `SIGSEGV` +- `SIGTERM` + +POSIX signal numbers. + +### `kill(pid, sig)` + +Send the signal `sig` to the process `pid`. + +### `exec(args[, options])` + +Execute a process with the arguments `args`. `options` is an +object containing optional parameters: + +- `block` - Boolean (default = true). If true, wait until the process is + terminated. In this case, `exec` return the exit code if positive + or the negated signal number if the process was interrupted by a + signal. If false, do not block and return the process id of the child. +- `usePath` - Boolean (default = true). If true, the file is searched in the + `PATH` environment variable. +- `file` - String (default = `args[0]`). Set the file to be executed. +- `cwd` - String. If present, set the working directory of the new process. +- `stdin`, `stdout`, `stderr` - If present, set the handle in the child for stdin, stdout or stderr. +- `env` - Object. If present, set the process environment from the object + key-value pairs. Otherwise use the same environment as the current + process. +- `uid` - Integer. If present, the process uid with `setuid`. +- `gid` - Integer. If present, the process gid with `setgid`. +- `groups` - Array of integer. If present, the supplementary + group IDs with `setgroup`. + +### `waitpid(pid, options)` + +`waitpid` Unix system call. Return the array `[ret, status]`. +`ret` contains `-errno` in case of error. + +- `WNOHANG` + +Constant for the `options` argument of `waitpid`. + +### `dup(fd)` + +`dup` Unix system call. + +### `dup2(oldfd, newfd)` + +`dup2` Unix system call. + +### `pipe()` + +`pipe` Unix system call. Return two handles as `[read_fd, write_fd]` or null in case of error. + +### `sleep(delay_ms)` + +Sleep during `delay_ms` milliseconds. + +### `sleepAsync(delay_ms)` + +Asynchronouse sleep during `delay_ms` milliseconds. Returns a promise. Example: + +```js +await os.sleepAsync(500); +``` + +### `setTimeout(func, delay)` + +Call the function `func` after `delay` ms. Return a timer ID. + +### `clearTimeout(id)` + +Cancel a timer. + +### `platform` + +Return a string representing the platform: `"linux"`, `"darwin"`, `"win32"` or `"js"`. + +### `Worker(module_filename)` + +Constructor to create a new thread (worker) with an API close to that of +`WebWorkers`. `module_filename` is a string specifying the +module filename which is executed in the newly created thread. As for +dynamically imported module, it is relative to the current script or +module path. Threads normally don't share any data and communicate +between each other with messages. Nested workers are not supported. An +example is available in `tests/test_worker.js`. + +The worker class has the following static properties: + +- `parent` - In the created worker, `Worker.parent` represents the parent + worker and is used to send or receive messages. + +The worker instances have the following properties: + +- `postMessage(msg)` - Send a message to the corresponding worker. `msg` is cloned in + the destination worker using an algorithm similar to the `HTML` + structured clone algorithm. `SharedArrayBuffer` are shared + between workers. + +- `onmessage` - Getter and setter. Set a function which is called each time a + message is received. The function is called with a single + argument. It is an object with a `data` property containing the + received message. The thread is not terminated if there is at least + one non `null` `onmessage` handler. + +## `qjs:std` module + +The `std` module provides wrappers to libc (`stdlib.h` and `stdio.h`) and a few other utilities. + +### `exit(n)` + +Exit the process. + +### `evalScript(str, options = undefined)` + +Evaluate the string `str` as a script (global +eval). `options` is an optional object containing the following +optional properties: + +- `backtrace_barrier` - Boolean (default = false). If true, error backtraces do not list the + stack frames below the evalScript. +- `async` - Boolean (default = false). If true, `await` is accepted in the + script and a promise is returned. The promise is resolved with an + object whose `value` property holds the value returned by the + script. + +### `loadScript(filename)` + +Evaluate the file `filename` as a script (global eval). + +### `loadFile(filename, [options])` + +Load the file `filename` and return it as a string assuming UTF-8 +encoding. Return `null` in case of I/O error. + +If `options.binary` is set to `true` a `Uint8Array` is returned instead. + +### `writeFile(filename, data)` + +Create the file `filename` and write `data` into it. + +`data` can be a string, a typed array or an `ArrayBuffer`. `undefined` is +treated as the empty string. + +When `data` is a string, the file is opened in text mode; otherwise it is +opened in binary mode. (This distinction is only relevant on Windows.) + +Throws an exception if the file cannot be created or written to. + +### `open(filename, flags, errorObj = undefined)` + +Open a file (wrapper to the libc `fopen()`). Return the FILE +object or `null` in case of I/O error. If `errorObj` is not +undefined, set its `errno` property to the error code or to 0 if +no error occurred. + +### `popen(command, flags, errorObj = undefined)` + +Open a process by creating a pipe (wrapper to the libc +`popen()`). Return the FILE +object or `null` in case of I/O error. If `errorObj` is not +undefined, set its `errno` property to the error code or to 0 if +no error occurred. + +### `fdopen(fd, flags, errorObj = undefined)` + +Open a file from a file handle (wrapper to the libc +`fdopen()`). Return the FILE +object or null` in case of I/O error. If `errorObj` is not +undefined, set its `errno` property to the error code or to 0 if +no error occurred. + +### `tmpfile(errorObj = undefined)` + +Open a temporary file. Return the FILE +object or `null` in case of I/O error. If `errorObj` is not +undefined, set its `errno` property to the error code or to 0 if +no error occurred. + +### `puts(str)` + +Equivalent to `std.out.puts(str)`. + +### `printf(fmt, ...args)` + +Equivalent to `std.out.printf(fmt, ...args)`. + +### `sprintf(fmt, ...args)` + +Equivalent to the libc sprintf(). + +### `in`, `out`, `err` + +Wrappers to the libc file `stdin`, `stdout`, `stderr`. + +### `Error` + +Enumeration object containing the integer value of common errors +(additional error codes may be defined): + +- `EINVAL` +- `EIO` +- `EACCES` +- `EEXIST` +- `ENOSPC` +- `ENOSYS` +- `EBUSY` +- `ENOENT` +- `EPERM` +- `EPIPE` + +### `strerror(errno)` + +Return a string that describes the error `errno`. + +### `gc()` + +Manually invoke the cycle removal algorithm. The cycle removal +algorithm is automatically started when needed, so this function is +useful in case of specific memory constraints or for testing. + +### `getenv(name)` + +Return the value of the environment variable `name` or +`undefined` if it is not defined. + +### `setenv(name, value)` + +Set the value of the environment variable `name` to the string +`value`. + +### `unsetenv(name)` + +Delete the environment variable `name`. + +### `getenviron()` + +Return an object containing the environment variables as key-value pairs. + +### `urlGet(url, options = undefined)` + +Download `url` using the `curl` command line +utility. `options` is an optional object containing the following +optional properties: + +- `binary` - Boolean (default = false). If true, the response is an ArrayBuffer + instead of a string. When a string is returned, the data is assumed + to be UTF-8 encoded. +- `full` - Boolean (default = false). If true, return the an object contains + the properties `response` (response content), + `responseHeaders` (headers separated by CRLF), `status` + (status code). `response` is `null` is case of protocol or + network error. If `full` is false, only the response is + returned if the status is between 200 and 299. Otherwise `null` + is returned. + +### `FILE` + +File object. + +#### `close()` + +Close the file. Return 0 if OK or `-errno` in case of I/O error. + +#### `puts(str)` + +Outputs the string with the UTF-8 encoding. + +#### `printf(fmt, ...args)` + +Formatted printf. + +The same formats as the standard C library `printf` are +supported. Integer format types (e.g. `%d`) truncate the Numbers +or BigInts to 32 bits. Use the `l` modifier (e.g. `%ld`) to +truncate to 64 bits. + +#### `flush()` + +Flush the buffered file. + +#### `seek(offset, whence)` + +Seek to a give file position (whence is +`std.SEEK_*`). `offset` can be a number or a BigInt. Return +0 if OK or `-errno` in case of I/O error. + +- `SEEK_SET` +- `SEEK_CUR` +- `SEEK_END` + +Constants for seek(). + +#### `tell()` + +Return the current file position. + +#### `tello()` + +Return the current file position as a BigInt. + +#### `eof()` + +Return true if end of file. + +#### `fileno()` + +Return the associated OS handle. + +#### `error()` + +Return true if there was an error. + +#### `clearerr()` + +Clear the error indication. + +#### `read(buffer, position = 0, length = buffer.length)` + +Read `length` bytes from the file to the ArrayBuffer `buffer` at byte +position `position`. Wrapper to the libc function `fread`. + +#### `write(buffer, position = 0, length = buffer.length)` + +Write `length` bytes to the file from the ArrayBuffer or string `buffer` +at byte position `position`. Wrapper to the libc function `fwrite`. + +#### `getline()` + +Return the next line from the file, assuming UTF-8 encoding, excluding +the trailing line feed. + +#### `readAsArrayBuffer(max_size = undefined)` + +Read `max_size` bytes from the file and return them as an ArrayBuffer. +If `max_size` is not present, the file is read until its end. + +#### `readAsString(max_size = undefined)` + +Read `max_size` bytes from the file and return them as a string +assuming UTF-8 encoding. If `max_size` is not present, the file +is read until its end. + +#### `getByte()` + +Return the next byte from the file. Return -1 if the end of file is reached. + +#### `putByte(c)` + +Write one byte to the file. diff --git a/userland/qjs/source/docs/docs/supported_platforms.md b/userland/qjs/source/docs/docs/supported_platforms.md new file mode 100644 index 0000000..bb817b3 --- /dev/null +++ b/userland/qjs/source/docs/docs/supported_platforms.md @@ -0,0 +1,20 @@ +--- +sidebar_position: 8 +--- + +# Supported Platforms + +| System | Supported versions | Notes | +|---|---|---| +| GNU/Linux | * | glibc and musl are supported | +| macOS | macOS >= 11 | Currently supported macOS releases | +| Windows | >= Windows 7* | VS >= 2022 and Clang are supported; requires `` | +| FreeBSD | * | Limited testing | +| OpenBSD | * | Limited testing | +| NetBSD | * | Limited testing | +| Android | NDK >= 26.0.10792818 | Limited testing | +| iOS | * | Limited testing | +| MinGW | MinGW-w64 | | +| Other | N/A | Missing? Open a PR! | + +- `*`: Windows 7 is EOL and only supported in this project as long as it doesn't interfere with its progress. diff --git a/userland/qjs/source/docs/docusaurus.config.js b/userland/qjs/source/docs/docusaurus.config.js new file mode 100644 index 0000000..25524ed --- /dev/null +++ b/userland/qjs/source/docs/docusaurus.config.js @@ -0,0 +1,114 @@ +// @ts-check +// `@type` JSDoc annotations allow editor autocompletion and type checking +// (when paired with `@ts-check`). +// There are various equivalent ways to declare your Docusaurus config. +// See: https://docusaurus.io/docs/api/docusaurus-config + +/** @type {import('@docusaurus/types').Config} */ +const config = { + title: 'QuickJS-NG', + tagline: 'QuickJS, the Next Generation: a mighty JavaScript engine', + favicon: 'img/favicon.ico', + + // Set the production url of your site here + url: 'https://quickjs-ng.github.io', + // Set the // pathname under which your site is served + // For GitHub pages deployment, it is often '//' + baseUrl: '/quickjs/', + + // GitHub pages deployment config. + // If you aren't using GitHub pages, you don't need these. + organizationName: 'quickjs-ng', // Usually your GitHub org/user name. + projectName: 'quickjs', // Usually your repo name. + + onBrokenLinks: 'throw', + onBrokenMarkdownLinks: 'throw', + + // Even if you don't use internationalization, you can use this field to set + // useful metadata like html lang. For example, if your site is Chinese, you + // may want to replace "en" with "zh-Hans". + i18n: { + defaultLocale: 'en', + locales: ['en'], + }, + + presets: [ + [ + 'classic', + /** @type {import('@docusaurus/preset-classic').Options} */ + ({ + docs: { + routeBasePath: '/', + sidebarPath: './sidebars.js', + // Please change this to your repo. + // Remove this to remove the "edit this page" links. + editUrl: 'https://github.com/quickjs-ng/quickjs/tree/master/docs/', + }, + blog: false, + theme: { + customCss: './src/css/custom.css', + }, + }), + ], + ], + + themeConfig: + /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ + ({ + // Replace with your project's social card + image: 'img/docusaurus-social-card.jpg', + navbar: { + title: 'QuickJS-NG', + items: [ + { + type: 'docSidebar', + sidebarId: 'docsSidebar', + position: 'left', + label: 'Documentation', + }, + { + href: 'https://github.com/quickjs-ng/quickjs', + label: 'GitHub', + position: 'right', + }, + ], + }, + footer: { + style: 'dark', + links: [ + { + title: 'Docs', + items: [ + ], + }, + { + title: 'Community', + items: [ + { + label: 'GitHub Discussions', + href: 'https://github.com/quickjs-ng/quickjs/discussions', + }, + { + label: 'Matrix', + href: 'https://matrix.to/#/%23quickjs-ng%3Amatrix.org?via=matrix.org', + }, + ], + }, + { + title: 'More', + items: [ + { + label: 'GitHub', + href: 'https://github.com/quickjs-ng/quickjs', + }, + ], + }, + ], + copyright: `Copyright © ${new Date().getFullYear()} QuickJS-NG project contributors.`, + }, + prism: { + }, + }), +}; + +export default config; diff --git a/userland/qjs/source/docs/package-lock.json b/userland/qjs/source/docs/package-lock.json new file mode 100644 index 0000000..f13c2d8 --- /dev/null +++ b/userland/qjs/source/docs/package-lock.json @@ -0,0 +1,14656 @@ +{ + "name": "docs", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/preset-classic": "3.5.2", + "@mdx-js/react": "3.0.1", + "clsx": "2.1.1", + "prism-react-renderer": "2.4.0", + "react": "18.3.1", + "react-dom": "18.3.1" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/types": "3.5.2" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@algolia/autocomplete-core": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", + "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", + "@algolia/autocomplete-shared": "1.9.3" + } + }, + "node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", + "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", + "dependencies": { + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" + } + }, + "node_modules/@algolia/autocomplete-preset-algolia": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", + "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", + "dependencies": { + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/autocomplete-shared": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", + "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/cache-browser-local-storage": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", + "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", + "dependencies": { + "@algolia/cache-common": "4.24.0" + } + }, + "node_modules/@algolia/cache-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", + "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==" + }, + "node_modules/@algolia/cache-in-memory": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", + "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", + "dependencies": { + "@algolia/cache-common": "4.24.0" + } + }, + "node_modules/@algolia/client-account": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", + "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-account/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-account/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", + "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-analytics/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-analytics/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.5.3.tgz", + "integrity": "sha512-3rdSdreBL2LGYu4DWmUGlMhaGy1vy36Xp42LdbTFsW/y3bhW5viptMHI5A3PKT0hPEMZUn+te1iM/EWvLUuVGQ==", + "peer": true, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", + "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-personalization/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.5.3.tgz", + "integrity": "sha512-qrokD+uoNxchbiF9aP8niQd/9SZ6BgYg4WaesFaubHhr9DFvwGm4IePEMha8vQcc3fSsY6uL+gOtKB3J6RF0NQ==", + "peer": true, + "dependencies": { + "@algolia/client-common": "5.5.3", + "@algolia/requester-browser-xhr": "5.5.3", + "@algolia/requester-fetch": "5.5.3", + "@algolia/requester-node-http": "5.5.3" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/events": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", + "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" + }, + "node_modules/@algolia/logger-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", + "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==" + }, + "node_modules/@algolia/logger-console": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", + "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", + "dependencies": { + "@algolia/logger-common": "4.24.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", + "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/requester-browser-xhr": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/requester-node-http": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.5.3.tgz", + "integrity": "sha512-LsfUPokiXEpvlYF7SwNjyyjkUX7IoW7oIhH6WkDUD4PCfEZkFbVplGQA0UrCiWOAbpb25P7mmP6+ldwjwqW6Kg==", + "peer": true, + "dependencies": { + "@algolia/client-common": "5.5.3" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", + "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==" + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.5.3.tgz", + "integrity": "sha512-RKaliEFHtVeD/fMxwrApkcI6ZxR+mU6pZna29r3NwVMpCXTJWWtlMpQmbr1RHzUsaAlpfv9pfGJN4nYPE8XWEg==", + "peer": true, + "dependencies": { + "@algolia/client-common": "5.5.3" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-node-http": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.5.3.tgz", + "integrity": "sha512-2wU+HlTVrVce7BMW2b3Gd62btk8B0jBbuKYYzu3OFeBD/aZa88eHABtjcjQCdw3x+wvkIPEc56UsZx9eHYLebg==", + "peer": true, + "dependencies": { + "@algolia/client-common": "5.5.3" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/transporter": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", + "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", + "dependencies": { + "@algolia/cache-common": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", + "dependencies": { + "@babel/types": "^7.25.6", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", + "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", + "dependencies": { + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz", + "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/traverse": "^7.25.4", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz", + "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", + "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", + "dependencies": { + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz", + "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-wrap-function": "^7.25.0", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", + "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz", + "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==", + "dependencies": { + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", + "dependencies": { + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.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==", + "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==", + "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==", + "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==" + }, + "node_modules/@babel/highlight/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==", + "engines": { + "node": ">=0.8.0" + } + }, + "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==", + "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==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "dependencies": { + "@babel/types": "^7.25.6" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz", + "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz", + "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz", + "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", + "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz", + "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz", + "integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", + "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz", + "integrity": "sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", + "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz", + "integrity": "sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-remap-async-to-generator": "^7.25.0", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/traverse": "^7.25.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", + "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", + "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz", + "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz", + "integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", + "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz", + "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/traverse": "^7.25.4", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", + "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", + "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", + "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", + "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz", + "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", + "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", + "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", + "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", + "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz", + "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", + "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz", + "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", + "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", + "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", + "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", + "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-simple-access": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz", + "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", + "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", + "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", + "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", + "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", + "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", + "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", + "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", + "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", + "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", + "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz", + "integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", + "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", + "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.1.tgz", + "integrity": "sha512-SLV/giH/V4SmloZ6Dt40HjTGTAIkxn33TVIHxNGNvo8ezMhrxBkzisj4op1KZYPIOHFLqhv60OHvX+YRu4xbmQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz", + "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.2.tgz", + "integrity": "sha512-KQsqEAVBpU82NM/B/N9j9WOdphom1SZH3R+2V7INrQUH+V9EBFwZsEJl8eBIVeQE62FxJCc70jzEZwqU7RcVqA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/types": "^7.25.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz", + "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz", + "integrity": "sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", + "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", + "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.4.tgz", + "integrity": "sha512-8hsyG+KUYGY0coX6KUCDancA0Vw225KJ2HJO0yCNr1vq5r+lJTleDaJf0K7iOhjw4SWhu03TMBzYTJ9krmzULQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", + "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", + "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", + "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", + "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", + "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.2.tgz", + "integrity": "sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-typescript": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", + "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", + "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", + "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz", + "integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.4.tgz", + "integrity": "sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==", + "dependencies": { + "@babel/compat-data": "^7.25.4", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.4", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", + "@babel/plugin-transform-class-properties": "^7.25.4", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.25.4", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.8", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.25.1", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.25.2", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-modules-systemjs": "^7.25.0", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.25.4", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.8", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.4", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.37.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.7.tgz", + "integrity": "sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-transform-react-display-name": "^7.24.7", + "@babel/plugin-transform-react-jsx": "^7.24.7", + "@babel/plugin-transform-react-jsx-development": "^7.24.7", + "@babel/plugin-transform-react-pure-annotations": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", + "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, + "node_modules/@babel/runtime": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.25.6.tgz", + "integrity": "sha512-Gz0Nrobx8szge6kQQ5Z5MX9L3ObqNwCQY1PSwSNzreFL7aHGxv8Fp2j3ETV6/wWdbiV+mW6OSm8oQhg3Tcsniw==", + "dependencies": { + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "dependencies": { + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@docsearch/css": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.1.tgz", + "integrity": "sha512-VtVb5DS+0hRIprU2CO6ZQjK2Zg4QU5HrDM1+ix6rT0umsYvFvatMAnf97NHZlVWDaaLlx7GRfR/7FikANiM2Fg==" + }, + "node_modules/@docsearch/react": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.1.tgz", + "integrity": "sha512-qXZkEPvybVhSXj0K7U3bXc233tk5e8PfhoZ6MhPOiik/qUQxYC+Dn9DnoS7CxHQQhHfCvTiN0eY9M12oRghEXw==", + "dependencies": { + "@algolia/autocomplete-core": "1.9.3", + "@algolia/autocomplete-preset-algolia": "1.9.3", + "@docsearch/css": "3.6.1", + "algoliasearch": "^4.19.1" + }, + "peerDependencies": { + "@types/react": ">= 16.8.0 < 19.0.0", + "react": ">= 16.8.0 < 19.0.0", + "react-dom": ">= 16.8.0 < 19.0.0", + "search-insights": ">= 1 < 3" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "search-insights": { + "optional": true + } + } + }, + "node_modules/@docusaurus/core": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.5.2.tgz", + "integrity": "sha512-4Z1WkhCSkX4KO0Fw5m/Vuc7Q3NxBG53NE5u59Rs96fWkMPZVSrzEPP16/Nk6cWb/shK7xXPndTmalJtw7twL/w==", + "dependencies": { + "@babel/core": "^7.23.3", + "@babel/generator": "^7.23.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.22.9", + "@babel/preset-env": "^7.22.9", + "@babel/preset-react": "^7.22.5", + "@babel/preset-typescript": "^7.22.5", + "@babel/runtime": "^7.22.6", + "@babel/runtime-corejs3": "^7.22.6", + "@babel/traverse": "^7.22.8", + "@docusaurus/cssnano-preset": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "autoprefixer": "^10.4.14", + "babel-loader": "^9.1.3", + "babel-plugin-dynamic-import-node": "^2.3.3", + "boxen": "^6.2.1", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "clean-css": "^5.3.2", + "cli-table3": "^0.6.3", + "combine-promises": "^1.1.0", + "commander": "^5.1.0", + "copy-webpack-plugin": "^11.0.0", + "core-js": "^3.31.1", + "css-loader": "^6.8.1", + "css-minimizer-webpack-plugin": "^5.0.1", + "cssnano": "^6.1.2", + "del": "^6.1.1", + "detect-port": "^1.5.1", + "escape-html": "^1.0.3", + "eta": "^2.2.0", + "eval": "^0.1.8", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "html-minifier-terser": "^7.2.0", + "html-tags": "^3.3.1", + "html-webpack-plugin": "^5.5.3", + "leven": "^3.1.0", + "lodash": "^4.17.21", + "mini-css-extract-plugin": "^2.7.6", + "p-map": "^4.0.0", + "postcss": "^8.4.26", + "postcss-loader": "^7.3.3", + "prompts": "^2.4.2", + "react-dev-utils": "^12.0.1", + "react-helmet-async": "^1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", + "react-loadable-ssr-addon-v5-slorber": "^1.0.1", + "react-router": "^5.3.4", + "react-router-config": "^5.1.1", + "react-router-dom": "^5.3.4", + "rtl-detect": "^1.0.4", + "semver": "^7.5.4", + "serve-handler": "^6.1.5", + "shelljs": "^0.8.5", + "terser-webpack-plugin": "^5.3.9", + "tslib": "^2.6.0", + "update-notifier": "^6.0.2", + "url-loader": "^4.1.1", + "webpack": "^5.88.1", + "webpack-bundle-analyzer": "^4.9.0", + "webpack-dev-server": "^4.15.1", + "webpack-merge": "^5.9.0", + "webpackbar": "^5.0.2" + }, + "bin": { + "docusaurus": "bin/docusaurus.mjs" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@mdx-js/react": "^3.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/cssnano-preset": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.5.2.tgz", + "integrity": "sha512-D3KiQXOMA8+O0tqORBrTOEQyQxNIfPm9jEaJoALjjSjc2M/ZAWcUfPQEnwr2JB2TadHw2gqWgpZckQmrVWkytA==", + "dependencies": { + "cssnano-preset-advanced": "^6.1.2", + "postcss": "^8.4.38", + "postcss-sort-media-queries": "^5.2.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/logger": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.5.2.tgz", + "integrity": "sha512-LHC540SGkeLfyT3RHK3gAMK6aS5TRqOD4R72BEU/DE2M/TY8WwEUAMY576UUc/oNJXv8pGhBmQB6N9p3pt8LQw==", + "dependencies": { + "chalk": "^4.1.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/mdx-loader": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.5.2.tgz", + "integrity": "sha512-ku3xO9vZdwpiMIVd8BzWV0DCqGEbCP5zs1iHfKX50vw6jX8vQo0ylYo1YJMZyz6e+JFJ17HYHT5FzVidz2IflA==", + "dependencies": { + "@docusaurus/logger": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@mdx-js/mdx": "^3.0.0", + "@slorber/remark-comment": "^1.0.0", + "escape-html": "^1.0.3", + "estree-util-value-to-estree": "^3.0.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "image-size": "^1.0.2", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "rehype-raw": "^7.0.0", + "remark-directive": "^3.0.0", + "remark-emoji": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.0", + "stringify-object": "^3.3.0", + "tslib": "^2.6.0", + "unified": "^11.0.3", + "unist-util-visit": "^5.0.0", + "url-loader": "^4.1.1", + "vfile": "^6.0.1", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/module-type-aliases": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.5.2.tgz", + "integrity": "sha512-Z+Xu3+2rvKef/YKTMxZHsEXp1y92ac0ngjDiExRdqGTmEKtCUpkbNYH8v5eXo5Ls+dnW88n6WTa+Q54kLOkwPg==", + "dependencies": { + "@docusaurus/types": "3.5.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "@types/react-router-dom": "*", + "react-helmet-async": "*", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/@docusaurus/plugin-content-blog": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.5.2.tgz", + "integrity": "sha512-R7ghWnMvjSf+aeNDH0K4fjyQnt5L0KzUEnUhmf1e3jZrv3wogeytZNN6n7X8yHcMsuZHPOrctQhXWnmxu+IRRg==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "cheerio": "1.0.0-rc.12", + "feed": "^4.2.2", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "reading-time": "^1.5.0", + "srcset": "^4.0.0", + "tslib": "^2.6.0", + "unist-util-visit": "^5.0.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-docs": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.5.2.tgz", + "integrity": "sha512-Bt+OXn/CPtVqM3Di44vHjE7rPCEsRCB/DMo2qoOuozB9f7+lsdrHvD0QCHdBs0uhz6deYJDppAr2VgqybKPlVQ==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@types/react-router-config": "^5.0.7", + "combine-promises": "^1.1.0", + "fs-extra": "^11.1.1", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-pages": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.5.2.tgz", + "integrity": "sha512-WzhHjNpoQAUz/ueO10cnundRz+VUtkjFhhaQ9jApyv1a46FPURO4cef89pyNIOMny1fjDz/NUN2z6Yi+5WUrCw==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-debug": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.5.2.tgz", + "integrity": "sha512-kBK6GlN0itCkrmHuCS6aX1wmoWc5wpd5KJlqQ1FyrF0cLDnvsYSnh7+ftdwzt7G6lGBho8lrVwkkL9/iQvaSOA==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "fs-extra": "^11.1.1", + "react-json-view-lite": "^1.2.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-analytics": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.5.2.tgz", + "integrity": "sha512-rjEkJH/tJ8OXRE9bwhV2mb/WP93V441rD6XnM6MIluu7rk8qg38iSxS43ga2V2Q/2ib53PcqbDEJDG/yWQRJhQ==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-gtag": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.5.2.tgz", + "integrity": "sha512-lm8XL3xLkTPHFKKjLjEEAHUrW0SZBSHBE1I+i/tmYMBsjCcUB5UJ52geS5PSiOCFVR74tbPGcPHEV/gaaxFeSA==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@types/gtag.js": "^0.0.12", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-tag-manager": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.5.2.tgz", + "integrity": "sha512-QkpX68PMOMu10Mvgvr5CfZAzZQFx8WLlOiUQ/Qmmcl6mjGK6H21WLT5x7xDmcpCoKA/3CegsqIqBR+nA137lQg==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-sitemap": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.5.2.tgz", + "integrity": "sha512-DnlqYyRAdQ4NHY28TfHuVk414ft2uruP4QWCH//jzpHjqvKyXjj2fmDtI8RPUBh9K8iZKFMHRnLtzJKySPWvFA==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "fs-extra": "^11.1.1", + "sitemap": "^7.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/preset-classic": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.5.2.tgz", + "integrity": "sha512-3ihfXQ95aOHiLB5uCu+9PRy2gZCeSZoDcqpnDvf3B+sTrMvMTr8qRUzBvWkoIqc82yG5prCboRjk1SVILKx6sg==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/plugin-content-blog": "3.5.2", + "@docusaurus/plugin-content-docs": "3.5.2", + "@docusaurus/plugin-content-pages": "3.5.2", + "@docusaurus/plugin-debug": "3.5.2", + "@docusaurus/plugin-google-analytics": "3.5.2", + "@docusaurus/plugin-google-gtag": "3.5.2", + "@docusaurus/plugin-google-tag-manager": "3.5.2", + "@docusaurus/plugin-sitemap": "3.5.2", + "@docusaurus/theme-classic": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/theme-search-algolia": "3.5.2", + "@docusaurus/types": "3.5.2" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-classic": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.5.2.tgz", + "integrity": "sha512-XRpinSix3NBv95Rk7xeMF9k4safMkwnpSgThn0UNQNumKvmcIYjfkwfh2BhwYh/BxMXQHJ/PdmNh22TQFpIaYg==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/plugin-content-blog": "3.5.2", + "@docusaurus/plugin-content-docs": "3.5.2", + "@docusaurus/plugin-content-pages": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/theme-translations": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "copy-text-to-clipboard": "^3.2.0", + "infima": "0.2.0-alpha.44", + "lodash": "^4.17.21", + "nprogress": "^0.2.0", + "postcss": "^8.4.26", + "prism-react-renderer": "^2.3.0", + "prismjs": "^1.29.0", + "react-router-dom": "^5.3.4", + "rtlcss": "^4.1.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-common": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.5.2.tgz", + "integrity": "sha512-QXqlm9S6x9Ibwjs7I2yEDgsCocp708DrCrgHgKwg2n2AY0YQ6IjU0gAK35lHRLOvAoJUfCKpQAwUykB0R7+Eew==", + "dependencies": { + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "clsx": "^2.0.0", + "parse-numeric-range": "^1.3.0", + "prism-react-renderer": "^2.3.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-search-algolia": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.5.2.tgz", + "integrity": "sha512-qW53kp3VzMnEqZGjakaV90sst3iN1o32PH+nawv1uepROO8aEGxptcq2R5rsv7aBShSRbZwIobdvSYKsZ5pqvA==", + "dependencies": { + "@docsearch/react": "^3.5.2", + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/plugin-content-docs": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/theme-translations": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "algoliasearch": "^4.18.0", + "algoliasearch-helper": "^3.13.3", + "clsx": "^2.0.0", + "eta": "^2.2.0", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-translations": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.5.2.tgz", + "integrity": "sha512-GPZLcu4aT1EmqSTmbdpVrDENGR2yObFEX8ssEFYTCiAIVc0EihNSdOIBTazUvgNqwvnoU1A8vIs1xyzc3LITTw==", + "dependencies": { + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/types": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.5.2.tgz", + "integrity": "sha512-N6GntLXoLVUwkZw7zCxwy9QiuEXIcTVzA9AkmNw16oc0AP3SXLrMmDMMBIfgqwuKWa6Ox6epHol9kMtJqekACw==", + "dependencies": { + "@mdx-js/mdx": "^3.0.0", + "@types/history": "^4.7.11", + "@types/react": "*", + "commander": "^5.1.0", + "joi": "^17.9.2", + "react-helmet-async": "^1.3.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1", + "webpack-merge": "^5.9.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/utils": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.5.2.tgz", + "integrity": "sha512-33QvcNFh+Gv+C2dP9Y9xWEzMgf3JzrpL2nW9PopidiohS1nDcyknKRx2DWaFvyVTTYIkkABVSr073VTj/NITNA==", + "dependencies": { + "@docusaurus/logger": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@svgr/webpack": "^8.1.0", + "escape-string-regexp": "^4.0.0", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "github-slugger": "^1.5.0", + "globby": "^11.1.0", + "gray-matter": "^4.0.3", + "jiti": "^1.20.0", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "micromatch": "^4.0.5", + "prompts": "^2.4.2", + "resolve-pathname": "^3.0.0", + "shelljs": "^0.8.5", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/types": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/types": { + "optional": true + } + } + }, + "node_modules/@docusaurus/utils-common": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.5.2.tgz", + "integrity": "sha512-i0AZjHiRgJU6d7faQngIhuHKNrszpL/SHQPgF1zH4H+Ij6E9NBYGy6pkcGWToIv7IVPbs+pQLh1P3whn0gWXVg==", + "dependencies": { + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/types": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/types": { + "optional": true + } + } + }, + "node_modules/@docusaurus/utils-validation": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.5.2.tgz", + "integrity": "sha512-m+Foq7augzXqB6HufdS139PFxDC5d5q2QKZy8q0qYYvGdI6nnlNsGH4cIGsgBnV7smz+mopl3g4asbSDvMV0jA==", + "dependencies": { + "@docusaurus/logger": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "fs-extra": "^11.2.0", + "joi": "^17.9.2", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" + }, + "node_modules/@mdx-js/mdx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.1.tgz", + "integrity": "sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-to-js": "^2.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-estree": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "periscopic": "^3.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/react": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.0.1.tgz", + "integrity": "sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", + "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==" + }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@slorber/remark-comment": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", + "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.1.0", + "micromark-util-symbol": "^1.0.1" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", + "dependencies": { + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/webpack": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", + "dependencies": { + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "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==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/acorn": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", + "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/gtag.js": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", + "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "node_modules/@types/node": { + "version": "22.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.6.0.tgz", + "integrity": "sha512-QyR8d5bmq+eR72TwQDfujwShHMcIrWIYsaQFtXRE58MHPTEKUNxjxvl0yS0qPMds5xbSDWtp7ZpvGFtd7dfMdQ==", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/prismjs": { + "version": "1.26.4", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.4.tgz", + "integrity": "sha512-rlAnzkW2sZOjbqZ743IHUhFcvzaGbqijwOu8QZnZCjfQzBqFE3s4lOTJEsxikImav9uzz/42I+O7YUs1mWgMlg==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.13", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", + "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==" + }, + "node_modules/@types/qs": { + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", + "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/react": { + "version": "18.3.8", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.8.tgz", + "integrity": "sha512-syBUrW3/XpnW4WJ41Pft+I+aPoDVbrBVQGEnbD7NijDGlVC+8gV/XKRY+7vMDlfPpbwYt0l1vd/Sj8bJGMbs9Q==", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-router": { + "version": "5.1.20", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", + "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*" + } + }, + "node_modules/@types/react-router-config": { + "version": "5.0.11", + "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", + "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "^5.1.0" + } + }, + "node_modules/@types/react-router-dom": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" + }, + "node_modules/@types/ws": { + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/algoliasearch": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", + "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-account": "4.24.0", + "@algolia/client-analytics": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-personalization": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/recommend": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/algoliasearch-helper": { + "version": "3.22.5", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.22.5.tgz", + "integrity": "sha512-lWvhdnc+aKOKx8jyA3bsdEgHzm/sglC4cYdMG4xSQyRiPLJVJtH/IVYZG3Hp6PkTEhQqhyVYkeP9z2IlcHJsWw==", + "dependencies": { + "@algolia/events": "^4.0.1" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 6" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/requester-browser-xhr": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/requester-node-http": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "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==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/bonjour-service": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "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==" + }, + "node_modules/boxen": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", + "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^6.2.0", + "chalk": "^4.1.2", + "cli-boxes": "^3.0.0", + "string-width": "^5.0.1", + "type-fest": "^2.5.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" + }, + "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==" + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001663", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz", + "integrity": "sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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==", + "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==" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + }, + "node_modules/combine-promises": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", + "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compressible/node_modules/mime-db": { + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", + "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/configstore": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", + "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", + "dependencies": { + "dot-prop": "^6.0.1", + "graceful-fs": "^4.2.6", + "unique-string": "^3.0.0", + "write-file-atomic": "^3.0.3", + "xdg-basedir": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/yeoman/configstore?sponsor=1" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" + }, + "node_modules/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/copy-text-to-clipboard": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", + "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", + "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "dependencies": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-js": { + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz", + "integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", + "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==", + "dependencies": { + "browserslist": "^4.23.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.38.1.tgz", + "integrity": "sha512-BY8Etc1FZqdw1glX0XNOq2FDwfrg/VGqoZOZCdaL+UmdaqDwQwYXkMJT4t6In+zfEfOJDcM9T0KdbBeJg8KKCQ==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "dependencies": { + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/css-declaration-sorter": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", + "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-loader": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", + "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "cssnano": "^6.0.1", + "jest-worker": "^29.4.3", + "postcss": "^8.4.24", + "schema-utils": "^4.0.1", + "serialize-javascript": "^6.0.1" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "lightningcss": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.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==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", + "dependencies": { + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-advanced": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", + "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", + "dependencies": { + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.0", + "cssnano-preset-default": "^6.1.2", + "postcss-discard-unused": "^6.0.5", + "postcss-merge-idents": "^6.0.3", + "postcss-reduce-idents": "^6.0.3", + "postcss-zindex": "^6.0.2" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-default": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", + "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", + "dependencies": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^4.0.2", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.1.0", + "postcss-convert-values": "^6.1.0", + "postcss-discard-comments": "^6.0.2", + "postcss-discard-duplicates": "^6.0.3", + "postcss-discard-empty": "^6.0.3", + "postcss-discard-overridden": "^6.0.2", + "postcss-merge-longhand": "^6.0.5", + "postcss-merge-rules": "^6.1.1", + "postcss-minify-font-values": "^6.1.0", + "postcss-minify-gradients": "^6.0.3", + "postcss-minify-params": "^6.1.0", + "postcss-minify-selectors": "^6.0.4", + "postcss-normalize-charset": "^6.0.2", + "postcss-normalize-display-values": "^6.0.2", + "postcss-normalize-positions": "^6.0.2", + "postcss-normalize-repeat-style": "^6.0.2", + "postcss-normalize-string": "^6.0.2", + "postcss-normalize-timing-functions": "^6.0.2", + "postcss-normalize-unicode": "^6.1.0", + "postcss-normalize-url": "^6.0.2", + "postcss-normalize-whitespace": "^6.0.2", + "postcss-ordered-values": "^6.0.2", + "postcss-reduce-initial": "^6.1.0", + "postcss-reduce-transforms": "^6.0.2", + "postcss-svgo": "^6.0.3", + "postcss-unique-selectors": "^6.0.4" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-utils": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "dependencies": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "node_modules/detect-port": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.6.1.tgz", + "integrity": "sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==", + "dependencies": { + "address": "^1.0.1", + "debug": "4" + }, + "bin": { + "detect": "bin/detect-port.js", + "detect-port": "bin/detect-port.js" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "dependencies": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port-alt/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/detect-port-alt/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?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==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dot-prop/node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.27", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.27.tgz", + "integrity": "sha512-o37j1vZqCoEgBuWWXLHQgTN/KDKe7zwpiY5CPeq2RvUqOyJw9xnrULzZAEVQ5p4h+zjMk7hgtOoPdnLxr7m/jw==" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/emoticon": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.1.0.tgz", + "integrity": "sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "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==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", + "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-value-to-estree": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.1.2.tgz", + "integrity": "sha512-S0gW2+XZkmsx00tU2uJ4L9hUT7IFabbml9pHh2WQqFmAbxit++YGZne0sKJbNwkj9Wvg9E4uqWl4nCIFQMmfag==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eta": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", + "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "url": "https://github.com/eta-dev/eta?sponsor=1" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eval": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", + "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", + "dependencies": { + "@types/node": "*", + "require-like": ">= 0.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", + "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.10", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/express/node_modules/path-to-regexp": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" + }, + "node_modules/express/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==" + }, + "node_modules/fast-url-parser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", + "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", + "dependencies": { + "punycode": "^1.3.2" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/feed": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", + "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", + "dependencies": { + "xml-js": "^1.6.11" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/file-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/file-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/file-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/filesize": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=10", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "eslint": ">= 6", + "typescript": ">= 2.7", + "vue-template-compiler": "*", + "webpack": ">= 4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dependencies": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", + "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-dirs/node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-yarn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", + "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", + "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^8.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.4.tgz", + "integrity": "sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", + "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", + "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/inline-style-parser": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", + "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==" + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/style-to-object": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", + "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==", + "dependencies": { + "inline-style-parser": "0.2.4" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", + "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "node_modules/html-minifier-terser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", + "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.15.1" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "engines": { + "node": ">=14" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", + "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/html-webpack-plugin/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", + "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", + "dependencies": { + "queue": "6.0.2" + }, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "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==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/infima": { + "version": "0.2.0-alpha.44", + "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.44.tgz", + "integrity": "sha512-tuRkUSO/lB3rEhLJk25atwAjgLuzq070+pOW8XcvpHky/YbENnRRdPd85IBkyeTgttmOy5ah+yHYsK1HhUd4lQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-npm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", + "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-yarn-global": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", + "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/joi": { + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "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==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "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==" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/latest-version": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", + "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", + "dependencies": { + "package-json": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/launch-editor": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "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==" + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", + "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", + "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", + "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", + "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/mdast-util-frontmatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", + "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", + "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.3.tgz", + "integrity": "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", + "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", + "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-directive": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", + "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-frontmatter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", + "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", + "dependencies": { + "fault": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", + "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", + "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.1.tgz", + "integrity": "sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg==", + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-label": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.2.tgz", + "integrity": "sha512-5E5I2pFzJyg2CtemqAbcyCktpHXuJbABnsb32wX2U8IQKhhVFBqkcZR5LRm1WVoFqa4kTueZK4abep7wdo9nrw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-space/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-title": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", + "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", + "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", + "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", + "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", + "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "dependencies": { + "mime-db": "~1.33.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.1.tgz", + "integrity": "sha512-+Vyi+GCCOHnrJ2VPS+6aPoXN2k2jgUzDRhTFLjjTBn23qyXJXkjUWQgTL+mXpF5/A8ixLdCc6kWsoeOjKGejKQ==", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-emoji": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", + "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" + }, + "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==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", + "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", + "dependencies": { + "got": "^12.1.0", + "registry-auth-token": "^5.0.1", + "registry-url": "^6.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "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==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", + "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + }, + "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==", + "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/parse-numeric-range": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", + "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "dependencies": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-to-regexp": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", + "dependencies": { + "isarray": "0.0.1" + } + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-calc": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-colormin": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", + "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-convert-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", + "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-comments": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", + "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", + "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-empty": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", + "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", + "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-unused": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", + "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-loader": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", + "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", + "dependencies": { + "cosmiconfig": "^8.3.5", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-merge-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", + "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", + "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^6.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-rules": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", + "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^4.0.2", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", + "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", + "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", + "dependencies": { + "colord": "^2.9.3", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-params": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", + "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", + "dependencies": { + "browserslist": "^4.23.0", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", + "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", + "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", + "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", + "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", + "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-string": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", + "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", + "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", + "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-url": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", + "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", + "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-ordered-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", + "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", + "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", + "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", + "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-sort-media-queries": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", + "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", + "dependencies": { + "sort-css-media-queries": "2.2.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.4.23" + } + }, + "node_modules/postcss-svgo": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", + "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^3.2.0" + }, + "engines": { + "node": "^14 || ^16 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", + "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "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==" + }, + "node_modules/postcss-zindex": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", + "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/prism-react-renderer": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.0.tgz", + "integrity": "sha512-327BsVCD/unU4CNLZTWVHyUHKnsqcvj2qbPlQ8MiBE2eq2rgctjigPA1Gp9HLF83kZ20zNN6jgizHJeEsyFYOw==", + "dependencies": { + "@types/prismjs": "^1.26.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.0.0" + } + }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + }, + "node_modules/pupa": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", + "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", + "dependencies": { + "escape-goat": "^4.0.0" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "dependencies": { + "inherits": "~2.0.3" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "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/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dev-utils": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-dev-utils/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/react-dev-utils/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-error-overlay": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" + }, + "node_modules/react-helmet-async": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", + "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-json-view-lite": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.5.0.tgz", + "integrity": "sha512-nWqA1E4jKPklL2jvHWs6s+7Na0qNgw9HCP6xehdQJeg6nPBTFZgGwyko9Q0oj+jQWKTTVRS30u0toM5wiuL3iw==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-loadable": { + "name": "@docusaurus/react-loadable", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", + "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", + "dependencies": { + "@types/react": "*" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-loadable-ssr-addon-v5-slorber": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", + "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", + "dependencies": { + "@babel/runtime": "^7.10.3" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "react-loadable": "*", + "webpack": ">=4.41.1 || 5.x" + } + }, + "node_modules/react-router": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", + "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-config": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", + "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", + "dependencies": { + "@babel/runtime": "^7.1.2" + }, + "peerDependencies": { + "react": ">=15", + "react-router": ">=5" + } + }, + "node_modules/react-router-dom": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", + "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.3.4", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reading-time": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", + "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/registry-auth-token": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/registry-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", + "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", + "dependencies": { + "rc": "1.2.8" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remark-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", + "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-emoji": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", + "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", + "dependencies": { + "@types/mdast": "^4.0.2", + "emoticon": "^4.0.1", + "mdast-util-find-and-replace": "^3.0.1", + "node-emoji": "^2.1.0", + "unified": "^11.0.4" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/remark-frontmatter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", + "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-frontmatter": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", + "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.1.tgz", + "integrity": "sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.1.tgz", + "integrity": "sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/renderkid/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==", + "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/renderkid/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==", + "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/renderkid/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "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/renderkid/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-like": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", + "engines": { + "node": "*" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + }, + "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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rtl-detect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", + "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==" + }, + "node_modules/rtlcss": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", + "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0", + "postcss": "^8.4.21", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "rtlcss": "bin/rtlcss.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "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==", + "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/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/search-insights": { + "version": "2.17.2", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.2.tgz", + "integrity": "sha512-zFNpOpUO+tY2D85KrxJ+aqwnIfdEGi06UH2+xEb+Bp9Mwznmauqc9djbnBibJO5mpfUPPa8st6Sx65+vbeO45g==", + "peer": true + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-handler": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", + "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", + "dependencies": { + "bytes": "3.0.0", + "content-disposition": "0.5.2", + "fast-url-parser": "1.1.3", + "mime-types": "2.1.18", + "minimatch": "3.1.2", + "path-is-inside": "1.0.2", + "path-to-regexp": "2.2.1", + "range-parser": "1.2.0" + } + }, + "node_modules/serve-handler/node_modules/path-to-regexp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", + "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==" + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/sitemap": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", + "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.6.0" + } + }, + "node_modules/sitemap/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sort-css-media-queries": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", + "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", + "engines": { + "node": ">= 6.3.0" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "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==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/srcset": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", + "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-to-object": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, + "node_modules/stylehacks": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", + "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "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==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + }, + "node_modules/svgo": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/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==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.33.0.tgz", + "integrity": "sha512-JuPVaB7s1gdFKPKTelwUyRq5Sid2A3Gko2S0PncwdBq7kN9Ti9HPWDQ06MPsEDGsZeVESjKEnyGy68quBk1w6g==", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "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==" + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/update-notifier": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", + "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", + "dependencies": { + "boxen": "^7.0.0", + "chalk": "^5.0.1", + "configstore": "^6.0.0", + "has-yarn": "^3.0.0", + "import-lazy": "^4.0.0", + "is-ci": "^3.0.1", + "is-installed-globally": "^0.4.0", + "is-npm": "^6.0.0", + "is-yarn-global": "^0.4.0", + "latest-version": "^7.0.0", + "pupa": "^3.1.0", + "semver": "^7.3.7", + "semver-diff": "^4.0.0", + "xdg-basedir": "^5.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/boxen": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", + "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.1", + "chalk": "^5.2.0", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/url-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "dependencies": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, + "node_modules/url-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/url-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/url-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/url-loader/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/url-loader/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/url-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" + }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/webpack": { + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", + "dependencies": { + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", + "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", + "dependencies": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/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==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", + "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.4", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/webpack/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpackbar": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.2.tgz", + "integrity": "sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==", + "dependencies": { + "chalk": "^4.1.0", + "consola": "^2.15.3", + "pretty-time": "^1.1.0", + "std-env": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "webpack": "3 || 4 || 5" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xdg-basedir": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/userland/qjs/source/docs/package.json b/userland/qjs/source/docs/package.json new file mode 100644 index 0000000..4acf04c --- /dev/null +++ b/userland/qjs/source/docs/package.json @@ -0,0 +1,42 @@ +{ + "private": true, + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids" + }, + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/preset-classic": "3.5.2", + "@mdx-js/react": "3.0.1", + "clsx": "2.1.1", + "prism-react-renderer": "2.4.0", + "react": "18.3.1", + "react-dom": "18.3.1" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/types": "3.5.2" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome version", + "last 3 firefox version", + "last 5 safari version" + ] + }, + "engines": { + "node": ">=18.0" + } +} diff --git a/userland/qjs/source/docs/sidebars.js b/userland/qjs/source/docs/sidebars.js new file mode 100644 index 0000000..3efb4ff --- /dev/null +++ b/userland/qjs/source/docs/sidebars.js @@ -0,0 +1,20 @@ +/** + * Creating a sidebar enables you to: + - create an ordered group of docs + - render a sidebar for each doc of that group + - provide next/previous navigation + + The sidebars can be generated from the filesystem, or explicitly defined here. + + Create as many sidebars as you want. + */ + +// @ts-check + +/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +const sidebars = { + // By default, Docusaurus generates a sidebar from the docs folder structure + docsSidebar: [{type: 'autogenerated', dirName: '.'}], +}; + +export default sidebars; diff --git a/userland/qjs/source/docs/src/css/custom.css b/userland/qjs/source/docs/src/css/custom.css new file mode 100644 index 0000000..2bc6a4c --- /dev/null +++ b/userland/qjs/source/docs/src/css/custom.css @@ -0,0 +1,30 @@ +/** + * Any CSS included here will be global. The classic template + * bundles Infima by default. Infima is a CSS framework designed to + * work well for content-centric websites. + */ + +/* You can override the default Infima variables here. */ +:root { + --ifm-color-primary: #2e8555; + --ifm-color-primary-dark: #29784c; + --ifm-color-primary-darker: #277148; + --ifm-color-primary-darkest: #205d3b; + --ifm-color-primary-light: #33925d; + --ifm-color-primary-lighter: #359962; + --ifm-color-primary-lightest: #3cad6e; + --ifm-code-font-size: 95%; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); +} + +/* For readability concerns, you should choose a lighter palette in dark mode. */ +[data-theme='dark'] { + --ifm-color-primary: #25c2a0; + --ifm-color-primary-dark: #21af90; + --ifm-color-primary-darker: #1fa588; + --ifm-color-primary-darkest: #1a8870; + --ifm-color-primary-light: #29d5b0; + --ifm-color-primary-lighter: #32d8b4; + --ifm-color-primary-lightest: #4fddbf; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); +} diff --git a/userland/qjs/source/docs/static/.nojekyll b/userland/qjs/source/docs/static/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/userland/qjs/source/docs/static/img/favicon.ico b/userland/qjs/source/docs/static/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c01d54bcd39a5f853428f3cd5aa0f383d963c484 GIT binary patch literal 3626 zcmZQzU}RuqP>=@E3JfBA3=Con3=A3!3=9ek3=C!r5OD?u28IS+1_mK+2nO*%IR1>C zVEh@o?)Woy@8Zwc{U-}waQL5a&G~=A4VVA%w*&u2yqfbr@bB0E0ssFa;lKZbzu*2J z{kZyT!VTvo2{&A15^lIKK<)lbmc1bNp0kJB4YEJshV%b~o9_R^->yQk8{v+ipO5~> z-b?zQaNTiE!VMR;_%n9zp?3d^KVt{NB!xl3B}cHoA$Ge!*-roC?nL|#d9(e$*Q;0m zJzu>7(|$jHg54DPY9`43PYE|%K;ix;{*2v$_%n9f;?LNT91aPWvDxqPKjEg!|F9cX z|LqPR{BL{k;D6i0hyQ!Oe-E}l{OyYW2{)WTZhaVk#;z*+-plK3-rKS{R# zjP3t~s}4~AIR8($4)T}l|ELEQ|Gn=Y{qJ(~)_<3qH~+iby7k}pDtO$a{0zo7Z~k|^eH-roz~67DG5r6}kZ{!*WG@V7#GkSIMymf|_Ithm^xy8( zx&L-2&iuDOdFsFY$&)D9;q+;E{0IK|)*tp|Cqu$D6#J9n&)9t-)&9tb{r^Kgo%tX5 z;=q6JYpehJ-{0`x{^&k%dIzO>7`8il6rTP=zFyp#c+JKGn*U+`FONTC_lq?9?f%D~ zb^ITH&iQ}*C71uPmmL4cUUvEKe{IHpms__X=?;|k(853b?TUX1*PUJ`+;9m;N`JBO zXY4+cY(Jfo)A4`srHcQSTekeS*t7|bEw^p^@Ac*lIIV!wKP3Nm zBH5oGf5z?y$@ZUh`X75KSAdjkIb`;UU5^+EW%HQy4hJ6=w> z;o^W~e_s3JnI0n7e*(Np8r60 z+y2iy@AbdzO4R@As|o*`Z)E=OzFqWx;+?AhGw-+jU-D$a|J6@t{@?t3@&A2qHvB*K zZs-5wZ+Ca!`g|E?FO1HNC$ani`Mc&?;{S_pPyT=S=I;Nme?R|!^Xb+9+xKt%|NZCJ z|DQj9{=a(V>i^H5KK}=SE0?bPzkl~Wh}rS~|9_ahFq-7@H}7s{(t)T>Hpn3cmL0wJGZ01uODP5GA@PHzi}sR z|NE~r{vUhX=6}LjyZ=EOO#g@Pw)`J|7Sj#MXPy7|+$#CM;>pzin_evZzw6cN{|8@h z`G5NT{{NRgo&10E^Tq!UzTN!)^xK2~Z+^b`|Ka!B|8Kv&?)>xr7qZR^RfAkTX|H?k%|J|nR{ZBZL2ovOT0+jASX&pp^(l|&i@vOuDiTPiBHGV?RtrC!($T$+-7CdYB-?mBPzqGZ`e|cw-|7t;!|0DNX zVf8=AE^IjJpw<7VL)PFpj5}rfKjyeKIRAm-EcUd`gqYLT$aaI+(J=pm%!@m1_uqfD z$$zhT2LGcDT9afqDDAk<)c@}_-{61Z1^fTOo6P<@bZUX!0x~=Pj9nS5+yx~*yFa4@B`IVXYB68pRv<{+6l5A +#include +#include +#include +#include +#include +#include +// #include +#include +// #include + +#include "cutils.h" +#include "dtoa.h" + +/* + TODO: + - simplify subnormal handling + - reduce max memory usage + - free format: could add shortcut if exact result + - use 64 bit limb_t when possible + - use another algorithm for free format dtoa in base 10 (ryu ?) +*/ + +#define USE_POW5_TABLE +/* use fast path to print small integers in free format */ +#define USE_FAST_INT + +#define LIMB_LOG2_BITS 5 + +#define LIMB_BITS (1 << LIMB_LOG2_BITS) + +typedef int32_t slimb_t; +typedef uint32_t limb_t; +typedef uint64_t dlimb_t; + +#define LIMB_DIGITS 9 + +#define JS_RADIX_MAX 36 + +#define DBIGNUM_LEN_MAX 52 /* ~ 2^(1072+53)*36^100 (dtoa) */ +#define MANT_LEN_MAX 18 /* < 36^100 */ + +typedef intptr_t mp_size_t; + +/* the represented number is sum(i, tab[i]*2^(LIMB_BITS * i)) */ +typedef struct { + int len; /* >= 1 */ + limb_t tab[]; +} mpb_t; + +static limb_t mp_add_ui(limb_t *tab, limb_t b, size_t n) +{ + size_t i; + limb_t k, a; + + k=b; + for(i=0;i> LIMB_BITS; + } + return l; +} + +/* WARNING: d must be >= 2^(LIMB_BITS-1) */ +static inline limb_t udiv1norm_init(limb_t d) +{ + limb_t a0, a1; + a1 = -d - 1; + a0 = -1; + return (((dlimb_t)a1 << LIMB_BITS) | a0) / d; +} + +/* return the quotient and the remainder in '*pr'of 'a1*2^LIMB_BITS+a0 + / d' with 0 <= a1 < d. */ +static inline limb_t udiv1norm(limb_t *pr, limb_t a1, limb_t a0, + limb_t d, limb_t d_inv) +{ + limb_t n1m, n_adj, q, r, ah; + dlimb_t a; + n1m = ((slimb_t)a0 >> (LIMB_BITS - 1)); + n_adj = a0 + (n1m & d); + a = (dlimb_t)d_inv * (a1 - n1m) + n_adj; + q = (a >> LIMB_BITS) + a1; + /* compute a - q * r and update q so that the remainder is between + 0 and d - 1 */ + a = ((dlimb_t)a1 << LIMB_BITS) | a0; + a = a - (dlimb_t)q * d - d; + ah = a >> LIMB_BITS; + q += 1 + ah; + r = (limb_t)a + (ah & d); + *pr = r; + return q; +} + +static limb_t mp_div1(limb_t *tabr, const limb_t *taba, limb_t n, + limb_t b, limb_t r) +{ + slimb_t i; + dlimb_t a1; + for(i = n - 1; i >= 0; i--) { + a1 = ((dlimb_t)r << LIMB_BITS) | taba[i]; + tabr[i] = a1 / b; + r = a1 % b; + } + return r; +} + +/* r = (a + high*B^n) >> shift. Return the remainder r (0 <= r < 2^shift). + 1 <= shift <= LIMB_BITS - 1 */ +static limb_t mp_shr(limb_t *tab_r, const limb_t *tab, mp_size_t n, + int shift, limb_t high) +{ + mp_size_t i; + limb_t l, a; + + assert(shift >= 1 && shift < LIMB_BITS); + l = high; + for(i = n - 1; i >= 0; i--) { + a = tab[i]; + tab_r[i] = (a >> shift) | (l << (LIMB_BITS - shift)); + l = a; + } + return l & (((limb_t)1 << shift) - 1); +} + +/* r = (a << shift) + low. 1 <= shift <= LIMB_BITS - 1, 0 <= low < + 2^shift. */ +static limb_t mp_shl(limb_t *tab_r, const limb_t *tab, mp_size_t n, + int shift, limb_t low) +{ + mp_size_t i; + limb_t l, a; + + assert(shift >= 1 && shift < LIMB_BITS); + l = low; + for(i = 0; i < n; i++) { + a = tab[i]; + tab_r[i] = (a << shift) | l; + l = (a >> (LIMB_BITS - shift)); + } + return l; +} + +static no_inline limb_t mp_div1norm(limb_t *tabr, const limb_t *taba, limb_t n, + limb_t b, limb_t r, limb_t b_inv, int shift) +{ + slimb_t i; + + if (shift != 0) { + r = (r << shift) | mp_shl(tabr, taba, n, shift, 0); + } + for(i = n - 1; i >= 0; i--) { + tabr[i] = udiv1norm(&r, r, taba[i], b, b_inv); + } + r >>= shift; + return r; +} + +static __maybe_unused void mpb_dump(const char *str, const mpb_t *a) +{ + int i; + + printf("%s= 0x", str); + for(i = a->len - 1; i >= 0; i--) { + printf("%08x", a->tab[i]); + if (i != 0) + printf("_"); + } + printf("\n"); +} + +static void mpb_renorm(mpb_t *r) +{ + while (r->len > 1 && r->tab[r->len - 1] == 0) + r->len--; +} + +#ifdef USE_POW5_TABLE +static const uint32_t pow5_table[17] = { + 0x00000005, 0x00000019, 0x0000007d, 0x00000271, + 0x00000c35, 0x00003d09, 0x0001312d, 0x0005f5e1, + 0x001dcd65, 0x009502f9, 0x02e90edd, 0x0e8d4a51, + 0x48c27395, 0x6bcc41e9, 0x1afd498d, 0x86f26fc1, + 0xa2bc2ec5, +}; + +static const uint8_t pow5h_table[4] = { + 0x00000001, 0x00000007, 0x00000023, 0x000000b1, +}; + +static const uint32_t pow5_inv_table[13] = { + 0x99999999, 0x47ae147a, 0x0624dd2f, 0xa36e2eb1, + 0x4f8b588e, 0x0c6f7a0b, 0xad7f29ab, 0x5798ee23, + 0x12e0be82, 0xb7cdfd9d, 0x5fd7fe17, 0x19799812, + 0xc25c2684, +}; +#endif + +/* return a^b */ +static uint64_t pow_ui(uint32_t a, uint32_t b) +{ + int i, n_bits; + uint64_t r; + if (b == 0) + return 1; + if (b == 1) + return a; +#ifdef USE_POW5_TABLE + if ((a == 5 || a == 10) && b <= 17) { + r = pow5_table[b - 1]; + if (b >= 14) { + r |= (uint64_t)pow5h_table[b - 14] << 32; + } + if (a == 10) + r <<= b; + return r; + } +#endif + r = a; + n_bits = 32 - clz32(b); + for(i = n_bits - 2; i >= 0; i--) { + r *= r; + if ((b >> i) & 1) + r *= a; + } + return r; +} + +static uint32_t pow_ui_inv(uint32_t *pr_inv, int *pshift, uint32_t a, uint32_t b) +{ + uint32_t r_inv, r; + int shift; +#ifdef USE_POW5_TABLE + if (a == 5 && b >= 1 && b <= 13) { + r = pow5_table[b - 1]; + shift = clz32(r); + r <<= shift; + r_inv = pow5_inv_table[b - 1]; + } else +#endif + { + r = pow_ui(a, b); + shift = clz32(r); + r <<= shift; + r_inv = udiv1norm_init(r); + } + *pshift = shift; + *pr_inv = r_inv; + return r; +} + +enum { + JS_RNDN, /* round to nearest, ties to even */ + JS_RNDNA, /* round to nearest, ties away from zero */ + JS_RNDZ, +}; + +static int mpb_get_bit(const mpb_t *r, int k) +{ + int l; + + l = (unsigned)k / LIMB_BITS; + k = k & (LIMB_BITS - 1); + if (l >= r->len) + return 0; + else + return (r->tab[l] >> k) & 1; +} + +/* compute round(r / 2^shift). 'shift' can be negative */ +static void mpb_shr_round(mpb_t *r, int shift, int rnd_mode) +{ + int l, i; + + if (shift == 0) + return; + if (shift < 0) { + shift = -shift; + l = (unsigned)shift / LIMB_BITS; + shift = shift & (LIMB_BITS - 1); + if (shift != 0) { + r->tab[r->len] = mp_shl(r->tab, r->tab, r->len, shift, 0); + r->len++; + mpb_renorm(r); + } + if (l > 0) { + for(i = r->len - 1; i >= 0; i--) + r->tab[i + l] = r->tab[i]; + for(i = 0; i < l; i++) + r->tab[i] = 0; + r->len += l; + } + } else { + limb_t bit1, bit2; + int k, add_one; + + switch(rnd_mode) { + default: + case JS_RNDZ: + add_one = 0; + break; + case JS_RNDN: + case JS_RNDNA: + bit1 = mpb_get_bit(r, shift - 1); + if (bit1) { + if (rnd_mode == JS_RNDNA) { + bit2 = 1; + } else { + /* bit2 = oring of all the bits after bit1 */ + bit2 = 0; + if (shift >= 2) { + k = shift - 1; + l = (unsigned)k / LIMB_BITS; + k = k & (LIMB_BITS - 1); + for(i = 0; i < min_int(l, r->len); i++) + bit2 |= r->tab[i]; + if (l < r->len) + bit2 |= r->tab[l] & (((limb_t)1 << k) - 1); + } + } + if (bit2) { + add_one = 1; + } else { + /* round to even */ + add_one = mpb_get_bit(r, shift); + } + } else { + add_one = 0; + } + break; + } + + l = (unsigned)shift / LIMB_BITS; + shift = shift & (LIMB_BITS - 1); + if (l >= r->len) { + r->len = 1; + r->tab[0] = add_one; + } else { + if (l > 0) { + r->len -= l; + for(i = 0; i < r->len; i++) + r->tab[i] = r->tab[i + l]; + } + if (shift != 0) { + mp_shr(r->tab, r->tab, r->len, shift, 0); + mpb_renorm(r); + } + if (add_one) { + limb_t a; + a = mp_add_ui(r->tab, 1, r->len); + if (a) + r->tab[r->len++] = a; + } + } + } +} + +/* return -1, 0 or 1 */ +static int mpb_cmp(const mpb_t *a, const mpb_t *b) +{ + mp_size_t i; + if (a->len < b->len) + return -1; + else if (a->len > b->len) + return 1; + for(i = a->len - 1; i >= 0; i--) { + if (a->tab[i] != b->tab[i]) { + if (a->tab[i] < b->tab[i]) + return -1; + else + return 1; + } + } + return 0; +} + +static void mpb_set_u64(mpb_t *r, uint64_t m) +{ +#if LIMB_BITS == 64 + r->tab[0] = m; + r->len = 1; +#else + r->tab[0] = m; + r->tab[1] = m >> LIMB_BITS; + if (r->tab[1] == 0) + r->len = 1; + else + r->len = 2; +#endif +} + +static uint64_t mpb_get_u64(mpb_t *r) +{ +#if LIMB_BITS == 64 + return r->tab[0]; +#else + if (r->len == 1) { + return r->tab[0]; + } else { + return r->tab[0] | ((uint64_t)r->tab[1] << LIMB_BITS); + } +#endif +} + +/* floor_log2() = position of the first non zero bit or -1 if zero. */ +static int mpb_floor_log2(mpb_t *a) +{ + limb_t v; + v = a->tab[a->len - 1]; + if (v == 0) + return -1; + else + return a->len * LIMB_BITS - 1 - clz32(v); +} + +#define MUL_LOG2_RADIX_BASE_LOG2 24 + +/* round((1 << MUL_LOG2_RADIX_BASE_LOG2)/log2(i + 2)) */ +static const uint32_t mul_log2_radix_table[JS_RADIX_MAX - 1] = { + 0x000000, 0xa1849d, 0x000000, 0x6e40d2, + 0x6308c9, 0x5b3065, 0x000000, 0x50c24e, + 0x4d104d, 0x4a0027, 0x4768ce, 0x452e54, + 0x433d00, 0x418677, 0x000000, 0x3ea16b, + 0x3d645a, 0x3c43c2, 0x3b3b9a, 0x3a4899, + 0x39680b, 0x3897b3, 0x37d5af, 0x372069, + 0x367686, 0x35d6df, 0x354072, 0x34b261, + 0x342bea, 0x33ac62, 0x000000, 0x32bfd9, + 0x3251dd, 0x31e8d6, 0x318465, +}; + +/* return floor(a / log2(radix)) for -2048 <= a <= 2047 */ +static int mul_log2_radix(int a, int radix) +{ + int radix_bits, mult; + + if ((radix & (radix - 1)) == 0) { + /* if the radix is a power of two better to do it exactly */ + radix_bits = 31 - clz32(radix); + if (a < 0) + a -= radix_bits - 1; + return a / radix_bits; + } else { + mult = mul_log2_radix_table[radix - 2]; + return ((int64_t)a * mult) >> MUL_LOG2_RADIX_BASE_LOG2; + } +} + +#if 0 +static void build_mul_log2_radix_table(void) +{ + int base, radix, mult, col, base_log2; + + base_log2 = 24; + base = 1 << base_log2; + col = 0; + for(radix = 2; radix <= 36; radix++) { + if ((radix & (radix - 1)) == 0) + mult = 0; + else + mult = lrint((double)base / log2(radix)); + printf("0x%06x, ", mult); + if (++col == 4) { + printf("\n"); + col = 0; + } + } + printf("\n"); +} + +static void mul_log2_radix_test(void) +{ + int radix, i, ref, r; + + for(radix = 2; radix <= 36; radix++) { + for(i = -2048; i <= 2047; i++) { + ref = (int)floor((double)i / log2(radix)); + r = mul_log2_radix(i, radix); + if (ref != r) { + printf("ERROR: radix=%d i=%d r=%d ref=%d\n", + radix, i, r, ref); + exit(1); + } + } + } + if (0) + build_mul_log2_radix_table(); +} +#endif + +static void u32toa_len(char *buf, uint32_t n, size_t len) +{ + int digit, i; + for(i = len - 1; i >= 0; i--) { + digit = n % 10; + n = n / 10; + buf[i] = digit + '0'; + } +} + +/* for power of 2 radixes. len >= 1 */ +static void u64toa_bin_len(char *buf, uint64_t n, unsigned int radix_bits, int len) +{ + int digit, i; + unsigned int mask; + + mask = (1 << radix_bits) - 1; + for(i = len - 1; i >= 0; i--) { + digit = n & mask; + n >>= radix_bits; + if (digit < 10) + digit += '0'; + else + digit += 'a' - 10; + buf[i] = digit; + } +} + +/* len >= 1. 2 <= radix <= 36 */ +static void limb_to_a(char *buf, limb_t n, unsigned int radix, int len) +{ + int digit, i; + + if (radix == 10) { + /* specific case with constant divisor */ +#if LIMB_BITS == 32 + u32toa_len(buf, n, len); +#else + /* XXX: optimize */ + for(i = len - 1; i >= 0; i--) { + digit = (limb_t)n % 10; + n = (limb_t)n / 10; + buf[i] = digit + '0'; + } +#endif + } else { + for(i = len - 1; i >= 0; i--) { + digit = (limb_t)n % radix; + n = (limb_t)n / radix; + if (digit < 10) + digit += '0'; + else + digit += 'a' - 10; + buf[i] = digit; + } + } +} + +size_t u32toa(char *buf, uint32_t n) +{ + char buf1[10], *q; + size_t len; + + q = buf1 + sizeof(buf1); + do { + *--q = n % 10 + '0'; + n /= 10; + } while (n != 0); + len = buf1 + sizeof(buf1) - q; + memcpy(buf, q, len); + return len; +} + +size_t i32toa(char *buf, int32_t n) +{ + if (n >= 0) { + return u32toa(buf, n); + } else { + buf[0] = '-'; + return u32toa(buf + 1, -(uint32_t)n) + 1; + } +} + +#ifdef USE_FAST_INT +size_t u64toa(char *buf, uint64_t n) +{ + if (n < 0x100000000) { + return u32toa(buf, n); + } else { + uint64_t n1; + char *q = buf; + uint32_t n2; + + n1 = n / 1000000000; + n %= 1000000000; + if (n1 >= 0x100000000) { + n2 = n1 / 1000000000; + n1 = n1 % 1000000000; + /* at most two digits */ + if (n2 >= 10) { + *q++ = n2 / 10 + '0'; + n2 %= 10; + } + *q++ = n2 + '0'; + u32toa_len(q, n1, 9); + q += 9; + } else { + q += u32toa(q, n1); + } + u32toa_len(q, n, 9); + q += 9; + return q - buf; + } +} + +size_t i64toa(char *buf, int64_t n) +{ + if (n >= 0) { + return u64toa(buf, n); + } else { + buf[0] = '-'; + return u64toa(buf + 1, -(uint64_t)n) + 1; + } +} + +/* XXX: only tested for 1 <= n < 2^53 */ +size_t u64toa_radix(char *buf, uint64_t n, unsigned int radix) +{ + int radix_bits, l; + if (likely(radix == 10)) + return u64toa(buf, n); + if ((radix & (radix - 1)) == 0) { + radix_bits = 31 - clz32(radix); + if (n == 0) + l = 1; + else + l = (64 - clz64(n) + radix_bits - 1) / radix_bits; + u64toa_bin_len(buf, n, radix_bits, l); + return l; + } else { + char buf1[41], *q; /* maximum length for radix = 3 */ + size_t len; + int digit; + q = buf1 + sizeof(buf1); + do { + digit = n % radix; + n /= radix; + if (digit < 10) + digit += '0'; + else + digit += 'a' - 10; + *--q = digit; + } while (n != 0); + len = buf1 + sizeof(buf1) - q; + memcpy(buf, q, len); + return len; + } +} + +size_t i64toa_radix(char *buf, int64_t n, unsigned int radix) +{ + if (n >= 0) { + return u64toa_radix(buf, n, radix); + } else { + buf[0] = '-'; + return u64toa_radix(buf + 1, -(uint64_t)n, radix) + 1; + } +} +#endif /* USE_FAST_INT */ + +static const uint8_t digits_per_limb_table[JS_RADIX_MAX - 1] = { +#if LIMB_BITS == 32 +32,20,16,13,12,11,10,10, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +#else +64,40,32,27,24,22,21,20,19,18,17,17,16,16,16,15,15,15,14,14,14,14,13,13,13,13,13,13,13,12,12,12,12,12,12, +#endif +}; + +static const uint32_t radix_base_table[JS_RADIX_MAX - 1] = { + 0x00000000, 0xcfd41b91, 0x00000000, 0x48c27395, + 0x81bf1000, 0x75db9c97, 0x40000000, 0xcfd41b91, + 0x3b9aca00, 0x8c8b6d2b, 0x19a10000, 0x309f1021, + 0x57f6c100, 0x98c29b81, 0x00000000, 0x18754571, + 0x247dbc80, 0x3547667b, 0x4c4b4000, 0x6b5a6e1d, + 0x94ace180, 0xcaf18367, 0x0b640000, 0x0e8d4a51, + 0x1269ae40, 0x17179149, 0x1cb91000, 0x23744899, + 0x2b73a840, 0x34e63b41, 0x40000000, 0x4cfa3cc1, + 0x5c13d840, 0x6d91b519, 0x81bf1000, +}; + +/* XXX: remove the table ? */ +static uint8_t dtoa_max_digits_table[JS_RADIX_MAX - 1] = { + 54, 35, 28, 24, 22, 20, 19, 18, 17, 17, 16, 16, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, +}; + +/* we limit the maximum number of significant digits for atod to about + 128 bits of precision for non power of two bases. The only + requirement for Javascript is at least 20 digits in base 10. For + power of two bases, we do an exact rounding in all the cases. */ +static uint8_t atod_max_digits_table[JS_RADIX_MAX - 1] = { + 64, 80, 32, 55, 49, 45, 21, 40, 38, 37, 35, 34, 33, 32, 16, 31, 30, 30, 29, 29, 28, 28, 27, 27, 27, 26, 26, 26, 26, 25, 12, 25, 25, 24, 24, +}; + +/* if abs(d) >= B^max_exponent, it is an overflow */ +static const int16_t max_exponent[JS_RADIX_MAX - 1] = { + 1024, 647, 512, 442, 397, 365, 342, 324, + 309, 297, 286, 277, 269, 263, 256, 251, + 246, 242, 237, 234, 230, 227, 224, 221, + 218, 216, 214, 211, 209, 207, 205, 203, + 202, 200, 199, +}; + +/* if abs(d) <= B^min_exponent, it is an underflow */ +static const int16_t min_exponent[JS_RADIX_MAX - 1] = { +-1075, -679, -538, -463, -416, -383, -359, -340, + -324, -311, -300, -291, -283, -276, -269, -263, + -258, -254, -249, -245, -242, -238, -235, -232, + -229, -227, -224, -222, -220, -217, -215, -214, + -212, -210, -208, +}; + +#if 0 +void build_tables(void) +{ + int r, j, radix, n, col, i; + + /* radix_base_table */ + for(radix = 2; radix <= 36; radix++) { + r = 1; + for(j = 0; j < digits_per_limb_table[radix - 2]; j++) { + r *= radix; + } + printf(" 0x%08x,", r); + if ((radix % 4) == 1) + printf("\n"); + } + printf("\n"); + + /* dtoa_max_digits_table */ + for(radix = 2; radix <= 36; radix++) { + /* Note: over estimated when the radix is a power of two */ + printf(" %d,", 1 + (int)ceil(53.0 / log2(radix))); + } + printf("\n"); + + /* atod_max_digits_table */ + for(radix = 2; radix <= 36; radix++) { + if ((radix & (radix - 1)) == 0) { + /* 64 bits is more than enough */ + n = (int)floor(64.0 / log2(radix)); + } else { + n = (int)floor(128.0 / log2(radix)); + } + printf(" %d,", n); + } + printf("\n"); + + printf("static const int16_t max_exponent[JS_RADIX_MAX - 1] = {\n"); + col = 0; + for(radix = 2; radix <= 36; radix++) { + printf("%5d, ", (int)ceil(1024 / log2(radix))); + if (++col == 8) { + col = 0; + printf("\n"); + } + } + printf("\n};\n\n"); + + printf("static const int16_t min_exponent[JS_RADIX_MAX - 1] = {\n"); + col = 0; + for(radix = 2; radix <= 36; radix++) { + printf("%5d, ", (int)floor(-1075 / log2(radix))); + if (++col == 8) { + col = 0; + printf("\n"); + } + } + printf("\n};\n\n"); + + printf("static const uint32_t pow5_table[16] = {\n"); + col = 0; + for(i = 2; i <= 17; i++) { + r = 1; + for(j = 0; j < i; j++) { + r *= 5; + } + printf("0x%08x, ", r); + if (++col == 4) { + col = 0; + printf("\n"); + } + } + printf("\n};\n\n"); + + /* high part */ + printf("static const uint8_t pow5h_table[4] = {\n"); + col = 0; + for(i = 14; i <= 17; i++) { + uint64_t r1; + r1 = 1; + for(j = 0; j < i; j++) { + r1 *= 5; + } + printf("0x%08x, ", (uint32_t)(r1 >> 32)); + if (++col == 4) { + col = 0; + printf("\n"); + } + } + printf("\n};\n\n"); +} +#endif + +/* n_digits >= 1. 0 <= dot_pos <= n_digits. If dot_pos == n_digits, + the dot is not displayed. 'a' is modified. */ +static int output_digits(char *buf, + mpb_t *a, int radix, int n_digits1, + int dot_pos) +{ + int n_digits, digits_per_limb, radix_bits, n, len; + + n_digits = n_digits1; + if ((radix & (radix - 1)) == 0) { + /* radix = 2^radix_bits */ + radix_bits = 31 - clz32(radix); + } else { + radix_bits = 0; + } + digits_per_limb = digits_per_limb_table[radix - 2]; + if (radix_bits != 0) { + for(;;) { + n = min_int(n_digits, digits_per_limb); + n_digits -= n; + u64toa_bin_len(buf + n_digits, a->tab[0], radix_bits, n); + if (n_digits == 0) + break; + mpb_shr_round(a, digits_per_limb * radix_bits, JS_RNDZ); + } + } else { + limb_t r; + while (n_digits != 0) { + n = min_int(n_digits, digits_per_limb); + n_digits -= n; + r = mp_div1(a->tab, a->tab, a->len, radix_base_table[radix - 2], 0); + mpb_renorm(a); + limb_to_a(buf + n_digits, r, radix, n); + } + } + + /* add the dot */ + len = n_digits1; + if (dot_pos != n_digits1) { + memmove(buf + dot_pos + 1, buf + dot_pos, n_digits1 - dot_pos); + buf[dot_pos] = '.'; + len++; + } + return len; +} + +/* return (a, e_offset) such that a = a * (radix1*2^radix_shift)^f * + 2^-e_offset. 'f' can be negative. */ +static int mul_pow(mpb_t *a, int radix1, int radix_shift, int f, bool is_int, int e) +{ + int e_offset, d, n, n0; + + e_offset = -f * radix_shift; + if (radix1 != 1) { + d = digits_per_limb_table[radix1 - 2]; + if (f >= 0) { + limb_t h, b; + + b = 0; + n0 = 0; + while (f != 0) { + n = min_int(f, d); + if (n != n0) { + b = pow_ui(radix1, n); + n0 = n; + } + h = mp_mul1(a->tab, a->tab, a->len, b, 0); + if (h != 0) { + a->tab[a->len++] = h; + } + f -= n; + } + } else { + int extra_bits, l, shift; + limb_t r, rem, b, b_inv; + + f = -f; + l = (f + d - 1) / d; /* high bound for the number of limbs (XXX: make it better) */ + e_offset += l * LIMB_BITS; + if (!is_int) { + /* at least 'e' bits are needed in the final result for rounding */ + extra_bits = max_int(e - mpb_floor_log2(a), 0); + } else { + /* at least two extra bits are needed in the final result + for rounding */ + extra_bits = max_int(2 + e - e_offset, 0); + } + e_offset += extra_bits; + mpb_shr_round(a, -(l * LIMB_BITS + extra_bits), JS_RNDZ); + + b = 0; + b_inv = 0; + shift = 0; + n0 = 0; + rem = 0; + while (f != 0) { + n = min_int(f, d); + if (n != n0) { + b = pow_ui_inv(&b_inv, &shift, radix1, n); + n0 = n; + } + r = mp_div1norm(a->tab, a->tab, a->len, b, 0, b_inv, shift); + rem |= r; + mpb_renorm(a); + f -= n; + } + /* if the remainder is non zero, use it for rounding */ + a->tab[0] |= (rem != 0); + } + } + return e_offset; +} + +/* tmp1 = round(m*2^e*radix^f). 'tmp0' is a temporary storage */ +static void mul_pow_round(mpb_t *tmp1, uint64_t m, int e, int radix1, int radix_shift, int f, + int rnd_mode) +{ + int e_offset; + + mpb_set_u64(tmp1, m); + e_offset = mul_pow(tmp1, radix1, radix_shift, f, true, e); + mpb_shr_round(tmp1, -e + e_offset, rnd_mode); +} + +/* return round(a*2^e_offset) rounded as a float64. 'a' is modified */ +static uint64_t round_to_d(int *pe, mpb_t *a, int e_offset, int rnd_mode) +{ + int e; + uint64_t m; + + if (a->tab[0] == 0 && a->len == 1) { + /* zero result */ + m = 0; + e = 0; /* don't care */ + } else { + int prec, prec1, e_min; + e = mpb_floor_log2(a) + 1 - e_offset; + prec1 = 53; + e_min = -1021; + if (e < e_min) { + /* subnormal result or zero */ + prec = prec1 - (e_min - e); + } else { + prec = prec1; + } + mpb_shr_round(a, e + e_offset - prec, rnd_mode); + m = mpb_get_u64(a); + m <<= (53 - prec); + /* mantissa overflow due to rounding */ + if (m >= (uint64_t)1 << 53) { + m >>= 1; + e++; + } + } + *pe = e; + return m; +} + +/* return (m, e) such that m*2^(e-53) = round(a * radix^f) with 2^52 + <= m < 2^53 or m = 0. + 'a' is modified. */ +static uint64_t mul_pow_round_to_d(int *pe, mpb_t *a, + int radix1, int radix_shift, int f, int rnd_mode) +{ + int e_offset; + + e_offset = mul_pow(a, radix1, radix_shift, f, false, 55); + return round_to_d(pe, a, e_offset, rnd_mode); +} + +#ifdef JS_DTOA_DUMP_STATS +static int out_len_count[17]; + +void js_dtoa_dump_stats(void) +{ + int i, sum; + sum = 0; + for(i = 0; i < 17; i++) + sum += out_len_count[i]; + for(i = 0; i < 17; i++) { + printf("%2d %8d %5.2f%%\n", + i + 1, out_len_count[i], (double)out_len_count[i] / sum * 100); + } +} +#endif + +/* return a maximum bound of the string length. The bound depends on + 'd' only if format = JS_DTOA_FORMAT_FRAC or if JS_DTOA_EXP_DISABLED + is enabled. */ +int js_dtoa_max_len(double d, int radix, int n_digits, int flags) +{ + int fmt = flags & JS_DTOA_FORMAT_MASK; + int n, e; + uint64_t a; + + if (fmt != JS_DTOA_FORMAT_FRAC) { + if (fmt == JS_DTOA_FORMAT_FREE) { + n = dtoa_max_digits_table[radix - 2]; + } else { + n = n_digits; + } + if ((flags & JS_DTOA_EXP_MASK) == JS_DTOA_EXP_DISABLED) { + /* no exponential */ + a = float64_as_uint64(d); + e = (a >> 52) & 0x7ff; + if (e == 0x7ff) { + /* NaN, Infinity */ + n = 0; + } else { + e -= 1023; + /* XXX: adjust */ + n += 10 + abs(mul_log2_radix(e - 1, radix)); + } + } else { + /* extra: sign, 1 dot and exponent "e-1000" */ + n += 1 + 1 + 6; + } + } else { + a = float64_as_uint64(d); + e = (a >> 52) & 0x7ff; + if (e == 0x7ff) { + /* NaN, Infinity */ + n = 0; + } else { + /* high bound for the integer part */ + e -= 1023; + /* x < 2^(e + 1) */ + if (e < 0) { + n = 1; + } else { + n = 2 + mul_log2_radix(e - 1, radix); + } + /* sign, extra digit, 1 dot */ + n += 1 + 1 + 1 + n_digits; + } + } + return max_int(n, 9); /* also include NaN and [-]Infinity */ +} + +#if defined(__SANITIZE_ADDRESS__) && 0 +static void *dtoa_malloc(uint64_t **pptr, size_t size) +{ + return malloc(size); +} +static void dtoa_free(void *ptr) +{ + free(ptr); +} +#else +static void *dtoa_malloc(uint64_t **pptr, size_t size) +{ + void *ret; + ret = *pptr; + *pptr += (size + 7) / 8; + return ret; +} + +static void dtoa_free(void *ptr) +{ +} +#endif + +/* return the length */ +int js_dtoa(char *buf, double d, int radix, int n_digits, int flags, + JSDTOATempMem *tmp_mem) +{ + uint64_t a, m, *mptr = tmp_mem->mem; + int e, sgn, l, E, P, i, E_max, radix1, radix_shift; + char *q; + mpb_t *tmp1, *mant_max; + int fmt = flags & JS_DTOA_FORMAT_MASK; + + tmp1 = dtoa_malloc(&mptr, sizeof(mpb_t) + sizeof(limb_t) * DBIGNUM_LEN_MAX); + mant_max = dtoa_malloc(&mptr, sizeof(mpb_t) + sizeof(limb_t) * MANT_LEN_MAX); + assert((mptr - tmp_mem->mem) <= sizeof(JSDTOATempMem) / sizeof(mptr[0])); + + radix_shift = ctz32(radix); + radix1 = radix >> radix_shift; + a = float64_as_uint64(d); + sgn = a >> 63; + e = (a >> 52) & 0x7ff; + m = a & (((uint64_t)1 << 52) - 1); + q = buf; + if (e == 0x7ff) { + if (m == 0) { + if (sgn) + *q++ = '-'; + memcpy(q, "Infinity", 8); + q += 8; + } else { + memcpy(q, "NaN", 3); + q += 3; + } + goto done; + } else if (e == 0) { + if (m == 0) { + tmp1->len = 1; + tmp1->tab[0] = 0; + E = 1; + if (fmt == JS_DTOA_FORMAT_FREE) + P = 1; + else if (fmt == JS_DTOA_FORMAT_FRAC) + P = n_digits + 1; + else + P = n_digits; + /* "-0" is displayed as "0" if JS_DTOA_MINUS_ZERO is not present */ + if (sgn && (flags & JS_DTOA_MINUS_ZERO)) + *q++ = '-'; + goto output; + } + /* denormal number: convert to a normal number */ + l = clz64(m) - 11; + e -= l - 1; + m <<= l; + } else { + m |= (uint64_t)1 << 52; + } + if (sgn) + *q++ = '-'; + /* remove the bias */ + e -= 1022; + /* d = 2^(e-53)*m */ + // printf("m=0x%016" PRIx64 " e=%d\n", m, e); +#ifdef USE_FAST_INT + if (fmt == JS_DTOA_FORMAT_FREE && + e >= 1 && e <= 53 && + (m & (((uint64_t)1 << (53 - e)) - 1)) == 0 && + (flags & JS_DTOA_EXP_MASK) != JS_DTOA_EXP_ENABLED) { + m >>= 53 - e; + /* 'm' is never zero */ + q += u64toa_radix(q, m, radix); + goto done; + } +#endif + + /* this choice of E implies F=round(x*B^(P-E) is such as: + B^(P-1) <= F < 2.B^P. */ + E = 1 + mul_log2_radix(e - 1, radix); + + if (fmt == JS_DTOA_FORMAT_FREE) { + int P_max, E0, e1, E_found, P_found; + uint64_t m1, mant_found, mant, mant_max1; + /* P_max is guarranteed to work by construction */ + P_max = dtoa_max_digits_table[radix - 2]; + E0 = E; + E_found = 0; + P_found = 0; + mant_found = 0; + /* find the minimum number of digits by successive tries */ + P = P_max; /* P_max is guarateed to work */ + for(;;) { + /* mant_max always fits on 64 bits */ + mant_max1 = pow_ui(radix, P); + /* compute the mantissa in base B */ + E = E0; + for(;;) { + /* XXX: add inexact flag */ + mul_pow_round(tmp1, m, e - 53, radix1, radix_shift, P - E, JS_RNDN); + mant = mpb_get_u64(tmp1); + if (mant < mant_max1) + break; + E++; /* at most one iteration is possible */ + } + /* remove useless trailing zero digits */ + while ((mant % radix) == 0) { + mant /= radix; + P--; + } + /* garanteed to work for P = P_max */ + if (P_found == 0) + goto prec_found; + /* convert back to base 2 */ + mpb_set_u64(tmp1, mant); + m1 = mul_pow_round_to_d(&e1, tmp1, radix1, radix_shift, E - P, JS_RNDN); + // printf("P=%2d: m=0x%016" PRIx64 " e=%d m1=0x%016" PRIx64 " e1=%d\n", P, m, e, m1, e1); + /* Note: (m, e) is never zero here, so the exponent for m1 + = 0 does not matter */ + if (m1 == m && e1 == e) { + prec_found: + P_found = P; + E_found = E; + mant_found = mant; + if (P == 1) + break; + P--; /* try lower exponent */ + } else { + break; + } + } + P = P_found; + E = E_found; + mpb_set_u64(tmp1, mant_found); +#ifdef JS_DTOA_DUMP_STATS + if (radix == 10) { + out_len_count[P - 1]++; + } +#endif + } else if (fmt == JS_DTOA_FORMAT_FRAC) { + int len; + + assert(n_digits >= 0 && n_digits <= JS_DTOA_MAX_DIGITS); + /* P = max_int(E, 1) + n_digits; */ + /* frac is rounded using RNDNA */ + mul_pow_round(tmp1, m, e - 53, radix1, radix_shift, n_digits, JS_RNDNA); + + /* we add one extra digit on the left and remove it if needed + to avoid testing if the result is < radix^P */ + len = output_digits(q, tmp1, radix, max_int(E + 1, 1) + n_digits, + max_int(E + 1, 1)); + if (q[0] == '0' && len >= 2 && q[1] != '.') { + len--; + memmove(q, q + 1, len); + } + q += len; + goto done; + } else { + int pow_shift; + assert(n_digits >= 1 && n_digits <= JS_DTOA_MAX_DIGITS); + P = n_digits; + /* mant_max = radix^P */ + mant_max->len = 1; + mant_max->tab[0] = 1; + pow_shift = mul_pow(mant_max, radix1, radix_shift, P, false, 0); + mpb_shr_round(mant_max, pow_shift, JS_RNDZ); + + for(;;) { + /* fixed and frac are rounded using RNDNA */ + mul_pow_round(tmp1, m, e - 53, radix1, radix_shift, P - E, JS_RNDNA); + if (mpb_cmp(tmp1, mant_max) < 0) + break; + E++; /* at most one iteration is possible */ + } + } + output: + if (fmt == JS_DTOA_FORMAT_FIXED) + E_max = n_digits; + else + E_max = dtoa_max_digits_table[radix - 2] + 4; + if ((flags & JS_DTOA_EXP_MASK) == JS_DTOA_EXP_ENABLED || + ((flags & JS_DTOA_EXP_MASK) == JS_DTOA_EXP_AUTO && (E <= -6 || E > E_max))) { + q += output_digits(q, tmp1, radix, P, 1); + E--; + if (radix == 10) { + *q++ = 'e'; + } else if (radix1 == 1 && radix_shift <= 4) { + E *= radix_shift; + *q++ = 'p'; + } else { + *q++ = '@'; + } + if (E < 0) { + *q++ = '-'; + E = -E; + } else { + *q++ = '+'; + } + q += u32toa(q, E); + } else if (E <= 0) { + *q++ = '0'; + *q++ = '.'; + for(i = 0; i < -E; i++) + *q++ = '0'; + q += output_digits(q, tmp1, radix, P, P); + } else { + q += output_digits(q, tmp1, radix, P, min_int(P, E)); + for(i = 0; i < E - P; i++) + *q++ = '0'; + } + done: + *q = '\0'; + dtoa_free(mant_max); + dtoa_free(tmp1); + return q - buf; +} + +static inline int to_digit(int c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + else if (c >= 'A' && c <= 'Z') + return c - 'A' + 10; + else if (c >= 'a' && c <= 'z') + return c - 'a' + 10; + else + return 36; +} + +/* r = r * radix_base + a. radix_base = 0 means radix_base = 2^32 */ +static void mpb_mul1_base(mpb_t *r, limb_t radix_base, limb_t a) +{ + int i; + if (r->tab[0] == 0 && r->len == 1) { + r->tab[0] = a; + } else { + if (radix_base == 0) { + for(i = r->len; i >= 0; i--) { + r->tab[i + 1] = r->tab[i]; + } + r->tab[0] = a; + } else { + r->tab[r->len] = mp_mul1(r->tab, r->tab, r->len, + radix_base, a); + } + r->len++; + mpb_renorm(r); + } +} + +/* XXX: add fast path for small integers */ +double js_atod(const char *str, const char **pnext, int radix, int flags, + JSATODTempMem *tmp_mem) +{ + uint64_t *mptr = tmp_mem->mem; + const char *p, *p_start; + limb_t cur_limb, radix_base, extra_digits; + int is_neg, digit_count, limb_digit_count, digits_per_limb, sep, radix1, radix_shift; + int radix_bits, expn, e, max_digits, expn_offset, dot_pos, sig_pos, pos; + mpb_t *tmp0; + double dval; + bool is_bin_exp, is_zero, expn_overflow; + uint64_t m, a; + + tmp0 = dtoa_malloc(&mptr, sizeof(mpb_t) + sizeof(limb_t) * DBIGNUM_LEN_MAX); + assert((mptr - tmp_mem->mem) <= sizeof(JSATODTempMem) / sizeof(mptr[0])); + /* optional separator between digits */ + sep = (flags & JS_ATOD_ACCEPT_UNDERSCORES) ? '_' : 256; + + p = str; + is_neg = 0; + if (p[0] == '+') { + p++; + p_start = p; + } else if (p[0] == '-') { + is_neg = 1; + p++; + p_start = p; + } else { + p_start = p; + } + + if (p[0] == '0') { + if ((p[1] == 'x' || p[1] == 'X') && + (radix == 0 || radix == 16)) { + p += 2; + radix = 16; + } else if ((p[1] == 'o' || p[1] == 'O') && + radix == 0 && (flags & JS_ATOD_ACCEPT_BIN_OCT)) { + p += 2; + radix = 8; + } else if ((p[1] == 'b' || p[1] == 'B') && + radix == 0 && (flags & JS_ATOD_ACCEPT_BIN_OCT)) { + p += 2; + radix = 2; + } else if ((p[1] >= '0' && p[1] <= '9') && + radix == 0 && (flags & JS_ATOD_ACCEPT_LEGACY_OCTAL)) { + int i; + sep = 256; + for (i = 1; (p[i] >= '0' && p[i] <= '7'); i++) + continue; + if (p[i] == '8' || p[i] == '9') + goto no_prefix; + p += 1; + radix = 8; + } else { + goto no_prefix; + } + /* there must be a digit after the prefix */ + if (to_digit((uint8_t)*p) >= radix) + goto fail; + no_prefix: ; + } else { + if (!(flags & JS_ATOD_INT_ONLY) && js__strstart(p, "Infinity", &p)) + goto overflow; + } + if (radix == 0) + radix = 10; + + cur_limb = 0; + expn_offset = 0; + digit_count = 0; + limb_digit_count = 0; + max_digits = atod_max_digits_table[radix - 2]; + digits_per_limb = digits_per_limb_table[radix - 2]; + radix_base = radix_base_table[radix - 2]; + radix_shift = ctz32(radix); + radix1 = radix >> radix_shift; + if (radix1 == 1) { + /* radix = 2^radix_bits */ + radix_bits = radix_shift; + } else { + radix_bits = 0; + } + tmp0->len = 1; + tmp0->tab[0] = 0; + extra_digits = 0; + pos = 0; + dot_pos = -1; + /* skip leading zeros */ + for(;;) { + if (*p == '.' && (p > p_start || to_digit(p[1]) < radix) && + !(flags & JS_ATOD_INT_ONLY)) { + if (*p == sep) + goto fail; + if (dot_pos >= 0) + break; + dot_pos = pos; + p++; + } + if (*p == sep && p > p_start && p[1] == '0') + p++; + if (*p != '0') + break; + p++; + pos++; + } + + sig_pos = pos; + for(;;) { + limb_t c; + if (*p == '.' && (p > p_start || to_digit(p[1]) < radix) && + !(flags & JS_ATOD_INT_ONLY)) { + if (*p == sep) + goto fail; + if (dot_pos >= 0) + break; + dot_pos = pos; + p++; + } + if (*p == sep && p > p_start && to_digit(p[1]) < radix) + p++; + c = to_digit(*p); + if (c >= radix) + break; + p++; + pos++; + if (digit_count < max_digits) { + /* XXX: could be faster when radix_bits != 0 */ + cur_limb = cur_limb * radix + c; + limb_digit_count++; + if (limb_digit_count == digits_per_limb) { + mpb_mul1_base(tmp0, radix_base, cur_limb); + cur_limb = 0; + limb_digit_count = 0; + } + digit_count++; + } else { + extra_digits |= c; + } + } + if (limb_digit_count != 0) { + mpb_mul1_base(tmp0, pow_ui(radix, limb_digit_count), cur_limb); + } + if (digit_count == 0) { + is_zero = true; + expn_offset = 0; + } else { + is_zero = false; + if (dot_pos < 0) + dot_pos = pos; + expn_offset = sig_pos + digit_count - dot_pos; + } + + /* Use the extra digits for rounding if the base is a power of + two. Otherwise they are just truncated. */ + if (radix_bits != 0 && extra_digits != 0) { + tmp0->tab[0] |= 1; + } + + /* parse the exponent, if any */ + expn = 0; + expn_overflow = false; + is_bin_exp = false; + if (!(flags & JS_ATOD_INT_ONLY) && + ((radix == 10 && (*p == 'e' || *p == 'E')) || + (radix != 10 && (*p == '@' || + (radix_bits >= 1 && radix_bits <= 4 && (*p == 'p' || *p == 'P'))))) && + p > p_start) { + bool exp_is_neg; + int c; + is_bin_exp = (*p == 'p' || *p == 'P'); + p++; + exp_is_neg = false; + if (*p == '+') { + p++; + } else if (*p == '-') { + exp_is_neg = true; + p++; + } + c = to_digit(*p); + if (c >= 10) + goto fail; /* XXX: could stop before the exponent part */ + expn = c; + p++; + for(;;) { + if (*p == sep && to_digit(p[1]) < 10) + p++; + c = to_digit(*p); + if (c >= 10) + break; + if (!expn_overflow) { + if (unlikely(expn > ((INT32_MAX - 2 - 9) / 10))) { + expn_overflow = true; + } else { + expn = expn * 10 + c; + } + } + p++; + } + if (exp_is_neg) + expn = -expn; + /* if zero result, the exponent can be arbitrarily large */ + if (!is_zero && expn_overflow) { + if (exp_is_neg) + a = 0; + else + a = (uint64_t)0x7ff << 52; /* infinity */ + goto done; + } + } + + if (p == p_start) + goto fail; + + if (is_zero) { + a = 0; + } else { + int expn1; + if (radix_bits != 0) { + if (!is_bin_exp) + expn *= radix_bits; + expn -= expn_offset * radix_bits; + expn1 = expn + digit_count * radix_bits; + if (expn1 >= 1024 + radix_bits) + goto overflow; + else if (expn1 <= -1075) + goto underflow; + m = round_to_d(&e, tmp0, -expn, JS_RNDN); + } else { + expn -= expn_offset; + expn1 = expn + digit_count; + if (expn1 >= max_exponent[radix - 2] + 1) + goto overflow; + else if (expn1 <= min_exponent[radix - 2]) + goto underflow; + m = mul_pow_round_to_d(&e, tmp0, radix1, radix_shift, expn, JS_RNDN); + } + if (m == 0) { + underflow: + a = 0; + } else if (e > 1024) { + overflow: + /* overflow */ + a = (uint64_t)0x7ff << 52; + } else if (e < -1073) { + /* underflow */ + /* XXX: check rounding */ + a = 0; + } else if (e < -1021) { + /* subnormal */ + a = m >> (-e - 1021); + } else { + a = ((uint64_t)(e + 1022) << 52) | (m & (((uint64_t)1 << 52) - 1)); + } + } + done: + a |= (uint64_t)is_neg << 63; + dval = uint64_as_float64(a); + done1: + if (pnext) + *pnext = p; + dtoa_free(tmp0); + return dval; + fail: + dval = NAN; + goto done1; +} diff --git a/userland/qjs/source/dtoa.h b/userland/qjs/source/dtoa.h new file mode 100644 index 0000000..85be040 --- /dev/null +++ b/userland/qjs/source/dtoa.h @@ -0,0 +1,87 @@ +/* + * Tiny float64 printing and parsing library + * + * Copyright (c) 2024 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef DTOA_H +#define DTOA_H + +//#define JS_DTOA_DUMP_STATS + +/* maximum number of digits for fixed and frac formats */ +#define JS_DTOA_MAX_DIGITS 101 + +/* radix != 10 is only supported with flags = JS_DTOA_FORMAT_FREE */ +/* use as many digits as necessary */ +#define JS_DTOA_FORMAT_FREE (0 << 0) +/* use n_digits significant digits (1 <= n_digits <= JS_DTOA_MAX_DIGITS) */ +#define JS_DTOA_FORMAT_FIXED (1 << 0) +/* force fractional format: [-]dd.dd with n_digits fractional digits. + 0 <= n_digits <= JS_DTOA_MAX_DIGITS */ +#define JS_DTOA_FORMAT_FRAC (2 << 0) +#define JS_DTOA_FORMAT_MASK (3 << 0) + +/* select exponential notation either in fixed or free format */ +#define JS_DTOA_EXP_AUTO (0 << 2) +#define JS_DTOA_EXP_ENABLED (1 << 2) +#define JS_DTOA_EXP_DISABLED (2 << 2) +#define JS_DTOA_EXP_MASK (3 << 2) + +#define JS_DTOA_MINUS_ZERO (1 << 4) /* show the minus sign for -0 */ + +/* only accepts integers (no dot, no exponent) */ +#define JS_ATOD_INT_ONLY (1 << 0) +/* accept Oo and Ob prefixes in addition to 0x prefix if radix = 0 */ +#define JS_ATOD_ACCEPT_BIN_OCT (1 << 1) +/* accept O prefix as octal if radix == 0 and properly formed (Annex B) */ +#define JS_ATOD_ACCEPT_LEGACY_OCTAL (1 << 2) +/* accept _ between digits as a digit separator */ +#define JS_ATOD_ACCEPT_UNDERSCORES (1 << 3) + +typedef struct { + uint64_t mem[37]; +} JSDTOATempMem; + +typedef struct { + uint64_t mem[27]; +} JSATODTempMem; + +/* return a maximum bound of the string length */ +int js_dtoa_max_len(double d, int radix, int n_digits, int flags); +/* return the string length */ +int js_dtoa(char *buf, double d, int radix, int n_digits, int flags, + JSDTOATempMem *tmp_mem); +double js_atod(const char *str, const char **pnext, int radix, int flags, + JSATODTempMem *tmp_mem); + +#ifdef JS_DTOA_DUMP_STATS +void js_dtoa_dump_stats(void); +#endif + +/* additional exported functions */ +size_t u32toa(char *buf, uint32_t n); +size_t i32toa(char *buf, int32_t n); +size_t u64toa(char *buf, uint64_t n); +size_t i64toa(char *buf, int64_t n); +size_t u64toa_radix(char *buf, uint64_t n, unsigned int radix); +size_t i64toa_radix(char *buf, int64_t n, unsigned int radix); + +#endif /* DTOA_H */ diff --git a/userland/qjs/source/examples/fib.c b/userland/qjs/source/examples/fib.c new file mode 100644 index 0000000..a9eb29d --- /dev/null +++ b/userland/qjs/source/examples/fib.c @@ -0,0 +1,67 @@ +/* + * QuickJS: Example of C module + * + * Copyright (c) 2017-2018 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#define countof(x) (sizeof(x) / sizeof((x)[0])) + +static int fib(int n) +{ + if (n <= 0) + return 0; + else if (n == 1) + return 1; + else + return fib(n - 1) + fib(n - 2); +} + +static JSValue js_fib(JSContext *ctx, JSValue this_val, + int argc, JSValue *argv) +{ + int n, res; + if (JS_ToInt32(ctx, &n, argv[0])) + return JS_EXCEPTION; + res = fib(n); + return JS_NewInt32(ctx, res); +} + +static const JSCFunctionListEntry js_fib_funcs[] = { + JS_CFUNC_DEF("fib", 1, js_fib ), +}; + +static int js_fib_init(JSContext *ctx, JSModuleDef *m) +{ + return JS_SetModuleExportList(ctx, m, js_fib_funcs, + countof(js_fib_funcs)); +} + +JS_MODULE_EXTERN JSModuleDef *js_init_module(JSContext *ctx, const char *module_name) +{ + JSModuleDef *m; + m = JS_NewCModule(ctx, module_name, js_fib_init); + if (!m) + return NULL; + JS_AddModuleExportList(ctx, m, js_fib_funcs, countof(js_fib_funcs)); + return m; +} diff --git a/userland/qjs/source/examples/fib_module.js b/userland/qjs/source/examples/fib_module.js new file mode 100644 index 0000000..6a81071 --- /dev/null +++ b/userland/qjs/source/examples/fib_module.js @@ -0,0 +1,10 @@ +/* fib module */ +export function fib(n) +{ + if (n <= 0) + return 0; + else if (n == 1) + return 1; + else + return fib(n - 1) + fib(n - 2); +} diff --git a/userland/qjs/source/examples/hello.js b/userland/qjs/source/examples/hello.js new file mode 100644 index 0000000..accefce --- /dev/null +++ b/userland/qjs/source/examples/hello.js @@ -0,0 +1 @@ +console.log("Hello World"); diff --git a/userland/qjs/source/examples/hello_module.js b/userland/qjs/source/examples/hello_module.js new file mode 100644 index 0000000..463660f --- /dev/null +++ b/userland/qjs/source/examples/hello_module.js @@ -0,0 +1,6 @@ +/* example of JS module */ + +import { fib } from "./fib_module.js"; + +console.log("Hello World"); +console.log("fib(10)=", fib(10)); diff --git a/userland/qjs/source/examples/meson.build b/userland/qjs/source/examples/meson.build new file mode 100644 index 0000000..08f0329 --- /dev/null +++ b/userland/qjs/source/examples/meson.build @@ -0,0 +1,17 @@ +shared_module( + 'fib', + 'fib.c', + + name_prefix: '', + gnu_symbol_visibility: 'hidden', + dependencies: qjs_module_dep, +) + +shared_module( + 'point', + 'point.c', + + name_prefix: '', + gnu_symbol_visibility: 'hidden', + dependencies: qjs_module_dep, +) diff --git a/userland/qjs/source/examples/pi_bigint.js b/userland/qjs/source/examples/pi_bigint.js new file mode 100644 index 0000000..e15abd1 --- /dev/null +++ b/userland/qjs/source/examples/pi_bigint.js @@ -0,0 +1,118 @@ +/* + * PI computation in Javascript using the BigInt type + */ +"use strict"; + +/* return floor(log2(a)) for a > 0 and 0 for a = 0 */ +function floor_log2(a) +{ + var k_max, a1, k, i; + k_max = 0n; + while ((a >> (2n ** k_max)) != 0n) { + k_max++; + } + k = 0n; + a1 = a; + for(i = k_max - 1n; i >= 0n; i--) { + a1 = a >> (2n ** i); + if (a1 != 0n) { + a = a1; + k |= (1n << i); + } + } + return k; +} + +/* return ceil(log2(a)) for a > 0 */ +function ceil_log2(a) +{ + return floor_log2(a - 1n) + 1n; +} + +/* return floor(sqrt(a)) (not efficient but simple) */ +function int_sqrt(a) +{ + var l, u, s; + if (a == 0n) + return a; + l = ceil_log2(a); + u = 1n << ((l + 1n) / 2n); + /* u >= floor(sqrt(a)) */ + for(;;) { + s = u; + u = ((a / s) + s) / 2n; + if (u >= s) + break; + } + return s; +} + +/* return pi * 2**prec */ +function calc_pi(prec) { + const CHUD_A = 13591409n; + const CHUD_B = 545140134n; + const CHUD_C = 640320n; + const CHUD_C3 = 10939058860032000n; /* C^3/24 */ + const CHUD_BITS_PER_TERM = 47.11041313821584202247; /* log2(C/12)*3 */ + + /* return [P, Q, G] */ + function chud_bs(a, b, need_G) { + var c, P, Q, G, P1, Q1, G1, P2, Q2, G2; + if (a == (b - 1n)) { + G = (2n * b - 1n) * (6n * b - 1n) * (6n * b - 5n); + P = G * (CHUD_B * b + CHUD_A); + if (b & 1n) + P = -P; + Q = b * b * b * CHUD_C3; + } else { + c = (a + b) >> 1n; + [P1, Q1, G1] = chud_bs(a, c, true); + [P2, Q2, G2] = chud_bs(c, b, need_G); + P = P1 * Q2 + P2 * G1; + Q = Q1 * Q2; + if (need_G) + G = G1 * G2; + else + G = 0n; + } + return [P, Q, G]; + } + + var n, P, Q, G; + /* number of serie terms */ + n = BigInt(Math.ceil(Number(prec) / CHUD_BITS_PER_TERM)) + 10n; + [P, Q, G] = chud_bs(0n, n, false); + Q = (CHUD_C / 12n) * (Q << prec) / (P + Q * CHUD_A); + G = int_sqrt(CHUD_C << (2n * prec)); + return (Q * G) >> prec; +} + +function main(args) { + var r, n_digits, n_bits, out; + if (args.length < 1) { + print("usage: pi n_digits"); + return; + } + n_digits = args[0] | 0; + + /* we add more bits to reduce the probability of bad rounding for + the last digits */ + n_bits = BigInt(Math.ceil(n_digits * Math.log2(10))) + 32n; + r = calc_pi(n_bits); + r = ((10n ** BigInt(n_digits)) * r) >> n_bits; + out = r.toString(); + print(out[0] + "." + out.slice(1)); +} + +var args; +if (typeof scriptArgs != "undefined") { + args = scriptArgs; + args.shift(); +} else if (typeof arguments != "undefined") { + args = arguments; +} else { + /* default: 1000 digits */ + args=[1000]; +} + +main(args); diff --git a/userland/qjs/source/examples/point.c b/userland/qjs/source/examples/point.c new file mode 100644 index 0000000..baa0638 --- /dev/null +++ b/userland/qjs/source/examples/point.c @@ -0,0 +1,154 @@ +/* + * QuickJS: Example of C module with a class + * + * Copyright (c) 2019 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include + +#define countof(x) (sizeof(x) / sizeof((x)[0])) + +/* Point Class */ + +typedef struct { + int x; + int y; +} JSPointData; + +static JSClassID js_point_class_id; + +static void js_point_finalizer(JSRuntime *rt, JSValue val) +{ + JSPointData *s = JS_GetOpaque(val, js_point_class_id); + /* Note: 's' can be NULL in case JS_SetOpaque() was not called */ + js_free_rt(rt, s); +} + +static JSValue js_point_ctor(JSContext *ctx, + JSValue new_target, + int argc, JSValue *argv) +{ + JSPointData *s; + JSValue obj = JS_UNDEFINED; + JSValue proto; + + s = js_mallocz(ctx, sizeof(*s)); + if (!s) + return JS_EXCEPTION; + if (JS_ToInt32(ctx, &s->x, argv[0])) + goto fail; + if (JS_ToInt32(ctx, &s->y, argv[1])) + goto fail; + /* using new_target to get the prototype is necessary when the + class is extended. */ + proto = JS_GetPropertyStr(ctx, new_target, "prototype"); + if (JS_IsException(proto)) + goto fail; + obj = JS_NewObjectProtoClass(ctx, proto, js_point_class_id); + JS_FreeValue(ctx, proto); + if (JS_IsException(obj)) + goto fail; + JS_SetOpaque(obj, s); + return obj; + fail: + js_free(ctx, s); + JS_FreeValue(ctx, obj); + return JS_EXCEPTION; +} + +static JSValue js_point_get_xy(JSContext *ctx, JSValue this_val, int magic) +{ + JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id); + if (!s) + return JS_EXCEPTION; + if (magic == 0) + return JS_NewInt32(ctx, s->x); + else + return JS_NewInt32(ctx, s->y); +} + +static JSValue js_point_set_xy(JSContext *ctx, JSValue this_val, JSValue val, int magic) +{ + JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id); + int v; + if (!s) + return JS_EXCEPTION; + if (JS_ToInt32(ctx, &v, val)) + return JS_EXCEPTION; + if (magic == 0) + s->x = v; + else + s->y = v; + return JS_UNDEFINED; +} + +static JSValue js_point_norm(JSContext *ctx, JSValue this_val, + int argc, JSValue *argv) +{ + JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id); + if (!s) + return JS_EXCEPTION; + return JS_NewFloat64(ctx, sqrt((double)s->x * s->x + (double)s->y * s->y)); +} + +static JSClassDef js_point_class = { + "Point", + .finalizer = js_point_finalizer, +}; + +static const JSCFunctionListEntry js_point_proto_funcs[] = { + JS_CGETSET_MAGIC_DEF("x", js_point_get_xy, js_point_set_xy, 0), + JS_CGETSET_MAGIC_DEF("y", js_point_get_xy, js_point_set_xy, 1), + JS_CFUNC_DEF("norm", 0, js_point_norm), +}; + +static int js_point_init(JSContext *ctx, JSModuleDef *m) +{ + JSValue point_proto, point_class; + JSRuntime *rt = JS_GetRuntime(ctx); + + /* create the Point class */ + JS_NewClassID(rt, &js_point_class_id); + JS_NewClass(rt, js_point_class_id, &js_point_class); + + point_proto = JS_NewObject(ctx); + JS_SetPropertyFunctionList(ctx, point_proto, js_point_proto_funcs, countof(js_point_proto_funcs)); + + point_class = JS_NewCFunction2(ctx, js_point_ctor, "Point", 2, JS_CFUNC_constructor, 0); + /* set proto.constructor and ctor.prototype */ + JS_SetConstructor(ctx, point_class, point_proto); + JS_SetClassProto(ctx, js_point_class_id, point_proto); + + JS_SetModuleExport(ctx, m, "Point", point_class); + return 0; +} + +JS_MODULE_EXTERN JSModuleDef *js_init_module(JSContext *ctx, const char *module_name) +{ + JSModuleDef *m; + m = JS_NewCModule(ctx, module_name, js_point_init); + if (!m) + return NULL; + JS_AddModuleExport(ctx, m, "Point"); + return m; +} diff --git a/userland/qjs/source/examples/test_fib.js b/userland/qjs/source/examples/test_fib.js new file mode 100644 index 0000000..f22c576 --- /dev/null +++ b/userland/qjs/source/examples/test_fib.js @@ -0,0 +1,8 @@ +/* example of JS module importing a C module */ +import * as os from "qjs:os"; + +const isWin = os.platform === 'win32'; +const { fib } = await import(`./fib.${isWin ? 'dll' : 'so'}`); + +console.log("Hello World"); +console.log("fib(10)=", fib(10)); diff --git a/userland/qjs/source/examples/test_point.js b/userland/qjs/source/examples/test_point.js new file mode 100644 index 0000000..1e0fafa --- /dev/null +++ b/userland/qjs/source/examples/test_point.js @@ -0,0 +1,43 @@ +/* example of JS module importing a C module */ +import * as os from "qjs:os"; + +const isWin = os.platform === 'win32'; +const { Point } = await import(`./point.${isWin ? 'dll' : 'so'}`); + +function assert(b, str) +{ + if (b) { + return; + } else { + throw Error("assertion failed: " + str); + } +} + +class ColorPoint extends Point { + constructor(x, y, color) { + super(x, y); + this.color = color; + } + get_color() { + return this.color; + } +}; + +function main() +{ + var pt, pt2; + + pt = new Point(2, 3); + assert(pt.x === 2); + assert(pt.y === 3); + pt.x = 4; + assert(pt.x === 4); + assert(pt.norm() == 5); + + pt2 = new ColorPoint(2, 3, 0xffffff); + assert(pt2.x === 2); + assert(pt2.color === 0xffffff); + assert(pt2.get_color() === 0xffffff); +} + +main(); diff --git a/userland/qjs/source/fuzz.c b/userland/qjs/source/fuzz.c new file mode 100644 index 0000000..5794e7b --- /dev/null +++ b/userland/qjs/source/fuzz.c @@ -0,0 +1,51 @@ +// clang -g -O1 -fsanitize=fuzzer -o fuzz fuzz.c +#include "quickjs.h" +#include "quickjs.c" +#include "cutils.h" +#include "libregexp.c" +#include "libunicode.c" +#include "dtoa.c" + +#include +#include +#include + +// note: LLVM output does not contain checksum, needs to be added +// manually (4 byte field at position 1) when adding to the corpus +// +// fill in UINT32_MAX to disable checksumming +int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) +{ + if (!len) + return 0; + JSRuntime *rt = JS_NewRuntime(); + if (!rt) + exit(1); + JSContext *ctx = JS_NewContext(rt); + if (!ctx) + exit(1); + size_t newlen = len + 4; + uint8_t *newbuf = malloc(newlen); + if (!newbuf) + exit(1); + uint32_t csum = bc_csum(&buf[1], len-1); // skip version field + newbuf[0] = buf[0]; // copy version field + put_u32(&newbuf[1], csum); // insert checksum + memcpy(&newbuf[5], &buf[1], len-1); // copy rest of payload + JSValue val = JS_ReadObject(ctx, newbuf, newlen, /*flags*/0); + free(newbuf); + if (JS_IsException(val)) { + JSValue exc = JS_GetException(ctx); + const char *str = JS_ToCString(ctx, exc); + JS_FreeValue(ctx, exc); + if (!str) + exit(1); + if (strstr(str, "checksum error")) + exit(1); + JS_FreeCString(ctx, str); + } + JS_FreeValue(ctx, val); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + return 0; +} diff --git a/userland/qjs/source/gc-stress-skip.txt b/userland/qjs/source/gc-stress-skip.txt new file mode 100644 index 0000000..7a0189d --- /dev/null +++ b/userland/qjs/source/gc-stress-skip.txt @@ -0,0 +1,3 @@ +# tests too allocation-heavy to run under FORCE_GC_AT_MALLOC (a full GC per +# object allocation makes them take way too long) +tests/test_builtin.js diff --git a/userland/qjs/source/gen/function_source.c b/userland/qjs/source/gen/function_source.c new file mode 100644 index 0000000..961e6bb --- /dev/null +++ b/userland/qjs/source/gen/function_source.c @@ -0,0 +1,82 @@ +/* File generated automatically by the QuickJS-ng compiler. */ + +#include "quickjs-libc.h" + +const uint32_t qjsc_function_source_size = 342; + +const uint8_t qjsc_function_source[342] = { + 0x1d, 0x95, 0xc4, 0x5d, 0x54, 0x05, 0x01, 0x30, + 0x74, 0x65, 0x73, 0x74, 0x73, 0x2f, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x6a, 0x73, + 0x01, 0x0c, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, + 0x01, 0x02, 0x66, 0x01, 0x0c, 0x65, 0x78, 0x70, + 0x65, 0x63, 0x74, 0x01, 0x34, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x28, + 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x34, 0x32, 0x20, 0x7d, 0x0d, + 0xe2, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x20, 0x0a, 0x01, 0xa8, 0x01, 0x00, 0x05, 0x00, + 0x03, 0x02, 0x02, 0x01, 0x74, 0x05, 0xe4, 0x03, + 0x02, 0x00, 0x30, 0xe6, 0x03, 0x04, 0x00, 0x70, + 0x01, 0xe4, 0x03, 0x04, 0x02, 0x70, 0x00, 0x10, + 0x00, 0x01, 0x00, 0xf2, 0x01, 0x00, 0x01, 0x00, + 0xe8, 0x03, 0x00, 0x1e, 0xe6, 0x03, 0x01, 0x06, + 0x0c, 0x43, 0x0a, 0x01, 0xe6, 0x03, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0xc2, + 0x2a, 0x28, 0xe2, 0x03, 0x03, 0x01, 0x00, 0x1a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x66, 0x28, 0x29, 0x20, 0x7b, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x34, 0x32, + 0x20, 0x7d, 0x0c, 0x03, 0xc8, 0x04, 0x08, 0xd2, + 0x08, 0xf0, 0x05, 0xc5, 0x00, 0xe8, 0x29, 0x04, + 0xf5, 0x00, 0x00, 0x00, 0xe7, 0x60, 0x00, 0x00, + 0xe4, 0x41, 0x3b, 0x00, 0x00, 0x00, 0x24, 0x00, + 0x00, 0xcf, 0x61, 0x00, 0x00, 0x64, 0x00, 0x00, + 0xae, 0xf0, 0x0b, 0x38, 0x9f, 0x00, 0x00, 0x00, + 0x61, 0x00, 0x00, 0xf5, 0x30, 0x60, 0x02, 0x00, + 0x60, 0x01, 0x00, 0x38, 0x3e, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x04, 0xf3, 0x00, 0x00, 0x00, + 0x9c, 0x32, 0x01, 0x00, 0x03, 0x00, 0xd0, 0x61, + 0x01, 0x00, 0x41, 0x3b, 0x00, 0x00, 0x00, 0x24, + 0x00, 0x00, 0xd1, 0x61, 0x02, 0x00, 0x64, 0x00, + 0x00, 0xae, 0xf0, 0x0b, 0x38, 0x9f, 0x00, 0x00, + 0x00, 0x61, 0x02, 0x00, 0xf5, 0x30, 0x67, 0x02, + 0x00, 0x67, 0x01, 0x00, 0x06, 0x2f, 0xe2, 0x03, + 0x01, 0x01, 0x22, 0x00, 0x16, 0x0a, 0x26, 0x20, + 0x04, 0x17, 0x19, 0x11, 0x16, 0x20, 0x1c, 0x1b, + 0x0c, 0x00, 0x0b, 0x08, 0x31, 0x1b, 0x0a, 0x11, + 0x12, 0x3f, 0x11, 0x2a, 0x04, 0x17, 0x19, 0x11, + 0x16, 0x20, 0x1c, 0x1b, 0x0c, 0x00, +}; + +static JSContext *JS_NewCustomContext(JSRuntime *rt) +{ + JSContext *ctx = JS_NewContext(rt); + if (!ctx) + return NULL; + return ctx; +} + +int main(int argc, char **argv) +{ + int r; + JSRuntime *rt; + JSContext *ctx; + r = 0; + rt = JS_NewRuntime(); + js_std_set_worker_new_context_func(JS_NewCustomContext); + js_std_init_handlers(rt); + JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader, js_module_check_attributes, NULL); + ctx = JS_NewCustomContext(rt); + js_std_add_helpers(ctx, argc, argv); + js_std_eval_binary(ctx, qjsc_function_source, qjsc_function_source_size, 0); + r = js_std_loop(ctx); + if (r) { + js_std_dump_error(ctx); + } + js_std_free_handlers(rt); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + return r; +} diff --git a/userland/qjs/source/gen/hello.c b/userland/qjs/source/gen/hello.c new file mode 100644 index 0000000..c84381a --- /dev/null +++ b/userland/qjs/source/gen/hello.c @@ -0,0 +1,53 @@ +/* File generated automatically by the QuickJS-ng compiler. */ + +#include "quickjs-libc.h" + +const uint32_t qjsc_hello_size = 108; + +const uint8_t qjsc_hello[108] = { + 0x1d, 0x9c, 0x9d, 0x68, 0xdc, 0x04, 0x01, 0x22, + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, + 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e, 0x6a, + 0x73, 0x01, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, + 0x6c, 0x65, 0x01, 0x06, 0x6c, 0x6f, 0x67, 0x01, + 0x16, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, + 0x6f, 0x72, 0x6c, 0x64, 0x0d, 0xe2, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x0a, 0x01, + 0xa8, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x19, 0x00, 0x08, 0xf0, 0x02, 0x29, 0x38, + 0xf2, 0x00, 0x00, 0x00, 0x41, 0xf3, 0x00, 0x00, + 0x00, 0x04, 0xf4, 0x00, 0x00, 0x00, 0x24, 0x01, + 0x00, 0x0e, 0x06, 0x2f, 0xe2, 0x03, 0x01, 0x01, + 0x02, 0x48, 0x0e, 0x00, +}; + +static JSContext *JS_NewCustomContext(JSRuntime *rt) +{ + JSContext *ctx = JS_NewContext(rt); + if (!ctx) + return NULL; + return ctx; +} + +int main(int argc, char **argv) +{ + int r; + JSRuntime *rt; + JSContext *ctx; + r = 0; + rt = JS_NewRuntime(); + js_std_set_worker_new_context_func(JS_NewCustomContext); + js_std_init_handlers(rt); + JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader, js_module_check_attributes, NULL); + ctx = JS_NewCustomContext(rt); + js_std_add_helpers(ctx, argc, argv); + js_std_eval_binary(ctx, qjsc_hello, qjsc_hello_size, 0); + r = js_std_loop(ctx); + if (r) { + js_std_dump_error(ctx); + } + js_std_free_handlers(rt); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + return r; +} diff --git a/userland/qjs/source/gen/hello_module.c b/userland/qjs/source/gen/hello_module.c new file mode 100644 index 0000000..5c8f58e --- /dev/null +++ b/userland/qjs/source/gen/hello_module.c @@ -0,0 +1,107 @@ +/* File generated automatically by the QuickJS-ng compiler. */ + +#include "quickjs-libc.h" + +const uint32_t qjsc_fib_module_size = 302; + +const uint8_t qjsc_fib_module[302] = { + 0x1d, 0xa5, 0x68, 0xc1, 0x51, 0x03, 0x01, 0x2c, + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, + 0x2f, 0x66, 0x69, 0x62, 0x5f, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x2e, 0x6a, 0x73, 0x01, 0x06, + 0x66, 0x69, 0x62, 0x01, 0x02, 0x6e, 0x0d, 0xe2, + 0x03, 0x00, 0x01, 0x00, 0x00, 0xe4, 0x03, 0x00, + 0x00, 0x00, 0x0c, 0x20, 0x0a, 0x01, 0xa8, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x09, + 0x00, 0xe4, 0x03, 0x00, 0x06, 0x0c, 0x43, 0x0a, + 0x01, 0xe4, 0x03, 0x01, 0x00, 0x01, 0x04, 0x00, + 0x01, 0x00, 0x1a, 0x01, 0xe6, 0x03, 0x00, 0x01, + 0x00, 0xe4, 0x03, 0x00, 0x02, 0xd7, 0xba, 0xa6, + 0xf0, 0x03, 0xba, 0x28, 0xd7, 0xbb, 0xab, 0xf0, + 0x03, 0xbb, 0x28, 0xe3, 0xd7, 0xbb, 0x9d, 0xf5, + 0xe3, 0xd7, 0xbc, 0x9d, 0xf5, 0x9c, 0x28, 0xe2, + 0x03, 0x02, 0x08, 0x14, 0x04, 0x02, 0x07, 0x0a, + 0x22, 0x00, 0x07, 0x0a, 0x23, 0x05, 0x07, 0x08, + 0x07, 0x08, 0x11, 0x0a, 0x07, 0x08, 0x07, 0x08, + 0x8d, 0x01, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x66, 0x69, 0x62, 0x28, 0x6e, + 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x28, 0x6e, 0x20, 0x3c, 0x3d, + 0x20, 0x30, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x30, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, + 0x66, 0x20, 0x28, 0x6e, 0x20, 0x3d, 0x3d, 0x20, + 0x31, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x69, 0x62, + 0x28, 0x6e, 0x20, 0x2d, 0x20, 0x31, 0x29, 0x20, + 0x2b, 0x20, 0x66, 0x69, 0x62, 0x28, 0x6e, 0x20, + 0x2d, 0x20, 0x32, 0x29, 0x3b, 0x0a, 0x7d, 0x08, + 0xf0, 0x05, 0xc5, 0x00, 0xe7, 0x29, 0x06, 0x2f, + 0xe2, 0x03, 0x01, 0x01, 0x00, 0x00, +}; + +const uint32_t qjsc_hello_module_size = 192; + +const uint8_t qjsc_hello_module[192] = { + 0x1d, 0xdb, 0x66, 0x1f, 0x10, 0x07, 0x01, 0x30, + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, + 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x5f, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x6a, 0x73, + 0x01, 0x1e, 0x2e, 0x2f, 0x66, 0x69, 0x62, 0x5f, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x6a, + 0x73, 0x01, 0x06, 0x66, 0x69, 0x62, 0x01, 0x0e, + 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x01, + 0x06, 0x6c, 0x6f, 0x67, 0x01, 0x16, 0x48, 0x65, + 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, + 0x64, 0x01, 0x10, 0x66, 0x69, 0x62, 0x28, 0x31, + 0x30, 0x29, 0x3d, 0x0d, 0xe2, 0x03, 0x01, 0xe4, + 0x03, 0x00, 0x00, 0x01, 0x00, 0xe6, 0x03, 0x00, + 0x00, 0x0c, 0x20, 0x0a, 0x01, 0xa8, 0x01, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x32, 0x00, + 0xe6, 0x03, 0x00, 0x1f, 0x08, 0xf0, 0x02, 0x29, + 0x38, 0xf4, 0x00, 0x00, 0x00, 0x41, 0xf5, 0x00, + 0x00, 0x00, 0x04, 0xf6, 0x00, 0x00, 0x00, 0x24, + 0x01, 0x00, 0x0e, 0x38, 0xf4, 0x00, 0x00, 0x00, + 0x41, 0xf5, 0x00, 0x00, 0x00, 0x04, 0xf7, 0x00, + 0x00, 0x00, 0x64, 0x00, 0x00, 0xc2, 0x0a, 0xf5, + 0x24, 0x02, 0x00, 0x0e, 0x06, 0x2f, 0xe2, 0x03, + 0x01, 0x01, 0x0c, 0x00, 0x04, 0x08, 0x00, 0x34, + 0x10, 0x30, 0x0f, 0x34, 0x10, 0x1b, 0x20, 0x00, +}; + +static JSContext *JS_NewCustomContext(JSRuntime *rt) +{ + JSContext *ctx = JS_NewContext(rt); + if (!ctx) + return NULL; + js_std_eval_binary(ctx, qjsc_fib_module, qjsc_fib_module_size, 1); + return ctx; +} + +int main(int argc, char **argv) +{ + int r; + JSRuntime *rt; + JSContext *ctx; + r = 0; + rt = JS_NewRuntime(); + js_std_set_worker_new_context_func(JS_NewCustomContext); + js_std_init_handlers(rt); + JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader, js_module_check_attributes, NULL); + ctx = JS_NewCustomContext(rt); + js_std_add_helpers(ctx, argc, argv); + js_std_eval_binary(ctx, qjsc_hello_module, qjsc_hello_module_size, 0); + r = js_std_loop(ctx); + if (r) { + js_std_dump_error(ctx); + } + js_std_free_handlers(rt); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + return r; +} diff --git a/userland/qjs/source/gen/repl.c b/userland/qjs/source/gen/repl.c new file mode 100644 index 0000000..f39a1d9 --- /dev/null +++ b/userland/qjs/source/gen/repl.c @@ -0,0 +1,3018 @@ +/* File generated automatically by the QuickJS-ng compiler. */ + +#include + +const uint32_t qjsc_repl_size = 24068; + +const uint8_t qjsc_repl[24068] = { + 0x1d, 0xae, 0x62, 0x46, 0x8b, 0xb5, 0x04, 0x01, + 0x0e, 0x72, 0x65, 0x70, 0x6c, 0x2e, 0x6a, 0x73, + 0x01, 0x0e, 0x71, 0x6a, 0x73, 0x3a, 0x73, 0x74, + 0x64, 0x01, 0x0c, 0x71, 0x6a, 0x73, 0x3a, 0x6f, + 0x73, 0x01, 0x12, 0x71, 0x6a, 0x73, 0x3a, 0x62, + 0x6a, 0x73, 0x6f, 0x6e, 0x01, 0x06, 0x73, 0x74, + 0x64, 0x01, 0x04, 0x6f, 0x73, 0x01, 0x0a, 0x62, + 0x6a, 0x73, 0x6f, 0x6e, 0x01, 0x02, 0x67, 0x01, + 0x10, 0x69, 0x73, 0x46, 0x69, 0x6e, 0x69, 0x74, + 0x65, 0x01, 0x0a, 0x69, 0x73, 0x4e, 0x61, 0x4e, + 0x01, 0x10, 0x49, 0x6e, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x79, 0x01, 0x0e, 0x63, 0x6f, 0x6e, 0x73, + 0x6f, 0x6c, 0x65, 0x01, 0x10, 0x6b, 0x65, 0x79, + 0x77, 0x6f, 0x72, 0x64, 0x73, 0x01, 0x0c, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x73, 0x01, 0x0c, 0x74, + 0x68, 0x65, 0x6d, 0x65, 0x73, 0x01, 0x0c, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x73, 0x01, 0x08, 0x75, + 0x74, 0x66, 0x38, 0x01, 0x12, 0x73, 0x68, 0x6f, + 0x77, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x01, 0x16, + 0x73, 0x68, 0x6f, 0x77, 0x5f, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x73, 0x01, 0x16, 0x73, 0x68, 0x6f, + 0x77, 0x5f, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, + 0x01, 0x14, 0x73, 0x68, 0x6f, 0x77, 0x5f, 0x64, + 0x65, 0x70, 0x74, 0x68, 0x01, 0x10, 0x68, 0x65, + 0x78, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x01, 0x14, + 0x75, 0x73, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x69, + 0x63, 0x74, 0x01, 0x0e, 0x68, 0x69, 0x73, 0x74, + 0x6f, 0x72, 0x79, 0x01, 0x1a, 0x68, 0x69, 0x73, + 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x01, 0x14, 0x63, 0x6c, 0x69, 0x70, + 0x5f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x01, 0x0c, + 0x70, 0x73, 0x74, 0x61, 0x74, 0x65, 0x01, 0x0c, + 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x01, 0x08, + 0x70, 0x6c, 0x65, 0x6e, 0x01, 0x06, 0x70, 0x73, + 0x31, 0x01, 0x06, 0x70, 0x73, 0x32, 0x01, 0x1e, + 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x01, + 0x12, 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x01, 0x0a, 0x6d, 0x65, 0x78, 0x70, + 0x72, 0x01, 0x0a, 0x6c, 0x65, 0x76, 0x65, 0x6c, + 0x01, 0x06, 0x63, 0x6d, 0x64, 0x01, 0x14, 0x63, + 0x75, 0x72, 0x73, 0x6f, 0x72, 0x5f, 0x70, 0x6f, + 0x73, 0x01, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, + 0x63, 0x6d, 0x64, 0x01, 0x1e, 0x6c, 0x61, 0x73, + 0x74, 0x5f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, + 0x5f, 0x70, 0x6f, 0x73, 0x01, 0x10, 0x74, 0x68, + 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x01, 0x10, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x66, 0x75, 0x6e, + 0x01, 0x14, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x5f, + 0x66, 0x6c, 0x61, 0x67, 0x01, 0x14, 0x75, 0x74, + 0x66, 0x38, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x01, 0x10, 0x75, 0x74, 0x66, 0x38, 0x5f, 0x76, + 0x61, 0x6c, 0x01, 0x0e, 0x74, 0x65, 0x72, 0x6d, + 0x5f, 0x66, 0x64, 0x01, 0x1a, 0x74, 0x65, 0x72, + 0x6d, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x62, + 0x75, 0x66, 0x01, 0x14, 0x74, 0x65, 0x72, 0x6d, + 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x01, 0x1a, + 0x74, 0x65, 0x72, 0x6d, 0x5f, 0x63, 0x75, 0x72, + 0x73, 0x6f, 0x72, 0x5f, 0x78, 0x01, 0x10, 0x74, + 0x65, 0x72, 0x6d, 0x49, 0x6e, 0x69, 0x74, 0x01, + 0x1c, 0x73, 0x69, 0x67, 0x69, 0x6e, 0x74, 0x5f, + 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x01, + 0x22, 0x74, 0x65, 0x72, 0x6d, 0x5f, 0x72, 0x65, + 0x61, 0x64, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x72, 0x01, 0x16, 0x68, 0x61, 0x6e, 0x64, + 0x6c, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x01, + 0x10, 0x69, 0x73, 0x5f, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x01, 0x10, 0x69, 0x73, 0x5f, 0x64, 0x69, + 0x67, 0x69, 0x74, 0x01, 0x0e, 0x69, 0x73, 0x5f, + 0x77, 0x6f, 0x72, 0x64, 0x01, 0x10, 0x69, 0x73, + 0x5f, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x01, 0x14, + 0x75, 0x63, 0x73, 0x5f, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x01, 0x2a, 0x69, 0x73, 0x5f, 0x74, + 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x5f, + 0x73, 0x75, 0x72, 0x72, 0x6f, 0x67, 0x61, 0x74, + 0x65, 0x01, 0x16, 0x69, 0x73, 0x5f, 0x62, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x01, 0x20, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x5f, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x78, 0x74, + 0x01, 0x12, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x5f, + 0x63, 0x73, 0x69, 0x01, 0x16, 0x6d, 0x6f, 0x76, + 0x65, 0x5f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, + 0x01, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x01, 0x0c, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, + 0x01, 0x1a, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x64, + 0x5f, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x01, + 0x0a, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x01, 0x0a, + 0x61, 0x6c, 0x65, 0x72, 0x74, 0x01, 0x22, 0x62, + 0x65, 0x67, 0x69, 0x6e, 0x6e, 0x69, 0x6e, 0x67, + 0x5f, 0x6f, 0x66, 0x5f, 0x6c, 0x69, 0x6e, 0x65, + 0x01, 0x16, 0x65, 0x6e, 0x64, 0x5f, 0x6f, 0x66, + 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x01, 0x18, 0x66, + 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x5f, 0x63, + 0x68, 0x61, 0x72, 0x01, 0x1a, 0x62, 0x61, 0x63, + 0x6b, 0x77, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x68, + 0x61, 0x72, 0x01, 0x22, 0x73, 0x6b, 0x69, 0x70, + 0x5f, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x66, 0x6f, + 0x72, 0x77, 0x61, 0x72, 0x64, 0x01, 0x24, 0x73, + 0x6b, 0x69, 0x70, 0x5f, 0x77, 0x6f, 0x72, 0x64, + 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x77, 0x61, 0x72, + 0x64, 0x01, 0x18, 0x66, 0x6f, 0x72, 0x77, 0x61, + 0x72, 0x64, 0x5f, 0x77, 0x6f, 0x72, 0x64, 0x01, + 0x1a, 0x62, 0x61, 0x63, 0x6b, 0x77, 0x61, 0x72, + 0x64, 0x5f, 0x77, 0x6f, 0x72, 0x64, 0x01, 0x18, + 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x73, 0x63, + 0x72, 0x65, 0x65, 0x6e, 0x01, 0x16, 0x61, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x5f, 0x6c, 0x69, 0x6e, + 0x65, 0x01, 0x16, 0x68, 0x69, 0x73, 0x74, 0x6f, + 0x72, 0x79, 0x5f, 0x61, 0x64, 0x64, 0x01, 0x20, + 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, + 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, + 0x01, 0x18, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x68, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x01, 0x1c, + 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x5f, + 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x01, 0x2e, + 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x5f, + 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, + 0x61, 0x63, 0x6b, 0x77, 0x61, 0x72, 0x64, 0x01, + 0x2c, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, + 0x5f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, + 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x01, + 0x1e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, + 0x63, 0x68, 0x61, 0x72, 0x5f, 0x64, 0x69, 0x72, + 0x01, 0x16, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x5f, 0x63, 0x68, 0x61, 0x72, 0x01, 0x12, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x64, + 0x01, 0x28, 0x62, 0x61, 0x63, 0x6b, 0x77, 0x61, + 0x72, 0x64, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x01, 0x1e, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x73, + 0x65, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x73, 0x01, + 0x1e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, + 0x73, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x64, 0x73, + 0x01, 0x16, 0x75, 0x70, 0x63, 0x61, 0x73, 0x65, + 0x5f, 0x77, 0x6f, 0x72, 0x64, 0x01, 0x1a, 0x64, + 0x6f, 0x77, 0x6e, 0x63, 0x61, 0x73, 0x65, 0x5f, + 0x77, 0x6f, 0x72, 0x64, 0x01, 0x16, 0x6b, 0x69, + 0x6c, 0x6c, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x6f, + 0x6e, 0x01, 0x12, 0x6b, 0x69, 0x6c, 0x6c, 0x5f, + 0x6c, 0x69, 0x6e, 0x65, 0x01, 0x24, 0x62, 0x61, + 0x63, 0x6b, 0x77, 0x61, 0x72, 0x64, 0x5f, 0x6b, + 0x69, 0x6c, 0x6c, 0x5f, 0x6c, 0x69, 0x6e, 0x65, + 0x01, 0x12, 0x6b, 0x69, 0x6c, 0x6c, 0x5f, 0x77, + 0x6f, 0x72, 0x64, 0x01, 0x24, 0x62, 0x61, 0x63, + 0x6b, 0x77, 0x61, 0x72, 0x64, 0x5f, 0x6b, 0x69, + 0x6c, 0x6c, 0x5f, 0x77, 0x6f, 0x72, 0x64, 0x01, + 0x08, 0x79, 0x61, 0x6e, 0x6b, 0x01, 0x12, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x63, + 0x01, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x74, 0x01, + 0x22, 0x69, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x01, 0x20, 0x67, 0x65, 0x74, 0x5f, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, + 0x77, 0x6f, 0x72, 0x64, 0x01, 0x24, 0x67, 0x65, + 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x01, 0x1e, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x01, 0x14, 0x63, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x01, 0x10, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x01, + 0x0c, 0x64, 0x75, 0x70, 0x73, 0x74, 0x72, 0x01, + 0x1a, 0x72, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, + 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x01, 0x1c, + 0x72, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x01, 0x16, + 0x72, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, + 0x5f, 0x63, 0x62, 0x01, 0x2a, 0x72, 0x65, 0x61, + 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x6d, + 0x70, 0x74, 0x01, 0x1c, 0x72, 0x65, 0x61, 0x64, + 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x01, 0x16, 0x68, 0x61, 0x6e, 0x64, + 0x6c, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x01, + 0x14, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x5f, + 0x6b, 0x65, 0x79, 0x01, 0x20, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x5f, 0x74, 0x6f, 0x5f, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x01, 0x20, 0x62, + 0x69, 0x67, 0x69, 0x6e, 0x74, 0x5f, 0x74, 0x6f, + 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x01, + 0x08, 0x75, 0x74, 0x69, 0x6c, 0x01, 0x0a, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x01, 0x20, 0x68, 0x61, + 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x01, 0x08, + 0x68, 0x65, 0x6c, 0x70, 0x01, 0x08, 0x6c, 0x6f, + 0x61, 0x64, 0x01, 0x08, 0x65, 0x78, 0x69, 0x74, + 0x01, 0x0e, 0x74, 0x6f, 0x5f, 0x62, 0x6f, 0x6f, + 0x6c, 0x01, 0x14, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x73, 0x01, 0x12, 0x63, + 0x6d, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x01, 0x24, 0x63, 0x6d, 0x64, 0x5f, 0x72, 0x65, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x01, 0x26, 0x72, 0x65, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x68, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x63, 0x6d, + 0x64, 0x01, 0x14, 0x68, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x5f, 0x63, 0x6d, 0x64, 0x01, 0x1c, 0x65, + 0x76, 0x61, 0x6c, 0x5f, 0x61, 0x6e, 0x64, 0x5f, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x01, 0x22, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x5f, 0x65, 0x76, 0x61, + 0x6c, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x01, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x5f, + 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x01, 0x1c, 0x68, 0x61, 0x6e, 0x64, + 0x6c, 0x65, 0x5f, 0x63, 0x6d, 0x64, 0x5f, 0x65, + 0x6e, 0x64, 0x01, 0x16, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x5f, 0x6a, 0x73, 0x01, + 0x16, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, + 0x66, 0x69, 0x6c, 0x65, 0x01, 0x18, 0x73, 0x61, + 0x76, 0x65, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, + 0x72, 0x79, 0x01, 0x18, 0x6c, 0x6f, 0x61, 0x64, + 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, + 0x01, 0x16, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x01, 0x06, 0x74, + 0x61, 0x62, 0x01, 0x0c, 0x66, 0x69, 0x6c, 0x65, + 0x6e, 0x6f, 0x01, 0x0c, 0x69, 0x73, 0x61, 0x74, + 0x74, 0x79, 0x01, 0x1a, 0x74, 0x74, 0x79, 0x47, + 0x65, 0x74, 0x57, 0x69, 0x6e, 0x53, 0x69, 0x7a, + 0x65, 0x01, 0x12, 0x74, 0x74, 0x79, 0x53, 0x65, + 0x74, 0x52, 0x61, 0x77, 0x01, 0x0c, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x6c, 0x01, 0x0c, 0x53, 0x49, + 0x47, 0x49, 0x4e, 0x54, 0x01, 0x1c, 0x73, 0x65, + 0x74, 0x52, 0x65, 0x61, 0x64, 0x48, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x72, 0x01, 0x02, 0x6c, 0x01, + 0x02, 0x69, 0x01, 0x08, 0x72, 0x65, 0x61, 0x64, + 0x01, 0x0c, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x01, 0x02, 0x63, 0x01, 0x02, 0x41, 0x01, 0x02, + 0x5a, 0x01, 0x02, 0x61, 0x01, 0x02, 0x7a, 0x01, + 0x02, 0x5f, 0x01, 0x02, 0x24, 0x01, 0x0a, 0x09, + 0x0d, 0x0a, 0x0c, 0x0b, 0x01, 0x10, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x01, 0x06, + 0x73, 0x74, 0x72, 0x01, 0x06, 0x6c, 0x65, 0x6e, + 0x01, 0x0e, 0x73, 0x74, 0x72, 0x5f, 0x6c, 0x65, + 0x6e, 0x01, 0x14, 0x63, 0x68, 0x61, 0x72, 0x43, + 0x6f, 0x64, 0x65, 0x41, 0x74, 0x01, 0x02, 0x64, + 0x01, 0x16, 0x63, 0x6f, 0x64, 0x65, 0x50, 0x6f, + 0x69, 0x6e, 0x74, 0x41, 0x74, 0x01, 0x02, 0x62, + 0x01, 0x04, 0x28, 0x29, 0x01, 0x04, 0x5b, 0x5d, + 0x01, 0x04, 0x7b, 0x7d, 0x01, 0x0a, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x01, 0x16, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x01, 0x02, 0x6a, 0x01, 0x0a, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x01, 0x08, 0x70, 0x75, 0x74, 0x73, + 0x01, 0x08, 0x6e, 0x6f, 0x6e, 0x65, 0x01, 0x12, + 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x01, 0x02, 0x6e, 0x01, 0x08, 0x63, 0x6f, + 0x64, 0x65, 0x01, 0x04, 0x1b, 0x5b, 0x01, 0x0a, + 0x64, 0x65, 0x6c, 0x74, 0x61, 0x01, 0x02, 0x0a, + 0x01, 0x06, 0x6d, 0x69, 0x6e, 0x01, 0x02, 0x43, + 0x01, 0x02, 0x44, 0x01, 0x0e, 0x63, 0x6d, 0x64, + 0x5f, 0x6c, 0x65, 0x6e, 0x01, 0x14, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x01, 0x04, 0x20, 0x08, 0x01, 0x06, 0x1b, 0x5b, + 0x4a, 0x01, 0x06, 0x6f, 0x75, 0x74, 0x01, 0x0a, + 0x66, 0x6c, 0x75, 0x73, 0x68, 0x01, 0x0c, 0x63, + 0x68, 0x61, 0x72, 0x41, 0x74, 0x01, 0x06, 0x70, + 0x6f, 0x73, 0x01, 0x0a, 0x63, 0x6c, 0x65, 0x61, + 0x72, 0x01, 0x12, 0x74, 0x72, 0x69, 0x6d, 0x52, + 0x69, 0x67, 0x68, 0x74, 0x01, 0x08, 0x70, 0x75, + 0x73, 0x68, 0x01, 0x06, 0x64, 0x69, 0x72, 0x01, + 0x06, 0x65, 0x6e, 0x64, 0x01, 0x04, 0x70, 0x31, + 0x01, 0x04, 0x70, 0x32, 0x01, 0x04, 0x70, 0x34, + 0x01, 0x04, 0x70, 0x33, 0x01, 0x16, 0x74, 0x6f, + 0x55, 0x70, 0x70, 0x65, 0x72, 0x43, 0x61, 0x73, + 0x65, 0x01, 0x16, 0x74, 0x6f, 0x4c, 0x6f, 0x77, + 0x65, 0x72, 0x43, 0x61, 0x73, 0x65, 0x01, 0x02, + 0x73, 0x01, 0x3c, 0x0a, 0x28, 0x50, 0x72, 0x65, + 0x73, 0x73, 0x20, 0x43, 0x74, 0x72, 0x6c, 0x2d, + 0x43, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, 0x20, + 0x74, 0x6f, 0x20, 0x71, 0x75, 0x69, 0x74, 0x29, + 0x0a, 0x01, 0x08, 0x6c, 0x69, 0x6e, 0x65, 0x01, + 0x02, 0x2e, 0x01, 0x0a, 0x73, 0x6c, 0x69, 0x63, + 0x65, 0x01, 0x08, 0x62, 0x61, 0x73, 0x65, 0x01, + 0x10, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x6f, + 0x73, 0x01, 0x06, 0x6f, 0x62, 0x6a, 0x01, 0x02, + 0x5c, 0x01, 0x12, 0x27, 0x22, 0x60, 0x40, 0x23, + 0x29, 0x5d, 0x7d, 0x5c, 0x01, 0x0e, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x4f, 0x66, 0x01, 0x02, 0x27, + 0x01, 0x02, 0x22, 0x01, 0x02, 0x60, 0x01, 0x02, + 0x5d, 0x01, 0x02, 0x2f, 0x01, 0x0a, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x01, 0x0e, 0x63, 0x74, 0x78, + 0x5f, 0x6f, 0x62, 0x6a, 0x01, 0x02, 0x72, 0x01, + 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x01, 0x04, + 0x6b, 0x77, 0x01, 0x0a, 0x70, 0x72, 0x6f, 0x70, + 0x73, 0x01, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x01, + 0x0c, 0x73, 0x79, 0x6d, 0x63, 0x6d, 0x70, 0x01, + 0x14, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x57, + 0x69, 0x74, 0x68, 0x01, 0x26, 0x67, 0x65, 0x74, + 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x01, 0x08, 0x73, 0x6f, 0x72, 0x74, 0x01, 0x06, + 0x63, 0x74, 0x78, 0x01, 0x06, 0x72, 0x65, 0x73, + 0x01, 0x02, 0x74, 0x01, 0x12, 0x6d, 0x61, 0x78, + 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x01, 0x06, + 0x63, 0x6f, 0x6c, 0x01, 0x0c, 0x6e, 0x5f, 0x63, + 0x6f, 0x6c, 0x73, 0x01, 0x06, 0x72, 0x6f, 0x77, + 0x01, 0x0c, 0x6e, 0x5f, 0x72, 0x6f, 0x77, 0x73, + 0x01, 0x02, 0x6d, 0x01, 0x02, 0x28, 0x01, 0x02, + 0x29, 0x01, 0x06, 0x6d, 0x61, 0x78, 0x01, 0x0a, + 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x01, 0x08, 0x63, + 0x65, 0x69, 0x6c, 0x01, 0x0c, 0x70, 0x61, 0x64, + 0x45, 0x6e, 0x64, 0x01, 0x0a, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x01, 0x0c, 0x64, 0x65, 0x66, 0x73, + 0x74, 0x72, 0x01, 0x04, 0x63, 0x62, 0x01, 0x02, + 0x20, 0x01, 0x0e, 0x74, 0x6f, 0x46, 0x69, 0x78, + 0x65, 0x64, 0x01, 0x04, 0x63, 0x31, 0x01, 0x1a, + 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x6f, 0x64, 0x65, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x01, 0x02, 0x1b, + 0x01, 0x02, 0x5b, 0x01, 0x02, 0x4f, 0x01, 0x02, + 0x3b, 0x01, 0x06, 0x66, 0x75, 0x6e, 0x01, 0x0a, + 0x72, 0x61, 0x64, 0x69, 0x78, 0x01, 0x04, 0x2d, + 0x30, 0x01, 0x02, 0x2d, 0x01, 0x04, 0x30, 0x78, + 0x01, 0x06, 0x76, 0x61, 0x6c, 0x01, 0x12, 0x6d, + 0x61, 0x78, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, + 0x01, 0x14, 0x75, 0x73, 0x65, 0x5f, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x73, 0x01, 0x0e, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x01, 0x16, 0x62, + 0x72, 0x65, 0x61, 0x6b, 0x4c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x01, 0x1c, 0x6d, 0x61, 0x78, 0x41, + 0x72, 0x72, 0x61, 0x79, 0x4c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x01, 0x1e, 0x6d, 0x61, 0x78, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x01, 0x1e, 0x6d, 0x61, 0x78, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x01, 0x08, 0x72, 0x65, + 0x66, 0x73, 0x01, 0x0c, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x73, 0x01, 0x0c, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x01, 0x14, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x01, 0x12, + 0x71, 0x75, 0x6f, 0x74, 0x65, 0x5f, 0x73, 0x74, + 0x72, 0x01, 0x14, 0x70, 0x75, 0x73, 0x68, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x01, 0x18, 0x61, + 0x70, 0x70, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x01, 0x12, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x5f, 0x74, 0x61, 0x67, 0x01, 0x12, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x5f, 0x72, 0x65, + 0x63, 0x01, 0x14, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x5f, 0x73, 0x74, 0x72, 0x01, 0x1e, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x70, 0x72, + 0x6f, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x01, 0x1a, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x70, + 0x72, 0x65, 0x74, 0x74, 0x79, 0x01, 0x10, 0x69, + 0x73, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x01, + 0x16, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x01, 0x1a, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x5f, 0x73, 0x69, 0x6e, + 0x67, 0x6c, 0x65, 0x01, 0x1a, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x5f, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x73, 0x01, 0x1a, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x6e, + 0x74, 0x01, 0x06, 0x6f, 0x70, 0x74, 0x01, 0x06, + 0x64, 0x65, 0x66, 0x01, 0x12, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x69, 0x66, 0x79, 0x01, 0x14, + 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x41, + 0x6c, 0x6c, 0x01, 0x04, 0x5c, 0x22, 0x01, 0x02, + 0x6f, 0x01, 0x08, 0x63, 0x61, 0x6c, 0x6c, 0x01, + 0x04, 0x6e, 0x30, 0x01, 0x02, 0x6b, 0x01, 0x06, + 0x6b, 0x65, 0x79, 0x01, 0x08, 0x74, 0x79, 0x70, + 0x65, 0x01, 0x0e, 0x69, 0x73, 0x61, 0x72, 0x72, + 0x61, 0x79, 0x01, 0x0e, 0x6e, 0x6f, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x01, 0x0c, 0x6e, 0x6f, 0x6b, + 0x65, 0x79, 0x73, 0x01, 0x0a, 0x62, 0x72, 0x61, + 0x63, 0x65, 0x01, 0x06, 0x73, 0x65, 0x70, 0x01, + 0x12, 0x6f, 0x62, 0x6a, 0x5f, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x01, 0x06, 0x74, 0x61, 0x67, 0x01, + 0x08, 0x63, 0x6f, 0x6e, 0x73, 0x01, 0x08, 0x64, + 0x65, 0x73, 0x63, 0x01, 0x0c, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x01, 0x06, 0x2e, 0x2e, 0x2e, + 0x01, 0x16, 0x5b, 0x43, 0x69, 0x72, 0x63, 0x75, + 0x6c, 0x61, 0x72, 0x20, 0x2a, 0x01, 0x0a, 0x44, + 0x61, 0x74, 0x65, 0x20, 0x01, 0x16, 0x74, 0x6f, + 0x47, 0x4d, 0x54, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x01, 0x04, 0x3a, 0x20, 0x01, 0x0e, 0x69, + 0x73, 0x41, 0x72, 0x72, 0x61, 0x79, 0x01, 0x06, + 0x29, 0x20, 0x5b, 0x01, 0x16, 0x5b, 0x46, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, + 0x01, 0x2c, 0x5b, 0x46, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x61, 0x6e, 0x6f, + 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x29, 0x5d, + 0x01, 0x04, 0x20, 0x5b, 0x01, 0x06, 0x5d, 0x20, + 0x7b, 0x01, 0x26, 0x3a, 0x20, 0x6e, 0x75, 0x6c, + 0x6c, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, + 0x79, 0x70, 0x65, 0x5d, 0x20, 0x7b, 0x01, 0x04, + 0x20, 0x7b, 0x01, 0x02, 0x7b, 0x01, 0x02, 0x7d, + 0x01, 0x02, 0x3c, 0x01, 0x1a, 0x20, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x20, 0x69, 0x74, 0x65, 0x6d, + 0x73, 0x3e, 0x01, 0x0e, 0x3c, 0x65, 0x6d, 0x70, + 0x74, 0x79, 0x3e, 0x01, 0x08, 0x2e, 0x2e, 0x2e, + 0x20, 0x01, 0x16, 0x20, 0x6d, 0x6f, 0x72, 0x65, + 0x20, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x01, 0x02, + 0x3a, 0x01, 0x0c, 0x47, 0x65, 0x74, 0x74, 0x65, + 0x72, 0x01, 0x0c, 0x53, 0x65, 0x74, 0x74, 0x65, + 0x72, 0x01, 0x20, 0x20, 0x6d, 0x6f, 0x72, 0x65, + 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x65, 0x73, 0x01, 0x06, 0x70, 0x6f, 0x70, + 0x01, 0x0c, 0x3c, 0x72, 0x65, 0x66, 0x20, 0x2a, + 0x01, 0x04, 0x3e, 0x20, 0x01, 0x0a, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x01, 0x10, 0x70, 0x72, 0x6f, + 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x01, 0x0a, 0x63, + 0x68, 0x75, 0x6e, 0x6b, 0x01, 0x0c, 0x72, 0x65, + 0x67, 0x65, 0x78, 0x70, 0x01, 0x14, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x01, 0x02, 0x2c, 0x01, 0x0a, 0x6f, 0x74, 0x68, + 0x65, 0x72, 0x01, 0x08, 0x64, 0x61, 0x74, 0x65, + 0x01, 0x06, 0x4e, 0x61, 0x4e, 0x01, 0x0e, 0x6b, + 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x01, 0x02, + 0x77, 0x01, 0x0a, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x01, 0x0c, 0x73, 0x65, 0x70, 0x6c, 0x65, 0x6e, + 0x01, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x01, 0x04, + 0x2c, 0x20, 0x01, 0x0c, 0x72, 0x65, 0x70, 0x65, + 0x61, 0x74, 0x01, 0x0c, 0x69, 0x6e, 0x64, 0x65, + 0x6e, 0x74, 0x01, 0x16, 0x61, 0x76, 0x61, 0x69, + 0x6c, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x01, + 0x0a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x01, 0x08, + 0x63, 0x6f, 0x6c, 0x73, 0x01, 0x10, 0x63, 0x6f, + 0x6c, 0x77, 0x69, 0x64, 0x74, 0x68, 0x01, 0x10, + 0x65, 0x6e, 0x64, 0x73, 0x57, 0x69, 0x74, 0x68, + 0x01, 0x14, 0x73, 0x68, 0x6f, 0x77, 0x48, 0x69, + 0x64, 0x64, 0x65, 0x6e, 0x01, 0x0a, 0x64, 0x65, + 0x70, 0x74, 0x68, 0x01, 0x0e, 0x69, 0x6e, 0x73, + 0x70, 0x65, 0x63, 0x74, 0x01, 0x0e, 0x70, 0x61, + 0x72, 0x74, 0x69, 0x61, 0x6c, 0x01, 0x02, 0x70, + 0x01, 0x02, 0x3f, 0x01, 0x08, 0x74, 0x72, 0x69, + 0x6d, 0x01, 0x26, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x3a, 0x20, 0x01, 0x06, + 0x73, 0x65, 0x6c, 0x01, 0x32, 0x2e, 0x68, 0x65, + 0x6c, 0x70, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x20, 0x68, 0x65, 0x6c, 0x70, 0x0a, 0x01, 0x10, + 0x2e, 0x78, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x01, 0x36, 0x68, 0x65, 0x78, 0x61, 0x64, 0x65, + 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x20, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x20, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x0a, 0x01, 0x10, 0x2e, + 0x64, 0x65, 0x63, 0x20, 0x20, 0x20, 0x20, 0x01, + 0x2e, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, + 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x0a, + 0x01, 0x10, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x20, + 0x20, 0x20, 0x01, 0x2c, 0x74, 0x6f, 0x67, 0x67, + 0x6c, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x69, 0x6e, + 0x67, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x0a, 0x01, 0x10, 0x2e, 0x73, 0x74, 0x72, + 0x69, 0x63, 0x74, 0x20, 0x01, 0x3c, 0x74, 0x6f, + 0x67, 0x67, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x63, 0x74, 0x20, 0x6d, 0x6f, 0x64, 0x65, + 0x20, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x0a, 0x01, 0x48, 0x2e, 0x64, + 0x65, 0x70, 0x74, 0x68, 0x20, 0x20, 0x20, 0x73, + 0x65, 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x20, 0x64, 0x65, 0x70, 0x74, 0x68, 0x20, + 0x28, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x3a, 0x20, 0x01, 0x04, 0x29, 0x0a, 0x01, 0x10, + 0x2e, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x20, + 0x01, 0x42, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, + 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x20, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, + 0x65, 0x73, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x0a, 0x01, 0x10, 0x2e, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x20, 0x20, 0x01, 0x2c, 0x74, + 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x20, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x0a, 0x01, 0x10, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x20, 0x20, 0x20, 0x01, + 0x08, 0x64, 0x61, 0x72, 0x6b, 0x01, 0x30, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x64, 0x61, + 0x72, 0x6b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x20, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x0a, 0x01, + 0x10, 0x2e, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x20, + 0x20, 0x01, 0x0a, 0x6c, 0x69, 0x67, 0x68, 0x74, + 0x01, 0x32, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x20, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, + 0x6d, 0x65, 0x0a, 0x01, 0x38, 0x2e, 0x63, 0x6c, + 0x65, 0x61, 0x72, 0x20, 0x20, 0x20, 0x63, 0x6c, + 0x65, 0x61, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, + 0x0a, 0x01, 0x4c, 0x2e, 0x6c, 0x6f, 0x61, 0x64, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x61, 0x64, + 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, + 0x63, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x72, 0x6f, + 0x6d, 0x20, 0x61, 0x20, 0x66, 0x69, 0x6c, 0x65, + 0x0a, 0x01, 0x1c, 0x2e, 0x71, 0x75, 0x69, 0x74, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x78, 0x69, 0x74, + 0x0a, 0x01, 0x02, 0x65, 0x01, 0x16, 0x6c, 0x61, + 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4f, + 0x66, 0x01, 0x06, 0x2e, 0x6a, 0x73, 0x01, 0x14, + 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x01, 0x1c, 0x31, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x20, 0x79, 0x65, 0x73, 0x20, 0x59, + 0x65, 0x73, 0x01, 0x0c, 0x1b, 0x5b, 0x48, 0x1b, + 0x5b, 0x4a, 0x01, 0x46, 0x51, 0x75, 0x69, 0x63, + 0x6b, 0x4a, 0x53, 0x2d, 0x6e, 0x67, 0x20, 0x2d, + 0x20, 0x54, 0x79, 0x70, 0x65, 0x20, 0x22, 0x2e, + 0x68, 0x65, 0x6c, 0x70, 0x22, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x0a, 0x01, + 0x08, 0x20, 0x20, 0x20, 0x20, 0x01, 0x08, 0x65, + 0x78, 0x70, 0x72, 0x01, 0x0c, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x01, 0x2a, 0x22, 0x75, 0x73, + 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, + 0x22, 0x3b, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x20, + 0x30, 0x3b, 0x01, 0x06, 0x6e, 0x6f, 0x77, 0x01, + 0x14, 0x65, 0x76, 0x61, 0x6c, 0x53, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x01, 0x22, 0x62, 0x61, 0x63, + 0x6b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x62, + 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x01, 0x0e, + 0x54, 0x68, 0x72, 0x6f, 0x77, 0x3a, 0x20, 0x01, + 0x04, 0x67, 0x63, 0x01, 0x0a, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x01, 0x0e, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x01, 0x12, 0x63, 0x61, 0x6e, + 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x01, 0x14, + 0x70, 0x75, 0x73, 0x68, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x01, 0x14, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x01, 0x12, + 0x70, 0x6f, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x01, 0x26, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x63, + 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x24, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x6c, 0x69, + 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, + 0x6e, 0x74, 0x01, 0x18, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x01, 0x16, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, + 0x72, 0x65, 0x67, 0x65, 0x78, 0x01, 0x18, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x5f, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x01, 0x16, 0x6a, 0x73, 0x5f, + 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, + 0x01, 0x16, 0x6a, 0x73, 0x5f, 0x6e, 0x6f, 0x5f, + 0x72, 0x65, 0x67, 0x65, 0x78, 0x01, 0x10, 0x6a, + 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x01, + 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x01, 0x12, 0x73, 0x65, 0x74, 0x5f, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x01, 0x0e, 0x63, 0x6f, + 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x0a, 0x64, + 0x65, 0x6c, 0x69, 0x6d, 0x01, 0x04, 0x69, 0x31, + 0x01, 0x02, 0x7c, 0x01, 0x14, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x01, + 0x04, 0x74, 0x6f, 0x01, 0x6a, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x7c, 0x63, 0x61, 0x73, 0x65, 0x7c, + 0x63, 0x61, 0x74, 0x63, 0x68, 0x7c, 0x63, 0x6f, + 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x7c, 0x64, + 0x65, 0x62, 0x75, 0x67, 0x67, 0x65, 0x72, 0x7c, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x7c, + 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x7c, 0x64, + 0x6f, 0x7c, 0x01, 0x5e, 0x65, 0x6c, 0x73, 0x65, + 0x7c, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, + 0x7c, 0x66, 0x6f, 0x72, 0x7c, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x7c, 0x69, 0x66, + 0x7c, 0x69, 0x6e, 0x7c, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x7c, 0x6e, + 0x65, 0x77, 0x7c, 0x01, 0x5e, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x7c, 0x73, 0x77, 0x69, 0x74, + 0x63, 0x68, 0x7c, 0x74, 0x68, 0x69, 0x73, 0x7c, + 0x74, 0x68, 0x72, 0x6f, 0x77, 0x7c, 0x74, 0x72, + 0x79, 0x7c, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, + 0x7c, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x7c, 0x77, + 0x69, 0x74, 0x68, 0x7c, 0x01, 0x5a, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x7c, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x7c, 0x65, 0x6e, 0x75, 0x6d, 0x7c, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x7c, 0x65, 0x78, + 0x70, 0x6f, 0x72, 0x74, 0x7c, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x64, 0x73, 0x7c, 0x73, 0x75, 0x70, + 0x65, 0x72, 0x7c, 0x01, 0x66, 0x69, 0x6d, 0x70, + 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x7c, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, + 0x65, 0x7c, 0x6c, 0x65, 0x74, 0x7c, 0x70, 0x61, + 0x63, 0x6b, 0x61, 0x67, 0x65, 0x7c, 0x70, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x7c, 0x70, 0x72, + 0x6f, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x7c, + 0x01, 0x28, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x7c, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x7c, + 0x79, 0x69, 0x65, 0x6c, 0x64, 0x7c, 0x01, 0x4e, + 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, + 0x64, 0x7c, 0x6e, 0x75, 0x6c, 0x6c, 0x7c, 0x74, + 0x72, 0x75, 0x65, 0x7c, 0x66, 0x61, 0x6c, 0x73, + 0x65, 0x7c, 0x49, 0x6e, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x79, 0x7c, 0x4e, 0x61, 0x4e, 0x7c, 0x01, + 0x1e, 0x65, 0x76, 0x61, 0x6c, 0x7c, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x7c, + 0x01, 0x0c, 0x61, 0x77, 0x61, 0x69, 0x74, 0x7c, + 0x01, 0x7a, 0x7c, 0x74, 0x68, 0x69, 0x73, 0x7c, + 0x73, 0x75, 0x70, 0x65, 0x72, 0x7c, 0x75, 0x6e, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x7c, + 0x6e, 0x75, 0x6c, 0x6c, 0x7c, 0x74, 0x72, 0x75, + 0x65, 0x7c, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x7c, + 0x49, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, + 0x7c, 0x4e, 0x61, 0x4e, 0x7c, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x7c, 0x01, + 0x14, 0x7c, 0x76, 0x6f, 0x69, 0x64, 0x7c, 0x76, + 0x61, 0x72, 0x7c, 0x01, 0x02, 0x09, 0x01, 0x02, + 0x0d, 0x01, 0x02, 0x2b, 0x01, 0x1c, 0x78, 0x64, + 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, + 0x68, 0x6f, 0x6d, 0x65, 0x01, 0x08, 0x68, 0x6f, + 0x6d, 0x65, 0x01, 0x0c, 0x67, 0x65, 0x74, 0x65, + 0x6e, 0x76, 0x01, 0x1c, 0x58, 0x44, 0x47, 0x5f, + 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x48, 0x4f, + 0x4d, 0x45, 0x01, 0x08, 0x48, 0x4f, 0x4d, 0x45, + 0x01, 0x10, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x01, 0x0a, 0x6c, 0x69, 0x6e, 0x75, + 0x78, 0x01, 0x1a, 0x2f, 0x2e, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x01, 0x08, 0x73, 0x74, 0x61, 0x74, 0x01, 0x16, + 0x55, 0x53, 0x45, 0x52, 0x50, 0x52, 0x4f, 0x46, + 0x49, 0x4c, 0x45, 0x01, 0x04, 0x2f, 0x2e, 0x01, + 0x02, 0x66, 0x01, 0x08, 0x6f, 0x70, 0x65, 0x6e, + 0x01, 0x16, 0x71, 0x6a, 0x73, 0x5f, 0x68, 0x69, + 0x73, 0x74, 0x6f, 0x72, 0x79, 0x01, 0x0a, 0x63, + 0x6c, 0x6f, 0x73, 0x65, 0x01, 0x10, 0x6c, 0x6f, + 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x01, 0x12, + 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x46, 0x47, 0x42, + 0x47, 0x01, 0x10, 0x4e, 0x4f, 0x5f, 0x43, 0x4f, + 0x4c, 0x4f, 0x52, 0x01, 0x0c, 0x61, 0x77, 0x61, + 0x69, 0x74, 0x20, 0x01, 0x0e, 0x63, 0x61, 0x74, + 0x63, 0x68, 0x20, 0x28, 0x01, 0x0c, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x20, 0x01, 0x0c, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x20, 0x01, 0x0a, 0x65, 0x6c, + 0x73, 0x65, 0x20, 0x01, 0x0e, 0x65, 0x78, 0x70, + 0x6f, 0x72, 0x74, 0x20, 0x01, 0x08, 0x66, 0x6f, + 0x72, 0x20, 0x01, 0x12, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x01, 0x08, 0x69, + 0x66, 0x20, 0x28, 0x01, 0x0e, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x20, 0x01, 0x16, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, + 0x20, 0x01, 0x08, 0x6c, 0x65, 0x74, 0x20, 0x01, + 0x08, 0x6e, 0x65, 0x77, 0x20, 0x01, 0x0c, 0x73, + 0x75, 0x70, 0x65, 0x72, 0x20, 0x01, 0x0a, 0x74, + 0x72, 0x79, 0x20, 0x7b, 0x01, 0x0e, 0x74, 0x79, + 0x70, 0x65, 0x6f, 0x66, 0x20, 0x01, 0x08, 0x76, + 0x61, 0x72, 0x20, 0x01, 0x0e, 0x77, 0x68, 0x69, + 0x6c, 0x65, 0x20, 0x28, 0x01, 0x0c, 0x79, 0x69, + 0x65, 0x6c, 0x64, 0x20, 0x01, 0x08, 0x1b, 0x5b, + 0x30, 0x6d, 0x01, 0x0a, 0x1b, 0x5b, 0x33, 0x30, + 0x6d, 0x01, 0x0a, 0x62, 0x6c, 0x61, 0x63, 0x6b, + 0x01, 0x0a, 0x1b, 0x5b, 0x33, 0x31, 0x6d, 0x01, + 0x06, 0x72, 0x65, 0x64, 0x01, 0x0a, 0x1b, 0x5b, + 0x33, 0x32, 0x6d, 0x01, 0x0a, 0x67, 0x72, 0x65, + 0x65, 0x6e, 0x01, 0x0a, 0x1b, 0x5b, 0x33, 0x33, + 0x6d, 0x01, 0x0c, 0x79, 0x65, 0x6c, 0x6c, 0x6f, + 0x77, 0x01, 0x0a, 0x1b, 0x5b, 0x33, 0x34, 0x6d, + 0x01, 0x08, 0x62, 0x6c, 0x75, 0x65, 0x01, 0x0a, + 0x1b, 0x5b, 0x33, 0x35, 0x6d, 0x01, 0x0e, 0x6d, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x61, 0x01, 0x0a, + 0x1b, 0x5b, 0x33, 0x36, 0x6d, 0x01, 0x08, 0x63, + 0x79, 0x61, 0x6e, 0x01, 0x0a, 0x1b, 0x5b, 0x33, + 0x37, 0x6d, 0x01, 0x0a, 0x77, 0x68, 0x69, 0x74, + 0x65, 0x01, 0x0e, 0x1b, 0x5b, 0x33, 0x30, 0x3b, + 0x31, 0x6d, 0x01, 0x08, 0x67, 0x72, 0x61, 0x79, + 0x01, 0x08, 0x67, 0x72, 0x65, 0x79, 0x01, 0x0e, + 0x1b, 0x5b, 0x33, 0x31, 0x3b, 0x31, 0x6d, 0x01, + 0x14, 0x62, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, + 0x72, 0x65, 0x64, 0x01, 0x0e, 0x1b, 0x5b, 0x33, + 0x32, 0x3b, 0x31, 0x6d, 0x01, 0x18, 0x62, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x5f, 0x67, 0x72, 0x65, + 0x65, 0x6e, 0x01, 0x0e, 0x1b, 0x5b, 0x33, 0x33, + 0x3b, 0x31, 0x6d, 0x01, 0x1a, 0x62, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x5f, 0x79, 0x65, 0x6c, 0x6c, + 0x6f, 0x77, 0x01, 0x0e, 0x1b, 0x5b, 0x33, 0x34, + 0x3b, 0x31, 0x6d, 0x01, 0x16, 0x62, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x5f, 0x62, 0x6c, 0x75, 0x65, + 0x01, 0x0e, 0x1b, 0x5b, 0x33, 0x35, 0x3b, 0x31, + 0x6d, 0x01, 0x1c, 0x62, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x5f, 0x6d, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x61, 0x01, 0x0e, 0x1b, 0x5b, 0x33, 0x36, 0x3b, + 0x31, 0x6d, 0x01, 0x16, 0x62, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x5f, 0x63, 0x79, 0x61, 0x6e, 0x01, + 0x0e, 0x1b, 0x5b, 0x33, 0x37, 0x3b, 0x31, 0x6d, + 0x01, 0x18, 0x62, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x5f, 0x77, 0x68, 0x69, 0x74, 0x65, 0x01, 0x0c, + 0x71, 0x6a, 0x73, 0x20, 0x3e, 0x20, 0x01, 0x0c, + 0x20, 0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x01, 0x02, + 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x03, 0x01, + 0x02, 0x04, 0x01, 0x02, 0x05, 0x01, 0x02, 0x06, + 0x01, 0x02, 0x07, 0x01, 0x02, 0x08, 0x01, 0x02, + 0x0b, 0x01, 0x02, 0x0c, 0x01, 0x02, 0x0e, 0x01, + 0x02, 0x10, 0x01, 0x02, 0x11, 0x01, 0x02, 0x12, + 0x01, 0x02, 0x13, 0x01, 0x02, 0x14, 0x01, 0x02, + 0x17, 0x01, 0x02, 0x18, 0x01, 0x02, 0x19, 0x01, + 0x06, 0x1b, 0x4f, 0x41, 0x01, 0x06, 0x1b, 0x4f, + 0x42, 0x01, 0x06, 0x1b, 0x4f, 0x43, 0x01, 0x06, + 0x1b, 0x4f, 0x44, 0x01, 0x06, 0x1b, 0x4f, 0x46, + 0x01, 0x06, 0x1b, 0x4f, 0x48, 0x01, 0x0c, 0x1b, + 0x5b, 0x31, 0x3b, 0x35, 0x43, 0x01, 0x0c, 0x1b, + 0x5b, 0x31, 0x3b, 0x35, 0x44, 0x01, 0x08, 0x1b, + 0x5b, 0x31, 0x7e, 0x01, 0x08, 0x1b, 0x5b, 0x33, + 0x7e, 0x01, 0x08, 0x1b, 0x5b, 0x34, 0x7e, 0x01, + 0x08, 0x1b, 0x5b, 0x35, 0x7e, 0x01, 0x08, 0x1b, + 0x5b, 0x36, 0x7e, 0x01, 0x06, 0x1b, 0x5b, 0x41, + 0x01, 0x06, 0x1b, 0x5b, 0x42, 0x01, 0x06, 0x1b, + 0x5b, 0x43, 0x01, 0x06, 0x1b, 0x5b, 0x44, 0x01, + 0x06, 0x1b, 0x5b, 0x46, 0x01, 0x06, 0x1b, 0x5b, + 0x48, 0x01, 0x04, 0x1b, 0x7f, 0x01, 0x04, 0x1b, + 0x62, 0x01, 0x04, 0x1b, 0x64, 0x01, 0x04, 0x1b, + 0x66, 0x01, 0x04, 0x1b, 0x6b, 0x01, 0x04, 0x1b, + 0x6c, 0x01, 0x04, 0x1b, 0x74, 0x01, 0x04, 0x1b, + 0x75, 0x01, 0x02, 0x7f, 0x01, 0x02, 0x78, 0x01, + 0x06, 0x64, 0x65, 0x63, 0x01, 0x08, 0x74, 0x69, + 0x6d, 0x65, 0x01, 0x0c, 0x73, 0x74, 0x72, 0x69, + 0x63, 0x74, 0x01, 0x0c, 0x68, 0x69, 0x64, 0x64, + 0x65, 0x6e, 0x01, 0x08, 0x71, 0x75, 0x69, 0x74, + 0x0d, 0xe2, 0x03, 0x03, 0xe4, 0x03, 0xe6, 0x03, + 0xe8, 0x03, 0x00, 0x00, 0x03, 0x00, 0x8c, 0x02, + 0x00, 0x01, 0x8c, 0x02, 0x01, 0x02, 0x8c, 0x02, + 0x02, 0x00, 0x0c, 0x20, 0x02, 0x01, 0xa8, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x01, 0x0f, + 0x00, 0xea, 0x03, 0x00, 0x1e, 0xec, 0x03, 0x01, + 0x1e, 0xee, 0x03, 0x02, 0x1e, 0x0c, 0x43, 0x02, + 0x01, 0x00, 0x01, 0x8d, 0x01, 0x01, 0x15, 0x6c, + 0x03, 0x5e, 0xf9, 0x0d, 0x8e, 0x01, 0xf0, 0x03, + 0x00, 0x01, 0x40, 0x30, 0xba, 0x02, 0x00, 0x00, + 0x40, 0x37, 0xc2, 0x02, 0x00, 0x01, 0x40, 0x45, + 0xc0, 0x02, 0x00, 0x02, 0x40, 0x53, 0xc4, 0x02, + 0x00, 0x03, 0x40, 0x52, 0xf6, 0x02, 0x00, 0x04, + 0x40, 0x54, 0xe0, 0x02, 0x00, 0x05, 0x40, 0x03, + 0xbc, 0x02, 0x00, 0x06, 0x40, 0x55, 0xce, 0x02, + 0x00, 0x07, 0x40, 0x51, 0xd6, 0x02, 0x00, 0x08, + 0x40, 0x34, 0xbe, 0x02, 0x00, 0x09, 0x40, 0x69, + 0xc6, 0x02, 0x00, 0x0a, 0x00, 0xca, 0x02, 0x00, + 0x0b, 0x40, 0x10, 0xcc, 0x02, 0x00, 0x0c, 0x40, + 0x4d, 0xf2, 0x03, 0x00, 0x0d, 0x40, 0x4b, 0xf4, + 0x03, 0x00, 0x0e, 0x40, 0x32, 0xf6, 0x03, 0x00, + 0x0f, 0x40, 0x4c, 0xf8, 0x03, 0x00, 0x10, 0x00, + 0xfa, 0x03, 0x00, 0x11, 0x40, 0x36, 0xfc, 0x03, + 0x00, 0x12, 0x40, 0x0d, 0xfe, 0x03, 0x00, 0x13, + 0x40, 0x5b, 0x80, 0x04, 0x00, 0x14, 0x40, 0x0e, + 0x82, 0x04, 0x00, 0x15, 0x40, 0x07, 0x84, 0x04, + 0x00, 0x16, 0x40, 0x40, 0x86, 0x04, 0x00, 0x17, + 0x40, 0x14, 0x88, 0x04, 0x00, 0x18, 0x40, 0x58, + 0x8a, 0x04, 0x00, 0x19, 0x40, 0x57, 0x8c, 0x04, + 0x00, 0x1a, 0x40, 0x4f, 0x8e, 0x04, 0x00, 0x1b, + 0x40, 0x5a, 0x90, 0x04, 0x00, 0x1c, 0x40, 0x23, + 0x92, 0x04, 0x00, 0x1d, 0x40, 0x24, 0x94, 0x04, + 0x00, 0x1e, 0x40, 0x29, 0x96, 0x04, 0x00, 0x1f, + 0x40, 0x3c, 0x98, 0x04, 0x00, 0x20, 0x40, 0x3a, + 0x9a, 0x04, 0x00, 0x21, 0x40, 0x3e, 0x9c, 0x04, + 0x00, 0x22, 0x40, 0x42, 0x9e, 0x04, 0x00, 0x23, + 0x40, 0x3f, 0xa0, 0x04, 0x00, 0x24, 0x40, 0x64, + 0xa2, 0x04, 0x00, 0x25, 0x40, 0x41, 0xa4, 0x04, + 0x00, 0x26, 0x40, 0x18, 0xa6, 0x04, 0x00, 0x27, + 0x40, 0x5f, 0xa8, 0x04, 0x00, 0x28, 0x40, 0x12, + 0xaa, 0x04, 0x00, 0x29, 0x40, 0x1b, 0xac, 0x04, + 0x00, 0x2a, 0x40, 0x13, 0xae, 0x04, 0x00, 0x2b, + 0x40, 0x15, 0xb0, 0x04, 0x00, 0x2c, 0x40, 0x2a, + 0xb2, 0x04, 0x00, 0x2d, 0x40, 0x26, 0xb4, 0x04, + 0x00, 0x2e, 0x40, 0x1c, 0xb6, 0x04, 0x00, 0x2f, + 0x40, 0x09, 0xb8, 0x04, 0x00, 0x30, 0x40, 0x0a, + 0xba, 0x04, 0x00, 0x31, 0x40, 0x00, 0xbc, 0x04, + 0x00, 0x32, 0x40, 0x04, 0xbe, 0x04, 0x00, 0x33, + 0x40, 0x01, 0xc0, 0x04, 0x00, 0x34, 0x40, 0x0f, + 0xc2, 0x04, 0x00, 0x35, 0x00, 0xc4, 0x04, 0x00, + 0x36, 0x40, 0x02, 0xc6, 0x04, 0x00, 0x37, 0x40, + 0x05, 0xc8, 0x04, 0x00, 0x38, 0x40, 0x06, 0xca, + 0x04, 0x00, 0x39, 0x40, 0x0b, 0xcc, 0x04, 0x00, + 0x3a, 0x40, 0x0c, 0xce, 0x04, 0x00, 0x3b, 0x40, + 0x1e, 0xd0, 0x04, 0x00, 0x3c, 0x40, 0x2f, 0xd2, + 0x04, 0x00, 0x3d, 0x40, 0x17, 0xd4, 0x04, 0x00, + 0x3e, 0x40, 0x1d, 0xd6, 0x04, 0x00, 0x3f, 0x40, + 0x6a, 0xd8, 0x04, 0x00, 0x40, 0x40, 0x1a, 0xda, + 0x04, 0x00, 0x41, 0x40, 0x11, 0xdc, 0x04, 0x00, + 0x42, 0x40, 0x16, 0xde, 0x04, 0x00, 0x43, 0x40, + 0x43, 0xe0, 0x04, 0x00, 0x44, 0x40, 0x2b, 0xe2, + 0x04, 0x00, 0x45, 0x00, 0xe4, 0x04, 0x00, 0x46, + 0x00, 0xe6, 0x04, 0x00, 0x47, 0x40, 0x4a, 0xe8, + 0x04, 0x00, 0x48, 0x00, 0xea, 0x04, 0x00, 0x49, + 0x00, 0xec, 0x04, 0x00, 0x4a, 0x00, 0xee, 0x04, + 0x00, 0x4b, 0x00, 0xf0, 0x04, 0x00, 0x4c, 0x40, + 0x1f, 0xf2, 0x04, 0x00, 0x4d, 0x40, 0x20, 0xf4, + 0x04, 0x00, 0x4e, 0x00, 0xf6, 0x04, 0x00, 0x4f, + 0x00, 0xf8, 0x04, 0x00, 0x50, 0x00, 0xfa, 0x04, + 0x00, 0x51, 0x00, 0xfc, 0x04, 0x00, 0x52, 0x40, + 0x22, 0xfe, 0x04, 0x00, 0x53, 0x00, 0x80, 0x05, + 0x00, 0x54, 0x00, 0x82, 0x05, 0x00, 0x55, 0x40, + 0x25, 0x84, 0x05, 0x00, 0x56, 0x00, 0x86, 0x05, + 0x00, 0x57, 0x00, 0x88, 0x05, 0x00, 0x58, 0x40, + 0x28, 0x8a, 0x05, 0x00, 0x59, 0x00, 0x8c, 0x05, + 0x00, 0x5a, 0x00, 0x8e, 0x05, 0x00, 0x5b, 0x00, + 0x90, 0x05, 0x00, 0x5c, 0x00, 0x92, 0x05, 0x00, + 0x5d, 0x00, 0x94, 0x05, 0x00, 0x5e, 0x00, 0x96, + 0x05, 0x00, 0x5f, 0x00, 0x98, 0x05, 0x00, 0x60, + 0x40, 0x27, 0x9a, 0x05, 0x00, 0x61, 0x00, 0x9c, + 0x05, 0x00, 0x62, 0x00, 0x9e, 0x05, 0x00, 0x63, + 0x00, 0xa0, 0x05, 0x00, 0x64, 0x00, 0xa2, 0x05, + 0x00, 0x65, 0x00, 0xa4, 0x05, 0x00, 0x66, 0x40, + 0x2c, 0xa6, 0x05, 0x00, 0x67, 0x00, 0xa8, 0x05, + 0x00, 0x68, 0x40, 0x35, 0xaa, 0x05, 0x00, 0x69, + 0x40, 0x31, 0xac, 0x05, 0x00, 0x6a, 0x40, 0x33, + 0xae, 0x05, 0x00, 0x6b, 0x40, 0x38, 0xb0, 0x05, + 0x00, 0x6c, 0x40, 0x39, 0xb2, 0x05, 0x00, 0x6d, + 0x40, 0x48, 0xb4, 0x05, 0x00, 0x6e, 0x40, 0x3d, + 0xb6, 0x05, 0x00, 0x6f, 0x40, 0x46, 0xb8, 0x05, + 0x00, 0x70, 0x40, 0x44, 0xba, 0x05, 0x00, 0x71, + 0x40, 0x3b, 0xbc, 0x05, 0x00, 0x72, 0x40, 0x2e, + 0xbe, 0x05, 0x00, 0x73, 0x40, 0x5e, 0xc0, 0x05, + 0x00, 0x74, 0x40, 0x08, 0xc2, 0x05, 0x00, 0x75, + 0x40, 0x47, 0xc4, 0x05, 0x00, 0x76, 0x40, 0x4e, + 0xc6, 0x05, 0x00, 0x77, 0x40, 0x50, 0xc8, 0x05, + 0x00, 0x78, 0x40, 0x56, 0xca, 0x05, 0x00, 0x79, + 0x40, 0x67, 0xcc, 0x05, 0x00, 0x7a, 0x40, 0x62, + 0xce, 0x05, 0x00, 0x7b, 0x40, 0x59, 0xd0, 0x05, + 0x00, 0x7c, 0x00, 0xd2, 0x05, 0x00, 0x7d, 0x40, + 0x2d, 0xd4, 0x05, 0x00, 0x7e, 0x40, 0x5c, 0xd6, + 0x05, 0x00, 0x7f, 0x40, 0x21, 0xd8, 0x05, 0x00, + 0x80, 0x01, 0x00, 0xda, 0x05, 0x00, 0x81, 0x01, + 0x40, 0x5d, 0xdc, 0x05, 0x00, 0x82, 0x01, 0x40, + 0x60, 0xde, 0x05, 0x00, 0x83, 0x01, 0x40, 0x61, + 0xe0, 0x05, 0x00, 0x84, 0x01, 0x40, 0x63, 0xe2, + 0x05, 0x00, 0x85, 0x01, 0x40, 0x65, 0xe4, 0x05, + 0x00, 0x86, 0x01, 0x40, 0x66, 0xe6, 0x05, 0x00, + 0x87, 0x01, 0x40, 0x68, 0xe8, 0x05, 0x00, 0x88, + 0x01, 0x40, 0x19, 0xea, 0x05, 0x00, 0x89, 0x01, + 0x40, 0x6b, 0xec, 0x05, 0x00, 0x8a, 0x01, 0x40, + 0x49, 0xee, 0x05, 0x00, 0x8b, 0x01, 0x00, 0xf0, + 0x05, 0x00, 0x8c, 0x01, 0x00, 0xea, 0x03, 0x00, + 0x1a, 0xec, 0x03, 0x01, 0x1a, 0xee, 0x03, 0x02, + 0x1a, 0x0c, 0x43, 0x02, 0x01, 0xc2, 0x04, 0x00, + 0x01, 0x00, 0x04, 0x00, 0x08, 0x00, 0x89, 0x01, + 0x01, 0xf2, 0x05, 0x00, 0x00, 0x00, 0xea, 0x03, + 0x00, 0x1a, 0xba, 0x04, 0x31, 0x00, 0xbe, 0x04, + 0x33, 0x00, 0xec, 0x03, 0x01, 0x1a, 0xc4, 0x04, + 0x36, 0x00, 0xe0, 0x02, 0x05, 0x00, 0xbc, 0x04, + 0x32, 0x00, 0xc6, 0x04, 0x37, 0x00, 0x64, 0x00, + 0x00, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x41, 0x7a, + 0x01, 0x00, 0x00, 0x24, 0x00, 0x00, 0xe8, 0xc2, + 0x50, 0xe9, 0x64, 0x03, 0x00, 0x41, 0x7b, 0x01, + 0x00, 0x00, 0xe4, 0x24, 0x01, 0x00, 0xf0, 0x35, + 0x64, 0x03, 0x00, 0x40, 0x7c, 0x01, 0x00, 0x00, + 0xf0, 0x14, 0x64, 0x03, 0x00, 0x41, 0x7c, 0x01, + 0x00, 0x00, 0xe4, 0x24, 0x01, 0x00, 0xd3, 0xf0, + 0x05, 0xcb, 0xba, 0x46, 0xe9, 0x64, 0x03, 0x00, + 0x40, 0x7d, 0x01, 0x00, 0x00, 0xf0, 0x0e, 0x64, + 0x03, 0x00, 0x41, 0x7d, 0x01, 0x00, 0x00, 0xe4, + 0x24, 0x01, 0x00, 0x0e, 0x64, 0x03, 0x00, 0x41, + 0x7e, 0x01, 0x00, 0x00, 0x64, 0x03, 0x00, 0x40, + 0x7f, 0x01, 0x00, 0x00, 0x5d, 0x04, 0x00, 0x24, + 0x02, 0x00, 0x0e, 0x5d, 0x05, 0x00, 0x11, 0xc2, + 0x40, 0x21, 0x01, 0x00, 0x5e, 0x06, 0x00, 0x64, + 0x03, 0x00, 0x41, 0x80, 0x01, 0x00, 0x00, 0xe4, + 0x5d, 0x07, 0x00, 0x24, 0x02, 0x00, 0x29, 0x0c, + 0x43, 0x02, 0x01, 0xc4, 0x04, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0xc8, 0x04, + 0x38, 0x00, 0xe3, 0xbd, 0xf5, 0x29, 0x0c, 0x43, + 0x02, 0x01, 0xc6, 0x04, 0x00, 0x02, 0x00, 0x06, + 0x00, 0x04, 0x00, 0x28, 0x02, 0x82, 0x06, 0x00, + 0x00, 0x00, 0x84, 0x06, 0x00, 0x01, 0x00, 0xec, + 0x03, 0x01, 0x1a, 0xba, 0x04, 0x31, 0x00, 0xbc, + 0x04, 0x32, 0x00, 0xc8, 0x04, 0x38, 0x00, 0x64, + 0x00, 0x00, 0x41, 0x83, 0x01, 0x00, 0x00, 0xe4, + 0xe5, 0x40, 0x84, 0x01, 0x00, 0x00, 0xba, 0xe5, + 0xef, 0x24, 0x04, 0x00, 0xcf, 0xba, 0xd0, 0xcc, + 0xcb, 0xa5, 0xf0, 0x0b, 0xe6, 0xe5, 0xcc, 0x46, + 0xf5, 0x0e, 0x92, 0x01, 0xf2, 0xf2, 0x29, 0x0c, + 0x43, 0x02, 0x01, 0xc8, 0x04, 0x01, 0x00, 0x01, + 0x04, 0x00, 0x04, 0x00, 0x5e, 0x01, 0x8a, 0x06, + 0x00, 0x01, 0x00, 0x82, 0x04, 0x15, 0x00, 0xc0, + 0x05, 0x74, 0x00, 0xb6, 0x04, 0x2f, 0x00, 0xb8, + 0x04, 0x30, 0x00, 0xe3, 0xf1, 0x06, 0xe4, 0xd7, + 0xf5, 0x0e, 0x29, 0xe5, 0xba, 0xae, 0xf0, 0x24, + 0xd7, 0xc3, 0x80, 0x00, 0xa8, 0xf0, 0x1d, 0xd7, + 0xc3, 0xc0, 0x00, 0xa5, 0xf0, 0x16, 0xe6, 0xc0, + 0x9e, 0xd7, 0xc2, 0x3f, 0xa1, 0xa3, 0xea, 0xe5, + 0x8d, 0xed, 0xba, 0xad, 0xf0, 0x33, 0xe4, 0xe6, + 0xf5, 0x0e, 0x29, 0xd7, 0xc3, 0xc0, 0x00, 0xa8, + 0xf0, 0x21, 0xd7, 0xc3, 0xf8, 0x00, 0xa5, 0xf0, + 0x1a, 0xbb, 0xd7, 0xc3, 0xe0, 0x00, 0xa8, 0x9c, + 0xd7, 0xc3, 0xf0, 0x00, 0xa8, 0x9c, 0xe9, 0xd7, + 0xbb, 0xc0, 0xe5, 0x9d, 0x9e, 0xbb, 0x9d, 0xa1, + 0xea, 0x29, 0xba, 0xe9, 0xe4, 0xd7, 0xf5, 0x0e, + 0x29, 0x0c, 0x43, 0x02, 0x01, 0xca, 0x04, 0x01, + 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x35, 0x01, + 0x8a, 0x06, 0x00, 0x01, 0x00, 0xd7, 0x96, 0x04, + 0x4c, 0x00, 0x00, 0x00, 0xad, 0x11, 0xf0, 0x2a, + 0x0e, 0xd7, 0x04, 0x86, 0x01, 0x00, 0x00, 0xa8, + 0x11, 0xf0, 0x09, 0x0e, 0xd7, 0x04, 0x87, 0x01, + 0x00, 0x00, 0xa6, 0x11, 0xf1, 0x14, 0x0e, 0xd7, + 0x04, 0x88, 0x01, 0x00, 0x00, 0xa8, 0x11, 0xf0, + 0x09, 0x0e, 0xd7, 0x04, 0x89, 0x01, 0x00, 0x00, + 0xa6, 0x28, 0x0c, 0x43, 0x02, 0x01, 0xcc, 0x04, + 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x02, 0x19, + 0x01, 0x8a, 0x06, 0x00, 0x01, 0x00, 0x07, 0x02, + 0x30, 0x07, 0x02, 0x39, 0xd7, 0x96, 0x04, 0x4c, + 0x00, 0x00, 0x00, 0xad, 0x11, 0xf0, 0x0e, 0x0e, + 0xd7, 0xc4, 0x00, 0xa8, 0x11, 0xf0, 0x06, 0x0e, + 0xd7, 0xc4, 0x01, 0xa6, 0x28, 0x0c, 0x43, 0x02, + 0x01, 0xce, 0x04, 0x01, 0x00, 0x01, 0x02, 0x00, + 0x02, 0x00, 0x2d, 0x01, 0x8a, 0x06, 0x00, 0x01, + 0x00, 0xca, 0x04, 0x39, 0x00, 0xcc, 0x04, 0x3a, + 0x00, 0xd7, 0x96, 0x04, 0x4c, 0x00, 0x00, 0x00, + 0xad, 0x11, 0xf0, 0x22, 0x0e, 0xe3, 0xd7, 0xf5, + 0x11, 0xf1, 0x1b, 0x0e, 0xe4, 0xd7, 0xf5, 0x11, + 0xf1, 0x14, 0x0e, 0xd7, 0x04, 0x8a, 0x01, 0x00, + 0x00, 0xab, 0x11, 0xf1, 0x09, 0x0e, 0xd7, 0x04, + 0x8b, 0x01, 0x00, 0x00, 0xab, 0x28, 0x0c, 0x43, + 0x02, 0x01, 0xd0, 0x04, 0x01, 0x00, 0x01, 0x04, + 0x00, 0x00, 0x00, 0x1d, 0x01, 0x8a, 0x06, 0x00, + 0x01, 0x00, 0xd7, 0x96, 0x04, 0x4c, 0x00, 0x00, + 0x00, 0xad, 0x11, 0xf0, 0x12, 0x0e, 0x04, 0x8c, + 0x01, 0x00, 0x00, 0x41, 0x8d, 0x01, 0x00, 0x00, + 0xd7, 0xba, 0x46, 0x24, 0x01, 0x00, 0x28, 0x0c, + 0x43, 0x02, 0x01, 0xd2, 0x04, 0x01, 0x04, 0x01, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x05, 0x9c, 0x06, + 0x00, 0x01, 0x00, 0x9e, 0x06, 0x00, 0x00, 0x00, + 0x8a, 0x06, 0x00, 0x01, 0x00, 0x84, 0x06, 0x00, + 0x02, 0x00, 0xa0, 0x06, 0x00, 0x03, 0x00, 0xd7, + 0xef, 0xd2, 0xba, 0xcf, 0xba, 0xd1, 0xcd, 0xce, + 0xa5, 0xf0, 0x25, 0xd7, 0x41, 0x91, 0x01, 0x00, + 0x00, 0xcd, 0x24, 0x01, 0x00, 0xd4, 0x01, 0x00, + 0xdc, 0x00, 0x00, 0xa5, 0x11, 0xf1, 0x09, 0x0e, + 0xcc, 0x01, 0x00, 0xe0, 0x00, 0x00, 0xa8, 0xf0, + 0x03, 0x92, 0x00, 0x92, 0x02, 0xf2, 0xd8, 0xcb, + 0x28, 0x0c, 0x43, 0x02, 0x01, 0xd4, 0x04, 0x01, + 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x29, 0x02, + 0x8a, 0x06, 0x00, 0x01, 0x00, 0xa4, 0x06, 0x00, + 0x00, 0x00, 0xd7, 0x96, 0x04, 0x4c, 0x00, 0x00, + 0x00, 0xae, 0xf0, 0x03, 0x09, 0x28, 0xd7, 0x41, + 0x93, 0x01, 0x00, 0x00, 0xba, 0x24, 0x01, 0x00, + 0xd3, 0x01, 0x00, 0xdc, 0x00, 0x00, 0xa8, 0x11, + 0xf0, 0x09, 0x0e, 0xcb, 0x01, 0x00, 0xe0, 0x00, + 0x00, 0xa5, 0x28, 0x0c, 0x43, 0x02, 0x01, 0xd6, + 0x04, 0x02, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, + 0x23, 0x02, 0x90, 0x06, 0x00, 0x01, 0x00, 0xa8, + 0x06, 0x00, 0x01, 0x00, 0xd7, 0xd8, 0x9c, 0x11, + 0x04, 0x95, 0x01, 0x00, 0x00, 0xad, 0xf1, 0x13, + 0x11, 0x04, 0x96, 0x01, 0x00, 0x00, 0xad, 0xf1, + 0x0a, 0x11, 0x04, 0x97, 0x01, 0x00, 0x00, 0xad, + 0xf0, 0x03, 0x0a, 0x28, 0x0e, 0x09, 0x28, 0x0c, + 0x43, 0x02, 0x01, 0xd8, 0x04, 0x03, 0x03, 0x03, + 0x06, 0x00, 0x03, 0x00, 0x62, 0x06, 0x9c, 0x06, + 0x00, 0x01, 0x00, 0xb0, 0x06, 0x00, 0x01, 0x00, + 0xb2, 0x06, 0x00, 0x01, 0x00, 0x84, 0x06, 0x00, + 0x00, 0x00, 0xb4, 0x06, 0x00, 0x01, 0x00, 0xb6, + 0x06, 0x00, 0x02, 0x00, 0xea, 0x03, 0x00, 0x1a, + 0xfc, 0x03, 0x12, 0x00, 0x80, 0x04, 0x14, 0x00, + 0xd8, 0xd0, 0xcc, 0xd7, 0xef, 0xa5, 0xf0, 0x5a, + 0xd9, 0xcc, 0xd3, 0x46, 0xd1, 0xcc, 0x8e, 0xd4, + 0xd7, 0xef, 0xa5, 0xf0, 0x08, 0xd9, 0xcc, 0x46, + 0xcd, 0xab, 0xf1, 0xf2, 0x64, 0x00, 0x00, 0x41, + 0x9c, 0x01, 0x00, 0x00, 0xe4, 0xe5, 0xcd, 0x46, + 0x11, 0xf1, 0x07, 0x0e, 0x04, 0x9d, 0x01, 0x00, + 0x00, 0x46, 0x24, 0x01, 0x00, 0x0e, 0x64, 0x00, + 0x00, 0x41, 0x9c, 0x01, 0x00, 0x00, 0xd7, 0x41, + 0x9e, 0x01, 0x00, 0x00, 0xca, 0x24, 0x02, 0x00, + 0x24, 0x01, 0x00, 0x0e, 0x64, 0x00, 0x00, 0x41, + 0x9c, 0x01, 0x00, 0x00, 0xe4, 0x04, 0x9d, 0x01, + 0x00, 0x00, 0x46, 0x24, 0x01, 0x00, 0x0e, 0xf2, + 0xa2, 0x29, 0x0c, 0x43, 0x02, 0x01, 0xda, 0x04, + 0x02, 0x00, 0x02, 0x05, 0x00, 0x01, 0x00, 0x1d, + 0x02, 0xbe, 0x06, 0x00, 0x01, 0x00, 0xc0, 0x06, + 0x00, 0x01, 0x00, 0xea, 0x03, 0x00, 0x1a, 0x64, + 0x00, 0x00, 0x41, 0x9c, 0x01, 0x00, 0x00, 0x04, + 0xa1, 0x01, 0x00, 0x00, 0xd7, 0xbb, 0xac, 0xf0, + 0x04, 0xd7, 0xf2, 0x02, 0xc6, 0x9c, 0xd8, 0x9c, + 0x24, 0x01, 0x00, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0xdc, 0x04, 0x01, 0x02, 0x01, 0x04, 0x00, 0x05, + 0x00, 0xa1, 0x01, 0x03, 0xc4, 0x06, 0x00, 0x01, + 0x00, 0x84, 0x06, 0x00, 0x00, 0x00, 0x82, 0x06, + 0x00, 0x01, 0x00, 0xc0, 0x04, 0x34, 0x00, 0xbe, + 0x04, 0x33, 0x00, 0xea, 0x03, 0x00, 0x1a, 0xca, + 0x02, 0x0b, 0x00, 0xda, 0x04, 0x41, 0x00, 0xd7, + 0xba, 0xa7, 0xf0, 0x4d, 0xd7, 0xba, 0xac, 0x68, + 0x97, 0x00, 0x00, 0x00, 0xe3, 0xe4, 0xbb, 0x9d, + 0xab, 0xf0, 0x19, 0x64, 0x02, 0x00, 0x41, 0x9c, + 0x01, 0x00, 0x00, 0x04, 0xa3, 0x01, 0x00, 0x00, + 0x24, 0x01, 0x00, 0x0e, 0xba, 0xe7, 0xd7, 0x8d, + 0xdb, 0xf2, 0xda, 0xe6, 0x41, 0xa4, 0x01, 0x00, + 0x00, 0xe4, 0xbb, 0x9d, 0xe3, 0x9d, 0xd7, 0x24, + 0x02, 0x00, 0xd0, 0x5d, 0x04, 0x00, 0xcc, 0x04, + 0xa5, 0x01, 0x00, 0x00, 0xf6, 0x0e, 0xd7, 0xcc, + 0x9d, 0xdb, 0xe3, 0xcc, 0x9c, 0xe7, 0xf2, 0xb5, + 0xd7, 0x8b, 0xdb, 0xd7, 0xba, 0xac, 0xf0, 0x48, + 0xe3, 0xba, 0xab, 0xf0, 0x22, 0x5d, 0x04, 0x00, + 0xbb, 0x04, 0x86, 0x01, 0x00, 0x00, 0xf6, 0x0e, + 0x5d, 0x04, 0x00, 0xe4, 0xbb, 0x9d, 0x04, 0xa5, + 0x01, 0x00, 0x00, 0xf6, 0x0e, 0xd7, 0x8d, 0xdb, + 0xe4, 0xbb, 0x9d, 0xe7, 0xf2, 0xd6, 0xe6, 0x41, + 0xa4, 0x01, 0x00, 0x00, 0xd7, 0xe3, 0x24, 0x02, + 0x00, 0xd0, 0x5d, 0x04, 0x00, 0xcc, 0x04, 0xa6, + 0x01, 0x00, 0x00, 0xf6, 0x0e, 0xd7, 0xcc, 0x9d, + 0xdb, 0xe3, 0xcc, 0x9d, 0xe7, 0xf2, 0xb5, 0x29, + 0x0c, 0x43, 0x02, 0x01, 0xde, 0x04, 0x00, 0x05, + 0x00, 0x06, 0x00, 0x0d, 0x00, 0x9c, 0x02, 0x05, + 0x84, 0x06, 0x00, 0x00, 0x00, 0xce, 0x06, 0x00, + 0x01, 0x00, 0x9c, 0x06, 0x00, 0x02, 0x00, 0xb0, + 0x06, 0x00, 0x03, 0x00, 0xd0, 0x06, 0x00, 0x04, + 0x00, 0xa8, 0x04, 0x28, 0x00, 0xac, 0x04, 0x2a, + 0x00, 0x86, 0x04, 0x17, 0x00, 0xae, 0x04, 0x2b, + 0x00, 0xea, 0x03, 0x00, 0x1a, 0xdc, 0x04, 0x42, + 0x00, 0xd2, 0x04, 0x3d, 0x00, 0xa4, 0x04, 0x26, + 0x00, 0xe8, 0x05, 0x88, 0x01, 0x00, 0xd8, 0x04, + 0x40, 0x00, 0xc0, 0x04, 0x34, 0x00, 0xbe, 0x04, + 0x33, 0x00, 0xaa, 0x04, 0x29, 0x00, 0xe3, 0xe4, + 0xac, 0x68, 0xc6, 0x00, 0x00, 0x00, 0xe5, 0x95, + 0xf0, 0x32, 0xe4, 0x41, 0x9e, 0x01, 0x00, 0x00, + 0xba, 0xe6, 0x24, 0x02, 0x00, 0xe3, 0x41, 0x9e, + 0x01, 0x00, 0x00, 0xba, 0xe6, 0x24, 0x02, 0x00, + 0xab, 0xf0, 0x19, 0x64, 0x04, 0x00, 0x41, 0x9c, + 0x01, 0x00, 0x00, 0xe3, 0x41, 0x9e, 0x01, 0x00, + 0x00, 0xe6, 0x24, 0x01, 0x00, 0x24, 0x01, 0x00, + 0x0e, 0xf2, 0x53, 0x5d, 0x05, 0x00, 0x5d, 0x06, + 0x00, 0xe4, 0x41, 0x9e, 0x01, 0x00, 0x00, 0xba, + 0xe6, 0x24, 0x02, 0x00, 0xf5, 0x8b, 0xf5, 0x0e, + 0xe5, 0xf0, 0x2e, 0x5d, 0x07, 0x00, 0xf0, 0x0e, + 0x5d, 0x07, 0x00, 0x04, 0xa3, 0x01, 0x00, 0x00, + 0x9c, 0xe3, 0x9c, 0xf2, 0x02, 0xe3, 0xd5, 0xef, + 0xe3, 0xef, 0x9d, 0xd2, 0x5d, 0x08, 0x00, 0xcd, + 0xf5, 0xc8, 0x04, 0x5d, 0x09, 0x00, 0xcd, 0xce, + 0xc7, 0x04, 0xbc, 0x46, 0xf7, 0x0e, 0xf2, 0x0e, + 0x64, 0x04, 0x00, 0x41, 0x9c, 0x01, 0x00, 0x00, + 0xe3, 0x24, 0x01, 0x00, 0x0e, 0x5d, 0x0a, 0x00, + 0x5d, 0x06, 0x00, 0xe3, 0xf5, 0x9c, 0x5d, 0x0b, + 0x00, 0x9b, 0x5f, 0x0a, 0x00, 0xba, 0xab, 0xf0, + 0x12, 0x64, 0x04, 0x00, 0x41, 0x9c, 0x01, 0x00, + 0x00, 0x04, 0xa9, 0x01, 0x00, 0x00, 0x24, 0x01, + 0x00, 0x0e, 0x64, 0x04, 0x00, 0x41, 0x9c, 0x01, + 0x00, 0x00, 0x04, 0xaa, 0x01, 0x00, 0x00, 0x24, + 0x01, 0x00, 0x0e, 0xe3, 0xe8, 0xe3, 0xef, 0xea, + 0x5d, 0x0c, 0x00, 0xe6, 0xa7, 0xf0, 0x19, 0x5d, + 0x05, 0x00, 0x5d, 0x06, 0x00, 0xe3, 0x41, 0x9e, + 0x01, 0x00, 0x00, 0xe6, 0x5d, 0x0c, 0x00, 0x24, + 0x02, 0x00, 0xf5, 0xf5, 0x0e, 0xf2, 0x1f, 0x5d, + 0x0c, 0x00, 0xe6, 0xa5, 0xf0, 0x18, 0x5d, 0x05, + 0x00, 0x5d, 0x06, 0x00, 0xe3, 0x41, 0x9e, 0x01, + 0x00, 0x00, 0x5d, 0x0c, 0x00, 0xe6, 0x24, 0x02, + 0x00, 0xf5, 0x8b, 0xf5, 0x0e, 0x5d, 0x0c, 0x00, + 0xea, 0x64, 0x04, 0x00, 0x40, 0xab, 0x01, 0x00, + 0x00, 0x41, 0xac, 0x01, 0x00, 0x00, 0x24, 0x00, + 0x00, 0x29, 0x0c, 0x43, 0x02, 0x01, 0xe0, 0x04, + 0x01, 0x00, 0x01, 0x04, 0x00, 0x02, 0x00, 0x22, + 0x01, 0x9c, 0x06, 0x00, 0x01, 0x00, 0xa8, 0x04, + 0x28, 0x00, 0xaa, 0x04, 0x29, 0x00, 0xd7, 0xf0, + 0x1f, 0xe3, 0x41, 0x9e, 0x01, 0x00, 0x00, 0xba, + 0xe4, 0x24, 0x02, 0x00, 0xd7, 0x9c, 0xe3, 0x41, + 0x9e, 0x01, 0x00, 0x00, 0xe4, 0x24, 0x01, 0x00, + 0x9c, 0xe7, 0xe4, 0xd7, 0xef, 0x9c, 0xe8, 0x29, + 0x0c, 0x43, 0x02, 0x01, 0xe2, 0x04, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0xb4, + 0x04, 0x2e, 0x00, 0x0a, 0xe7, 0x29, 0x0c, 0x43, + 0x02, 0x01, 0xe4, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x07, 0x00, 0xa8, 0x04, 0x28, + 0x00, 0xaa, 0x04, 0x29, 0x00, 0xc6, 0xe7, 0xba, + 0xe8, 0xc2, 0xfe, 0x28, 0x0c, 0x43, 0x02, 0x01, + 0xe6, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0xe8, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, + 0x00, 0x03, 0x00, 0xaa, 0x04, 0x29, 0x00, 0xba, + 0xe7, 0x29, 0x0c, 0x43, 0x02, 0x01, 0xea, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, + 0x00, 0xa8, 0x04, 0x28, 0x00, 0xaa, 0x04, 0x29, + 0x00, 0xe3, 0xef, 0xe8, 0x29, 0x0c, 0x43, 0x02, + 0x01, 0xec, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x03, 0x00, 0x1d, 0x00, 0xaa, 0x04, 0x29, 0x00, + 0xa8, 0x04, 0x28, 0x00, 0xd4, 0x04, 0x3e, 0x00, + 0xe3, 0xe4, 0xef, 0xa5, 0xf0, 0x17, 0xe3, 0x8e, + 0xe7, 0xe5, 0xe4, 0x41, 0xad, 0x01, 0x00, 0x00, + 0xe3, 0x24, 0x01, 0x00, 0xf5, 0xf0, 0x06, 0xe3, + 0x8e, 0xe7, 0xf2, 0xee, 0x29, 0x0c, 0x43, 0x02, + 0x01, 0xee, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x03, 0x00, 0x1c, 0x00, 0xaa, 0x04, 0x29, 0x00, + 0xd4, 0x04, 0x3e, 0x00, 0xa8, 0x04, 0x28, 0x00, + 0xe3, 0xba, 0xa7, 0xf0, 0x17, 0xe3, 0x8d, 0xe7, + 0xe4, 0xe5, 0x41, 0xad, 0x01, 0x00, 0x00, 0xe3, + 0x24, 0x01, 0x00, 0xf5, 0xf0, 0x06, 0xe3, 0x8d, + 0xe7, 0xf2, 0xee, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0xf0, 0x04, 0x01, 0x00, 0x01, 0x04, 0x00, 0x02, + 0x00, 0x35, 0x01, 0xdc, 0x06, 0x00, 0x01, 0x00, + 0xa8, 0x04, 0x28, 0x00, 0xce, 0x04, 0x3b, 0x00, + 0xd7, 0xe3, 0xef, 0xa5, 0xf0, 0x15, 0xe4, 0xe3, + 0x41, 0xad, 0x01, 0x00, 0x00, 0xd7, 0x24, 0x01, + 0x00, 0xf5, 0x95, 0xf0, 0x06, 0xd7, 0x8e, 0xdb, + 0xf2, 0xe7, 0xd7, 0xe3, 0xef, 0xa5, 0xf0, 0x14, + 0xe4, 0xe3, 0x41, 0xad, 0x01, 0x00, 0x00, 0xd7, + 0x24, 0x01, 0x00, 0xf5, 0xf0, 0x06, 0xd7, 0x8e, + 0xdb, 0xf2, 0xe8, 0xd7, 0x28, 0x0c, 0x43, 0x02, + 0x01, 0xf2, 0x04, 0x01, 0x00, 0x01, 0x05, 0x00, + 0x02, 0x00, 0x37, 0x01, 0xdc, 0x06, 0x00, 0x01, + 0x00, 0xce, 0x04, 0x3b, 0x00, 0xa8, 0x04, 0x28, + 0x00, 0xd7, 0xba, 0xa7, 0xf0, 0x17, 0xe3, 0xe4, + 0x41, 0xad, 0x01, 0x00, 0x00, 0xd7, 0xbb, 0x9d, + 0x24, 0x01, 0x00, 0xf5, 0x95, 0xf0, 0x06, 0xd7, + 0x8d, 0xdb, 0xf2, 0xe6, 0xd7, 0xba, 0xa7, 0xf0, + 0x16, 0xe3, 0xe4, 0x41, 0xad, 0x01, 0x00, 0x00, + 0xd7, 0xbb, 0x9d, 0x24, 0x01, 0x00, 0xf5, 0xf0, + 0x06, 0xd7, 0x8d, 0xdb, 0xf2, 0xe7, 0xd7, 0x28, + 0x0c, 0x43, 0x02, 0x01, 0xf4, 0x04, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x05, 0x00, 0xf0, + 0x04, 0x4c, 0x00, 0xaa, 0x04, 0x29, 0x00, 0xe3, + 0xe4, 0xf5, 0xe8, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0xf6, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x05, 0x00, 0xf2, 0x04, 0x4d, 0x00, 0xaa, + 0x04, 0x29, 0x00, 0xe3, 0xe4, 0xf5, 0xe8, 0x29, + 0x0c, 0x43, 0x02, 0x01, 0xf8, 0x04, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x01, 0x00, 0x0e, 0x00, 0xd6, + 0x05, 0x7f, 0x00, 0xe3, 0x04, 0xaf, 0x01, 0x00, + 0x00, 0x47, 0x24, 0x00, 0x00, 0x0e, 0xc2, 0xfe, + 0x28, 0x0c, 0x43, 0x02, 0x01, 0xfa, 0x04, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x17, 0x00, + 0xea, 0x03, 0x00, 0x1a, 0xfc, 0x04, 0x52, 0x00, + 0xa8, 0x04, 0x28, 0x00, 0x64, 0x00, 0x00, 0x41, + 0x9c, 0x01, 0x00, 0x00, 0x04, 0xa3, 0x01, 0x00, + 0x00, 0x24, 0x01, 0x00, 0x0e, 0xe4, 0xe5, 0xf5, + 0x0e, 0xb9, 0x28, 0x0c, 0x43, 0x02, 0x01, 0xfc, + 0x04, 0x01, 0x00, 0x01, 0x03, 0x00, 0x02, 0x00, + 0x36, 0x01, 0x9c, 0x06, 0x00, 0x01, 0x00, 0x90, + 0x04, 0x1c, 0x00, 0x92, 0x04, 0x1d, 0x00, 0xd7, + 0x41, 0xb0, 0x01, 0x00, 0x00, 0x24, 0x00, 0x00, + 0xdf, 0xf0, 0x27, 0xe3, 0xef, 0xf0, 0x18, 0xe3, + 0xe3, 0xef, 0xbb, 0x9d, 0x46, 0x95, 0xf0, 0x0f, + 0xe3, 0x41, 0x33, 0x00, 0x00, 0x00, 0x8d, 0x42, + 0x33, 0x00, 0x00, 0x00, 0xf2, 0xe6, 0xe3, 0x41, + 0xb1, 0x01, 0x00, 0x00, 0xd7, 0x24, 0x01, 0x00, + 0x0e, 0xe3, 0xef, 0xe8, 0x29, 0x0c, 0x43, 0x02, + 0x01, 0xfe, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x20, 0x00, 0x92, 0x04, 0x1d, 0x00, + 0x90, 0x04, 0x1c, 0x00, 0xa8, 0x04, 0x28, 0x00, + 0xaa, 0x04, 0x29, 0x00, 0xe3, 0xba, 0xa7, 0xf0, + 0x1b, 0xe3, 0xe4, 0xef, 0xab, 0xf0, 0x0c, 0xe4, + 0x41, 0xb1, 0x01, 0x00, 0x00, 0xe5, 0x24, 0x01, + 0x00, 0x0e, 0xe3, 0x8d, 0xe7, 0xe4, 0xe3, 0x46, + 0xed, 0xef, 0xea, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0x80, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, + 0x00, 0x12, 0x00, 0x92, 0x04, 0x1d, 0x00, 0x90, + 0x04, 0x1c, 0x00, 0xa8, 0x04, 0x28, 0x00, 0xaa, + 0x04, 0x29, 0x00, 0xe3, 0xe4, 0xef, 0xbb, 0x9d, + 0xa5, 0xf0, 0x0a, 0xe3, 0x8e, 0xe7, 0xe4, 0xe3, + 0x46, 0xed, 0xef, 0xea, 0x29, 0x0c, 0x43, 0x02, + 0x01, 0x82, 0x05, 0x01, 0x03, 0x01, 0x05, 0x00, + 0x04, 0x00, 0x3d, 0x04, 0xe4, 0x06, 0x00, 0x01, + 0x00, 0xdc, 0x06, 0x00, 0x00, 0x00, 0x84, 0x06, + 0x00, 0x01, 0x00, 0xbe, 0x01, 0x00, 0x02, 0x00, + 0xaa, 0x04, 0x29, 0x00, 0x90, 0x04, 0x1c, 0x00, + 0x92, 0x04, 0x1d, 0x00, 0xa8, 0x04, 0x28, 0x00, + 0xe3, 0xcf, 0xbb, 0xd0, 0xcc, 0xe4, 0xef, 0xa6, + 0xf0, 0x33, 0xe4, 0xef, 0xcc, 0xd7, 0x99, 0x9c, + 0xe5, 0x9c, 0xe4, 0xef, 0x9b, 0xd1, 0xe4, 0xcd, + 0x46, 0x41, 0x9e, 0x01, 0x00, 0x00, 0xba, 0xcb, + 0x24, 0x02, 0x00, 0xe6, 0x41, 0x9e, 0x01, 0x00, + 0x00, 0xba, 0xcb, 0x24, 0x02, 0x00, 0xab, 0xf0, + 0x08, 0xcd, 0xe9, 0xe4, 0xcd, 0x46, 0xea, 0x29, + 0x92, 0x01, 0xf2, 0xc9, 0x29, 0x0c, 0x43, 0x02, + 0x01, 0x84, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x05, 0x00, 0x82, 0x05, 0x55, 0x00, + 0xe3, 0xb9, 0x23, 0x01, 0x00, 0x0c, 0x43, 0x02, + 0x01, 0x86, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x05, 0x00, 0x82, 0x05, 0x55, 0x00, + 0xe3, 0xbb, 0x23, 0x01, 0x00, 0x0c, 0x43, 0x02, + 0x01, 0x88, 0x05, 0x01, 0x02, 0x01, 0x04, 0x00, + 0x05, 0x00, 0x65, 0x03, 0xe4, 0x06, 0x00, 0x01, + 0x00, 0xb0, 0x06, 0x00, 0x00, 0x00, 0xe6, 0x06, + 0x00, 0x01, 0x00, 0xaa, 0x04, 0x29, 0x00, 0xd4, + 0x04, 0x3e, 0x00, 0xa8, 0x04, 0x28, 0x00, 0xb2, + 0x04, 0x2d, 0x00, 0x98, 0x05, 0x60, 0x00, 0xe3, + 0xcf, 0xd7, 0xba, 0xa5, 0xf0, 0x15, 0x91, 0x00, + 0xe4, 0xe5, 0x41, 0xad, 0x01, 0x00, 0x00, 0xcb, + 0x24, 0x01, 0x00, 0xf5, 0xf0, 0x05, 0x91, 0x00, + 0xf2, 0xef, 0xcb, 0xbb, 0x9c, 0xd0, 0xe4, 0xe5, + 0x41, 0xad, 0x01, 0x00, 0x00, 0xcc, 0x24, 0x01, + 0x00, 0xf5, 0xf0, 0x05, 0x92, 0x01, 0xf2, 0xef, + 0xcb, 0xba, 0xa8, 0xf0, 0x2f, 0xcb, 0xe5, 0xef, + 0xa5, 0xf0, 0x29, 0xe6, 0x5d, 0x04, 0x00, 0xad, + 0xf0, 0x09, 0x5d, 0x04, 0x00, 0xca, 0xd7, 0xf7, + 0x0e, 0x29, 0xe5, 0x41, 0x9e, 0x01, 0x00, 0x00, + 0xba, 0xcb, 0x24, 0x02, 0x00, 0xe5, 0x41, 0x9e, + 0x01, 0x00, 0x00, 0xcc, 0x24, 0x01, 0x00, 0x9c, + 0xe9, 0xcb, 0xe7, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0x8a, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, + 0x00, 0x04, 0x00, 0x88, 0x05, 0x58, 0x00, 0xe3, + 0xbb, 0xf5, 0x29, 0x0c, 0x43, 0x02, 0x01, 0x8c, + 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x1f, 0x00, 0xa8, 0x04, 0x28, 0x00, 0xea, 0x03, + 0x00, 0x1a, 0x88, 0x05, 0x58, 0x00, 0xe3, 0xef, + 0xba, 0xab, 0xf0, 0x15, 0x64, 0x01, 0x00, 0x41, + 0x9c, 0x01, 0x00, 0x00, 0x04, 0xa3, 0x01, 0x00, + 0x00, 0x24, 0x01, 0x00, 0x0e, 0xc2, 0xfd, 0x28, + 0xe5, 0xbb, 0xf5, 0x0e, 0x29, 0x0c, 0x43, 0x02, + 0x01, 0x8e, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x04, 0x00, 0x88, 0x05, 0x58, 0x00, + 0xe3, 0xb9, 0xf5, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0x90, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x02, + 0x00, 0x51, 0x01, 0xdc, 0x06, 0x00, 0x00, 0x00, + 0xaa, 0x04, 0x29, 0x00, 0xa8, 0x04, 0x28, 0x00, + 0xe3, 0xcf, 0xe4, 0xef, 0xbb, 0xa7, 0xf0, 0x49, + 0xcb, 0xba, 0xa7, 0xf0, 0x44, 0xcb, 0xe4, 0xef, + 0xab, 0xf0, 0x03, 0x91, 0x00, 0xe4, 0x41, 0x9e, + 0x01, 0x00, 0x00, 0xba, 0xcb, 0xbb, 0x9d, 0x24, + 0x02, 0x00, 0xe4, 0x41, 0x9e, 0x01, 0x00, 0x00, + 0xcb, 0xcb, 0xbb, 0x9c, 0x24, 0x02, 0x00, 0x9c, + 0xe4, 0x41, 0x9e, 0x01, 0x00, 0x00, 0xcb, 0xbb, + 0x9d, 0xcb, 0x24, 0x02, 0x00, 0x9c, 0xe4, 0x41, + 0x9e, 0x01, 0x00, 0x00, 0xcb, 0xbb, 0x9c, 0x24, + 0x01, 0x00, 0x9c, 0xe8, 0xcb, 0xbb, 0x9c, 0xe7, + 0x29, 0x0c, 0x43, 0x02, 0x01, 0x92, 0x05, 0x00, + 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x55, 0x04, + 0xe8, 0x06, 0x00, 0x00, 0x00, 0xea, 0x06, 0x00, + 0x01, 0x00, 0xec, 0x06, 0x00, 0x02, 0x00, 0xee, + 0x06, 0x00, 0x03, 0x00, 0xf2, 0x04, 0x4d, 0x00, + 0xaa, 0x04, 0x29, 0x00, 0xf0, 0x04, 0x4c, 0x00, + 0xa8, 0x04, 0x28, 0x00, 0xe3, 0xe4, 0xf5, 0xcf, + 0xe5, 0xcb, 0xf5, 0xd0, 0xe5, 0xe4, 0xf5, 0xd1, + 0xe3, 0xcd, 0xf5, 0xd2, 0xca, 0xa5, 0xf0, 0x41, + 0xcc, 0xe4, 0xa6, 0xf0, 0x3c, 0xe4, 0xce, 0xa6, + 0xf0, 0x37, 0xce, 0xcd, 0xa5, 0xf0, 0x32, 0xe6, + 0x41, 0x9e, 0x01, 0x00, 0x00, 0xba, 0xcb, 0x24, + 0x02, 0x00, 0xe6, 0x41, 0x9e, 0x01, 0x00, 0x00, + 0xce, 0xcd, 0x24, 0x02, 0x00, 0x9c, 0xe6, 0x41, + 0x9e, 0x01, 0x00, 0x00, 0xcc, 0xce, 0x24, 0x02, + 0x00, 0x9c, 0xe6, 0x41, 0x9e, 0x01, 0x00, 0x00, + 0xca, 0x24, 0x02, 0x00, 0x9c, 0xea, 0xcd, 0xe8, + 0x29, 0x0c, 0x43, 0x02, 0x01, 0x94, 0x05, 0x00, + 0x01, 0x00, 0x05, 0x00, 0x03, 0x00, 0x30, 0x01, + 0xe6, 0x06, 0x00, 0x00, 0x00, 0xf0, 0x04, 0x4c, + 0x00, 0xaa, 0x04, 0x29, 0x00, 0xa8, 0x04, 0x28, + 0x00, 0xe3, 0xe4, 0xf5, 0xcf, 0xe5, 0x41, 0x9e, + 0x01, 0x00, 0x00, 0xba, 0xe4, 0x24, 0x02, 0x00, + 0xe5, 0x41, 0x9e, 0x01, 0x00, 0x00, 0xe4, 0xcb, + 0x24, 0x02, 0x00, 0x41, 0xb8, 0x01, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x9c, 0xe5, 0x41, 0x9e, 0x01, + 0x00, 0x00, 0xcb, 0x24, 0x01, 0x00, 0x9c, 0xe9, + 0x29, 0x0c, 0x43, 0x02, 0x01, 0x96, 0x05, 0x00, + 0x01, 0x00, 0x05, 0x00, 0x03, 0x00, 0x30, 0x01, + 0xe6, 0x06, 0x00, 0x00, 0x00, 0xf0, 0x04, 0x4c, + 0x00, 0xaa, 0x04, 0x29, 0x00, 0xa8, 0x04, 0x28, + 0x00, 0xe3, 0xe4, 0xf5, 0xcf, 0xe5, 0x41, 0x9e, + 0x01, 0x00, 0x00, 0xba, 0xe4, 0x24, 0x02, 0x00, + 0xe5, 0x41, 0x9e, 0x01, 0x00, 0x00, 0xe4, 0xcb, + 0x24, 0x02, 0x00, 0x41, 0xb9, 0x01, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x9c, 0xe5, 0x41, 0x9e, 0x01, + 0x00, 0x00, 0xcb, 0x24, 0x01, 0x00, 0x9c, 0xe9, + 0x29, 0x0c, 0x43, 0x02, 0x01, 0x98, 0x05, 0x03, + 0x01, 0x03, 0x04, 0x00, 0x06, 0x00, 0x5e, 0x04, + 0xb0, 0x06, 0x00, 0x01, 0x00, 0xe6, 0x06, 0x00, + 0x01, 0x00, 0xe4, 0x06, 0x00, 0x01, 0x00, 0xf4, + 0x06, 0x00, 0x00, 0x00, 0xa8, 0x04, 0x28, 0x00, + 0xb2, 0x04, 0x2d, 0x00, 0x98, 0x05, 0x60, 0x00, + 0x94, 0x04, 0x1e, 0x00, 0xaa, 0x04, 0x29, 0x00, + 0xb0, 0x04, 0x2c, 0x00, 0xe3, 0x41, 0x9e, 0x01, + 0x00, 0x00, 0xd7, 0xd8, 0x24, 0x02, 0x00, 0xcf, + 0xe4, 0xe5, 0xae, 0xf0, 0x05, 0xcb, 0xea, 0xf2, + 0x10, 0xd9, 0xba, 0xa5, 0xf0, 0x07, 0xcb, 0xe6, + 0x9c, 0xea, 0xf2, 0x05, 0xe6, 0xcb, 0x9c, 0xea, + 0xe3, 0x41, 0x9e, 0x01, 0x00, 0x00, 0xba, 0xd7, + 0x24, 0x02, 0x00, 0xe3, 0x41, 0x9e, 0x01, 0x00, + 0x00, 0xd8, 0x24, 0x01, 0x00, 0x9c, 0xe7, 0x5d, + 0x04, 0x00, 0xd8, 0xa7, 0xf0, 0x0d, 0x5d, 0x04, + 0x00, 0xd8, 0xd7, 0x9d, 0x9d, 0x5e, 0x04, 0x00, + 0xf2, 0x0c, 0x5d, 0x04, 0x00, 0xd7, 0xa7, 0xf0, + 0x05, 0xd7, 0x5e, 0x04, 0x00, 0xe5, 0x5e, 0x05, + 0x00, 0x29, 0x0c, 0x43, 0x02, 0x01, 0x9a, 0x05, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x07, + 0x00, 0x98, 0x05, 0x60, 0x00, 0xaa, 0x04, 0x29, + 0x00, 0xa8, 0x04, 0x28, 0x00, 0xe3, 0xe4, 0xe5, + 0xef, 0xbb, 0xf7, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0x9c, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, + 0x00, 0x06, 0x00, 0x98, 0x05, 0x60, 0x00, 0xaa, + 0x04, 0x29, 0x00, 0xe3, 0xba, 0xe4, 0xb9, 0xf7, + 0x29, 0x0c, 0x43, 0x02, 0x01, 0x9e, 0x05, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x08, 0x00, + 0x98, 0x05, 0x60, 0x00, 0xaa, 0x04, 0x29, 0x00, + 0xf0, 0x04, 0x4c, 0x00, 0xe3, 0xe4, 0xe5, 0xe4, + 0xf5, 0xbb, 0xf7, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0xa0, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x03, + 0x00, 0x08, 0x00, 0x98, 0x05, 0x60, 0x00, 0xf2, + 0x04, 0x4d, 0x00, 0xaa, 0x04, 0x29, 0x00, 0xe3, + 0xe4, 0xe5, 0xf5, 0xe5, 0xb9, 0xf7, 0x29, 0x0c, + 0x43, 0x02, 0x01, 0xa2, 0x05, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0xe0, 0x04, + 0x44, 0x00, 0x94, 0x04, 0x1e, 0x00, 0xe3, 0xe4, + 0xf5, 0x29, 0x0c, 0x43, 0x02, 0x01, 0xa4, 0x05, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x00, 0x32, + 0x00, 0xb2, 0x04, 0x2d, 0x00, 0xa4, 0x05, 0x66, + 0x00, 0xea, 0x03, 0x00, 0x1a, 0xd2, 0x05, 0x7d, + 0x00, 0xbc, 0x05, 0x72, 0x00, 0xe3, 0xe4, 0xad, + 0xf0, 0x17, 0x64, 0x02, 0x00, 0x41, 0x9c, 0x01, + 0x00, 0x00, 0x04, 0xa3, 0x01, 0x00, 0x00, 0x24, + 0x01, 0x00, 0x0e, 0xe6, 0xba, 0xf5, 0x0e, 0x29, + 0x64, 0x02, 0x00, 0x41, 0x9c, 0x01, 0x00, 0x00, + 0x04, 0xbb, 0x01, 0x00, 0x00, 0x24, 0x01, 0x00, + 0x0e, 0x5d, 0x04, 0x00, 0xf4, 0x0e, 0x29, 0x0c, + 0x43, 0x02, 0x01, 0xa6, 0x05, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x02, 0x00, 0x05, 0x00, 0xa8, 0x04, + 0x28, 0x00, 0xaa, 0x04, 0x29, 0x00, 0xc6, 0xe7, + 0xba, 0xe8, 0x29, 0x0c, 0x43, 0x02, 0x01, 0xa8, + 0x05, 0x02, 0x01, 0x02, 0x04, 0x00, 0x02, 0x00, + 0x39, 0x03, 0xf8, 0x06, 0x00, 0x01, 0x00, 0xe6, + 0x06, 0x00, 0x01, 0x00, 0xdc, 0x06, 0x00, 0x00, + 0x00, 0xce, 0x04, 0x3b, 0x00, 0xd0, 0x04, 0x3c, + 0x00, 0xd8, 0xcf, 0xcb, 0xba, 0xa7, 0xf0, 0x0e, + 0xe3, 0xd7, 0xcb, 0xbb, 0x9d, 0x46, 0xf5, 0xf0, + 0x05, 0x91, 0x00, 0xf2, 0xef, 0xcb, 0xba, 0xa7, + 0xf0, 0x0e, 0xe4, 0xd7, 0xcb, 0xbb, 0x9d, 0x46, + 0xf5, 0xf0, 0x05, 0x91, 0x00, 0xf2, 0xef, 0xcb, + 0xba, 0xa7, 0x11, 0xf0, 0x0d, 0x0e, 0xd7, 0xcb, + 0xbb, 0x9d, 0x46, 0x04, 0xbd, 0x01, 0x00, 0x00, + 0xad, 0x28, 0x0c, 0x43, 0x02, 0x01, 0xaa, 0x05, + 0x02, 0x01, 0x02, 0x04, 0x00, 0x01, 0x00, 0x1f, + 0x03, 0xf8, 0x06, 0x00, 0x01, 0x00, 0xe6, 0x06, + 0x00, 0x01, 0x00, 0xdc, 0x06, 0x00, 0x00, 0x00, + 0xce, 0x04, 0x3b, 0x00, 0xd8, 0xcf, 0xcb, 0xba, + 0xa7, 0xf0, 0x0e, 0xe3, 0xd7, 0xcb, 0xbb, 0x9d, + 0x46, 0xf5, 0xf0, 0x05, 0x91, 0x00, 0xf2, 0xef, + 0xd7, 0x41, 0xbe, 0x01, 0x00, 0x00, 0xcb, 0xd8, + 0x25, 0x02, 0x00, 0x0c, 0x43, 0x02, 0x01, 0xac, + 0x05, 0x02, 0x04, 0x02, 0x05, 0x00, 0x07, 0x04, + 0x9e, 0x02, 0x06, 0xf8, 0x06, 0x00, 0x01, 0x00, + 0xdc, 0x06, 0x00, 0x01, 0x00, 0x8a, 0x06, 0x00, + 0x00, 0x00, 0xfe, 0x06, 0x00, 0x01, 0x00, 0x80, + 0x07, 0x00, 0x02, 0x00, 0x82, 0x07, 0x00, 0x03, + 0x00, 0xf0, 0x03, 0x00, 0x01, 0xd6, 0x05, 0x7f, + 0x00, 0xce, 0x04, 0x3b, 0x00, 0xaa, 0x05, 0x69, + 0x00, 0xf4, 0x03, 0x0e, 0x00, 0xac, 0x05, 0x6a, + 0x00, 0xd6, 0x02, 0x08, 0x00, 0x07, 0x02, 0x20, + 0x07, 0x36, 0x00, 0x00, 0x01, 0x00, 0x13, 0x00, + 0x00, 0x00, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x06, + 0x0d, 0xf5, 0xff, 0xff, 0xff, 0x13, 0x00, 0x01, + 0x20, 0x00, 0x14, 0x00, 0x10, 0x07, 0x1a, 0x5e, + 0x5b, 0x64, 0x67, 0x69, 0x6d, 0x73, 0x75, 0x76, + 0x79, 0x5d, 0x2b, 0x24, 0x07, 0x7c, 0x00, 0x00, + 0x01, 0x00, 0x36, 0x00, 0x00, 0x00, 0x0e, 0x06, + 0x00, 0x00, 0x00, 0x06, 0x0d, 0xf5, 0xff, 0xff, + 0xff, 0x13, 0x00, 0x09, 0x24, 0x07, 0x00, 0x64, + 0x00, 0x64, 0x00, 0x67, 0x00, 0x67, 0x00, 0x69, + 0x00, 0x69, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x73, + 0x00, 0x73, 0x00, 0x75, 0x00, 0x76, 0x00, 0x79, + 0x00, 0x79, 0x00, 0x0e, 0xdc, 0xff, 0xff, 0xff, + 0x0b, 0x14, 0x00, 0x10, 0xd8, 0xba, 0xa6, 0xf0, + 0x03, 0xe3, 0x28, 0xd7, 0xd8, 0xbb, 0x9d, 0x46, + 0xcf, 0xd8, 0xbb, 0xad, 0xf0, 0x17, 0xcb, 0x04, + 0xc2, 0x01, 0x00, 0x00, 0xad, 0x11, 0xf1, 0x09, + 0x0e, 0xcb, 0x04, 0xbd, 0x01, 0x00, 0x00, 0xad, + 0xf0, 0x03, 0xe4, 0x28, 0x04, 0xc3, 0x01, 0x00, + 0x00, 0x41, 0xc4, 0x01, 0x00, 0x00, 0xcb, 0x24, + 0x01, 0x00, 0xba, 0xa8, 0xf0, 0x02, 0x29, 0xcb, + 0x04, 0xbd, 0x01, 0x00, 0x00, 0xad, 0x68, 0xd9, + 0x00, 0x00, 0x00, 0xd8, 0x8d, 0xdc, 0xd7, 0xd8, + 0xbb, 0x9d, 0x46, 0xd3, 0x11, 0x04, 0xc5, 0x01, + 0x00, 0x00, 0xad, 0xf1, 0x13, 0x11, 0x04, 0xc6, + 0x01, 0x00, 0x00, 0xad, 0xf1, 0x0a, 0x11, 0x04, + 0xc7, 0x01, 0x00, 0x00, 0xad, 0xf0, 0x07, 0x04, + 0x88, 0x01, 0x00, 0x00, 0x28, 0x11, 0x04, 0xc8, + 0x01, 0x00, 0x00, 0xad, 0xf0, 0x05, 0x26, 0x00, + 0x00, 0x28, 0x11, 0x04, 0xc9, 0x01, 0x00, 0x00, + 0xad, 0xf0, 0x07, 0xc4, 0x00, 0xc4, 0x01, 0x34, + 0x28, 0xe5, 0xcb, 0xf5, 0x68, 0x88, 0x00, 0x00, + 0x00, 0xe6, 0xd7, 0xd8, 0xf6, 0xd0, 0xd8, 0xcc, + 0xef, 0x9d, 0xd1, 0xcc, 0x04, 0x03, 0x00, 0x00, + 0x00, 0xad, 0x11, 0xf1, 0x09, 0x0e, 0xcc, 0x04, + 0x02, 0x00, 0x00, 0x00, 0xad, 0xf0, 0x03, 0x0a, + 0x28, 0xcc, 0x04, 0x01, 0x00, 0x00, 0x00, 0xad, + 0xf0, 0x03, 0x07, 0x28, 0xcc, 0x04, 0x08, 0x00, + 0x00, 0x00, 0xad, 0xf0, 0x03, 0xe3, 0x28, 0x5d, + 0x04, 0x00, 0xcc, 0x8c, 0xf5, 0xf1, 0x03, 0xba, + 0x28, 0x5d, 0x05, 0x00, 0xd7, 0xcd, 0xf6, 0xd6, + 0xf9, 0x11, 0xf1, 0x04, 0x0e, 0xce, 0xf8, 0xf0, + 0x03, 0xce, 0x28, 0xce, 0xcc, 0x46, 0xfa, 0xf1, + 0x05, 0xce, 0xcc, 0x46, 0x28, 0xcd, 0xbd, 0xa8, + 0xf0, 0x24, 0xd7, 0xcd, 0xbb, 0x9d, 0x46, 0x04, + 0xc9, 0x01, 0x00, 0x00, 0xad, 0xf0, 0x17, 0xcc, + 0x41, 0xca, 0x01, 0x00, 0x00, 0xc4, 0x02, 0xc4, + 0x03, 0x34, 0x24, 0x01, 0x00, 0xf0, 0x07, 0x5d, + 0x06, 0x00, 0x23, 0x00, 0x00, 0x0e, 0x0b, 0x28, + 0xe3, 0x28, 0x0c, 0x43, 0x02, 0x01, 0xae, 0x05, + 0x02, 0x0b, 0x02, 0x06, 0x00, 0x05, 0x01, 0x96, + 0x02, 0x0d, 0xf8, 0x06, 0x00, 0x01, 0x00, 0xdc, + 0x06, 0x00, 0x01, 0x00, 0xf4, 0x06, 0x00, 0x00, + 0x00, 0x82, 0x07, 0x00, 0x01, 0x00, 0x96, 0x07, + 0x00, 0x02, 0x00, 0x98, 0x07, 0x00, 0x03, 0x00, + 0x84, 0x06, 0x00, 0x04, 0x00, 0xb4, 0x06, 0x00, + 0x05, 0x00, 0x9a, 0x07, 0x00, 0x06, 0x00, 0x9c, + 0x07, 0x04, 0x00, 0x30, 0x9e, 0x07, 0x00, 0x07, + 0x00, 0xa0, 0x07, 0x00, 0x09, 0x00, 0xa2, 0x07, + 0x0d, 0x00, 0x21, 0xaa, 0x05, 0x69, 0x00, 0xac, + 0x05, 0x6a, 0x00, 0xa8, 0x05, 0x68, 0x00, 0xfa, + 0x03, 0x11, 0x00, 0xba, 0x02, 0x00, 0x00, 0x0c, + 0x43, 0x02, 0x01, 0xa2, 0x07, 0x02, 0x00, 0x02, + 0x03, 0x00, 0x00, 0x00, 0x34, 0x02, 0x90, 0x06, + 0x00, 0x01, 0x00, 0xa8, 0x06, 0x00, 0x01, 0x00, + 0xd7, 0xba, 0x46, 0xd8, 0xba, 0x46, 0xac, 0xf0, + 0x1b, 0xd7, 0xba, 0x46, 0x04, 0x8a, 0x01, 0x00, + 0x00, 0xab, 0xf0, 0x03, 0xbb, 0x28, 0xd8, 0xba, + 0x46, 0x04, 0x8a, 0x01, 0x00, 0x00, 0xab, 0xf0, + 0x03, 0xb9, 0x28, 0xd7, 0xd8, 0xa5, 0xf0, 0x03, + 0xb9, 0x28, 0xd7, 0xd8, 0xa7, 0xf0, 0x04, 0xbb, + 0x8c, 0x28, 0xba, 0x28, 0xe3, 0xd7, 0xd8, 0xf6, + 0xcf, 0xe4, 0xd7, 0xd8, 0xcb, 0xef, 0x9d, 0xf6, + 0xd1, 0x26, 0x00, 0x00, 0xd2, 0xe5, 0xd7, 0xd8, + 0xf6, 0xf1, 0x2b, 0x60, 0x07, 0x00, 0xe6, 0x7e, + 0xf2, 0x1e, 0xc8, 0x07, 0x61, 0x07, 0x00, 0x41, + 0xd2, 0x01, 0x00, 0x00, 0xcb, 0x24, 0x01, 0x00, + 0xf0, 0x0e, 0xce, 0x41, 0xb1, 0x01, 0x00, 0x00, + 0x61, 0x07, 0x00, 0x24, 0x01, 0x00, 0x0e, 0x81, + 0x00, 0xf0, 0xe0, 0x0e, 0x83, 0xba, 0xc8, 0x04, + 0xcd, 0xd0, 0xc7, 0x04, 0xc2, 0x0a, 0xa5, 0xf0, + 0x6b, 0xcc, 0xf9, 0xf1, 0x67, 0xcc, 0x06, 0xae, + 0xf0, 0x62, 0x5d, 0x04, 0x00, 0x41, 0xd3, 0x01, + 0x00, 0x00, 0xcc, 0x24, 0x01, 0x00, 0xc8, 0x08, + 0xba, 0xc8, 0x05, 0xc7, 0x05, 0xc7, 0x08, 0xef, + 0xa5, 0xf0, 0x38, 0xc7, 0x08, 0xc7, 0x05, 0x46, + 0xc9, 0x09, 0x96, 0x04, 0x4c, 0x00, 0x00, 0x00, + 0xab, 0xf0, 0x24, 0xc6, 0xc7, 0x09, 0x8c, 0x9c, + 0xc7, 0x09, 0xac, 0xf0, 0x1a, 0xc7, 0x09, 0x41, + 0xd2, 0x01, 0x00, 0x00, 0xcb, 0x24, 0x01, 0x00, + 0xf0, 0x0d, 0xce, 0x41, 0xb1, 0x01, 0x00, 0x00, + 0xc7, 0x09, 0x24, 0x01, 0x00, 0x0e, 0x92, 0x05, + 0xf2, 0xc2, 0x5d, 0x04, 0x00, 0x41, 0x66, 0x00, + 0x00, 0x00, 0xcc, 0x24, 0x01, 0x00, 0xd0, 0x92, + 0x04, 0xf2, 0x90, 0xce, 0xef, 0xbb, 0xa7, 0xf0, + 0x45, 0xc5, 0x00, 0xc8, 0x0a, 0xc5, 0x00, 0x0e, + 0xce, 0x41, 0xd4, 0x01, 0x00, 0x00, 0x61, 0x0a, + 0x00, 0x24, 0x01, 0x00, 0x0e, 0xbb, 0xc9, 0x05, + 0xc8, 0x04, 0xc7, 0x04, 0xce, 0xef, 0xa5, 0xf0, + 0x1d, 0xce, 0xc7, 0x04, 0x46, 0xce, 0xc7, 0x04, + 0xbb, 0x9d, 0x46, 0xac, 0xf0, 0x0c, 0xce, 0xc7, + 0x05, 0x90, 0xc8, 0x05, 0xce, 0xc7, 0x04, 0x46, + 0x48, 0x92, 0x04, 0xf2, 0xde, 0xce, 0xc7, 0x05, + 0x42, 0x33, 0x00, 0x00, 0x00, 0x0b, 0xce, 0x4b, + 0x79, 0x01, 0x00, 0x00, 0xcb, 0xef, 0x4b, 0xae, + 0x01, 0x00, 0x00, 0xcd, 0x4b, 0xd5, 0x01, 0x00, + 0x00, 0x28, 0x0c, 0x43, 0x02, 0x01, 0xb0, 0x05, + 0x00, 0x0d, 0x00, 0x07, 0x00, 0x0a, 0x00, 0xa1, + 0x03, 0x0d, 0xf2, 0x05, 0x00, 0x00, 0x00, 0xac, + 0x07, 0x00, 0x01, 0x00, 0xf4, 0x06, 0x00, 0x02, + 0x00, 0x84, 0x06, 0x00, 0x03, 0x00, 0xb4, 0x06, + 0x00, 0x04, 0x00, 0x9e, 0x06, 0x00, 0x05, 0x00, + 0xae, 0x07, 0x00, 0x06, 0x00, 0xb0, 0x07, 0x00, + 0x07, 0x00, 0xb2, 0x07, 0x00, 0x08, 0x00, 0xb4, + 0x07, 0x00, 0x09, 0x00, 0xb6, 0x07, 0x00, 0x0a, + 0x00, 0xb8, 0x07, 0x00, 0x0b, 0x00, 0xba, 0x07, + 0x00, 0x0c, 0x00, 0xae, 0x05, 0x6b, 0x00, 0xa8, + 0x04, 0x28, 0x00, 0xaa, 0x04, 0x29, 0x00, 0xe0, + 0x04, 0x44, 0x00, 0xb2, 0x04, 0x2d, 0x00, 0xb0, + 0x05, 0x6c, 0x00, 0xca, 0x02, 0x0b, 0x00, 0xbe, + 0x04, 0x33, 0x00, 0xea, 0x03, 0x00, 0x1a, 0xbc, + 0x05, 0x72, 0x00, 0xe3, 0xe4, 0xe5, 0xf6, 0xd4, + 0x40, 0x79, 0x01, 0x00, 0x00, 0xd3, 0xef, 0xba, + 0xad, 0xf0, 0x02, 0x29, 0xcb, 0xba, 0x46, 0xd5, + 0xef, 0xc8, 0x05, 0xbb, 0xd2, 0xce, 0xcb, 0xef, + 0xa5, 0xf0, 0x2a, 0xcb, 0xce, 0x46, 0xc8, 0x06, + 0xba, 0xc8, 0x04, 0xc7, 0x04, 0xc7, 0x05, 0xa5, + 0xf0, 0x17, 0xc7, 0x06, 0xc7, 0x04, 0x46, 0xcd, + 0xc7, 0x04, 0x46, 0xae, 0xf0, 0x07, 0xc7, 0x04, + 0xc8, 0x05, 0xf2, 0x05, 0x92, 0x04, 0xf2, 0xe4, + 0x92, 0x03, 0xf2, 0xd2, 0xcc, 0x40, 0xae, 0x01, + 0x00, 0x00, 0xd2, 0xce, 0xc7, 0x05, 0xa5, 0xf0, + 0x0b, 0xe6, 0xcd, 0xce, 0x46, 0xf5, 0x0e, 0x92, + 0x03, 0xf2, 0xf1, 0x5d, 0x04, 0x00, 0x5d, 0x05, + 0x00, 0xad, 0xf0, 0x54, 0xcb, 0xef, 0xbb, 0xab, + 0xf0, 0x4e, 0xcb, 0xba, 0x46, 0xd1, 0xcc, 0x40, + 0xd5, 0x01, 0x00, 0x00, 0xcd, 0x46, 0xc9, 0x0c, + 0xfb, 0xf0, 0x1a, 0xe6, 0x04, 0xde, 0x01, 0x00, + 0x00, 0xf5, 0x0e, 0xc7, 0x0c, 0xef, 0xba, 0xab, + 0xf0, 0x2e, 0xe6, 0x04, 0xdf, 0x01, 0x00, 0x00, + 0xf5, 0x0e, 0xf2, 0x24, 0xc7, 0x0c, 0x96, 0x04, + 0x4d, 0x00, 0x00, 0x00, 0xab, 0x11, 0xf1, 0x0e, + 0x0e, 0xc7, 0x0c, 0xfa, 0xf0, 0x12, 0xcd, 0x04, + 0x08, 0x00, 0x00, 0x00, 0xab, 0xf0, 0x09, 0xe6, + 0x04, 0xbd, 0x01, 0x00, 0x00, 0xf5, 0x0e, 0x5d, + 0x04, 0x00, 0x5d, 0x05, 0x00, 0xad, 0x68, 0xdc, + 0x00, 0x00, 0x00, 0xcb, 0xef, 0xbc, 0xa8, 0x68, + 0xd3, 0x00, 0x00, 0x00, 0xba, 0xc8, 0x07, 0xba, + 0xd2, 0xce, 0xcb, 0xef, 0xa5, 0xf0, 0x18, 0x5d, + 0x06, 0x00, 0x41, 0xe0, 0x01, 0x00, 0x00, 0xc7, + 0x07, 0xcb, 0xce, 0x46, 0xef, 0x24, 0x02, 0x00, + 0xc8, 0x07, 0x92, 0x03, 0xf2, 0xe4, 0xbc, 0x93, + 0x07, 0x5d, 0x06, 0x00, 0x41, 0xe0, 0x01, 0x00, + 0x00, 0xbb, 0x5d, 0x06, 0x00, 0x41, 0xe1, 0x01, + 0x00, 0x00, 0x5d, 0x07, 0x00, 0xbb, 0x9c, 0xc7, + 0x07, 0x9a, 0x24, 0x01, 0x00, 0x24, 0x02, 0x00, + 0xc8, 0x09, 0x5d, 0x06, 0x00, 0x41, 0xe2, 0x01, + 0x00, 0x00, 0xcb, 0xef, 0xc7, 0x09, 0x9a, 0x24, + 0x01, 0x00, 0xc8, 0x0b, 0x64, 0x08, 0x00, 0x41, + 0x9c, 0x01, 0x00, 0x00, 0x04, 0xa3, 0x01, 0x00, + 0x00, 0x24, 0x01, 0x00, 0x0e, 0xba, 0xc8, 0x0a, + 0xc7, 0x0a, 0xc7, 0x0b, 0xa5, 0xf0, 0x58, 0xba, + 0xc8, 0x08, 0xc7, 0x08, 0xc7, 0x09, 0xa5, 0xf0, + 0x39, 0xc7, 0x08, 0xc7, 0x0b, 0x99, 0xc7, 0x0a, + 0x9c, 0xd6, 0xcb, 0xef, 0xa8, 0xf1, 0x2b, 0xcb, + 0xce, 0x46, 0xd1, 0xc7, 0x08, 0xc7, 0x09, 0xbb, + 0x9d, 0xac, 0xf0, 0x0d, 0xcd, 0x41, 0xe3, 0x01, + 0x00, 0x00, 0xc7, 0x07, 0x24, 0x01, 0x00, 0xd1, + 0x64, 0x08, 0x00, 0x41, 0x9c, 0x01, 0x00, 0x00, + 0xcd, 0x24, 0x01, 0x00, 0x0e, 0x92, 0x08, 0xf2, + 0xc2, 0x64, 0x08, 0x00, 0x41, 0x9c, 0x01, 0x00, + 0x00, 0x04, 0xa3, 0x01, 0x00, 0x00, 0x24, 0x01, + 0x00, 0x0e, 0x92, 0x0a, 0xf2, 0xa3, 0x5d, 0x09, + 0x00, 0xf4, 0x0e, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0xb4, 0x05, 0x02, 0x01, 0x02, 0x02, 0x00, 0x00, + 0x00, 0x10, 0x03, 0x9c, 0x06, 0x00, 0x01, 0x00, + 0xc8, 0x07, 0x00, 0x01, 0x00, 0xac, 0x07, 0x00, + 0x00, 0x00, 0xc6, 0xcf, 0xd8, 0x8f, 0xdc, 0xba, + 0xa7, 0xf0, 0x06, 0xd7, 0x93, 0x00, 0xf2, 0xf5, + 0xcb, 0x28, 0x0c, 0x43, 0x02, 0x01, 0xbc, 0x05, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x07, 0x00, 0x1e, + 0x00, 0xea, 0x03, 0x00, 0x1a, 0x98, 0x04, 0x20, + 0x00, 0xd2, 0x04, 0x3d, 0x00, 0xbe, 0x04, 0x33, + 0x00, 0xc0, 0x04, 0x34, 0x00, 0xac, 0x04, 0x2a, + 0x00, 0xae, 0x04, 0x2b, 0x00, 0x64, 0x00, 0x00, + 0x41, 0x9c, 0x01, 0x00, 0x00, 0xe4, 0x24, 0x01, + 0x00, 0x0e, 0xe5, 0xe4, 0xf5, 0xe6, 0x9b, 0x5e, + 0x04, 0x00, 0xc6, 0x5e, 0x05, 0x00, 0xba, 0x5e, + 0x06, 0x00, 0x29, 0x0c, 0x43, 0x02, 0x01, 0xbe, + 0x05, 0x02, 0x01, 0x02, 0x05, 0x00, 0x11, 0x00, + 0x80, 0x01, 0x03, 0xca, 0x07, 0x00, 0x01, 0x00, + 0xcc, 0x07, 0x00, 0x01, 0x00, 0xae, 0x07, 0x00, + 0x00, 0x00, 0xa8, 0x04, 0x28, 0x00, 0xaa, 0x04, + 0x29, 0x00, 0x90, 0x04, 0x1c, 0x00, 0x92, 0x04, + 0x1d, 0x00, 0xba, 0x05, 0x71, 0x00, 0x96, 0x04, + 0x1f, 0x00, 0x98, 0x04, 0x20, 0x00, 0xa4, 0x04, + 0x26, 0x00, 0xb4, 0x05, 0x6e, 0x00, 0x9a, 0x04, + 0x21, 0x00, 0x9e, 0x04, 0x23, 0x00, 0x84, 0x04, + 0x16, 0x00, 0xa2, 0x04, 0x25, 0x00, 0x9c, 0x04, + 0x22, 0x00, 0xbc, 0x05, 0x72, 0x00, 0xde, 0x04, + 0x43, 0x00, 0xb8, 0x05, 0x70, 0x00, 0xd7, 0x11, + 0xf1, 0x03, 0x0e, 0xc6, 0xeb, 0xef, 0xe8, 0xe5, + 0xef, 0xea, 0xd8, 0x5e, 0x04, 0x00, 0x5d, 0x05, + 0x00, 0x5e, 0x06, 0x00, 0x5d, 0x07, 0x00, 0xf0, + 0x22, 0x5d, 0x06, 0x00, 0x5d, 0x08, 0x00, 0x04, + 0xe7, 0x01, 0x00, 0x00, 0x5d, 0x09, 0x00, 0x5d, + 0x06, 0x00, 0xef, 0x9d, 0xf6, 0x9c, 0x5f, 0x06, + 0x00, 0x5d, 0x0a, 0x00, 0x9c, 0x5e, 0x06, 0x00, + 0xf2, 0x36, 0x5d, 0x0b, 0x00, 0xf0, 0x20, 0x5d, + 0x0c, 0x00, 0xc3, 0xe8, 0x03, 0x9a, 0xcf, 0x5d, + 0x06, 0x00, 0xcb, 0x41, 0xe8, 0x01, 0x00, 0x00, + 0xc0, 0x24, 0x01, 0x00, 0x04, 0xe7, 0x01, 0x00, + 0x00, 0x9c, 0x9c, 0x5e, 0x06, 0x00, 0x5d, 0x06, + 0x00, 0xef, 0x5e, 0x09, 0x00, 0x5d, 0x06, 0x00, + 0x5d, 0x0d, 0x00, 0x9c, 0x5e, 0x06, 0x00, 0x5d, + 0x0e, 0x00, 0xf4, 0x0e, 0x5d, 0x0f, 0x00, 0xf4, + 0x0e, 0xba, 0x5e, 0x10, 0x00, 0x29, 0x0c, 0x43, + 0x02, 0x01, 0xc0, 0x05, 0x01, 0x01, 0x01, 0x03, + 0x00, 0x04, 0x02, 0x85, 0x01, 0x02, 0xd2, 0x07, + 0x00, 0x01, 0x00, 0x8a, 0x06, 0x00, 0x00, 0x00, + 0xc2, 0x02, 0x01, 0x00, 0xb8, 0x05, 0x70, 0x00, + 0xb6, 0x05, 0x6f, 0x00, 0xc2, 0x05, 0x75, 0x00, + 0x07, 0x02, 0x30, 0x07, 0x02, 0x39, 0xe3, 0x41, + 0xea, 0x01, 0x00, 0x00, 0xd7, 0x24, 0x01, 0x00, + 0xcf, 0xe4, 0x11, 0xba, 0xad, 0xf0, 0x14, 0xcb, + 0x04, 0xeb, 0x01, 0x00, 0x00, 0xab, 0xf0, 0x06, + 0xcb, 0xe9, 0xbb, 0xe8, 0x29, 0xe6, 0xcb, 0xf5, + 0x0e, 0x29, 0x11, 0xbb, 0xad, 0xf0, 0x24, 0xe5, + 0xcb, 0x9c, 0xe9, 0xcb, 0x04, 0xec, 0x01, 0x00, + 0x00, 0xab, 0xf0, 0x04, 0xbc, 0xe8, 0x29, 0xcb, + 0x04, 0xed, 0x01, 0x00, 0x00, 0xab, 0xf0, 0x04, + 0xbd, 0xe8, 0x29, 0xe6, 0xe5, 0xf5, 0x0e, 0xba, + 0xe8, 0x29, 0x11, 0xbc, 0xad, 0xf0, 0x25, 0xe5, + 0xcb, 0x9c, 0xe9, 0xcb, 0x04, 0xee, 0x01, 0x00, + 0x00, 0xab, 0x11, 0xf1, 0x0e, 0x0e, 0xcb, 0xc4, + 0x00, 0xa8, 0x11, 0xf0, 0x06, 0x0e, 0xcb, 0xc4, + 0x01, 0xa6, 0xf1, 0x17, 0xe6, 0xe5, 0xf5, 0x0e, + 0xba, 0xe8, 0x29, 0x11, 0xbd, 0xad, 0xf0, 0x0b, + 0xe5, 0xcb, 0x9c, 0xe9, 0xe6, 0xe5, 0xf5, 0x0e, + 0xba, 0xe8, 0x29, 0x0c, 0x43, 0x02, 0x01, 0xc2, + 0x05, 0x01, 0x01, 0x01, 0x05, 0x00, 0x0e, 0x00, + 0xb6, 0x01, 0x02, 0x62, 0x00, 0x01, 0x00, 0xde, + 0x07, 0x00, 0x00, 0x00, 0xb4, 0x04, 0x2e, 0x00, + 0xd2, 0x04, 0x3d, 0x00, 0xe0, 0x04, 0x44, 0x00, + 0xb2, 0x05, 0x6d, 0x00, 0xb0, 0x04, 0x2c, 0x00, + 0xba, 0x05, 0x71, 0x00, 0xa8, 0x04, 0x28, 0x00, + 0xec, 0x03, 0x01, 0x1a, 0xba, 0x04, 0x31, 0x00, + 0xec, 0x05, 0x8a, 0x01, 0x00, 0xb2, 0x04, 0x2d, + 0x00, 0xe6, 0x04, 0x47, 0x00, 0xaa, 0x04, 0x29, + 0x00, 0xde, 0x04, 0x43, 0x00, 0xe3, 0xf0, 0x11, + 0xe4, 0xd7, 0xf5, 0xbb, 0xad, 0xf0, 0x05, 0xe5, + 0xd7, 0xf5, 0x0e, 0x09, 0xe7, 0xf3, 0x80, 0x00, + 0xe6, 0xd7, 0x46, 0xd3, 0xf0, 0x5a, 0xcb, 0x5e, + 0x04, 0x00, 0xcb, 0xd7, 0xf5, 0x11, 0xb9, 0xad, + 0xf0, 0x09, 0x5d, 0x05, 0x00, 0x5d, 0x06, 0x00, + 0xf5, 0x29, 0x11, 0xc2, 0xfe, 0xad, 0xf0, 0x07, + 0x5d, 0x05, 0x00, 0x07, 0xf5, 0x29, 0x11, 0xc2, + 0xfd, 0xad, 0xf0, 0x2b, 0x64, 0x07, 0x00, 0x41, + 0x7e, 0x01, 0x00, 0x00, 0x64, 0x07, 0x00, 0x40, + 0x7f, 0x01, 0x00, 0x00, 0x07, 0x24, 0x02, 0x00, + 0x0e, 0x64, 0x07, 0x00, 0x41, 0x80, 0x01, 0x00, + 0x00, 0x5d, 0x08, 0x00, 0x07, 0x24, 0x02, 0x00, + 0x0e, 0x5d, 0x09, 0x00, 0xf4, 0x29, 0x0e, 0x5d, + 0x04, 0x00, 0x5e, 0x0a, 0x00, 0xf2, 0x20, 0xe4, + 0xd7, 0xf5, 0xbb, 0xad, 0xf0, 0x14, 0xd7, 0x04, + 0xe7, 0x01, 0x00, 0x00, 0xa8, 0xf0, 0x0b, 0xe5, + 0xd7, 0xf5, 0x0e, 0xe5, 0x5e, 0x0a, 0x00, 0xf2, + 0x06, 0x5d, 0x0b, 0x00, 0xf4, 0x0e, 0x5d, 0x0c, + 0x00, 0xba, 0xa5, 0xf0, 0x04, 0xba, 0xf2, 0x14, + 0x5d, 0x0c, 0x00, 0x5d, 0x06, 0x00, 0xef, 0xa7, + 0xf0, 0x07, 0x5d, 0x06, 0x00, 0xef, 0xf2, 0x04, + 0x5d, 0x0c, 0x00, 0x5e, 0x0c, 0x00, 0x5d, 0x0d, + 0x00, 0xf4, 0x29, 0x0c, 0x43, 0x02, 0x01, 0xc4, + 0x05, 0x02, 0x01, 0x02, 0x05, 0x00, 0x02, 0x01, + 0x6f, 0x03, 0x90, 0x06, 0x00, 0x01, 0x00, 0xe0, + 0x07, 0x00, 0x01, 0x00, 0xf4, 0x06, 0x00, 0x00, + 0x00, 0xf2, 0x03, 0x0d, 0x00, 0xca, 0x02, 0x0b, + 0x00, 0x07, 0x02, 0x30, 0xe3, 0xd7, 0xf5, 0xf1, + 0x0a, 0xd7, 0x41, 0x3b, 0x00, 0x00, 0x00, 0x25, + 0x00, 0x00, 0xd7, 0xba, 0xab, 0xf0, 0x15, 0xbb, + 0xd7, 0x9a, 0xba, 0xa5, 0xf0, 0x09, 0x04, 0xf1, + 0x01, 0x00, 0x00, 0xcf, 0xf2, 0x4c, 0xc4, 0x00, + 0xcf, 0xf2, 0x47, 0xd8, 0xc2, 0x10, 0xab, 0xf0, + 0x37, 0xd7, 0xe4, 0x41, 0xe1, 0x01, 0x00, 0x00, + 0xd7, 0x24, 0x01, 0x00, 0xad, 0xf0, 0x29, 0xd7, + 0xba, 0xa5, 0xf0, 0x0c, 0xd7, 0x8b, 0xdb, 0x04, + 0xf2, 0x01, 0x00, 0x00, 0xcf, 0xf2, 0x03, 0xc6, + 0xcf, 0xcb, 0x04, 0xf3, 0x01, 0x00, 0x00, 0xd7, + 0x41, 0x3b, 0x00, 0x00, 0x00, 0xc2, 0x10, 0x24, + 0x01, 0x00, 0x9c, 0x9c, 0xcf, 0xf2, 0x0b, 0xd7, + 0x41, 0x3b, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0xcf, 0xcb, 0x28, 0x0c, 0x43, 0x02, 0x01, 0xc6, + 0x05, 0x02, 0x01, 0x02, 0x05, 0x00, 0x00, 0x00, + 0x40, 0x03, 0x90, 0x06, 0x00, 0x01, 0x00, 0xe0, + 0x07, 0x00, 0x01, 0x00, 0xf4, 0x06, 0x00, 0x00, + 0x00, 0xd8, 0xc2, 0x10, 0xab, 0xf0, 0x29, 0xd7, + 0xba, 0xa5, 0xf0, 0x0c, 0xd7, 0x8b, 0xdb, 0x04, + 0xf2, 0x01, 0x00, 0x00, 0xcf, 0xf2, 0x03, 0xc6, + 0xcf, 0xcb, 0x04, 0xf3, 0x01, 0x00, 0x00, 0xd7, + 0x41, 0x3b, 0x00, 0x00, 0x00, 0xc2, 0x10, 0x24, + 0x01, 0x00, 0x9c, 0x9c, 0xcf, 0xf2, 0x0b, 0xd7, + 0x41, 0x3b, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0xcf, 0xcb, 0x04, 0x9f, 0x01, 0x00, 0x00, 0x9c, + 0x28, 0x0c, 0x43, 0x02, 0x01, 0x00, 0x04, 0x18, + 0x04, 0x06, 0x19, 0x12, 0x0e, 0xea, 0x01, 0x1c, + 0xe8, 0x07, 0x00, 0x01, 0x00, 0x88, 0x04, 0x00, + 0x01, 0x40, 0x0a, 0xea, 0x07, 0x00, 0x01, 0x40, + 0x07, 0xec, 0x07, 0x00, 0x01, 0x40, 0x0d, 0xee, + 0x07, 0x00, 0x00, 0x00, 0x8c, 0x01, 0x00, 0x01, + 0x00, 0xf0, 0x07, 0x00, 0x02, 0x40, 0x15, 0xf2, + 0x07, 0x00, 0x03, 0x40, 0x09, 0xf4, 0x07, 0x00, + 0x04, 0x40, 0x0c, 0xf6, 0x07, 0x00, 0x05, 0x40, + 0x02, 0xf8, 0x07, 0x00, 0x06, 0x40, 0x04, 0x72, + 0x00, 0x07, 0x40, 0x05, 0xfa, 0x07, 0x00, 0x08, + 0x40, 0x00, 0xfc, 0x07, 0x00, 0x09, 0x40, 0x0f, + 0xfe, 0x07, 0x00, 0x0a, 0x40, 0x0e, 0x80, 0x08, + 0x00, 0x0b, 0x40, 0x03, 0x82, 0x08, 0x00, 0x0c, + 0x40, 0x01, 0x84, 0x08, 0x00, 0x0d, 0x40, 0x0b, + 0x86, 0x08, 0x00, 0x0e, 0x40, 0x06, 0x88, 0x08, + 0x00, 0x0f, 0x40, 0x08, 0x8a, 0x08, 0x00, 0x10, + 0x40, 0x10, 0x8c, 0x08, 0x00, 0x11, 0x40, 0x13, + 0x8e, 0x08, 0x00, 0x12, 0x40, 0x14, 0x90, 0x08, + 0x00, 0x13, 0x40, 0x11, 0x92, 0x08, 0x00, 0x14, + 0x40, 0x12, 0x94, 0x08, 0x00, 0x15, 0x40, 0x16, + 0x96, 0x08, 0x00, 0x16, 0x40, 0x17, 0x98, 0x08, + 0x00, 0x17, 0x40, 0x18, 0xf6, 0x03, 0x0f, 0x00, + 0xcc, 0x02, 0x0c, 0x00, 0xba, 0x02, 0x00, 0x00, + 0xc4, 0x05, 0x76, 0x00, 0x8c, 0x04, 0x1a, 0x00, + 0xc6, 0x05, 0x77, 0x00, 0xc2, 0x02, 0x01, 0x00, + 0xce, 0x02, 0x07, 0x00, 0xd6, 0x02, 0x08, 0x00, + 0xc4, 0x02, 0x03, 0x00, 0xc0, 0x02, 0x02, 0x00, + 0xf6, 0x02, 0x04, 0x00, 0xbc, 0x02, 0x06, 0x00, + 0xe0, 0x02, 0x05, 0x00, 0xfc, 0x03, 0x12, 0x00, + 0x80, 0x04, 0x14, 0x00, 0xca, 0x02, 0x0b, 0x00, + 0xbe, 0x04, 0x33, 0x00, 0x0c, 0x43, 0x02, 0x01, + 0x8c, 0x01, 0x02, 0x00, 0x02, 0x01, 0x00, 0x01, + 0x00, 0x0e, 0x02, 0x9a, 0x08, 0x00, 0x01, 0x00, + 0x9c, 0x08, 0x00, 0x01, 0x00, 0xf6, 0x03, 0x00, + 0x02, 0xd7, 0xfa, 0xf0, 0x03, 0xd8, 0x28, 0xd7, + 0xf9, 0xf0, 0x03, 0xe3, 0x28, 0xd7, 0x28, 0x0c, + 0x43, 0x02, 0x01, 0x80, 0x08, 0x01, 0x00, 0x01, + 0x04, 0x00, 0x01, 0x00, 0x50, 0x01, 0xf4, 0x06, + 0x00, 0x01, 0x00, 0xcc, 0x02, 0x01, 0x02, 0xd7, + 0x41, 0x8d, 0x01, 0x00, 0x00, 0x04, 0xc5, 0x01, + 0x00, 0x00, 0x24, 0x01, 0x00, 0xf0, 0x0b, 0xe3, + 0x41, 0x0f, 0x02, 0x00, 0x00, 0xd7, 0x25, 0x01, + 0x00, 0xe3, 0x41, 0x0f, 0x02, 0x00, 0x00, 0xd7, + 0x24, 0x01, 0x00, 0x41, 0xbe, 0x01, 0x00, 0x00, + 0xbb, 0xb9, 0x24, 0x02, 0x00, 0x41, 0x10, 0x02, + 0x00, 0x00, 0x04, 0x11, 0x02, 0x00, 0x00, 0x04, + 0xc6, 0x01, 0x00, 0x00, 0x24, 0x02, 0x00, 0xdb, + 0x04, 0xc5, 0x01, 0x00, 0x00, 0xd7, 0x71, 0x9c, + 0x04, 0xc5, 0x01, 0x00, 0x00, 0x9c, 0x28, 0x0c, + 0x43, 0x02, 0x01, 0x82, 0x08, 0x01, 0x00, 0x01, + 0x04, 0x00, 0x01, 0x00, 0x0d, 0x01, 0xf4, 0x06, + 0x00, 0x01, 0x00, 0xfa, 0x07, 0x08, 0x00, 0xe3, + 0x41, 0xb1, 0x01, 0x00, 0x00, 0xc6, 0xd7, 0x9c, + 0x24, 0x01, 0x00, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0x84, 0x08, 0x01, 0x00, 0x01, 0x04, 0x00, 0x01, + 0x00, 0x0c, 0x01, 0xf4, 0x06, 0x00, 0x01, 0x00, + 0xfa, 0x07, 0x08, 0x00, 0xe3, 0xe3, 0xef, 0xbb, + 0x9d, 0x72, 0x13, 0x46, 0xd7, 0x9c, 0x48, 0x29, + 0x0c, 0x43, 0x02, 0x01, 0x86, 0x08, 0x01, 0x00, + 0x01, 0x04, 0x00, 0x01, 0x00, 0x1f, 0x01, 0xa4, + 0x08, 0x00, 0x01, 0x00, 0xba, 0x02, 0x02, 0x02, + 0xe3, 0x40, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x3b, + 0x00, 0x00, 0x00, 0x41, 0x13, 0x02, 0x00, 0x00, + 0xd7, 0x24, 0x01, 0x00, 0x41, 0xbe, 0x01, 0x00, + 0x00, 0xc2, 0x08, 0xb9, 0x25, 0x02, 0x00, 0x0c, + 0x43, 0x02, 0x01, 0x88, 0x08, 0x02, 0x13, 0x02, + 0x07, 0x00, 0x1a, 0x02, 0x89, 0x0b, 0x15, 0x90, + 0x06, 0x00, 0x01, 0x00, 0xa6, 0x04, 0x00, 0x01, + 0x00, 0xbe, 0x06, 0x00, 0x00, 0x00, 0xa8, 0x08, + 0x00, 0x01, 0x00, 0x84, 0x06, 0x00, 0x02, 0x00, + 0xaa, 0x08, 0x00, 0x03, 0x00, 0x62, 0x00, 0x04, + 0x00, 0xac, 0x08, 0x00, 0x05, 0x00, 0xae, 0x08, + 0x00, 0x06, 0x00, 0xb0, 0x08, 0x00, 0x07, 0x00, + 0xb2, 0x08, 0x00, 0x08, 0x00, 0xb4, 0x08, 0x00, + 0x09, 0x00, 0xb6, 0x08, 0x00, 0x0a, 0x00, 0xb8, + 0x08, 0x00, 0x0b, 0x00, 0xba, 0x08, 0x00, 0x0c, + 0x00, 0xbc, 0x08, 0x00, 0x0d, 0x00, 0xbe, 0x08, + 0x00, 0x0e, 0x00, 0x9e, 0x06, 0x00, 0x0f, 0x00, + 0xb0, 0x06, 0x00, 0x10, 0x00, 0xc0, 0x08, 0x00, + 0x11, 0x00, 0xc2, 0x08, 0x00, 0x12, 0x00, 0x82, + 0x08, 0x0c, 0x00, 0xc4, 0x05, 0x03, 0x02, 0x8c, + 0x04, 0x04, 0x02, 0xc6, 0x05, 0x05, 0x02, 0xf6, + 0x07, 0x05, 0x00, 0x80, 0x08, 0x0b, 0x00, 0xc2, + 0x02, 0x06, 0x02, 0xf8, 0x07, 0x06, 0x00, 0x72, + 0x07, 0x00, 0xfa, 0x07, 0x08, 0x00, 0x86, 0x08, + 0x0e, 0x00, 0xce, 0x02, 0x07, 0x02, 0xcc, 0x02, + 0x01, 0x02, 0xd6, 0x02, 0x08, 0x02, 0xc4, 0x02, + 0x09, 0x02, 0xc0, 0x02, 0x0a, 0x02, 0xf6, 0x02, + 0x0b, 0x02, 0xbc, 0x02, 0x0c, 0x02, 0xe0, 0x02, + 0x0d, 0x02, 0xea, 0x07, 0x02, 0x01, 0x88, 0x08, + 0x0f, 0x00, 0xf2, 0x07, 0x03, 0x00, 0x88, 0x04, + 0x01, 0x01, 0xba, 0x02, 0x02, 0x02, 0x84, 0x08, + 0x0d, 0x00, 0xf4, 0x07, 0x04, 0x00, 0x07, 0x32, + 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, + 0x5f, 0x24, 0x5d, 0x5b, 0x30, 0x2d, 0x39, 0x61, + 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x5f, 0x24, 0x5d, + 0x2a, 0x07, 0x9a, 0x01, 0x00, 0x00, 0x01, 0x00, + 0x45, 0x00, 0x00, 0x00, 0x0e, 0x06, 0x00, 0x00, + 0x00, 0x06, 0x0d, 0xf5, 0xff, 0xff, 0xff, 0x13, + 0x00, 0x09, 0x24, 0x04, 0x00, 0x24, 0x00, 0x24, + 0x00, 0x41, 0x00, 0x5a, 0x00, 0x5f, 0x00, 0x5f, + 0x00, 0x61, 0x00, 0x7a, 0x00, 0x0f, 0x1c, 0x00, + 0x00, 0x00, 0x24, 0x05, 0x00, 0x24, 0x00, 0x24, + 0x00, 0x30, 0x00, 0x39, 0x00, 0x41, 0x00, 0x5a, + 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x61, 0x00, 0x7a, + 0x00, 0x0d, 0xdf, 0xff, 0xff, 0xff, 0x14, 0x00, + 0x10, 0xd7, 0x96, 0xc9, 0x06, 0x11, 0x04, 0x49, + 0x00, 0x00, 0x00, 0xad, 0xf1, 0x0a, 0x11, 0x04, + 0x4b, 0x00, 0x00, 0x00, 0xad, 0xf0, 0x06, 0xe3, + 0xd7, 0xf5, 0x0e, 0x29, 0x11, 0x04, 0x4a, 0x00, + 0x00, 0x00, 0xad, 0xf0, 0x11, 0xe3, 0xe4, 0xd7, + 0xe5, 0xf0, 0x05, 0xc2, 0x10, 0xf2, 0x03, 0xc2, + 0x0a, 0xf6, 0xf5, 0x0e, 0x29, 0x11, 0x04, 0x95, + 0x00, 0x00, 0x00, 0xad, 0xf0, 0x11, 0xe3, 0xe6, + 0xd7, 0xe5, 0xf0, 0x05, 0xc2, 0x10, 0xf2, 0x03, + 0xc2, 0x0a, 0xf6, 0xf5, 0x0e, 0x29, 0x11, 0x04, + 0x4c, 0x00, 0x00, 0x00, 0xad, 0xf0, 0x26, 0xd7, + 0xef, 0x5d, 0x04, 0x00, 0xa7, 0xf0, 0x15, 0xd7, + 0x41, 0x9e, 0x01, 0x00, 0x00, 0xba, 0x5d, 0x04, + 0x00, 0x24, 0x02, 0x00, 0x04, 0x22, 0x02, 0x00, + 0x00, 0x9c, 0xdb, 0xe3, 0x5d, 0x05, 0x00, 0xd7, + 0xf5, 0xf5, 0x0e, 0x29, 0x11, 0x04, 0x4e, 0x00, + 0x00, 0x00, 0xad, 0xf0, 0x0a, 0xe3, 0x5d, 0x06, + 0x00, 0xd7, 0xf5, 0xf5, 0x0e, 0x29, 0x11, 0x04, + 0x4d, 0x00, 0x00, 0x00, 0xad, 0xf1, 0x0d, 0x11, + 0x04, 0x1b, 0x00, 0x00, 0x00, 0xad, 0x68, 0xe2, + 0x04, 0x00, 0x00, 0xd7, 0xf9, 0xf0, 0x06, 0xe3, + 0xd7, 0xf5, 0x0e, 0x29, 0x5d, 0x07, 0x00, 0x41, + 0xc4, 0x01, 0x00, 0x00, 0xd7, 0x24, 0x01, 0x00, + 0xd3, 0xba, 0xa8, 0xf0, 0x13, 0xe3, 0x04, 0x23, + 0x02, 0x00, 0x00, 0xcb, 0x71, 0x9c, 0x04, 0xc8, + 0x01, 0x00, 0x00, 0x9c, 0xf5, 0x0e, 0x29, 0x5d, + 0x08, 0x00, 0x41, 0xc4, 0x01, 0x00, 0x00, 0xd7, + 0x24, 0x01, 0x00, 0xd3, 0xba, 0xa8, 0xf0, 0x27, + 0xe3, 0x04, 0x23, 0x02, 0x00, 0x00, 0x5d, 0x07, + 0x00, 0xef, 0x71, 0x9c, 0x04, 0xc8, 0x01, 0x00, + 0x00, 0x9c, 0xf5, 0x0e, 0x5d, 0x07, 0x00, 0x41, + 0xb1, 0x01, 0x00, 0x00, 0x5d, 0x08, 0x00, 0xcb, + 0x46, 0x24, 0x01, 0x00, 0x0e, 0x29, 0x5d, 0x09, + 0x00, 0xef, 0xc8, 0x0c, 0x5d, 0x0a, 0x00, 0xd7, + 0xf5, 0xc8, 0x0d, 0x5d, 0x08, 0x00, 0x41, 0xb1, + 0x01, 0x00, 0x00, 0xd7, 0x24, 0x01, 0x00, 0x0e, + 0xd7, 0x5d, 0x0b, 0x00, 0xa9, 0xf0, 0x22, 0xe3, + 0x04, 0x24, 0x02, 0x00, 0x00, 0x5d, 0x0c, 0x00, + 0x41, 0x0f, 0x02, 0x00, 0x00, 0xd7, 0x41, 0x25, + 0x02, 0x00, 0x00, 0x24, 0x00, 0x00, 0x24, 0x01, + 0x00, 0x71, 0x9c, 0xf5, 0x0e, 0xf3, 0x96, 0x01, + 0xd7, 0x5d, 0x0d, 0x00, 0xa9, 0xf0, 0x10, 0xe3, + 0xd7, 0x41, 0x3b, 0x00, 0x00, 0x00, 0x24, 0x00, + 0x00, 0xf5, 0x0e, 0xf3, 0x80, 0x01, 0xd7, 0x5d, + 0x0e, 0x00, 0xa9, 0x11, 0xf1, 0x10, 0x0e, 0xd7, + 0x5d, 0x0f, 0x00, 0xa9, 0x11, 0xf1, 0x07, 0x0e, + 0xd7, 0x5d, 0x10, 0x00, 0xa9, 0xf0, 0x1f, 0xe3, + 0x04, 0xec, 0x01, 0x00, 0x00, 0xc7, 0x0d, 0x71, + 0x9c, 0x04, 0x26, 0x02, 0x00, 0x00, 0x9c, 0xd7, + 0x71, 0x9c, 0x04, 0xc8, 0x01, 0x00, 0x00, 0x9c, + 0xf5, 0x0e, 0xf3, 0x49, 0x01, 0xd7, 0x5d, 0x06, + 0x00, 0xa9, 0xf0, 0x2a, 0xe3, 0x04, 0xec, 0x01, + 0x00, 0x00, 0xc7, 0x0d, 0x71, 0x9c, 0x04, 0x26, + 0x02, 0x00, 0x00, 0x9c, 0x5d, 0x05, 0x00, 0xd7, + 0xf5, 0x71, 0x9c, 0x04, 0xc8, 0x01, 0x00, 0x00, + 0x9c, 0xf5, 0x0e, 0xd7, 0xef, 0xc8, 0x0f, 0xbb, + 0xc8, 0x08, 0xf3, 0x19, 0x01, 0x5d, 0x11, 0x00, + 0x41, 0x27, 0x02, 0x00, 0x00, 0xd7, 0x24, 0x01, + 0x00, 0xf0, 0x0f, 0xe3, 0x04, 0xec, 0x01, 0x00, + 0x00, 0xf5, 0x0e, 0xbb, 0xc8, 0x07, 0xf3, 0xfd, + 0x00, 0xc7, 0x0d, 0x41, 0x8d, 0x01, 0x00, 0x00, + 0x04, 0x9e, 0x00, 0x00, 0x00, 0x24, 0x01, 0x00, + 0xf0, 0x2b, 0xd7, 0x5d, 0x12, 0x00, 0x40, 0x48, + 0x00, 0x00, 0x00, 0xa9, 0xf0, 0x1f, 0xe3, 0xc6, + 0xc7, 0x0d, 0x71, 0x9c, 0x04, 0xde, 0x01, 0x00, + 0x00, 0x9c, 0xd7, 0xef, 0x71, 0x9c, 0x04, 0x28, + 0x02, 0x00, 0x00, 0x9c, 0xf5, 0x0e, 0xbb, 0xc8, + 0x07, 0xf3, 0xc2, 0x00, 0xc7, 0x06, 0x04, 0x1b, + 0x00, 0x00, 0x00, 0xad, 0xf0, 0x2d, 0xd7, 0x40, + 0x3a, 0x00, 0x00, 0x00, 0xf0, 0x1a, 0xe3, 0x04, + 0x29, 0x02, 0x00, 0x00, 0xd7, 0x40, 0x3a, 0x00, + 0x00, 0x00, 0x71, 0x9c, 0x04, 0xc8, 0x01, 0x00, + 0x00, 0x9c, 0xf5, 0x0e, 0xf3, 0x97, 0x00, 0xe3, + 0x04, 0x2a, 0x02, 0x00, 0x00, 0xf5, 0x0e, 0xf3, + 0x8c, 0x00, 0xd7, 0x40, 0x40, 0x00, 0x00, 0x00, + 0x11, 0xf0, 0x0d, 0x0e, 0xd7, 0x40, 0x40, 0x00, + 0x00, 0x00, 0x40, 0x3a, 0x00, 0x00, 0x00, 0x11, + 0xf1, 0x07, 0x0e, 0x04, 0x9d, 0x00, 0x00, 0x00, + 0xc8, 0x0e, 0xc7, 0x0d, 0x04, 0x9d, 0x00, 0x00, + 0x00, 0xae, 0xf0, 0x1b, 0xe3, 0xc6, 0xc7, 0x0e, + 0x71, 0x9c, 0x04, 0x2b, 0x02, 0x00, 0x00, 0x9c, + 0xc7, 0x0d, 0x71, 0x9c, 0x04, 0x2c, 0x02, 0x00, + 0x00, 0x9c, 0xf5, 0x0e, 0xf2, 0x40, 0xd7, 0x40, + 0x48, 0x00, 0x00, 0x00, 0xf9, 0xf0, 0x15, 0xe3, + 0x04, 0xec, 0x01, 0x00, 0x00, 0xc7, 0x0e, 0x71, + 0x9c, 0x04, 0x2d, 0x02, 0x00, 0x00, 0x9c, 0xf5, + 0x0e, 0xf2, 0x23, 0xc7, 0x0e, 0x04, 0x9d, 0x00, + 0x00, 0x00, 0xae, 0xf0, 0x11, 0xe3, 0xc6, 0xc7, + 0x0e, 0x71, 0x9c, 0x04, 0x2e, 0x02, 0x00, 0x00, + 0x9c, 0xf5, 0x0e, 0xf2, 0x09, 0xe3, 0x04, 0x2f, + 0x02, 0x00, 0x00, 0xf5, 0x0e, 0x04, 0x30, 0x02, + 0x00, 0x00, 0xc8, 0x0a, 0x07, 0xc8, 0x04, 0xba, + 0xcf, 0xba, 0xd0, 0xba, 0xd2, 0xc7, 0x07, 0x68, + 0xc1, 0x00, 0x00, 0x00, 0x04, 0xc8, 0x01, 0x00, + 0x00, 0xc8, 0x0a, 0xd7, 0xef, 0xc8, 0x0f, 0xd8, + 0x5d, 0x13, 0x00, 0xa7, 0xf0, 0x12, 0xc7, 0x0f, + 0xf0, 0x0e, 0xe3, 0x04, 0x22, 0x02, 0x00, 0x00, + 0xf5, 0x0e, 0xe3, 0xc7, 0x0a, 0xf5, 0x29, 0xba, + 0xd1, 0xcd, 0xc7, 0x0f, 0xa5, 0x68, 0x7f, 0x00, + 0x00, 0x00, 0x92, 0x03, 0xcd, 0xd7, 0xaa, 0xf0, + 0x0e, 0x5d, 0x14, 0x00, 0xd7, 0xcd, 0x46, 0xd8, + 0xbb, 0x9c, 0xf6, 0x0e, 0xf2, 0x3e, 0xcd, 0xc8, + 0x10, 0xcd, 0xbb, 0x9c, 0xc7, 0x0f, 0xa5, 0xf0, + 0x0d, 0xcd, 0xbb, 0x9c, 0xd7, 0xaa, 0x95, 0xf0, + 0x05, 0x92, 0x02, 0xf2, 0xed, 0xcd, 0xc7, 0x10, + 0xa7, 0xf0, 0x19, 0xe3, 0x04, 0x31, 0x02, 0x00, + 0x00, 0xcd, 0xc7, 0x10, 0x9d, 0xbb, 0x9c, 0x71, + 0x9c, 0x04, 0x32, 0x02, 0x00, 0x00, 0x9c, 0xf5, + 0x0e, 0xf2, 0x09, 0xe3, 0x04, 0x33, 0x02, 0x00, + 0x00, 0xf5, 0x0e, 0xce, 0x5d, 0x15, 0x00, 0xa8, + 0xf0, 0x1f, 0xc7, 0x0f, 0xce, 0x9d, 0xbf, 0xa7, + 0xf0, 0x17, 0xe3, 0x04, 0x34, 0x02, 0x00, 0x00, + 0xc7, 0x0f, 0xce, 0x9d, 0x71, 0x9c, 0x04, 0x35, + 0x02, 0x00, 0x00, 0x9c, 0xf5, 0x0e, 0xf2, 0x06, + 0x92, 0x02, 0xf3, 0x7e, 0xff, 0xbb, 0xc8, 0x08, + 0xcd, 0xc7, 0x0f, 0xae, 0xf0, 0x0c, 0xc7, 0x0f, + 0xc3, 0xe8, 0x03, 0xa7, 0xf0, 0x04, 0xbb, 0xc8, + 0x09, 0xc7, 0x09, 0xf1, 0x24, 0x5d, 0x16, 0x00, + 0xf0, 0x0f, 0x5d, 0x17, 0x00, 0x41, 0xd3, 0x01, + 0x00, 0x00, 0xd7, 0x24, 0x01, 0x00, 0xf2, 0x0d, + 0x5d, 0x17, 0x00, 0x41, 0x31, 0x00, 0x00, 0x00, + 0xd7, 0x24, 0x01, 0x00, 0xc9, 0x04, 0xef, 0xcf, + 0xc7, 0x08, 0xf0, 0x1e, 0xcc, 0xcb, 0xa5, 0xf0, + 0x19, 0xc7, 0x04, 0xcc, 0x46, 0x8c, 0xd5, 0xcd, + 0xba, 0xa0, 0xae, 0x11, 0xf1, 0x06, 0x0e, 0xcd, + 0xc7, 0x0f, 0xa8, 0xf1, 0x05, 0x92, 0x01, 0xf2, + 0xe4, 0xcc, 0xcb, 0xa5, 0x68, 0x48, 0x01, 0x00, + 0x00, 0xc7, 0x0a, 0xf1, 0x12, 0x5d, 0x18, 0x00, + 0x04, 0x2e, 0x02, 0x00, 0x00, 0xf5, 0x0e, 0x04, + 0x30, 0x02, 0x00, 0x00, 0xc8, 0x0a, 0xd8, 0x5d, + 0x13, 0x00, 0xa7, 0xf0, 0x13, 0xcc, 0xcb, 0xa5, + 0xf0, 0x0e, 0xe3, 0x04, 0x22, 0x02, 0x00, 0x00, + 0xf5, 0x0e, 0xe3, 0xc7, 0x0a, 0xf5, 0x29, 0xcc, + 0xd1, 0xcd, 0xcb, 0xa5, 0x68, 0x10, 0x01, 0x00, + 0x00, 0xc7, 0x04, 0xcd, 0x46, 0xc8, 0x05, 0x5d, + 0x17, 0x00, 0x41, 0x6d, 0x00, 0x00, 0x00, 0xd7, + 0xc7, 0x05, 0x24, 0x02, 0x00, 0xc9, 0x11, 0x68, + 0xf0, 0x00, 0x00, 0x00, 0xc7, 0x11, 0x40, 0x43, + 0x00, 0x00, 0x00, 0xf1, 0x19, 0xe3, 0x04, 0xec, + 0x01, 0x00, 0x00, 0x5d, 0x06, 0x00, 0xc7, 0x05, + 0xf5, 0x71, 0x9c, 0x04, 0xc8, 0x01, 0x00, 0x00, + 0x9c, 0xf5, 0x0e, 0xf2, 0x2e, 0xc7, 0x05, 0x8c, + 0xc7, 0x05, 0xba, 0xa0, 0xad, 0x11, 0xf1, 0x11, + 0x0e, 0xc7, 0x05, 0x41, 0xca, 0x01, 0x00, 0x00, + 0xc4, 0x00, 0xc4, 0x01, 0x34, 0x24, 0x01, 0x00, + 0xf0, 0x08, 0xe3, 0xc7, 0x05, 0xf5, 0x0e, 0xf2, + 0x0a, 0xe3, 0x5d, 0x05, 0x00, 0xc7, 0x05, 0xf5, + 0xf5, 0x0e, 0xe3, 0x04, 0x36, 0x02, 0x00, 0x00, + 0xf5, 0x0e, 0x04, 0x44, 0x00, 0x00, 0x00, 0xc7, + 0x11, 0xaa, 0xf0, 0x12, 0x5d, 0x14, 0x00, 0xc7, + 0x11, 0x40, 0x44, 0x00, 0x00, 0x00, 0xd8, 0xbb, + 0x9c, 0xf6, 0x0e, 0xf2, 0x57, 0x26, 0x00, 0x00, + 0xc8, 0x12, 0xc7, 0x11, 0x40, 0x45, 0x00, 0x00, + 0x00, 0xf0, 0x11, 0xc7, 0x12, 0x41, 0xb1, 0x01, + 0x00, 0x00, 0x04, 0x37, 0x02, 0x00, 0x00, 0x24, + 0x01, 0x00, 0x0e, 0xc7, 0x11, 0x40, 0x46, 0x00, + 0x00, 0x00, 0xf0, 0x11, 0xc7, 0x12, 0x41, 0xb1, + 0x01, 0x00, 0x00, 0x04, 0x38, 0x02, 0x00, 0x00, + 0x24, 0x01, 0x00, 0x0e, 0xe3, 0x04, 0xec, 0x01, + 0x00, 0x00, 0xc7, 0x12, 0x41, 0x63, 0x00, 0x00, + 0x00, 0x04, 0xc9, 0x01, 0x00, 0x00, 0x24, 0x01, + 0x00, 0x71, 0x9c, 0x04, 0xc8, 0x01, 0x00, 0x00, + 0x9c, 0xf5, 0x0e, 0x92, 0x03, 0xce, 0x5d, 0x19, + 0x00, 0xa7, 0xf0, 0x1d, 0xcb, 0xce, 0x9d, 0xbf, + 0xa7, 0xf0, 0x16, 0xe3, 0x04, 0x34, 0x02, 0x00, + 0x00, 0xcb, 0xce, 0x9d, 0x71, 0x9c, 0x04, 0x39, + 0x02, 0x00, 0x00, 0x9c, 0xf5, 0x0e, 0xf2, 0x06, + 0x92, 0x02, 0xf3, 0xee, 0xfe, 0xc7, 0x0a, 0xf0, + 0x06, 0xe3, 0xc7, 0x0a, 0xf5, 0x0e, 0x5d, 0x08, + 0x00, 0x41, 0x3a, 0x02, 0x00, 0x00, 0xd7, 0x24, + 0x01, 0x00, 0x0e, 0x5d, 0x07, 0x00, 0x41, 0xc4, + 0x01, 0x00, 0x00, 0xd7, 0x24, 0x01, 0x00, 0xd5, + 0xba, 0xa7, 0xf0, 0x26, 0x5d, 0x09, 0x00, 0xc7, + 0x0c, 0x04, 0x3b, 0x02, 0x00, 0x00, 0xcd, 0x71, + 0x9c, 0x04, 0x3c, 0x02, 0x00, 0x00, 0x9c, 0x5d, + 0x09, 0x00, 0xc7, 0x0c, 0x46, 0x71, 0x9c, 0x48, + 0x29, 0xe3, 0x5d, 0x06, 0x00, 0xd7, 0xf5, 0xf5, + 0x0e, 0x29, 0x0c, 0x43, 0x02, 0x01, 0x8a, 0x08, + 0x02, 0x01, 0x02, 0x03, 0x00, 0x05, 0x00, 0x3d, + 0x03, 0xf4, 0x06, 0x00, 0x01, 0x00, 0xb6, 0x06, + 0x00, 0x01, 0x00, 0xfa, 0x08, 0x00, 0x00, 0x00, + 0xec, 0x07, 0x03, 0x01, 0xfe, 0x07, 0x0a, 0x00, + 0xfc, 0x07, 0x09, 0x00, 0xfc, 0x03, 0x0e, 0x02, + 0x80, 0x04, 0x0f, 0x02, 0xe3, 0xf0, 0x30, 0xe4, + 0xd8, 0xae, 0xf0, 0x13, 0xe5, 0x41, 0xb1, 0x01, + 0x00, 0x00, 0xe6, 0x40, 0x9d, 0x01, 0x00, 0x00, + 0x24, 0x01, 0x00, 0x0e, 0xd8, 0xe8, 0xd8, 0xf0, + 0x16, 0xe6, 0x5d, 0x04, 0x00, 0xd8, 0x46, 0x46, + 0xd3, 0xf0, 0x0c, 0xe5, 0x41, 0xb1, 0x01, 0x00, + 0x00, 0xcb, 0x24, 0x01, 0x00, 0x0e, 0xe5, 0x41, + 0xb1, 0x01, 0x00, 0x00, 0xd7, 0x24, 0x01, 0x00, + 0x29, 0x0c, 0x43, 0x02, 0x01, 0x8c, 0x08, 0x01, + 0x00, 0x01, 0x03, 0x00, 0x01, 0x02, 0x2c, 0x01, + 0xf4, 0x06, 0x00, 0x01, 0x00, 0x8a, 0x08, 0x10, + 0x00, 0x07, 0x02, 0x30, 0x07, 0x02, 0x39, 0xd7, + 0xba, 0x46, 0xc4, 0x00, 0xa8, 0xf0, 0x14, 0xd7, + 0xba, 0x46, 0xc4, 0x01, 0xa6, 0xf0, 0x0c, 0xe3, + 0xd7, 0x04, 0x4a, 0x00, 0x00, 0x00, 0xf6, 0x0e, + 0xf2, 0x0a, 0xe3, 0xd7, 0x04, 0x3e, 0x02, 0x00, + 0x00, 0xf6, 0x0e, 0xe3, 0x04, 0x26, 0x02, 0x00, + 0x00, 0xf5, 0x29, 0x0c, 0x43, 0x02, 0x01, 0x8e, + 0x08, 0x01, 0x04, 0x01, 0x05, 0x00, 0x03, 0x14, + 0xa0, 0x04, 0x05, 0xf4, 0x06, 0x00, 0x01, 0x00, + 0xb6, 0x06, 0x00, 0x00, 0x00, 0xfe, 0x08, 0x00, + 0x01, 0x00, 0x9e, 0x06, 0x00, 0x02, 0x00, 0xba, + 0x07, 0x00, 0x03, 0x00, 0xec, 0x07, 0x03, 0x01, + 0x8a, 0x08, 0x10, 0x00, 0x90, 0x08, 0x13, 0x00, + 0x07, 0x20, 0x5e, 0x22, 0x28, 0x5b, 0x5e, 0x5c, + 0x5c, 0x22, 0x5d, 0x7c, 0x5c, 0x5c, 0x2e, 0x29, + 0x2a, 0x22, 0x07, 0xa2, 0x01, 0x00, 0x00, 0x02, + 0x01, 0x49, 0x00, 0x00, 0x00, 0x0e, 0x06, 0x00, + 0x00, 0x00, 0x06, 0x0d, 0xf5, 0xff, 0xff, 0xff, + 0x13, 0x00, 0x09, 0x01, 0x22, 0x00, 0x0f, 0x2d, + 0x00, 0x00, 0x00, 0x2a, 0x00, 0x15, 0x01, 0x01, + 0x13, 0x01, 0x0f, 0x14, 0x00, 0x00, 0x00, 0x24, + 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x23, 0x00, + 0x5b, 0x00, 0x5d, 0x00, 0xff, 0xff, 0x0d, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x5c, 0x00, 0x05, 0x14, + 0x01, 0x2b, 0x00, 0x0d, 0xce, 0xff, 0xff, 0xff, + 0x01, 0x22, 0x00, 0x14, 0x00, 0x10, 0x07, 0x20, + 0x5e, 0x27, 0x28, 0x5b, 0x5e, 0x5c, 0x5c, 0x27, + 0x5d, 0x7c, 0x5c, 0x5c, 0x2e, 0x29, 0x2a, 0x27, + 0x07, 0xa2, 0x01, 0x00, 0x00, 0x02, 0x01, 0x49, + 0x00, 0x00, 0x00, 0x0e, 0x06, 0x00, 0x00, 0x00, + 0x06, 0x0d, 0xf5, 0xff, 0xff, 0xff, 0x13, 0x00, + 0x09, 0x01, 0x27, 0x00, 0x0f, 0x2d, 0x00, 0x00, + 0x00, 0x2a, 0x00, 0x15, 0x01, 0x01, 0x13, 0x01, + 0x0f, 0x14, 0x00, 0x00, 0x00, 0x24, 0x03, 0x00, + 0x00, 0x00, 0x26, 0x00, 0x28, 0x00, 0x5b, 0x00, + 0x5d, 0x00, 0xff, 0xff, 0x0d, 0x04, 0x00, 0x00, + 0x00, 0x01, 0x5c, 0x00, 0x05, 0x14, 0x01, 0x2b, + 0x00, 0x0d, 0xce, 0xff, 0xff, 0xff, 0x01, 0x27, + 0x00, 0x14, 0x00, 0x10, 0x07, 0x16, 0x5e, 0x5c, + 0x3c, 0x5b, 0x5e, 0x5c, 0x3e, 0x5d, 0x2b, 0x5c, + 0x3e, 0x07, 0x5e, 0x00, 0x00, 0x01, 0x00, 0x27, + 0x00, 0x00, 0x00, 0x0e, 0x06, 0x00, 0x00, 0x00, + 0x06, 0x0d, 0xf5, 0xff, 0xff, 0xff, 0x13, 0x00, + 0x09, 0x01, 0x3c, 0x00, 0x24, 0x02, 0x00, 0x00, + 0x00, 0x3d, 0x00, 0x3f, 0x00, 0xff, 0xff, 0x0e, + 0xf0, 0xff, 0xff, 0xff, 0x01, 0x3e, 0x00, 0x14, + 0x00, 0x10, 0x07, 0x16, 0x5e, 0x5c, 0x5b, 0x5b, + 0x5e, 0x5c, 0x5d, 0x5d, 0x2b, 0x5c, 0x5d, 0x07, + 0x5e, 0x00, 0x00, 0x01, 0x00, 0x27, 0x00, 0x00, + 0x00, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x06, 0x0d, + 0xf5, 0xff, 0xff, 0xff, 0x13, 0x00, 0x09, 0x01, + 0x5b, 0x00, 0x24, 0x02, 0x00, 0x00, 0x00, 0x5c, + 0x00, 0x5e, 0x00, 0xff, 0xff, 0x0e, 0xf0, 0xff, + 0xff, 0xff, 0x01, 0x5d, 0x00, 0x14, 0x00, 0x10, + 0x07, 0x02, 0x30, 0x07, 0x02, 0x31, 0x07, 0x02, + 0x32, 0x07, 0x02, 0x33, 0x07, 0x02, 0x34, 0x07, + 0x02, 0x35, 0x07, 0x02, 0x36, 0x07, 0x02, 0x37, + 0x07, 0x02, 0x38, 0x07, 0x02, 0x39, 0x07, 0x56, + 0x5e, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x7a, + 0x5f, 0x5d, 0x2b, 0x5b, 0x2e, 0x5d, 0x3f, 0x5b, + 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x7a, 0x5f, 0x5d, + 0x2a, 0x5b, 0x65, 0x45, 0x70, 0x50, 0x5d, 0x3f, + 0x5b, 0x2b, 0x2d, 0x5d, 0x3f, 0x5b, 0x30, 0x2d, + 0x39, 0x5d, 0x2a, 0x07, 0x96, 0x02, 0x00, 0x00, + 0x01, 0x00, 0x83, 0x00, 0x00, 0x00, 0x0e, 0x06, + 0x00, 0x00, 0x00, 0x06, 0x0d, 0xf5, 0xff, 0xff, + 0xff, 0x13, 0x00, 0x09, 0x24, 0x03, 0x00, 0x30, + 0x00, 0x39, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x61, + 0x00, 0x7a, 0x00, 0x0e, 0xec, 0xff, 0xff, 0xff, + 0x0f, 0x07, 0x00, 0x00, 0x00, 0x24, 0x01, 0x00, + 0x2e, 0x00, 0x2e, 0x00, 0x0f, 0x14, 0x00, 0x00, + 0x00, 0x24, 0x03, 0x00, 0x30, 0x00, 0x39, 0x00, + 0x5f, 0x00, 0x5f, 0x00, 0x61, 0x00, 0x7a, 0x00, + 0x0d, 0xe7, 0xff, 0xff, 0xff, 0x0f, 0x13, 0x00, + 0x00, 0x00, 0x24, 0x04, 0x00, 0x45, 0x00, 0x45, + 0x00, 0x50, 0x00, 0x50, 0x00, 0x65, 0x00, 0x65, + 0x00, 0x70, 0x00, 0x70, 0x00, 0x0f, 0x0b, 0x00, + 0x00, 0x00, 0x24, 0x02, 0x00, 0x2b, 0x00, 0x2b, + 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x0f, 0x0c, 0x00, + 0x00, 0x00, 0x24, 0x01, 0x00, 0x30, 0x00, 0x39, + 0x00, 0x0d, 0xef, 0xff, 0xff, 0xff, 0x14, 0x00, + 0x10, 0xe3, 0xf1, 0x05, 0xe4, 0xd7, 0xf5, 0x29, + 0xd7, 0xef, 0xba, 0xa7, 0x68, 0x13, 0x02, 0x00, + 0x00, 0x04, 0x9d, 0x01, 0x00, 0x00, 0xcf, 0xd7, + 0xd0, 0xba, 0xd1, 0x07, 0xd2, 0xd7, 0xba, 0x46, + 0x11, 0x04, 0xc6, 0x01, 0x00, 0x00, 0xad, 0xf0, + 0x19, 0x04, 0x4c, 0x00, 0x00, 0x00, 0xcf, 0xd7, + 0x41, 0xca, 0x01, 0x00, 0x00, 0xc4, 0x00, 0xc4, + 0x01, 0x34, 0x24, 0x01, 0x00, 0xd2, 0xf3, 0xb3, + 0x01, 0x11, 0x04, 0xc5, 0x01, 0x00, 0x00, 0xad, + 0xf0, 0x19, 0x04, 0x4c, 0x00, 0x00, 0x00, 0xcf, + 0xd7, 0x41, 0xca, 0x01, 0x00, 0x00, 0xc4, 0x02, + 0xc4, 0x03, 0x34, 0x24, 0x01, 0x00, 0xd2, 0xf3, + 0x92, 0x01, 0x11, 0x04, 0xc9, 0x01, 0x00, 0x00, + 0xad, 0xf0, 0x0a, 0x04, 0x40, 0x02, 0x00, 0x00, + 0xcf, 0xf3, 0x80, 0x01, 0x11, 0x04, 0x31, 0x02, + 0x00, 0x00, 0xad, 0xf0, 0x1e, 0xd7, 0x41, 0xca, + 0x01, 0x00, 0x00, 0xc4, 0x04, 0xc4, 0x05, 0x34, + 0x24, 0x01, 0x00, 0xd6, 0x68, 0x65, 0x01, 0x00, + 0x00, 0x04, 0x41, 0x02, 0x00, 0x00, 0xcf, 0xf3, + 0x5a, 0x01, 0x11, 0x04, 0xec, 0x01, 0x00, 0x00, + 0xad, 0xf0, 0x1b, 0xd7, 0x41, 0xca, 0x01, 0x00, + 0x00, 0xc4, 0x06, 0xc4, 0x07, 0x34, 0x24, 0x01, + 0x00, 0xd6, 0xf0, 0x2e, 0x04, 0x41, 0x02, 0x00, + 0x00, 0xcf, 0xf3, 0x37, 0x01, 0x11, 0x04, 0xc8, + 0x01, 0x00, 0x00, 0xad, 0xf1, 0x1c, 0x11, 0x04, + 0x30, 0x02, 0x00, 0x00, 0xad, 0xf1, 0x13, 0x11, + 0x04, 0x42, 0x02, 0x00, 0x00, 0xad, 0xf1, 0x0a, + 0x11, 0x04, 0xe7, 0x01, 0x00, 0x00, 0xad, 0xf0, + 0x0c, 0x04, 0x43, 0x02, 0x00, 0x00, 0xcf, 0xbb, + 0xd1, 0xf3, 0x08, 0x01, 0x11, 0x04, 0xbd, 0x01, + 0x00, 0x00, 0xad, 0xf0, 0x0a, 0x04, 0x41, 0x02, + 0x00, 0x00, 0xcf, 0xf3, 0xf6, 0x00, 0x11, 0xc4, + 0x08, 0xad, 0xf1, 0x37, 0x11, 0xc4, 0x09, 0xad, + 0xf1, 0x31, 0x11, 0xc4, 0x0a, 0xad, 0xf1, 0x2b, + 0x11, 0xc4, 0x0b, 0xad, 0xf1, 0x25, 0x11, 0xc4, + 0x0c, 0xad, 0xf1, 0x1f, 0x11, 0xc4, 0x0d, 0xad, + 0xf1, 0x19, 0x11, 0xc4, 0x0e, 0xad, 0xf1, 0x13, + 0x11, 0xc4, 0x0f, 0xad, 0xf1, 0x0d, 0x11, 0xc4, + 0x10, 0xad, 0xf1, 0x07, 0x11, 0xc4, 0x11, 0xad, + 0xf0, 0x19, 0x04, 0x4a, 0x00, 0x00, 0x00, 0xcf, + 0xd7, 0x41, 0xca, 0x01, 0x00, 0x00, 0xc4, 0x12, + 0xc4, 0x13, 0x34, 0x24, 0x01, 0x00, 0xd2, 0xf3, + 0xa2, 0x00, 0x11, 0x04, 0xf2, 0x01, 0x00, 0x00, + 0xad, 0xf0, 0x06, 0xbb, 0xd1, 0xf3, 0x94, 0x00, + 0xe5, 0xd7, 0xf5, 0xf0, 0x06, 0xd7, 0xef, 0xbb, + 0x9d, 0xd1, 0xd7, 0x41, 0xd2, 0x01, 0x00, 0x00, + 0x04, 0xa7, 0x00, 0x00, 0x00, 0x24, 0x01, 0x00, + 0xf0, 0x09, 0x04, 0x44, 0x02, 0x00, 0x00, 0xcf, + 0xf2, 0x71, 0xd7, 0x41, 0xd2, 0x01, 0x00, 0x00, + 0x04, 0xa3, 0x00, 0x00, 0x00, 0x24, 0x01, 0x00, + 0xf0, 0x09, 0x04, 0x4e, 0x00, 0x00, 0x00, 0xcf, + 0xf2, 0x59, 0xd7, 0x04, 0xfb, 0x00, 0x00, 0x00, + 0xad, 0x11, 0xf1, 0x09, 0x0e, 0xd7, 0x04, 0x45, + 0x02, 0x00, 0x00, 0xad, 0xf0, 0x09, 0x04, 0x46, + 0x02, 0x00, 0x00, 0xcf, 0xf2, 0x3d, 0xd7, 0x04, + 0x03, 0x00, 0x00, 0x00, 0xad, 0x11, 0xf1, 0x09, + 0x0e, 0xd7, 0x04, 0x02, 0x00, 0x00, 0x00, 0xad, + 0xf0, 0x09, 0x04, 0x4b, 0x00, 0x00, 0x00, 0xcf, + 0xf2, 0x21, 0xd7, 0x04, 0x01, 0x00, 0x00, 0x00, + 0xad, 0xf0, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00, + 0xcf, 0xf2, 0x10, 0xd7, 0x04, 0x49, 0x00, 0x00, + 0x00, 0xad, 0xf0, 0x07, 0x04, 0x49, 0x00, 0x00, + 0x00, 0xcf, 0x0e, 0xce, 0xf0, 0x06, 0xce, 0xba, + 0x46, 0xef, 0xd1, 0xcd, 0xba, 0xa7, 0xf0, 0x0d, + 0xd7, 0x41, 0xbe, 0x01, 0x00, 0x00, 0xba, 0xcd, + 0x24, 0x02, 0x00, 0xd0, 0xe4, 0xcc, 0xcb, 0xf6, + 0x0e, 0xd7, 0x41, 0xbe, 0x01, 0x00, 0x00, 0xcc, + 0xef, 0x24, 0x01, 0x00, 0xdb, 0xf3, 0xea, 0xfd, + 0x29, 0x0c, 0x43, 0x02, 0x01, 0x90, 0x08, 0x01, + 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x19, 0x02, + 0xf4, 0x06, 0x00, 0x01, 0x00, 0x8a, 0x06, 0x00, + 0x00, 0x00, 0xd7, 0xd7, 0xef, 0xbb, 0x9d, 0x46, + 0xd3, 0x04, 0xec, 0x01, 0x00, 0x00, 0xad, 0x11, + 0xf1, 0x09, 0x0e, 0xcb, 0x04, 0x2f, 0x02, 0x00, + 0x00, 0xad, 0x28, 0x0c, 0x43, 0x02, 0x01, 0x92, + 0x08, 0x01, 0x04, 0x01, 0x06, 0x00, 0x03, 0x00, + 0x6e, 0x05, 0x84, 0x06, 0x00, 0x01, 0x00, 0x8e, + 0x09, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x01, + 0x00, 0x92, 0x09, 0x00, 0x02, 0x00, 0xf4, 0x06, + 0x00, 0x03, 0x00, 0xfa, 0x07, 0x08, 0x00, 0x90, + 0x08, 0x13, 0x00, 0x92, 0x08, 0x14, 0x00, 0xe3, + 0xd7, 0x46, 0xef, 0xcf, 0xe3, 0xd7, 0xbb, 0x9c, + 0x46, 0x04, 0x36, 0x02, 0x00, 0x00, 0xad, 0xf0, + 0x0e, 0xd7, 0xbc, 0x9c, 0xdb, 0xcb, 0xbc, 0xe3, + 0xd7, 0x46, 0xef, 0x9c, 0x9c, 0xcf, 0xcb, 0xd0, + 0xe4, 0xe3, 0xd7, 0x46, 0xf5, 0xf0, 0x41, 0xbb, + 0xd1, 0xd7, 0x8e, 0xdf, 0xe3, 0xef, 0xa5, 0xf0, + 0x37, 0xcd, 0x93, 0x01, 0xe3, 0xd7, 0x46, 0xd6, + 0x04, 0xc8, 0x01, 0x00, 0x00, 0xad, 0x11, 0xf1, + 0x09, 0x0e, 0xce, 0x04, 0x30, 0x02, 0x00, 0x00, + 0xad, 0xf1, 0x1d, 0xf2, 0x0e, 0x11, 0x7e, 0x81, + 0x00, 0x0e, 0xdb, 0x81, 0x00, 0x0e, 0xcf, 0x83, + 0xf2, 0x06, 0xe5, 0xd7, 0xf5, 0xf2, 0xef, 0x0e, + 0xcb, 0x93, 0x01, 0xbc, 0xd1, 0xf2, 0xc3, 0xd7, + 0xcc, 0x26, 0x02, 0x00, 0x28, 0x0c, 0x43, 0x02, + 0x01, 0x94, 0x08, 0x02, 0x02, 0x02, 0x03, 0x00, + 0x05, 0x00, 0x67, 0x04, 0x84, 0x06, 0x00, 0x01, + 0x00, 0x94, 0x09, 0x00, 0x01, 0x00, 0xb8, 0x08, + 0x00, 0x00, 0x00, 0xf4, 0x06, 0x00, 0x01, 0x00, + 0xfa, 0x07, 0x08, 0x00, 0x8a, 0x08, 0x10, 0x00, + 0x8c, 0x08, 0x11, 0x00, 0x8e, 0x08, 0x12, 0x00, + 0x90, 0x08, 0x13, 0x00, 0xc6, 0xcf, 0xd7, 0xd8, + 0xa6, 0xf0, 0x60, 0xe3, 0xd7, 0x90, 0xdb, 0x46, + 0xd4, 0x04, 0xc8, 0x01, 0x00, 0x00, 0xad, 0x11, + 0xf1, 0x09, 0x0e, 0xcc, 0x04, 0x30, 0x02, 0x00, + 0x00, 0xad, 0xf0, 0x11, 0xcb, 0xef, 0xbb, 0xa7, + 0xf0, 0x27, 0xe4, 0x04, 0xe7, 0x01, 0x00, 0x00, + 0xf5, 0x0e, 0xf2, 0x1d, 0xe4, 0xcb, 0xf5, 0x0e, + 0xe3, 0xd7, 0x46, 0x04, 0x36, 0x02, 0x00, 0x00, + 0xad, 0xf0, 0x0e, 0xe5, 0xcc, 0xf5, 0x0e, 0xd7, + 0x8e, 0xdb, 0xe3, 0xd7, 0x90, 0xdb, 0x46, 0xd0, + 0xe6, 0xcc, 0xf5, 0x0e, 0x5d, 0x04, 0x00, 0xcc, + 0xf5, 0xf0, 0x08, 0x04, 0xe7, 0x01, 0x00, 0x00, + 0xf2, 0x06, 0x04, 0x4b, 0x02, 0x00, 0x00, 0xcf, + 0xf2, 0x9d, 0x29, 0x0c, 0x43, 0x02, 0x01, 0x96, + 0x08, 0x02, 0x00, 0x02, 0x04, 0x00, 0x01, 0x00, + 0x1a, 0x02, 0xf4, 0x06, 0x00, 0x01, 0x00, 0xc8, + 0x07, 0x00, 0x01, 0x00, 0x8a, 0x08, 0x10, 0x00, + 0xd8, 0xba, 0xa7, 0xf0, 0x12, 0xd7, 0x04, 0xe7, + 0x01, 0x00, 0x00, 0x41, 0x4c, 0x02, 0x00, 0x00, + 0xd8, 0x24, 0x01, 0x00, 0x9c, 0xdb, 0xe3, 0xd7, + 0xf5, 0x29, 0x0c, 0x43, 0x02, 0x01, 0x98, 0x08, + 0x02, 0x0c, 0x02, 0x07, 0x00, 0x0b, 0x00, 0xd2, + 0x04, 0x0e, 0x9a, 0x09, 0x00, 0x01, 0x00, 0x84, + 0x02, 0x00, 0x01, 0x00, 0x9c, 0x09, 0x00, 0x00, + 0x00, 0x94, 0x09, 0x00, 0x01, 0x00, 0x90, 0x09, + 0x00, 0x02, 0x00, 0xb8, 0x08, 0x00, 0x03, 0x00, + 0x9e, 0x09, 0x00, 0x04, 0x00, 0x84, 0x06, 0x00, + 0x05, 0x00, 0x8e, 0x09, 0x00, 0x06, 0x00, 0xaa, + 0x08, 0x00, 0x07, 0x00, 0xb2, 0x07, 0x00, 0x08, + 0x00, 0xa0, 0x09, 0x00, 0x09, 0x00, 0xf2, 0x05, + 0x00, 0x0a, 0x00, 0xa2, 0x09, 0x00, 0x0b, 0x00, + 0xf0, 0x07, 0x02, 0x00, 0x92, 0x08, 0x14, 0x00, + 0x94, 0x08, 0x15, 0x00, 0xfa, 0x07, 0x08, 0x00, + 0x8c, 0x08, 0x11, 0x00, 0x8e, 0x08, 0x12, 0x00, + 0x90, 0x08, 0x13, 0x00, 0xca, 0x02, 0x10, 0x02, + 0x8a, 0x08, 0x10, 0x00, 0x96, 0x08, 0x16, 0x00, + 0x98, 0x08, 0x17, 0x00, 0xe3, 0xd7, 0x9d, 0xbc, + 0x9d, 0xcf, 0x06, 0x11, 0xf8, 0xf1, 0x0d, 0x7e, + 0x81, 0x00, 0x0e, 0xd0, 0x81, 0x00, 0x0e, 0xd1, + 0x83, 0xf2, 0x07, 0x0e, 0xe4, 0xd8, 0xf5, 0xf2, + 0xef, 0xcd, 0xcb, 0xa6, 0xf0, 0x0c, 0xe5, 0xd8, + 0xcc, 0xf6, 0x0e, 0xcc, 0xcd, 0x26, 0x02, 0x00, + 0x28, 0xe6, 0xd8, 0xbb, 0x9c, 0x46, 0x04, 0x36, + 0x02, 0x00, 0x00, 0xad, 0xf0, 0x0d, 0x5d, 0x04, + 0x00, 0xe6, 0xd8, 0x46, 0xf5, 0x0e, 0xd8, 0xbc, + 0x9c, 0xdc, 0x5d, 0x05, 0x00, 0xe6, 0xd8, 0x46, + 0xf5, 0x0e, 0x5d, 0x06, 0x00, 0xe6, 0xd8, 0x46, + 0xf5, 0xf1, 0x07, 0xd8, 0xcd, 0x26, 0x02, 0x00, + 0x28, 0xd7, 0xbc, 0x9c, 0xdb, 0xcb, 0xbc, 0x9d, + 0xcf, 0xc6, 0xd2, 0xd8, 0xbb, 0x9c, 0xc8, 0x04, + 0xe6, 0xd8, 0x46, 0x41, 0x52, 0x02, 0x00, 0x00, + 0x04, 0xec, 0x01, 0x00, 0x00, 0x24, 0x01, 0x00, + 0x68, 0x79, 0x01, 0x00, 0x00, 0xba, 0xc8, 0x07, + 0x26, 0x00, 0x00, 0xc8, 0x0a, 0xc7, 0x04, 0xc8, + 0x05, 0xc7, 0x05, 0xcc, 0xa5, 0xf0, 0x45, 0xe6, + 0xc7, 0x05, 0x46, 0xba, 0x46, 0x04, 0xbd, 0x01, + 0x00, 0x00, 0xad, 0x11, 0xf1, 0x0e, 0x0e, 0xe6, + 0xc7, 0x05, 0xbb, 0x9c, 0x46, 0x04, 0x36, 0x02, + 0x00, 0x00, 0xad, 0xf1, 0x27, 0xf2, 0x10, 0x11, + 0x7e, 0x81, 0x00, 0x0e, 0xc8, 0x05, 0x81, 0x00, + 0x0e, 0xc8, 0x06, 0x83, 0xf2, 0x07, 0xe4, 0xc7, + 0x05, 0xf5, 0xf2, 0xec, 0x0e, 0xc7, 0x0a, 0xc7, + 0x07, 0x90, 0xc8, 0x07, 0xc7, 0x06, 0x48, 0x92, + 0x05, 0xf2, 0xb7, 0x5d, 0x07, 0x00, 0x41, 0xa4, + 0x01, 0x00, 0x00, 0xcb, 0xbd, 0x9a, 0xc7, 0x0a, + 0xef, 0xc2, 0x10, 0x24, 0x03, 0x00, 0xc8, 0x09, + 0xc7, 0x09, 0xbb, 0xa7, 0xf0, 0x67, 0x26, 0x00, + 0x00, 0xc8, 0x0b, 0xba, 0xc8, 0x08, 0xba, 0xc8, + 0x07, 0xc7, 0x07, 0xc7, 0x0a, 0xef, 0xa5, 0xf0, + 0x2f, 0xc7, 0x0b, 0xc7, 0x08, 0x5d, 0x07, 0x00, + 0x41, 0xe0, 0x01, 0x00, 0x00, 0xc7, 0x0b, 0xc7, + 0x08, 0x46, 0x11, 0xf1, 0x03, 0x0e, 0xba, 0xc7, + 0x0a, 0xc7, 0x07, 0x46, 0xbc, 0x9c, 0x24, 0x02, + 0x00, 0x48, 0xc7, 0x08, 0xbb, 0x9c, 0xc7, 0x09, + 0x9b, 0xc8, 0x08, 0x92, 0x07, 0xf2, 0xcb, 0xba, + 0xc8, 0x06, 0xba, 0xc8, 0x08, 0xc7, 0x08, 0xc7, + 0x09, 0xa5, 0xf0, 0x0f, 0xc7, 0x06, 0xc7, 0x0b, + 0xc7, 0x08, 0x46, 0x9c, 0xc8, 0x06, 0x92, 0x08, + 0xf2, 0xec, 0xc7, 0x06, 0xcb, 0xa6, 0xf1, 0x05, + 0x91, 0x09, 0xf2, 0x95, 0xc7, 0x09, 0xbb, 0xa7, + 0x68, 0x99, 0x00, 0x00, 0x00, 0xba, 0xc8, 0x06, + 0xc7, 0x09, 0xbb, 0x9d, 0xc8, 0x08, 0xc7, 0x04, + 0xc8, 0x05, 0xc7, 0x05, 0xcc, 0xa5, 0x68, 0x7f, + 0x00, 0x00, 0x00, 0xe6, 0xc7, 0x05, 0x46, 0xba, + 0x46, 0x04, 0xbd, 0x01, 0x00, 0x00, 0xad, 0x11, + 0xf1, 0x0e, 0x0e, 0xe6, 0xc7, 0x05, 0xbb, 0x9c, + 0x46, 0x04, 0x36, 0x02, 0x00, 0x00, 0xad, 0xf1, + 0x5e, 0xc7, 0x06, 0xce, 0xef, 0x9c, 0xc8, 0x06, + 0x5d, 0x08, 0x00, 0xce, 0xf5, 0x0e, 0x04, 0x42, + 0x02, 0x00, 0x00, 0xd2, 0xc7, 0x08, 0xc7, 0x09, + 0xbb, 0x9d, 0xad, 0xf0, 0x11, 0x5d, 0x09, 0x00, + 0x04, 0xa3, 0x01, 0x00, 0x00, 0xd7, 0xf6, 0x0e, + 0xba, 0xc8, 0x08, 0xf2, 0x23, 0x5d, 0x09, 0x00, + 0xc6, 0xc7, 0x0b, 0xc7, 0x08, 0x90, 0xc8, 0x08, + 0x46, 0xc7, 0x06, 0x9d, 0xf6, 0x0e, 0xf2, 0x10, + 0x11, 0x7e, 0x81, 0x00, 0x0e, 0xc8, 0x05, 0x81, + 0x00, 0x0e, 0xc8, 0x06, 0x83, 0xf2, 0x0a, 0x5d, + 0x0a, 0x00, 0xd7, 0xc7, 0x05, 0xf6, 0xf2, 0xe9, + 0x0e, 0x92, 0x05, 0xf3, 0x7e, 0xff, 0xc7, 0x05, + 0xc8, 0x04, 0xc7, 0x04, 0xc8, 0x05, 0xc7, 0x05, + 0xcc, 0xa5, 0xf0, 0x37, 0x5d, 0x08, 0x00, 0xce, + 0xf5, 0x0e, 0x04, 0x42, 0x02, 0x00, 0x00, 0xd2, + 0x5d, 0x09, 0x00, 0x04, 0xa3, 0x01, 0x00, 0x00, + 0xd7, 0xf6, 0x0e, 0xf2, 0x10, 0x11, 0x7e, 0x81, + 0x00, 0x0e, 0xc8, 0x05, 0x81, 0x00, 0x0e, 0xc8, + 0x06, 0x83, 0xf2, 0x0a, 0x5d, 0x0a, 0x00, 0xd7, + 0xc7, 0x05, 0xf6, 0xf2, 0xe9, 0x0e, 0x92, 0x05, + 0xf2, 0xc5, 0x5d, 0x09, 0x00, 0x04, 0xa3, 0x01, + 0x00, 0x00, 0xd7, 0xbc, 0x9d, 0xdf, 0xf6, 0x0e, + 0x5d, 0x05, 0x00, 0xe6, 0xcc, 0x46, 0xf5, 0x0e, + 0xcc, 0xe3, 0x26, 0x02, 0x00, 0x28, 0xc5, 0x00, + 0xd0, 0xc5, 0x01, 0xc8, 0x0b, 0xc5, 0x02, 0xc8, + 0x0c, 0xc5, 0x03, 0xc8, 0x0d, 0xc5, 0x04, 0xc8, + 0x0e, 0xc5, 0x05, 0xc8, 0x0f, 0xc5, 0x06, 0xc8, + 0x10, 0xc5, 0x07, 0xc8, 0x11, 0xc5, 0x08, 0xc8, + 0x12, 0xc5, 0x09, 0xc8, 0x13, 0xc5, 0x0a, 0xc8, + 0x14, 0xc5, 0x0b, 0xc8, 0x15, 0xc5, 0x0c, 0xc8, + 0x16, 0xc5, 0x0d, 0xc8, 0x17, 0x0b, 0xcf, 0xd8, + 0x96, 0x04, 0x4d, 0x00, 0x00, 0x00, 0xad, 0xf0, + 0x1c, 0xd8, 0x07, 0xae, 0xf0, 0x17, 0xd8, 0xd3, + 0x40, 0x53, 0x02, 0x00, 0x00, 0xdc, 0xcb, 0x40, + 0x54, 0x02, 0x00, 0x00, 0xdd, 0xcb, 0x40, 0xfe, + 0x00, 0x00, 0x00, 0xde, 0xd8, 0x96, 0x04, 0x4b, + 0x00, 0x00, 0x00, 0xae, 0xf0, 0x03, 0x09, 0xdc, + 0xcc, 0xd9, 0xbc, 0xf6, 0xdd, 0xcc, 0xda, 0x0a, + 0xf6, 0xde, 0xcc, 0xcb, 0x40, 0xf8, 0x01, 0x00, + 0x00, 0x5d, 0x10, 0x00, 0x41, 0xa4, 0x01, 0x00, + 0x00, 0x5d, 0x11, 0x00, 0xc2, 0x50, 0x24, 0x02, + 0x00, 0xf6, 0xd1, 0xcc, 0xcb, 0x40, 0xf9, 0x01, + 0x00, 0x00, 0xc2, 0x64, 0xf6, 0xd2, 0xcc, 0xcb, + 0x40, 0xfa, 0x01, 0x00, 0x00, 0xce, 0xc2, 0x0a, + 0x9c, 0xf6, 0xc8, 0x04, 0xcc, 0xcb, 0x40, 0xfb, + 0x01, 0x00, 0x00, 0xc2, 0x4e, 0xf6, 0xc8, 0x05, + 0x0b, 0x26, 0x01, 0x00, 0xc8, 0x06, 0x26, 0x00, + 0x00, 0xc8, 0x07, 0x26, 0x00, 0x00, 0xc8, 0x08, + 0x26, 0x00, 0x00, 0xc8, 0x09, 0x04, 0x9d, 0x01, + 0x00, 0x00, 0xc8, 0x0a, 0xc7, 0x0f, 0xd7, 0xba, + 0xf6, 0x0e, 0xc7, 0x17, 0xba, 0xba, 0xf6, 0x0e, + 0xc7, 0x10, 0xc6, 0xf5, 0x0e, 0xc7, 0x09, 0x41, + 0x63, 0x00, 0x00, 0x00, 0xc6, 0x25, 0x01, 0x00, + 0x0c, 0x43, 0x02, 0x01, 0xca, 0x05, 0x01, 0x00, + 0x01, 0x07, 0x00, 0x05, 0x00, 0x3c, 0x01, 0xe8, + 0x07, 0x00, 0x01, 0x00, 0xea, 0x03, 0x00, 0x1a, + 0xc8, 0x05, 0x78, 0x00, 0x8a, 0x04, 0x19, 0x00, + 0x86, 0x04, 0x17, 0x00, 0x88, 0x04, 0x18, 0x00, + 0x64, 0x00, 0x00, 0x41, 0x9c, 0x01, 0x00, 0x00, + 0xe4, 0x41, 0x55, 0x02, 0x00, 0x00, 0xd7, 0x0b, + 0xe5, 0x4b, 0x54, 0x02, 0x00, 0x00, 0xe6, 0x4b, + 0xfe, 0x00, 0x00, 0x00, 0x5d, 0x04, 0x00, 0x4b, + 0x53, 0x02, 0x00, 0x00, 0x24, 0x02, 0x00, 0x24, + 0x01, 0x00, 0x0e, 0x64, 0x00, 0x00, 0x41, 0x9c, + 0x01, 0x00, 0x00, 0x04, 0xa3, 0x01, 0x00, 0x00, + 0x24, 0x01, 0x00, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0xcc, 0x05, 0x01, 0x05, 0x01, 0x04, 0x00, 0x03, + 0x00, 0xaf, 0x01, 0x06, 0x90, 0x06, 0x00, 0x01, + 0x00, 0xdc, 0x06, 0x00, 0x00, 0x00, 0xa8, 0x04, + 0x00, 0x01, 0x00, 0xac, 0x09, 0x00, 0x02, 0x00, + 0xde, 0x07, 0x00, 0x03, 0x00, 0xae, 0x09, 0x00, + 0x04, 0x00, 0xce, 0x05, 0x7b, 0x00, 0xd6, 0x05, + 0x7f, 0x00, 0xea, 0x03, 0x00, 0x1a, 0xd7, 0x04, + 0x58, 0x02, 0x00, 0x00, 0xad, 0xf0, 0x06, 0xe3, + 0xf4, 0x0e, 0x0a, 0x28, 0xd7, 0xba, 0x46, 0x04, + 0xc2, 0x01, 0x00, 0x00, 0xae, 0xf0, 0x0e, 0xd7, + 0xba, 0x46, 0x04, 0xbd, 0x01, 0x00, 0x00, 0xae, + 0xf0, 0x03, 0x09, 0x28, 0xbb, 0xcf, 0xcb, 0xd7, + 0xef, 0xa5, 0xf0, 0x10, 0xd7, 0xcb, 0x46, 0x04, + 0xe7, 0x01, 0x00, 0x00, 0xae, 0xf0, 0x05, 0x92, + 0x00, 0xf2, 0xec, 0xd7, 0x41, 0x9e, 0x01, 0x00, + 0x00, 0xbb, 0xcb, 0x24, 0x02, 0x00, 0xd0, 0xba, + 0xd1, 0xe4, 0x7d, 0xf2, 0x21, 0xc8, 0x04, 0xc7, + 0x04, 0x41, 0xd2, 0x01, 0x00, 0x00, 0xcc, 0x24, + 0x01, 0x00, 0xf0, 0x12, 0xe4, 0xc7, 0x04, 0x46, + 0xd2, 0x92, 0x02, 0xc7, 0x04, 0xcc, 0xad, 0xf0, + 0x05, 0xba, 0xd1, 0xf2, 0x05, 0x80, 0xf0, 0xde, + 0x0e, 0x0e, 0xce, 0xf0, 0x1d, 0xcd, 0xbc, 0xa5, + 0xf0, 0x18, 0xce, 0xd7, 0x41, 0x9e, 0x01, 0x00, + 0x00, 0xcb, 0x24, 0x01, 0x00, 0x41, 0x59, 0x02, + 0x00, 0x00, 0x24, 0x00, 0x00, 0xf5, 0x0e, 0xf2, + 0x1b, 0x64, 0x02, 0x00, 0x41, 0x9c, 0x01, 0x00, + 0x00, 0x04, 0x5a, 0x02, 0x00, 0x00, 0xcc, 0x71, + 0x9c, 0x04, 0xa3, 0x01, 0x00, 0x00, 0x9c, 0x24, + 0x01, 0x00, 0x0e, 0x0a, 0x28, 0x0c, 0x43, 0x02, + 0x01, 0xce, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, + 0x09, 0x01, 0xd7, 0x01, 0x01, 0xb6, 0x09, 0x00, + 0x00, 0x00, 0xea, 0x03, 0x00, 0x1a, 0x8c, 0x04, + 0x1a, 0x00, 0x84, 0x04, 0x16, 0x00, 0x8e, 0x04, + 0x1b, 0x00, 0x8a, 0x04, 0x19, 0x00, 0x88, 0x04, + 0x18, 0x00, 0x86, 0x04, 0x17, 0x00, 0x80, 0x04, + 0x14, 0x00, 0xfe, 0x03, 0x13, 0x00, 0x0c, 0x42, + 0x02, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x0f, 0x01, 0xbe, 0x06, 0x00, 0x01, + 0x00, 0xd7, 0xf0, 0x07, 0x04, 0x86, 0x00, 0x00, + 0x00, 0x28, 0x04, 0xe7, 0x01, 0x00, 0x00, 0x28, + 0xc5, 0x00, 0x4c, 0x5b, 0x02, 0x00, 0x00, 0xcf, + 0x64, 0x00, 0x00, 0x41, 0x9c, 0x01, 0x00, 0x00, + 0x04, 0x5c, 0x02, 0x00, 0x00, 0x04, 0x5d, 0x02, + 0x00, 0x00, 0x9c, 0xcb, 0xe4, 0xf5, 0x9c, 0x04, + 0x5e, 0x02, 0x00, 0x00, 0x9c, 0x04, 0x5f, 0x02, + 0x00, 0x00, 0x9c, 0xcb, 0xe4, 0x95, 0xf5, 0x9c, + 0x04, 0x60, 0x02, 0x00, 0x00, 0x9c, 0x04, 0x61, + 0x02, 0x00, 0x00, 0x9c, 0xcb, 0xe5, 0xf5, 0x9c, + 0x04, 0x62, 0x02, 0x00, 0x00, 0x9c, 0x04, 0x63, + 0x02, 0x00, 0x00, 0x9c, 0xcb, 0xe6, 0xf5, 0x9c, + 0x04, 0x64, 0x02, 0x00, 0x00, 0x9c, 0x04, 0x65, + 0x02, 0x00, 0x00, 0x5d, 0x04, 0x00, 0x71, 0x9c, + 0x04, 0x66, 0x02, 0x00, 0x00, 0x9c, 0x9c, 0x04, + 0x67, 0x02, 0x00, 0x00, 0x9c, 0xcb, 0x5d, 0x05, + 0x00, 0xf5, 0x9c, 0x04, 0x68, 0x02, 0x00, 0x00, + 0x9c, 0x04, 0x69, 0x02, 0x00, 0x00, 0x9c, 0xcb, + 0x5d, 0x06, 0x00, 0xf5, 0x9c, 0x04, 0x6a, 0x02, + 0x00, 0x00, 0x9c, 0x04, 0x6b, 0x02, 0x00, 0x00, + 0x9c, 0xcb, 0x5d, 0x07, 0x00, 0x5d, 0x08, 0x00, + 0x40, 0x6c, 0x02, 0x00, 0x00, 0xab, 0xf5, 0x9c, + 0x04, 0x6d, 0x02, 0x00, 0x00, 0x9c, 0x04, 0x6e, + 0x02, 0x00, 0x00, 0x9c, 0xcb, 0x5d, 0x07, 0x00, + 0x5d, 0x08, 0x00, 0x40, 0x6f, 0x02, 0x00, 0x00, + 0xab, 0xf5, 0x9c, 0x04, 0x70, 0x02, 0x00, 0x00, + 0x9c, 0x04, 0x71, 0x02, 0x00, 0x00, 0x9c, 0x04, + 0x72, 0x02, 0x00, 0x00, 0x9c, 0x04, 0x73, 0x02, + 0x00, 0x00, 0x9c, 0x24, 0x01, 0x00, 0x29, 0x0c, + 0x43, 0x02, 0x01, 0xd0, 0x05, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x01, 0x00, 0x5a, 0x02, 0xf4, 0x06, + 0x00, 0x01, 0x00, 0xe8, 0x09, 0x04, 0x00, 0x03, + 0xea, 0x03, 0x00, 0x1a, 0xd7, 0x41, 0x75, 0x02, + 0x00, 0x00, 0x04, 0xbd, 0x01, 0x00, 0x00, 0x24, + 0x01, 0x00, 0xd7, 0x41, 0x75, 0x02, 0x00, 0x00, + 0x04, 0xc9, 0x01, 0x00, 0x00, 0x24, 0x01, 0x00, + 0xa6, 0xf0, 0x09, 0xd7, 0x04, 0x76, 0x02, 0x00, + 0x00, 0x9c, 0xdb, 0x6b, 0x13, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x41, 0x77, 0x02, 0x00, 0x00, + 0xd7, 0x24, 0x01, 0x00, 0x0e, 0x0e, 0x29, 0xcf, + 0x6b, 0x1c, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, + 0x41, 0x9c, 0x01, 0x00, 0x00, 0xc6, 0xcb, 0x71, + 0x9c, 0x04, 0xa3, 0x01, 0x00, 0x00, 0x9c, 0x24, + 0x01, 0x00, 0x0e, 0x0e, 0x29, 0x30, 0x0c, 0x43, + 0x02, 0x01, 0xd2, 0x05, 0x01, 0x00, 0x01, 0x03, + 0x00, 0x02, 0x00, 0x10, 0x01, 0xe8, 0x09, 0x00, + 0x01, 0x00, 0xec, 0x05, 0x8a, 0x01, 0x00, 0xea, + 0x03, 0x00, 0x1a, 0xe3, 0xf4, 0x0e, 0x64, 0x01, + 0x00, 0x41, 0x69, 0x01, 0x00, 0x00, 0xd7, 0x24, + 0x01, 0x00, 0x29, 0x0c, 0x43, 0x02, 0x01, 0xd4, + 0x05, 0x02, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, + 0x14, 0x02, 0xf4, 0x06, 0x00, 0x01, 0x00, 0x9c, + 0x08, 0x00, 0x01, 0x00, 0xd7, 0xf0, 0x10, 0x04, + 0x78, 0x02, 0x00, 0x00, 0x41, 0x8d, 0x01, 0x00, + 0x00, 0xd7, 0x24, 0x01, 0x00, 0x28, 0xd8, 0x28, + 0x0c, 0x42, 0x02, 0x01, 0x00, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x02, 0x00, 0x06, 0x01, 0xf4, 0x06, + 0x00, 0x01, 0x00, 0xd4, 0x05, 0x7e, 0x00, 0x8c, + 0x04, 0x1a, 0x00, 0xe3, 0xd7, 0x0a, 0xf6, 0xe8, + 0x29, 0x0c, 0x42, 0x02, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x03, 0x00, 0x02, 0x00, 0x07, 0x01, 0xf4, + 0x06, 0x00, 0x01, 0x00, 0xd4, 0x05, 0x7e, 0x00, + 0x8c, 0x04, 0x1a, 0x00, 0xe3, 0xd7, 0x0a, 0xf6, + 0x95, 0xe8, 0x29, 0x0c, 0x42, 0x02, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x03, 0x00, 0x02, 0x00, 0x07, + 0x01, 0xf4, 0x06, 0x00, 0x01, 0x00, 0xd4, 0x05, + 0x7e, 0x00, 0x84, 0x04, 0x16, 0x00, 0xe3, 0xd7, + 0xe4, 0x95, 0xf6, 0xe8, 0x29, 0x0c, 0x42, 0x02, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x03, 0x00, 0x02, + 0x00, 0x07, 0x01, 0xf4, 0x06, 0x00, 0x01, 0x00, + 0xd4, 0x05, 0x7e, 0x00, 0x8e, 0x04, 0x1b, 0x00, + 0xe3, 0xd7, 0xe4, 0x95, 0xf6, 0xe8, 0x29, 0x0c, + 0x42, 0x02, 0x01, 0x00, 0x01, 0x00, 0x01, 0x02, + 0x00, 0x01, 0x00, 0x09, 0x01, 0xf4, 0x06, 0x00, + 0x01, 0x00, 0x8a, 0x04, 0x19, 0x00, 0xd7, 0x8c, + 0x11, 0xf1, 0x03, 0x0e, 0xbc, 0xe7, 0x29, 0x0c, + 0x42, 0x02, 0x01, 0x00, 0x01, 0x00, 0x01, 0x03, + 0x00, 0x02, 0x00, 0x07, 0x01, 0xf4, 0x06, 0x00, + 0x01, 0x00, 0xd4, 0x05, 0x7e, 0x00, 0x88, 0x04, + 0x18, 0x00, 0xe3, 0xd7, 0xe4, 0x95, 0xf6, 0xe8, + 0x29, 0x0c, 0x42, 0x02, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x03, 0x00, 0x02, 0x00, 0x07, 0x01, 0xf4, + 0x06, 0x00, 0x01, 0x00, 0xd4, 0x05, 0x7e, 0x00, + 0x86, 0x04, 0x17, 0x00, 0xe3, 0xd7, 0xe4, 0x95, + 0xf6, 0xe8, 0x29, 0x0c, 0x42, 0x02, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x08, + 0x00, 0xfe, 0x03, 0x13, 0x00, 0x80, 0x04, 0x14, + 0x00, 0xe3, 0x40, 0x6c, 0x02, 0x00, 0x00, 0xe8, + 0x29, 0x0c, 0x42, 0x02, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x02, 0x00, 0x08, 0x00, 0xfe, + 0x03, 0x13, 0x00, 0x80, 0x04, 0x14, 0x00, 0xe3, + 0x40, 0x6f, 0x02, 0x00, 0x00, 0xe8, 0x29, 0x0c, + 0x42, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x01, 0x00, 0x11, 0x00, 0xea, 0x03, 0x00, + 0x1a, 0x64, 0x00, 0x00, 0x41, 0x9c, 0x01, 0x00, + 0x00, 0x04, 0x79, 0x02, 0x00, 0x00, 0x24, 0x01, + 0x00, 0x29, 0x0c, 0x42, 0x02, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, + 0xd2, 0x05, 0x7d, 0x00, 0xe3, 0xba, 0xf5, 0x29, + 0x0c, 0x43, 0x02, 0x01, 0xd8, 0x05, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x02, 0x00, 0x14, 0x00, 0xea, + 0x03, 0x00, 0x1a, 0xda, 0x05, 0x81, 0x01, 0x00, + 0x64, 0x00, 0x00, 0x41, 0x9c, 0x01, 0x00, 0x00, + 0x04, 0x7a, 0x02, 0x00, 0x00, 0x24, 0x01, 0x00, + 0x0e, 0xe4, 0xf4, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0xda, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, + 0x00, 0x0c, 0x00, 0xbe, 0x05, 0x73, 0x00, 0xb4, + 0x05, 0x6e, 0x00, 0xa6, 0x04, 0x27, 0x00, 0xdc, + 0x05, 0x82, 0x01, 0x00, 0xe3, 0xe4, 0x04, 0x7b, + 0x02, 0x00, 0x00, 0xe5, 0xf6, 0xe6, 0xf6, 0x29, + 0x0c, 0x43, 0x02, 0x01, 0xdc, 0x05, 0x01, 0x00, + 0x01, 0x02, 0x00, 0x02, 0x00, 0x09, 0x01, 0xf8, + 0x09, 0x00, 0x01, 0x00, 0xde, 0x05, 0x83, 0x01, + 0x00, 0xda, 0x05, 0x81, 0x01, 0x00, 0xe3, 0xd7, + 0xf5, 0xf1, 0x04, 0xe4, 0xf4, 0x0e, 0x29, 0x0c, + 0x43, 0x02, 0x01, 0xde, 0x05, 0x01, 0x01, 0x01, + 0x02, 0x00, 0x06, 0x00, 0x39, 0x02, 0xf8, 0x09, + 0x00, 0x01, 0x00, 0xd0, 0x06, 0x00, 0x00, 0x00, + 0xa4, 0x04, 0x26, 0x00, 0xcc, 0x05, 0x7a, 0x00, + 0xe8, 0x05, 0x88, 0x01, 0x00, 0x96, 0x04, 0x1f, + 0x00, 0xa6, 0x04, 0x27, 0x00, 0xe0, 0x05, 0x84, + 0x01, 0x00, 0xd7, 0xf1, 0x03, 0x09, 0x28, 0xe3, + 0xf0, 0x0d, 0xe3, 0x04, 0xa3, 0x01, 0x00, 0x00, + 0x9c, 0xd7, 0x9c, 0xdb, 0xf2, 0x08, 0xe4, 0xd7, + 0xf5, 0xf0, 0x03, 0x09, 0x28, 0xe5, 0xd7, 0xf5, + 0xd3, 0xba, 0x46, 0xea, 0xcb, 0xbb, 0x46, 0x5e, + 0x04, 0x00, 0xe6, 0xf0, 0x05, 0xd7, 0xe7, 0x09, + 0x28, 0xc6, 0xe7, 0x5d, 0x05, 0x00, 0xd7, 0xf5, + 0x0e, 0x0a, 0x28, 0x0c, 0x43, 0x02, 0x01, 0xe0, + 0x05, 0x01, 0x01, 0x01, 0x06, 0x00, 0x06, 0x00, + 0x4a, 0x02, 0xf8, 0x09, 0x00, 0x01, 0x00, 0xfa, + 0x09, 0x00, 0x00, 0x00, 0x8e, 0x04, 0x1b, 0x00, + 0xec, 0x03, 0x01, 0x1a, 0xa0, 0x04, 0x24, 0x00, + 0xea, 0x03, 0x00, 0x1a, 0xe2, 0x05, 0x85, 0x01, + 0x00, 0xe4, 0x05, 0x86, 0x01, 0x00, 0xe3, 0xf0, + 0x09, 0x04, 0x7e, 0x02, 0x00, 0x00, 0xd7, 0x9c, + 0xdb, 0x64, 0x01, 0x00, 0x41, 0x7f, 0x02, 0x00, + 0x00, 0x24, 0x00, 0x00, 0xe9, 0x38, 0xcd, 0x00, + 0x00, 0x00, 0x41, 0x18, 0x00, 0x00, 0x00, 0x64, + 0x03, 0x00, 0x40, 0x80, 0x02, 0x00, 0x00, 0xd7, + 0x0b, 0x0a, 0x4b, 0x81, 0x02, 0x00, 0x00, 0x0a, + 0x4b, 0x8e, 0x00, 0x00, 0x00, 0x24, 0x03, 0x00, + 0xd3, 0x41, 0x88, 0x00, 0x00, 0x00, 0x5d, 0x04, + 0x00, 0x5d, 0x05, 0x00, 0x24, 0x02, 0x00, 0x29, + 0x0c, 0x43, 0x02, 0x01, 0xe2, 0x05, 0x01, 0x00, + 0x01, 0x02, 0x00, 0x06, 0x00, 0x27, 0x01, 0xfa, + 0x09, 0x00, 0x01, 0x00, 0xec, 0x03, 0x01, 0x1a, + 0xa0, 0x04, 0x24, 0x00, 0xa2, 0x04, 0x25, 0x00, + 0xca, 0x05, 0x79, 0x00, 0xf0, 0x03, 0x00, 0x01, + 0xe6, 0x05, 0x87, 0x01, 0x00, 0xd7, 0x40, 0x44, + 0x00, 0x00, 0x00, 0xdb, 0x64, 0x00, 0x00, 0x41, + 0x7f, 0x02, 0x00, 0x00, 0x24, 0x00, 0x00, 0xe4, + 0x9d, 0xe9, 0xe6, 0xd7, 0xf5, 0x0e, 0x5d, 0x04, + 0x00, 0xd7, 0x42, 0x8a, 0x01, 0x00, 0x00, 0x5d, + 0x05, 0x00, 0xf4, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0xe4, 0x05, 0x01, 0x00, 0x01, 0x04, 0x00, 0x06, + 0x00, 0xa1, 0x01, 0x01, 0x6e, 0x00, 0x01, 0x00, + 0x86, 0x04, 0x17, 0x00, 0xea, 0x03, 0x00, 0x1a, + 0xfc, 0x03, 0x12, 0x00, 0x80, 0x04, 0x14, 0x00, + 0xbe, 0x02, 0x09, 0x00, 0xe6, 0x05, 0x87, 0x01, + 0x00, 0xe3, 0xf0, 0x15, 0x64, 0x01, 0x00, 0x41, + 0x9c, 0x01, 0x00, 0x00, 0xe5, 0xe6, 0x40, 0x37, + 0x00, 0x00, 0x00, 0x46, 0x24, 0x01, 0x00, 0x0e, + 0xd7, 0x5d, 0x04, 0x00, 0xa9, 0xf0, 0x3b, 0x64, + 0x01, 0x00, 0x41, 0x9c, 0x01, 0x00, 0x00, 0xd7, + 0x24, 0x01, 0x00, 0x0e, 0x64, 0x01, 0x00, 0x41, + 0x9c, 0x01, 0x00, 0x00, 0x04, 0xa3, 0x01, 0x00, + 0x00, 0x24, 0x01, 0x00, 0x0e, 0xd7, 0x40, 0x39, + 0x00, 0x00, 0x00, 0xf0, 0x44, 0x64, 0x01, 0x00, + 0x41, 0x9c, 0x01, 0x00, 0x00, 0xd7, 0x40, 0x39, + 0x00, 0x00, 0x00, 0x24, 0x01, 0x00, 0x0e, 0xf2, + 0x30, 0x64, 0x01, 0x00, 0x41, 0x9c, 0x01, 0x00, + 0x00, 0x04, 0x82, 0x02, 0x00, 0x00, 0x24, 0x01, + 0x00, 0x0e, 0x64, 0x01, 0x00, 0x41, 0x9c, 0x01, + 0x00, 0x00, 0xd7, 0x24, 0x01, 0x00, 0x0e, 0x64, + 0x01, 0x00, 0x41, 0x9c, 0x01, 0x00, 0x00, 0x04, + 0xa3, 0x01, 0x00, 0x00, 0x24, 0x01, 0x00, 0x0e, + 0xe3, 0xf0, 0x13, 0x64, 0x01, 0x00, 0x41, 0x9c, + 0x01, 0x00, 0x00, 0xe5, 0x40, 0x9d, 0x01, 0x00, + 0x00, 0x24, 0x01, 0x00, 0x0e, 0x5d, 0x05, 0x00, + 0xf4, 0x29, 0x0c, 0x43, 0x02, 0x01, 0xe6, 0x05, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x11, + 0x00, 0xa6, 0x04, 0x27, 0x00, 0xea, 0x03, 0x00, + 0x1a, 0xda, 0x05, 0x81, 0x01, 0x00, 0xba, 0xe7, + 0x64, 0x01, 0x00, 0x41, 0x83, 0x02, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x0e, 0xe5, 0xf4, 0x29, 0x0c, + 0x43, 0x02, 0x01, 0xe8, 0x05, 0x01, 0x17, 0x01, + 0x04, 0x0f, 0x03, 0x0a, 0x84, 0x04, 0x18, 0x9c, + 0x06, 0x00, 0x01, 0x40, 0x06, 0x84, 0x06, 0x00, + 0x00, 0x40, 0x04, 0x8a, 0x06, 0x00, 0x01, 0x40, + 0x08, 0xb0, 0x06, 0x00, 0x02, 0x40, 0x0a, 0xbe, + 0x06, 0x00, 0x03, 0x40, 0x05, 0xb6, 0x06, 0x00, + 0x04, 0x40, 0x02, 0x88, 0x0a, 0x00, 0x05, 0x40, + 0x00, 0xa6, 0x04, 0x00, 0x06, 0x00, 0x8a, 0x0a, + 0x00, 0x07, 0x00, 0x8c, 0x0a, 0x00, 0x08, 0x40, + 0x09, 0x98, 0x07, 0x00, 0x09, 0x40, 0x0e, 0x8e, + 0x0a, 0x00, 0x0a, 0x40, 0x03, 0x90, 0x0a, 0x00, + 0x0b, 0x40, 0x01, 0x92, 0x0a, 0x00, 0x0c, 0x40, + 0x07, 0x94, 0x0a, 0x00, 0x0d, 0x00, 0x96, 0x0a, + 0x00, 0x0e, 0x00, 0x98, 0x0a, 0x00, 0x0f, 0x00, + 0x9a, 0x0a, 0x00, 0x10, 0x00, 0x9c, 0x0a, 0x00, + 0x11, 0x00, 0x9e, 0x0a, 0x00, 0x12, 0x40, 0x0b, + 0xa0, 0x0a, 0x00, 0x13, 0x40, 0x0c, 0xa2, 0x0a, + 0x00, 0x14, 0x40, 0x0d, 0xa4, 0x0a, 0x00, 0x15, + 0x00, 0xa6, 0x0a, 0x00, 0x16, 0x00, 0xce, 0x04, + 0x3b, 0x00, 0xd6, 0x04, 0x3f, 0x00, 0xcc, 0x04, + 0x3a, 0x00, 0x0c, 0x43, 0x02, 0x01, 0x8e, 0x0a, + 0x01, 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x05, + 0x01, 0x8a, 0x06, 0x00, 0x01, 0x00, 0x88, 0x0a, + 0x05, 0x00, 0xe3, 0xd7, 0x9c, 0xe7, 0x29, 0x0c, + 0x43, 0x02, 0x01, 0x90, 0x0a, 0x01, 0x00, 0x01, + 0x04, 0x00, 0x01, 0x00, 0x0d, 0x01, 0x8a, 0x06, + 0x00, 0x01, 0x00, 0x88, 0x0a, 0x05, 0x00, 0xe3, + 0x41, 0x9e, 0x01, 0x00, 0x00, 0xe3, 0xef, 0xbb, + 0x9d, 0x25, 0x01, 0x00, 0x0c, 0x43, 0x02, 0x01, + 0x92, 0x0a, 0x01, 0x00, 0x01, 0x05, 0x00, 0x02, + 0x00, 0x14, 0x01, 0x8a, 0x06, 0x00, 0x01, 0x00, + 0x90, 0x0a, 0x0b, 0x00, 0x88, 0x0a, 0x05, 0x00, + 0xe3, 0xf4, 0xdb, 0xe4, 0x41, 0x9e, 0x01, 0x00, + 0x00, 0xba, 0xe4, 0xef, 0xbb, 0x9d, 0x24, 0x02, + 0x00, 0xe8, 0xd7, 0x28, 0x0c, 0x43, 0x02, 0x01, + 0x94, 0x0a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, + 0x00, 0x49, 0x00, 0xb6, 0x06, 0x04, 0x00, 0x8e, + 0x0a, 0x0a, 0x00, 0x84, 0x06, 0x00, 0x00, 0xbe, + 0x06, 0x03, 0x00, 0x9c, 0x06, 0x00, 0x01, 0x92, + 0x0a, 0x0c, 0x00, 0x04, 0x94, 0x02, 0x00, 0x00, + 0xe7, 0xe4, 0x04, 0xc9, 0x01, 0x00, 0x00, 0xf5, + 0x0e, 0xe5, 0x8e, 0xe9, 0xe5, 0xe6, 0xbb, 0x9d, + 0xa5, 0xf0, 0x31, 0x5d, 0x04, 0x00, 0xe5, 0x46, + 0x04, 0x86, 0x00, 0x00, 0x00, 0xab, 0xf0, 0x1f, + 0x5d, 0x04, 0x00, 0xe5, 0xbb, 0x9c, 0x46, 0x04, + 0xc9, 0x01, 0x00, 0x00, 0xab, 0xf0, 0x10, 0xe5, + 0xbc, 0x9c, 0xe9, 0x5d, 0x05, 0x00, 0x04, 0xc9, + 0x01, 0x00, 0x00, 0xf5, 0x0e, 0x29, 0xe5, 0x8e, + 0xe9, 0xf2, 0xca, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0x96, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, + 0x00, 0x1f, 0x00, 0xb6, 0x06, 0x04, 0x00, 0x84, + 0x06, 0x00, 0x00, 0xbe, 0x06, 0x03, 0x00, 0x9c, + 0x06, 0x00, 0x01, 0x04, 0x94, 0x02, 0x00, 0x00, + 0xe7, 0xe4, 0x8e, 0xe8, 0xe4, 0xe5, 0xa5, 0xf0, + 0x11, 0xe6, 0xe4, 0x46, 0x04, 0xa3, 0x01, 0x00, + 0x00, 0xab, 0xf1, 0x06, 0xe4, 0x8e, 0xe8, 0xf2, + 0xec, 0x29, 0x0c, 0x43, 0x02, 0x01, 0x98, 0x0a, + 0x01, 0x00, 0x01, 0x03, 0x00, 0x07, 0x00, 0x4c, + 0x01, 0xaa, 0x0a, 0x00, 0x01, 0x00, 0xb6, 0x06, + 0x04, 0x00, 0x8e, 0x0a, 0x0a, 0x00, 0x84, 0x06, + 0x00, 0x00, 0xbe, 0x06, 0x03, 0x00, 0x9c, 0x06, + 0x00, 0x01, 0x8a, 0x06, 0x01, 0x00, 0x92, 0x0a, + 0x0c, 0x00, 0x04, 0x4c, 0x00, 0x00, 0x00, 0xe7, + 0xe4, 0xd7, 0xf5, 0x0e, 0xe5, 0xe6, 0xa5, 0xf0, + 0x3d, 0x5d, 0x04, 0x00, 0xe5, 0x90, 0xe9, 0x46, + 0x5f, 0x05, 0x00, 0x04, 0xa3, 0x01, 0x00, 0x00, + 0xab, 0xf0, 0x09, 0x04, 0x37, 0x00, 0x00, 0x00, + 0xe7, 0xf2, 0xe2, 0x5d, 0x05, 0x00, 0x04, 0xc2, + 0x01, 0x00, 0x00, 0xab, 0xf0, 0x0b, 0xe5, 0xe6, + 0xa8, 0xf1, 0x13, 0xe5, 0x8e, 0xe9, 0xf2, 0xcd, + 0x5d, 0x05, 0x00, 0xd7, 0xab, 0xf0, 0xc6, 0x5d, + 0x06, 0x00, 0xf4, 0x0e, 0x29, 0x29, 0x0c, 0x43, + 0x02, 0x01, 0x9a, 0x0a, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x09, 0x00, 0xc4, 0x01, 0x00, 0xb6, 0x06, + 0x04, 0x00, 0x8e, 0x0a, 0x0a, 0x00, 0x84, 0x06, + 0x00, 0x00, 0xbe, 0x06, 0x03, 0x00, 0x9c, 0x06, + 0x00, 0x01, 0x8a, 0x06, 0x01, 0x00, 0x90, 0x0a, + 0x0b, 0x00, 0x92, 0x0a, 0x0c, 0x00, 0xce, 0x04, + 0x00, 0x02, 0x04, 0x40, 0x02, 0x00, 0x00, 0xe7, + 0xe4, 0x04, 0xc9, 0x01, 0x00, 0x00, 0xf5, 0x0e, + 0xe5, 0xe6, 0xa5, 0x68, 0xb1, 0x00, 0x00, 0x00, + 0x5d, 0x04, 0x00, 0xe5, 0x90, 0xe9, 0x46, 0x5f, + 0x05, 0x00, 0x04, 0xa3, 0x01, 0x00, 0x00, 0xab, + 0xf0, 0x09, 0x04, 0x37, 0x00, 0x00, 0x00, 0xe7, + 0xf2, 0xdf, 0x5d, 0x05, 0x00, 0x04, 0xc2, 0x01, + 0x00, 0x00, 0xab, 0xf0, 0x0b, 0xe5, 0xe6, 0xa5, + 0xf0, 0xcf, 0xe5, 0x8e, 0xe9, 0xf2, 0xca, 0x5d, + 0x06, 0x00, 0xf4, 0x04, 0xec, 0x01, 0x00, 0x00, + 0xab, 0xf0, 0x13, 0x5d, 0x05, 0x00, 0x04, 0xc8, + 0x01, 0x00, 0x00, 0xab, 0xf0, 0xb3, 0x5d, 0x07, + 0x00, 0xf4, 0x0e, 0xf2, 0xac, 0x5d, 0x05, 0x00, + 0x04, 0xec, 0x01, 0x00, 0x00, 0xab, 0xf0, 0x2e, + 0xe4, 0x04, 0xec, 0x01, 0x00, 0x00, 0xf5, 0x0e, + 0x5d, 0x04, 0x00, 0xe5, 0x46, 0x04, 0xec, 0x01, + 0x00, 0x00, 0xab, 0x11, 0xf1, 0x0d, 0x0e, 0x5d, + 0x04, 0x00, 0xe5, 0x46, 0x04, 0xc8, 0x01, 0x00, + 0x00, 0xab, 0x68, 0x7d, 0xff, 0xff, 0xff, 0xe5, + 0x8e, 0xe9, 0xf3, 0x75, 0xff, 0x5d, 0x05, 0x00, + 0x04, 0xc9, 0x01, 0x00, 0x00, 0xab, 0x68, 0x69, + 0xff, 0xff, 0xff, 0x5d, 0x07, 0x00, 0xf4, 0x0e, + 0xe5, 0xe6, 0xa5, 0xf0, 0x11, 0x5d, 0x08, 0x00, + 0x5d, 0x04, 0x00, 0xe5, 0x46, 0xf5, 0xf0, 0x06, + 0xe5, 0x8e, 0xe9, 0xf2, 0xec, 0x29, 0x0c, 0x43, + 0x02, 0x01, 0x9c, 0x0a, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x05, 0x00, 0x41, 0x00, 0xb6, 0x06, 0x04, + 0x00, 0x84, 0x06, 0x00, 0x00, 0xbe, 0x06, 0x03, + 0x00, 0xce, 0x04, 0x00, 0x02, 0x9c, 0x06, 0x00, + 0x01, 0x04, 0x4a, 0x00, 0x00, 0x00, 0xe7, 0xe4, + 0xe5, 0xa5, 0xf0, 0x36, 0xe6, 0x5d, 0x04, 0x00, + 0xe4, 0x46, 0xf5, 0x11, 0xf1, 0x25, 0x0e, 0x5d, + 0x04, 0x00, 0xe4, 0x46, 0x04, 0xbd, 0x01, 0x00, + 0x00, 0xab, 0xf0, 0x1e, 0xe4, 0xe5, 0xbb, 0x9d, + 0xab, 0x11, 0xf1, 0x0f, 0x0e, 0x5d, 0x04, 0x00, + 0xe4, 0xbb, 0x9c, 0x46, 0x04, 0xbd, 0x01, 0x00, + 0x00, 0xac, 0xf0, 0x06, 0xe4, 0x8e, 0xe8, 0xf2, + 0xc7, 0x29, 0x0c, 0x43, 0x02, 0x01, 0xa4, 0x0a, + 0x00, 0x03, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x95, + 0x02, 0x03, 0xf4, 0x06, 0x00, 0x00, 0x00, 0x8e, + 0x09, 0x00, 0x01, 0x00, 0xac, 0x0a, 0x00, 0x02, + 0x00, 0x8c, 0x0a, 0x08, 0x00, 0x84, 0x06, 0x00, + 0x00, 0xbe, 0x06, 0x03, 0x00, 0xce, 0x04, 0x00, + 0x02, 0x9c, 0x06, 0x00, 0x01, 0xb0, 0x06, 0x02, + 0x00, 0x9e, 0x0a, 0x12, 0x00, 0xb6, 0x06, 0x04, + 0x00, 0xa0, 0x0a, 0x13, 0x00, 0xa2, 0x0a, 0x14, + 0x00, 0xbb, 0xe7, 0xe4, 0xe5, 0xa5, 0xf0, 0x0f, + 0xe6, 0x5d, 0x04, 0x00, 0xe4, 0x46, 0xf5, 0xf0, + 0x06, 0xe4, 0x8e, 0xe8, 0xf2, 0xee, 0x5d, 0x04, + 0x00, 0x41, 0x9e, 0x01, 0x00, 0x00, 0x5d, 0x05, + 0x00, 0xe4, 0x24, 0x02, 0x00, 0xcf, 0x04, 0x97, + 0x02, 0x00, 0x00, 0xcb, 0x9c, 0x04, 0x97, 0x02, + 0x00, 0x00, 0x9c, 0xd0, 0x5d, 0x06, 0x00, 0x41, + 0xc4, 0x01, 0x00, 0x00, 0xcc, 0x24, 0x01, 0x00, + 0xba, 0xa8, 0xf0, 0x7c, 0x04, 0x46, 0x02, 0x00, + 0x00, 0x5e, 0x07, 0x00, 0xcb, 0x04, 0x03, 0x00, + 0x00, 0x00, 0xad, 0x11, 0xf1, 0x09, 0x0e, 0xcb, + 0x04, 0x02, 0x00, 0x00, 0x00, 0xad, 0xf0, 0x0b, + 0x04, 0x4b, 0x00, 0x00, 0x00, 0x5e, 0x07, 0x00, + 0xf2, 0x43, 0xcb, 0x04, 0x03, 0x00, 0x00, 0x00, + 0xad, 0x11, 0xf1, 0x09, 0x0e, 0xcb, 0x04, 0x02, + 0x00, 0x00, 0x00, 0xad, 0xf0, 0x0b, 0x04, 0x4b, + 0x00, 0x00, 0x00, 0x5e, 0x07, 0x00, 0xf2, 0x25, + 0xcb, 0x04, 0x01, 0x00, 0x00, 0x00, 0xad, 0xf0, + 0x0b, 0x04, 0x01, 0x00, 0x00, 0x00, 0x5e, 0x07, + 0x00, 0xf2, 0x12, 0xcb, 0x04, 0x49, 0x00, 0x00, + 0x00, 0xad, 0xf0, 0x09, 0x04, 0x49, 0x00, 0x00, + 0x00, 0x5e, 0x07, 0x00, 0x5d, 0x08, 0x00, 0x41, + 0xc4, 0x01, 0x00, 0x00, 0xcc, 0x24, 0x01, 0x00, + 0xba, 0xa8, 0xf0, 0x03, 0xba, 0xe7, 0x29, 0xe4, + 0xd1, 0xcd, 0xe5, 0xa5, 0xf0, 0x12, 0x5d, 0x04, + 0x00, 0xcd, 0x46, 0x04, 0xe7, 0x01, 0x00, 0x00, + 0xab, 0xf0, 0x05, 0x92, 0x02, 0xf2, 0xeb, 0xcd, + 0xe5, 0xa5, 0xf0, 0x17, 0x5d, 0x04, 0x00, 0xcd, + 0x46, 0x04, 0xde, 0x01, 0x00, 0x00, 0xab, 0xf0, + 0x0a, 0x04, 0x1b, 0x00, 0x00, 0x00, 0x5e, 0x07, + 0x00, 0x29, 0x5d, 0x09, 0x00, 0x41, 0xc4, 0x01, + 0x00, 0x00, 0xcc, 0x24, 0x01, 0x00, 0xba, 0xa8, + 0xf0, 0x0a, 0x04, 0x17, 0x02, 0x00, 0x00, 0x5e, + 0x07, 0x00, 0x29, 0x04, 0x98, 0x02, 0x00, 0x00, + 0x5e, 0x07, 0x00, 0xba, 0xe7, 0x29, 0x0c, 0x43, + 0x02, 0x01, 0xa6, 0x0a, 0x02, 0x00, 0x02, 0x03, + 0x00, 0x02, 0x00, 0x2b, 0x02, 0x84, 0x02, 0x00, + 0x01, 0x00, 0xb2, 0x0a, 0x00, 0x01, 0x00, 0x98, + 0x07, 0x09, 0x00, 0xb6, 0x06, 0x04, 0x00, 0xe3, + 0xef, 0xd7, 0xa5, 0xf0, 0x12, 0xe3, 0x41, 0xb1, + 0x01, 0x00, 0x00, 0x04, 0x16, 0x00, 0x00, 0x00, + 0x24, 0x01, 0x00, 0x0e, 0xf2, 0xea, 0xe3, 0xef, + 0xd8, 0xa5, 0xf0, 0x0e, 0xe3, 0x41, 0xb1, 0x01, + 0x00, 0x00, 0xe4, 0x24, 0x01, 0x00, 0x0e, 0xf2, + 0xee, 0x29, 0xc5, 0x00, 0xc8, 0x0a, 0xc5, 0x01, + 0xc8, 0x0b, 0xc5, 0x02, 0xc8, 0x0c, 0xc5, 0x03, + 0xc8, 0x0d, 0xc5, 0x04, 0xc8, 0x0e, 0xc5, 0x05, + 0xc8, 0x0f, 0xc5, 0x06, 0xc8, 0x10, 0xc5, 0x07, + 0xc8, 0x11, 0xc5, 0x08, 0xc8, 0x15, 0xc5, 0x09, + 0xc8, 0x16, 0xd7, 0xef, 0xd2, 0xc6, 0xc8, 0x05, + 0xba, 0xc8, 0x06, 0xbb, 0xc8, 0x08, 0x26, 0x00, + 0x00, 0xc8, 0x09, 0x04, 0x97, 0x02, 0x00, 0x00, + 0x04, 0x9a, 0x02, 0x00, 0x00, 0x9c, 0x04, 0x9b, + 0x02, 0x00, 0x00, 0x9c, 0x04, 0x9c, 0x02, 0x00, + 0x00, 0x9c, 0x04, 0x9d, 0x02, 0x00, 0x00, 0x9c, + 0x04, 0x9e, 0x02, 0x00, 0x00, 0x9c, 0x04, 0x9f, + 0x02, 0x00, 0x00, 0x9c, 0x04, 0xa0, 0x02, 0x00, + 0x00, 0x9c, 0x04, 0xa1, 0x02, 0x00, 0x00, 0x9c, + 0x04, 0xa2, 0x02, 0x00, 0x00, 0x9c, 0xc8, 0x12, + 0x04, 0xa3, 0x02, 0x00, 0x00, 0xc8, 0x13, 0x04, + 0xa4, 0x02, 0x00, 0x00, 0xc8, 0x14, 0xba, 0xcf, + 0xcb, 0xce, 0xa5, 0x68, 0x6a, 0x01, 0x00, 0x00, + 0x07, 0xc8, 0x04, 0xcb, 0xd1, 0xd7, 0xcb, 0x90, + 0xcf, 0x46, 0xd4, 0x11, 0x04, 0xe7, 0x01, 0x00, + 0x00, 0xad, 0xf1, 0x1c, 0x11, 0x04, 0xa5, 0x02, + 0x00, 0x00, 0xad, 0xf1, 0x13, 0x11, 0x04, 0xa6, + 0x02, 0x00, 0x00, 0xad, 0xf1, 0x0a, 0x11, 0x04, + 0xa3, 0x01, 0x00, 0x00, 0xad, 0xf0, 0x04, 0x0e, + 0xf2, 0xc7, 0x11, 0x04, 0xa7, 0x02, 0x00, 0x00, + 0xad, 0xf1, 0x0a, 0x11, 0x04, 0xf2, 0x01, 0x00, + 0x00, 0xad, 0xf0, 0x18, 0xcb, 0xce, 0xa5, 0xf0, + 0x0d, 0xd7, 0xcb, 0x46, 0xcc, 0xab, 0xf0, 0x06, + 0x92, 0x00, 0x0e, 0xf2, 0xa4, 0xbb, 0xc8, 0x08, + 0x0e, 0xf2, 0x9e, 0x11, 0x04, 0xc9, 0x01, 0x00, + 0x00, 0xad, 0xf0, 0x44, 0xcb, 0xce, 0xa5, 0xf0, + 0x13, 0xd7, 0xcb, 0x46, 0x04, 0x86, 0x00, 0x00, + 0x00, 0xab, 0xf0, 0x08, 0xc7, 0x0d, 0xf4, 0x0e, + 0xf3, 0xdc, 0x00, 0xcb, 0xce, 0xa5, 0xf0, 0x13, + 0xd7, 0xcb, 0x46, 0x04, 0xc9, 0x01, 0x00, 0x00, + 0xab, 0xf0, 0x08, 0xc7, 0x0e, 0xf4, 0x0e, 0xf3, + 0xc5, 0x00, 0xc7, 0x08, 0xf0, 0x0b, 0xc7, 0x10, + 0xf4, 0x0e, 0xba, 0xc8, 0x08, 0xf3, 0xb7, 0x00, + 0xbb, 0xc8, 0x08, 0x0e, 0xf3, 0x53, 0xff, 0x11, + 0x04, 0xc5, 0x01, 0x00, 0x00, 0xad, 0xf1, 0x13, + 0x11, 0x04, 0xc6, 0x01, 0x00, 0x00, 0xad, 0xf1, + 0x0a, 0x11, 0x04, 0xc7, 0x01, 0x00, 0x00, 0xad, + 0xf0, 0x0c, 0xc7, 0x0f, 0xcc, 0xf5, 0x0e, 0xba, + 0xc8, 0x08, 0xf3, 0x8a, 0x00, 0x11, 0x04, 0xde, + 0x01, 0x00, 0x00, 0xad, 0xf1, 0x13, 0x11, 0x04, + 0xec, 0x01, 0x00, 0x00, 0xad, 0xf1, 0x0a, 0x11, + 0x04, 0x2f, 0x02, 0x00, 0x00, 0xad, 0xf0, 0x0f, + 0xbb, 0xc8, 0x08, 0x92, 0x06, 0xc7, 0x0a, 0xcc, + 0xf5, 0x0e, 0x0e, 0xf3, 0x04, 0xff, 0x11, 0x04, + 0xdf, 0x01, 0x00, 0x00, 0xad, 0xf1, 0x13, 0x11, + 0x04, 0xc8, 0x01, 0x00, 0x00, 0xad, 0xf1, 0x0a, + 0x11, 0x04, 0x30, 0x02, 0x00, 0x00, 0xad, 0xf0, + 0x25, 0xba, 0xc8, 0x08, 0xc7, 0x06, 0xba, 0xa7, + 0xf0, 0x13, 0xe4, 0xc7, 0x0b, 0xf4, 0xcc, 0xf6, + 0xf0, 0x0b, 0x91, 0x06, 0xc7, 0x0c, 0xf4, 0x0e, + 0x0e, 0xf3, 0xce, 0xfe, 0x04, 0x37, 0x00, 0x00, + 0x00, 0xc8, 0x04, 0xf2, 0x21, 0xe5, 0xcc, 0xf5, + 0xf0, 0x0a, 0xc7, 0x11, 0xf4, 0x0e, 0xba, 0xc8, + 0x08, 0xf2, 0x13, 0xe3, 0xcc, 0xf5, 0xf0, 0x07, + 0xc7, 0x15, 0xf4, 0x0e, 0xf2, 0x08, 0xbb, 0xc8, + 0x08, 0x0e, 0xf3, 0xa5, 0xfe, 0x0e, 0xc7, 0x04, + 0x68, 0x9f, 0xfe, 0xff, 0xff, 0xc7, 0x16, 0xcd, + 0xcb, 0xf6, 0x0e, 0xf3, 0x94, 0xfe, 0xc7, 0x16, + 0xce, 0xce, 0xf6, 0x0e, 0xc7, 0x05, 0xc7, 0x06, + 0xc7, 0x09, 0x26, 0x03, 0x00, 0x28, 0x0c, 0x43, + 0x02, 0x01, 0xea, 0x05, 0x01, 0x02, 0x01, 0x04, + 0x00, 0x02, 0x00, 0x9d, 0x01, 0x03, 0xf4, 0x06, + 0x00, 0x01, 0x00, 0xd0, 0x0a, 0x00, 0x00, 0x00, + 0xd2, 0x0a, 0x00, 0x01, 0x00, 0xea, 0x03, 0x00, + 0x1a, 0xec, 0x03, 0x01, 0x1a, 0x64, 0x00, 0x00, + 0x41, 0xaa, 0x02, 0x00, 0x00, 0x04, 0xab, 0x02, + 0x00, 0x00, 0x24, 0x01, 0x00, 0xd3, 0xf0, 0x16, + 0xcb, 0xba, 0x46, 0x04, 0xc9, 0x01, 0x00, 0x00, + 0xad, 0xf0, 0x0b, 0xcb, 0x04, 0xc9, 0x01, 0x00, + 0x00, 0x9c, 0xd7, 0x9c, 0x28, 0x64, 0x00, 0x00, + 0x41, 0xaa, 0x02, 0x00, 0x00, 0x04, 0xac, 0x02, + 0x00, 0x00, 0x24, 0x01, 0x00, 0xd0, 0x64, 0x01, + 0x00, 0x40, 0xad, 0x02, 0x00, 0x00, 0x04, 0xae, + 0x02, 0x00, 0x00, 0xad, 0xf0, 0x0c, 0xcc, 0xf0, + 0x09, 0xcc, 0x04, 0xaf, 0x02, 0x00, 0x00, 0x9c, + 0xcf, 0x64, 0x01, 0x00, 0x41, 0xb0, 0x02, 0x00, + 0x00, 0xcb, 0x04, 0xc9, 0x01, 0x00, 0x00, 0x9c, + 0x24, 0x01, 0x00, 0xbb, 0x46, 0xba, 0xad, 0xf0, + 0x0b, 0xcb, 0x04, 0xc9, 0x01, 0x00, 0x00, 0x9c, + 0xd7, 0x9c, 0x28, 0xcc, 0x11, 0xf1, 0x1b, 0x0e, + 0x64, 0x00, 0x00, 0x41, 0xaa, 0x02, 0x00, 0x00, + 0x04, 0xb1, 0x02, 0x00, 0x00, 0x24, 0x01, 0x00, + 0x11, 0xf1, 0x07, 0x0e, 0x04, 0xbd, 0x01, 0x00, + 0x00, 0x04, 0xb2, 0x02, 0x00, 0x00, 0x9c, 0xd7, + 0x9c, 0x28, 0x0c, 0x43, 0x02, 0x01, 0xec, 0x05, + 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x67, + 0x03, 0xf4, 0x06, 0x00, 0x00, 0x00, 0xe6, 0x0a, + 0x00, 0x01, 0x00, 0xe8, 0x09, 0x05, 0x00, 0x03, + 0x90, 0x04, 0x1c, 0x00, 0xea, 0x03, 0x00, 0x1a, + 0xea, 0x05, 0x89, 0x01, 0x00, 0xe3, 0x41, 0xbe, + 0x01, 0x00, 0x00, 0xc3, 0x18, 0xfc, 0x24, 0x01, + 0x00, 0x41, 0x63, 0x00, 0x00, 0x00, 0x04, 0xa3, + 0x01, 0x00, 0x00, 0x24, 0x01, 0x00, 0x41, 0x59, + 0x02, 0x00, 0x00, 0x24, 0x00, 0x00, 0xd3, 0xf0, + 0x43, 0x6b, 0x38, 0x00, 0x00, 0x00, 0x64, 0x01, + 0x00, 0x41, 0xb4, 0x02, 0x00, 0x00, 0xe5, 0x04, + 0xb5, 0x02, 0x00, 0x00, 0xf5, 0x04, 0x47, 0x02, + 0x00, 0x00, 0x24, 0x02, 0x00, 0xd4, 0x41, 0x9c, + 0x01, 0x00, 0x00, 0xcb, 0x04, 0xa3, 0x01, 0x00, + 0x00, 0x9c, 0x24, 0x01, 0x00, 0x0e, 0xcc, 0x41, + 0xb6, 0x02, 0x00, 0x00, 0x24, 0x00, 0x00, 0x0e, + 0x0e, 0x29, 0xd1, 0x6b, 0x06, 0x00, 0x00, 0x00, + 0x0e, 0x29, 0x30, 0x29, 0x0c, 0x43, 0x02, 0x01, + 0xee, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x04, + 0x00, 0x2f, 0x01, 0x90, 0x06, 0x00, 0x00, 0x00, + 0xea, 0x03, 0x00, 0x1a, 0xea, 0x05, 0x89, 0x01, + 0x00, 0x90, 0x04, 0x1c, 0x00, 0x92, 0x04, 0x1d, + 0x00, 0x64, 0x00, 0x00, 0x41, 0xb7, 0x02, 0x00, + 0x00, 0xe4, 0x04, 0xb5, 0x02, 0x00, 0x00, 0xf5, + 0x24, 0x01, 0x00, 0xd3, 0xf0, 0x1a, 0xcb, 0x41, + 0x59, 0x02, 0x00, 0x00, 0x24, 0x00, 0x00, 0x41, + 0x64, 0x00, 0x00, 0x00, 0x04, 0xa3, 0x01, 0x00, + 0x00, 0x24, 0x01, 0x00, 0xed, 0xef, 0xea, 0x29, + 0x0c, 0x43, 0x02, 0x01, 0xf0, 0x05, 0x00, 0x02, + 0x00, 0x04, 0x00, 0x04, 0x02, 0x51, 0x02, 0xba, + 0x07, 0x00, 0x00, 0x00, 0xf4, 0x06, 0x00, 0x01, + 0x00, 0xea, 0x03, 0x00, 0x1a, 0xfe, 0x03, 0x13, + 0x00, 0x80, 0x04, 0x14, 0x00, 0x86, 0x04, 0x17, + 0x00, 0x07, 0x16, 0x28, 0x5c, 0x64, 0x2b, 0x29, + 0x3b, 0x28, 0x5c, 0x64, 0x2b, 0x29, 0x07, 0x76, + 0x00, 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x00, + 0x0e, 0x06, 0x00, 0x00, 0x00, 0x06, 0x0d, 0xf5, + 0xff, 0xff, 0xff, 0x13, 0x00, 0x13, 0x01, 0x24, + 0x01, 0x00, 0x30, 0x00, 0x39, 0x00, 0x0e, 0xf4, + 0xff, 0xff, 0xff, 0x14, 0x01, 0x01, 0x3b, 0x00, + 0x13, 0x02, 0x24, 0x01, 0x00, 0x30, 0x00, 0x39, + 0x00, 0x0e, 0xf4, 0xff, 0xff, 0xff, 0x14, 0x02, + 0x14, 0x00, 0x10, 0x64, 0x00, 0x00, 0x41, 0xaa, + 0x02, 0x00, 0x00, 0x04, 0xb8, 0x02, 0x00, 0x00, + 0x24, 0x01, 0x00, 0xd4, 0xf0, 0x21, 0xcc, 0x41, + 0xca, 0x01, 0x00, 0x00, 0xc4, 0x00, 0xc4, 0x01, + 0x34, 0x24, 0x01, 0x00, 0xd3, 0xf0, 0x10, 0xcb, + 0xbc, 0x46, 0x8c, 0xba, 0xae, 0xf0, 0x08, 0xe4, + 0x40, 0x6f, 0x02, 0x00, 0x00, 0xe9, 0x64, 0x00, + 0x00, 0x41, 0xaa, 0x02, 0x00, 0x00, 0x04, 0xb9, + 0x02, 0x00, 0x00, 0x24, 0x01, 0x00, 0xd4, 0xf0, + 0x0b, 0xcc, 0xba, 0x46, 0x8c, 0xba, 0xae, 0xf0, + 0x03, 0x09, 0xea, 0x29, 0xc5, 0x00, 0xc8, 0x35, + 0xc5, 0x01, 0xc8, 0x36, 0xc5, 0x02, 0xc8, 0x37, + 0xc5, 0x03, 0xc8, 0x38, 0xc5, 0x04, 0xc8, 0x39, + 0xc5, 0x05, 0xc8, 0x3a, 0xc5, 0x06, 0xc8, 0x3b, + 0xc5, 0x07, 0xc8, 0x3c, 0xc5, 0x08, 0xc8, 0x3d, + 0xc5, 0x09, 0xc8, 0x3e, 0xc5, 0x0a, 0xc8, 0x3f, + 0xc5, 0x0b, 0xc8, 0x40, 0xc5, 0x0c, 0xc8, 0x41, + 0xc5, 0x0d, 0xc8, 0x42, 0xc5, 0x0e, 0xc8, 0x43, + 0xc5, 0x0f, 0xc8, 0x44, 0xc5, 0x10, 0xc8, 0x45, + 0xc5, 0x11, 0xc8, 0x46, 0xc5, 0x12, 0xc8, 0x47, + 0xc5, 0x13, 0xc8, 0x48, 0xc5, 0x14, 0xc8, 0x49, + 0xc5, 0x15, 0xc8, 0x4a, 0xc5, 0x16, 0xc8, 0x4b, + 0xc5, 0x17, 0xc8, 0x4c, 0xc5, 0x18, 0xc8, 0x4d, + 0xc5, 0x19, 0xc8, 0x4e, 0xc5, 0x1a, 0xc8, 0x4f, + 0xc5, 0x1b, 0xc8, 0x50, 0xc5, 0x1c, 0xc8, 0x51, + 0xc5, 0x1d, 0xc8, 0x52, 0xc5, 0x1e, 0xc8, 0x53, + 0xc5, 0x1f, 0xc8, 0x54, 0xc5, 0x20, 0xc8, 0x55, + 0xc5, 0x21, 0xc8, 0x56, 0xc5, 0x22, 0xc8, 0x57, + 0xc5, 0x23, 0xc8, 0x58, 0xc5, 0x24, 0xc8, 0x59, + 0xc5, 0x25, 0xc8, 0x5a, 0xc5, 0x26, 0xc8, 0x5b, + 0xc5, 0x27, 0xc8, 0x5c, 0xc5, 0x28, 0xc8, 0x5d, + 0xc5, 0x29, 0xc8, 0x5e, 0xc5, 0x2a, 0xc8, 0x5f, + 0xc5, 0x2b, 0xc8, 0x60, 0xc5, 0x2c, 0xc8, 0x61, + 0xc5, 0x2d, 0xc8, 0x62, 0xc5, 0x2e, 0xc8, 0x63, + 0xc5, 0x2f, 0xc8, 0x64, 0xc5, 0x30, 0xc8, 0x65, + 0xc5, 0x31, 0xc8, 0x66, 0xc5, 0x32, 0xc8, 0x67, + 0xc5, 0x33, 0xc8, 0x68, 0xc5, 0x34, 0xc8, 0x69, + 0xc5, 0x35, 0xc8, 0x6a, 0xc5, 0x36, 0xc8, 0x6b, + 0xc5, 0x37, 0xc8, 0x6c, 0xc5, 0x38, 0xc8, 0x6e, + 0xc5, 0x39, 0xc8, 0x72, 0xc5, 0x3a, 0xc8, 0x73, + 0xc5, 0x3b, 0xc8, 0x74, 0xc5, 0x3c, 0xc8, 0x75, + 0xc5, 0x3d, 0xc8, 0x76, 0xc5, 0x3e, 0xc8, 0x77, + 0xc5, 0x40, 0xc8, 0x79, 0xc5, 0x41, 0xc8, 0x7a, + 0xc5, 0x42, 0xc8, 0x7b, 0xc5, 0x43, 0xc8, 0x7c, + 0xc5, 0x44, 0xc8, 0x7d, 0xc5, 0x45, 0xc8, 0x7e, + 0xc5, 0x51, 0xc8, 0x80, 0xc5, 0x52, 0xc8, 0x81, + 0xc5, 0x53, 0xc8, 0x82, 0xc5, 0x54, 0xc8, 0x83, + 0xc5, 0x55, 0xc8, 0x84, 0xc5, 0x56, 0xc8, 0x85, + 0xc5, 0x57, 0xc8, 0x86, 0xc5, 0x58, 0xc8, 0x87, + 0xc5, 0x59, 0xc8, 0x88, 0xc5, 0x5a, 0xc8, 0x89, + 0xc5, 0x5b, 0xc8, 0x8a, 0xc5, 0x5c, 0xc8, 0x8b, + 0xc5, 0x5d, 0xc8, 0x8c, 0xd7, 0x64, 0x02, 0x00, + 0x42, 0xf7, 0x00, 0x00, 0x00, 0xd7, 0x64, 0x01, + 0x00, 0x42, 0xf6, 0x00, 0x00, 0x00, 0xd7, 0x64, + 0x00, 0x00, 0x42, 0xf5, 0x00, 0x00, 0x00, 0xd7, + 0x40, 0x9d, 0x00, 0x00, 0x00, 0xcf, 0xd7, 0x40, + 0xa1, 0x00, 0x00, 0x00, 0xd0, 0xd7, 0x40, 0xa0, + 0x00, 0x00, 0x00, 0xd1, 0xd7, 0x40, 0xa2, 0x00, + 0x00, 0x00, 0xd2, 0xd7, 0x40, 0xbb, 0x00, 0x00, + 0x00, 0xc8, 0x04, 0xd7, 0x40, 0xb0, 0x00, 0x00, + 0x00, 0xc8, 0x05, 0xd7, 0x40, 0x9e, 0x00, 0x00, + 0x00, 0xc8, 0x06, 0xd7, 0x40, 0xa7, 0x00, 0x00, + 0x00, 0xc8, 0x07, 0xd7, 0x40, 0xab, 0x00, 0x00, + 0x00, 0xc8, 0x08, 0xd7, 0x40, 0x9f, 0x00, 0x00, + 0x00, 0xc8, 0x09, 0xd7, 0x40, 0xa3, 0x00, 0x00, + 0x00, 0xc8, 0x0a, 0xd7, 0x40, 0xa5, 0x00, 0x00, + 0x00, 0xc8, 0x0b, 0xd7, 0x40, 0xa6, 0x00, 0x00, + 0x00, 0xc8, 0x0c, 0xd7, 0x40, 0xf9, 0x00, 0x00, + 0x00, 0xc8, 0x0d, 0xd7, 0x40, 0xfa, 0x00, 0x00, + 0x00, 0xc8, 0x0e, 0xd7, 0x40, 0xfb, 0x00, 0x00, + 0x00, 0xc8, 0x0f, 0xd7, 0x40, 0xfc, 0x00, 0x00, + 0x00, 0xc8, 0x10, 0x04, 0xba, 0x02, 0x00, 0x00, + 0x04, 0xbb, 0x02, 0x00, 0x00, 0x04, 0xbc, 0x02, + 0x00, 0x00, 0x04, 0xbd, 0x02, 0x00, 0x00, 0x04, + 0xbe, 0x02, 0x00, 0x00, 0x04, 0xbf, 0x02, 0x00, + 0x00, 0x04, 0xc0, 0x02, 0x00, 0x00, 0x04, 0xc1, + 0x02, 0x00, 0x00, 0x04, 0xc2, 0x02, 0x00, 0x00, + 0x04, 0xc3, 0x02, 0x00, 0x00, 0x04, 0xc4, 0x02, + 0x00, 0x00, 0x04, 0xc5, 0x02, 0x00, 0x00, 0x04, + 0xc6, 0x02, 0x00, 0x00, 0x04, 0x06, 0x00, 0x00, + 0x00, 0x04, 0xc7, 0x02, 0x00, 0x00, 0x04, 0x08, + 0x00, 0x00, 0x00, 0x04, 0xc8, 0x02, 0x00, 0x00, + 0x04, 0xc9, 0x02, 0x00, 0x00, 0x04, 0xca, 0x02, + 0x00, 0x00, 0x04, 0xcb, 0x02, 0x00, 0x00, 0x04, + 0xcc, 0x02, 0x00, 0x00, 0x26, 0x15, 0x00, 0xc8, + 0x11, 0x0b, 0x04, 0xcd, 0x02, 0x00, 0x00, 0x4b, + 0x9d, 0x01, 0x00, 0x00, 0x04, 0xce, 0x02, 0x00, + 0x00, 0x4b, 0xcf, 0x02, 0x00, 0x00, 0x04, 0xd0, + 0x02, 0x00, 0x00, 0x4b, 0xd1, 0x02, 0x00, 0x00, + 0x04, 0xd2, 0x02, 0x00, 0x00, 0x4b, 0xd3, 0x02, + 0x00, 0x00, 0x04, 0xd4, 0x02, 0x00, 0x00, 0x4b, + 0xd5, 0x02, 0x00, 0x00, 0x04, 0xd6, 0x02, 0x00, + 0x00, 0x4b, 0xd7, 0x02, 0x00, 0x00, 0x04, 0xd8, + 0x02, 0x00, 0x00, 0x4b, 0xd9, 0x02, 0x00, 0x00, + 0x04, 0xda, 0x02, 0x00, 0x00, 0x4b, 0xdb, 0x02, + 0x00, 0x00, 0x04, 0xdc, 0x02, 0x00, 0x00, 0x4b, + 0xdd, 0x02, 0x00, 0x00, 0x04, 0xde, 0x02, 0x00, + 0x00, 0x4b, 0xdf, 0x02, 0x00, 0x00, 0x04, 0xde, + 0x02, 0x00, 0x00, 0x4b, 0xe0, 0x02, 0x00, 0x00, + 0x04, 0xe1, 0x02, 0x00, 0x00, 0x4b, 0xe2, 0x02, + 0x00, 0x00, 0x04, 0xe3, 0x02, 0x00, 0x00, 0x4b, + 0xe4, 0x02, 0x00, 0x00, 0x04, 0xe5, 0x02, 0x00, + 0x00, 0x4b, 0xe6, 0x02, 0x00, 0x00, 0x04, 0xe7, + 0x02, 0x00, 0x00, 0x4b, 0xe8, 0x02, 0x00, 0x00, + 0x04, 0xe9, 0x02, 0x00, 0x00, 0x4b, 0xea, 0x02, + 0x00, 0x00, 0x04, 0xeb, 0x02, 0x00, 0x00, 0x4b, + 0xec, 0x02, 0x00, 0x00, 0x04, 0xed, 0x02, 0x00, + 0x00, 0x4b, 0xee, 0x02, 0x00, 0x00, 0xc8, 0x12, + 0x0b, 0x0b, 0x04, 0xdb, 0x02, 0x00, 0x00, 0x4b, + 0x41, 0x02, 0x00, 0x00, 0x04, 0xee, 0x02, 0x00, + 0x00, 0x4b, 0x4b, 0x00, 0x00, 0x00, 0x04, 0xdd, + 0x02, 0x00, 0x00, 0x4b, 0x94, 0x02, 0x00, 0x00, + 0x04, 0xd9, 0x02, 0x00, 0x00, 0x4b, 0x44, 0x02, + 0x00, 0x00, 0x04, 0xe4, 0x02, 0x00, 0x00, 0x4b, + 0x16, 0x00, 0x00, 0x00, 0x04, 0xe2, 0x02, 0x00, + 0x00, 0x4b, 0x37, 0x00, 0x00, 0x00, 0x04, 0xe6, + 0x02, 0x00, 0x00, 0x4b, 0x1b, 0x00, 0x00, 0x00, + 0x04, 0xe4, 0x02, 0x00, 0x00, 0x4b, 0x98, 0x02, + 0x00, 0x00, 0x04, 0xee, 0x02, 0x00, 0x00, 0x4b, + 0x46, 0x02, 0x00, 0x00, 0x04, 0xee, 0x02, 0x00, + 0x00, 0x4b, 0x01, 0x00, 0x00, 0x00, 0x04, 0xd3, + 0x02, 0x00, 0x00, 0x4b, 0x4a, 0x00, 0x00, 0x00, + 0x04, 0xdd, 0x02, 0x00, 0x00, 0x4b, 0x43, 0x02, + 0x00, 0x00, 0x04, 0xdd, 0x02, 0x00, 0x00, 0x4b, + 0x3e, 0x02, 0x00, 0x00, 0x04, 0xdb, 0x02, 0x00, + 0x00, 0x4b, 0x40, 0x02, 0x00, 0x00, 0x04, 0xec, + 0x02, 0x00, 0x00, 0x4b, 0x4c, 0x00, 0x00, 0x00, + 0x04, 0xee, 0x02, 0x00, 0x00, 0x4b, 0x4e, 0x00, + 0x00, 0x00, 0x04, 0xea, 0x02, 0x00, 0x00, 0x4b, + 0x17, 0x02, 0x00, 0x00, 0x04, 0xee, 0x02, 0x00, + 0x00, 0x4b, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x6c, + 0x02, 0x00, 0x00, 0x0b, 0x04, 0xdb, 0x02, 0x00, + 0x00, 0x4b, 0x41, 0x02, 0x00, 0x00, 0x04, 0xea, + 0x02, 0x00, 0x00, 0x4b, 0x4b, 0x00, 0x00, 0x00, + 0x04, 0xe0, 0x02, 0x00, 0x00, 0x4b, 0x94, 0x02, + 0x00, 0x00, 0x04, 0xd9, 0x02, 0x00, 0x00, 0x4b, + 0x44, 0x02, 0x00, 0x00, 0x04, 0xcf, 0x02, 0x00, + 0x00, 0x4b, 0x16, 0x00, 0x00, 0x00, 0x04, 0xd1, + 0x02, 0x00, 0x00, 0x4b, 0x37, 0x00, 0x00, 0x00, + 0x04, 0xe6, 0x02, 0x00, 0x00, 0x4b, 0x1b, 0x00, + 0x00, 0x00, 0x04, 0xcf, 0x02, 0x00, 0x00, 0x4b, + 0x98, 0x02, 0x00, 0x00, 0x04, 0xea, 0x02, 0x00, + 0x00, 0x4b, 0x46, 0x02, 0x00, 0x00, 0x04, 0xea, + 0x02, 0x00, 0x00, 0x4b, 0x01, 0x00, 0x00, 0x00, + 0x04, 0xd3, 0x02, 0x00, 0x00, 0x4b, 0x4a, 0x00, + 0x00, 0x00, 0x04, 0xcf, 0x02, 0x00, 0x00, 0x4b, + 0x43, 0x02, 0x00, 0x00, 0x04, 0xcf, 0x02, 0x00, + 0x00, 0x4b, 0x3e, 0x02, 0x00, 0x00, 0x04, 0xdb, + 0x02, 0x00, 0x00, 0x4b, 0x40, 0x02, 0x00, 0x00, + 0x04, 0xec, 0x02, 0x00, 0x00, 0x4b, 0x4c, 0x00, + 0x00, 0x00, 0x04, 0xe0, 0x02, 0x00, 0x00, 0x4b, + 0x4e, 0x00, 0x00, 0x00, 0x04, 0xea, 0x02, 0x00, + 0x00, 0x4b, 0x17, 0x02, 0x00, 0x00, 0x04, 0xea, + 0x02, 0x00, 0x00, 0x4b, 0x49, 0x00, 0x00, 0x00, + 0x4b, 0x6f, 0x02, 0x00, 0x00, 0xc9, 0x13, 0x40, + 0x6c, 0x02, 0x00, 0x00, 0xc8, 0x14, 0x0a, 0xc8, + 0x15, 0x09, 0xc8, 0x16, 0x0a, 0xc8, 0x17, 0x09, + 0xc8, 0x18, 0xbc, 0xc8, 0x19, 0x09, 0xc8, 0x1a, + 0x09, 0xc8, 0x1b, 0x26, 0x00, 0x00, 0xc8, 0x1c, + 0xc6, 0xc8, 0x1e, 0xc6, 0xc8, 0x1f, 0xc6, 0xc8, + 0x20, 0xba, 0xc8, 0x21, 0x04, 0xef, 0x02, 0x00, + 0x00, 0xc8, 0x22, 0x04, 0xf0, 0x02, 0x00, 0x00, + 0xc8, 0x23, 0xba, 0xc8, 0x25, 0xc6, 0xc8, 0x26, + 0xba, 0xc8, 0x27, 0xc6, 0xc8, 0x28, 0xba, 0xc8, + 0x29, 0xc6, 0xc8, 0x2a, 0xba, 0xc8, 0x2b, 0x09, + 0xc8, 0x2e, 0xba, 0xc8, 0x2f, 0xba, 0xc8, 0x30, + 0xba, 0xc8, 0x34, 0x0b, 0xc7, 0x48, 0x4b, 0xf1, + 0x02, 0x00, 0x00, 0xc7, 0x4b, 0x4b, 0xf2, 0x02, + 0x00, 0x00, 0xc7, 0x66, 0x4b, 0xf3, 0x02, 0x00, + 0x00, 0xc7, 0x5a, 0x4b, 0xf4, 0x02, 0x00, 0x00, + 0xc7, 0x49, 0x4b, 0xf5, 0x02, 0x00, 0x00, 0xc7, + 0x4a, 0x4b, 0xf6, 0x02, 0x00, 0x00, 0xc7, 0x46, + 0x4b, 0xf7, 0x02, 0x00, 0x00, 0xc7, 0x5b, 0x4b, + 0xf8, 0x02, 0x00, 0x00, 0xc7, 0x6c, 0x4b, 0xa5, + 0x02, 0x00, 0x00, 0xc7, 0x51, 0x4b, 0xa3, 0x01, + 0x00, 0x00, 0xc7, 0x61, 0x4b, 0xf9, 0x02, 0x00, + 0x00, 0xc7, 0x50, 0x4b, 0xfa, 0x02, 0x00, 0x00, + 0xc7, 0x51, 0x4b, 0xa6, 0x02, 0x00, 0x00, 0xc7, + 0x54, 0x4b, 0xfb, 0x02, 0x00, 0x00, 0xc7, 0x53, + 0x4b, 0xfc, 0x02, 0x00, 0x00, 0xc7, 0x45, 0x4b, + 0xfd, 0x02, 0x00, 0x00, 0xc7, 0x47, 0x4b, 0xfe, + 0x02, 0x00, 0x00, 0xc7, 0x47, 0x4b, 0xff, 0x02, + 0x00, 0x00, 0xc7, 0x5c, 0x4b, 0x00, 0x03, 0x00, + 0x00, 0xc7, 0x64, 0x4b, 0x01, 0x03, 0x00, 0x00, + 0xc7, 0x67, 0x4b, 0x02, 0x03, 0x00, 0x00, 0xc7, + 0x65, 0x4b, 0x03, 0x03, 0x00, 0x00, 0xc7, 0x53, + 0x4b, 0x04, 0x03, 0x00, 0x00, 0xc7, 0x54, 0x4b, + 0x05, 0x03, 0x00, 0x00, 0xc7, 0x4a, 0x4b, 0x06, + 0x03, 0x00, 0x00, 0xc7, 0x4b, 0x4b, 0x07, 0x03, + 0x00, 0x00, 0xc7, 0x4e, 0x4b, 0x08, 0x03, 0x00, + 0x00, 0xc7, 0x4f, 0x4b, 0x09, 0x03, 0x00, 0x00, + 0xc7, 0x4e, 0x4b, 0x0a, 0x03, 0x00, 0x00, 0xc7, + 0x4f, 0x4b, 0x0b, 0x03, 0x00, 0x00, 0xc7, 0x48, + 0x4b, 0x0c, 0x03, 0x00, 0x00, 0xc7, 0x59, 0x4b, + 0x0d, 0x03, 0x00, 0x00, 0xc7, 0x49, 0x4b, 0x0e, + 0x03, 0x00, 0x00, 0xc7, 0x56, 0x4b, 0x0f, 0x03, + 0x00, 0x00, 0xc7, 0x57, 0x4b, 0x10, 0x03, 0x00, + 0x00, 0xc7, 0x53, 0x4b, 0x11, 0x03, 0x00, 0x00, + 0xc7, 0x54, 0x4b, 0x12, 0x03, 0x00, 0x00, 0xc7, + 0x4a, 0x4b, 0x13, 0x03, 0x00, 0x00, 0xc7, 0x4b, + 0x4b, 0x14, 0x03, 0x00, 0x00, 0xc7, 0x49, 0x4b, + 0x15, 0x03, 0x00, 0x00, 0xc7, 0x48, 0x4b, 0x16, + 0x03, 0x00, 0x00, 0xc7, 0x64, 0x4b, 0x17, 0x03, + 0x00, 0x00, 0xc7, 0x4f, 0x4b, 0x18, 0x03, 0x00, + 0x00, 0xc7, 0x63, 0x4b, 0x19, 0x03, 0x00, 0x00, + 0xc7, 0x4e, 0x4b, 0x1a, 0x03, 0x00, 0x00, 0xc7, + 0x62, 0x4b, 0x1b, 0x03, 0x00, 0x00, 0xc7, 0x5f, + 0x4b, 0x1c, 0x03, 0x00, 0x00, 0xc7, 0x5d, 0x4b, + 0x1d, 0x03, 0x00, 0x00, 0xc7, 0x5e, 0x4b, 0x1e, + 0x03, 0x00, 0x00, 0xc7, 0x5b, 0x4b, 0x1f, 0x03, + 0x00, 0x00, 0xc8, 0x6d, 0x0b, 0xc9, 0x78, 0xc5, + 0x3f, 0x42, 0x55, 0x02, 0x00, 0x00, 0xcb, 0x41, + 0x67, 0x00, 0x00, 0x00, 0x0b, 0xc7, 0x7b, 0x4b, + 0x67, 0x01, 0x00, 0x00, 0xc7, 0x7c, 0x4b, 0x68, + 0x01, 0x00, 0x00, 0xc5, 0x46, 0x4c, 0x20, 0x03, + 0x00, 0x00, 0x4b, 0x20, 0x03, 0x00, 0x00, 0xc5, + 0x47, 0x4c, 0x21, 0x03, 0x00, 0x00, 0x4b, 0x21, + 0x03, 0x00, 0x00, 0xc5, 0x48, 0x4c, 0x22, 0x03, + 0x00, 0x00, 0x4b, 0x22, 0x03, 0x00, 0x00, 0xc5, + 0x49, 0x4c, 0x23, 0x03, 0x00, 0x00, 0x4b, 0x23, + 0x03, 0x00, 0x00, 0xc5, 0x4a, 0x4c, 0x54, 0x02, + 0x00, 0x00, 0x4b, 0x54, 0x02, 0x00, 0x00, 0xc5, + 0x4b, 0x4c, 0x24, 0x03, 0x00, 0x00, 0x4b, 0x24, + 0x03, 0x00, 0x00, 0xc5, 0x4c, 0x4c, 0x3d, 0x02, + 0x00, 0x00, 0x4b, 0x3d, 0x02, 0x00, 0x00, 0xc5, + 0x4d, 0x4c, 0x6c, 0x02, 0x00, 0x00, 0x4b, 0x6c, + 0x02, 0x00, 0x00, 0xc5, 0x4e, 0x4c, 0x6f, 0x02, + 0x00, 0x00, 0x4b, 0x6f, 0x02, 0x00, 0x00, 0xc5, + 0x4f, 0x4c, 0xaf, 0x01, 0x00, 0x00, 0x4b, 0xaf, + 0x01, 0x00, 0x00, 0xc5, 0x50, 0x4c, 0x25, 0x03, + 0x00, 0x00, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x07, + 0x24, 0x02, 0x00, 0xc8, 0x7f, 0xc7, 0x8c, 0xf4, + 0x0e, 0xc7, 0x8b, 0xf4, 0x0e, 0xc7, 0x35, 0xf4, + 0x0e, 0xc7, 0x80, 0xf4, 0x29, 0x08, 0xf0, 0x02, + 0x29, 0xc5, 0x00, 0x38, 0x94, 0x00, 0x00, 0x00, + 0xf5, 0x0e, 0x06, 0x2f, +}; + diff --git a/userland/qjs/source/gen/standalone.c b/userland/qjs/source/gen/standalone.c new file mode 100644 index 0000000..f274228 --- /dev/null +++ b/userland/qjs/source/gen/standalone.c @@ -0,0 +1,319 @@ +/* File generated automatically by the QuickJS-ng compiler. */ + +#include + +const uint32_t qjsc_standalone_size = 2473; + +const uint8_t qjsc_standalone[2473] = { + 0x1d, 0xf0, 0xe0, 0x5c, 0xc6, 0x4c, 0x01, 0x1a, + 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x6c, 0x6f, + 0x6e, 0x65, 0x2e, 0x6a, 0x73, 0x01, 0x0e, 0x71, + 0x6a, 0x73, 0x3a, 0x73, 0x74, 0x64, 0x01, 0x0c, + 0x71, 0x6a, 0x73, 0x3a, 0x6f, 0x73, 0x01, 0x12, + 0x71, 0x6a, 0x73, 0x3a, 0x62, 0x6a, 0x73, 0x6f, + 0x6e, 0x01, 0x22, 0x63, 0x6f, 0x6d, 0x70, 0x69, + 0x6c, 0x65, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, + 0x6c, 0x6f, 0x6e, 0x65, 0x01, 0x1a, 0x72, 0x75, + 0x6e, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x6c, + 0x6f, 0x6e, 0x65, 0x01, 0x06, 0x73, 0x74, 0x64, + 0x01, 0x04, 0x6f, 0x73, 0x01, 0x0a, 0x62, 0x6a, + 0x73, 0x6f, 0x6e, 0x01, 0x28, 0x4a, 0x53, 0x5f, + 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x42, 0x4a, + 0x5f, 0x42, 0x59, 0x54, 0x45, 0x43, 0x4f, 0x44, + 0x45, 0x01, 0x2a, 0x4a, 0x53, 0x5f, 0x52, 0x45, + 0x41, 0x44, 0x5f, 0x4f, 0x42, 0x4a, 0x5f, 0x52, + 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, + 0x01, 0x2a, 0x4a, 0x53, 0x5f, 0x57, 0x52, 0x49, + 0x54, 0x45, 0x5f, 0x4f, 0x42, 0x4a, 0x5f, 0x42, + 0x59, 0x54, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x01, + 0x2c, 0x4a, 0x53, 0x5f, 0x57, 0x52, 0x49, 0x54, + 0x45, 0x5f, 0x4f, 0x42, 0x4a, 0x5f, 0x52, 0x45, + 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x01, + 0x32, 0x4a, 0x53, 0x5f, 0x57, 0x52, 0x49, 0x54, + 0x45, 0x5f, 0x4f, 0x42, 0x4a, 0x5f, 0x53, 0x54, + 0x52, 0x49, 0x50, 0x5f, 0x53, 0x4f, 0x55, 0x52, + 0x43, 0x45, 0x01, 0x0e, 0x54, 0x72, 0x61, 0x69, + 0x6c, 0x65, 0x72, 0x01, 0x16, 0x65, 0x6e, 0x63, + 0x6f, 0x64, 0x65, 0x41, 0x73, 0x63, 0x69, 0x69, + 0x01, 0x16, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, + 0x41, 0x73, 0x63, 0x69, 0x69, 0x01, 0x06, 0x74, + 0x78, 0x74, 0x01, 0x02, 0x63, 0x01, 0x14, 0x63, + 0x68, 0x61, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x41, + 0x74, 0x01, 0x06, 0x6d, 0x61, 0x70, 0x01, 0x06, + 0x62, 0x75, 0x66, 0x01, 0x18, 0x66, 0x72, 0x6f, + 0x6d, 0x43, 0x68, 0x61, 0x72, 0x43, 0x6f, 0x64, + 0x65, 0x01, 0x0c, 0x69, 0x6e, 0x46, 0x69, 0x6c, + 0x65, 0x01, 0x0e, 0x6f, 0x75, 0x74, 0x46, 0x69, + 0x6c, 0x65, 0x01, 0x12, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x45, 0x78, 0x65, 0x01, 0x04, 0x6a, + 0x73, 0x01, 0x08, 0x63, 0x6f, 0x64, 0x65, 0x01, + 0x10, 0x62, 0x79, 0x74, 0x65, 0x63, 0x6f, 0x64, + 0x65, 0x01, 0x16, 0x65, 0x78, 0x65, 0x46, 0x69, + 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x01, 0x06, + 0x65, 0x78, 0x65, 0x01, 0x0e, 0x65, 0x78, 0x65, + 0x53, 0x69, 0x7a, 0x65, 0x01, 0x12, 0x6e, 0x65, + 0x77, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x01, + 0x0c, 0x6e, 0x65, 0x77, 0x45, 0x78, 0x65, 0x01, + 0x04, 0x64, 0x77, 0x01, 0x0a, 0x6e, 0x65, 0x77, + 0x46, 0x64, 0x01, 0x10, 0x6c, 0x6f, 0x61, 0x64, + 0x46, 0x69, 0x6c, 0x65, 0x01, 0x1e, 0x66, 0x61, + 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, + 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x01, 0x14, 0x65, + 0x76, 0x61, 0x6c, 0x53, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x01, 0x18, 0x63, 0x6f, 0x6d, 0x70, 0x69, + 0x6c, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x01, + 0x1c, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x01, + 0x0a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x01, 0x0e, + 0x65, 0x78, 0x65, 0x50, 0x61, 0x74, 0x68, 0x01, + 0x0a, 0x61, 0x72, 0x67, 0x76, 0x30, 0x01, 0x0c, + 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x01, 0x36, + 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x20, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x3a, 0x20, 0x01, 0x0c, 0x62, 0x75, 0x66, + 0x66, 0x65, 0x72, 0x01, 0x10, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x65, 0x72, 0x01, 0x08, 0x53, + 0x69, 0x7a, 0x65, 0x01, 0x0a, 0x4d, 0x61, 0x67, + 0x69, 0x63, 0x01, 0x12, 0x4d, 0x61, 0x67, 0x69, + 0x63, 0x53, 0x69, 0x7a, 0x65, 0x01, 0x10, 0x44, + 0x61, 0x74, 0x61, 0x53, 0x69, 0x7a, 0x65, 0x01, + 0x12, 0x73, 0x65, 0x74, 0x55, 0x69, 0x6e, 0x74, + 0x33, 0x32, 0x01, 0x08, 0x6f, 0x70, 0x65, 0x6e, + 0x01, 0x10, 0x4f, 0x5f, 0x57, 0x52, 0x4f, 0x4e, + 0x4c, 0x59, 0x01, 0x0e, 0x4f, 0x5f, 0x43, 0x52, + 0x45, 0x41, 0x54, 0x01, 0x0e, 0x4f, 0x5f, 0x54, + 0x52, 0x55, 0x4e, 0x43, 0x01, 0x22, 0x66, 0x61, + 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x01, + 0x14, 0x62, 0x79, 0x74, 0x65, 0x4c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x01, 0x0a, 0x63, 0x6c, 0x6f, + 0x73, 0x65, 0x01, 0x3c, 0x66, 0x61, 0x69, 0x6c, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x72, + 0x69, 0x74, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x66, 0x69, + 0x6c, 0x65, 0x01, 0x08, 0x66, 0x69, 0x6c, 0x65, + 0x01, 0x02, 0x72, 0x01, 0x0e, 0x74, 0x72, 0x61, + 0x69, 0x6c, 0x65, 0x72, 0x01, 0x0a, 0x6d, 0x61, + 0x67, 0x69, 0x63, 0x01, 0x16, 0x62, 0x79, 0x74, + 0x65, 0x63, 0x6f, 0x64, 0x65, 0x6c, 0x65, 0x6e, + 0x01, 0x04, 0x72, 0x62, 0x01, 0x08, 0x73, 0x65, + 0x65, 0x6b, 0x01, 0x10, 0x53, 0x45, 0x45, 0x4b, + 0x5f, 0x45, 0x4e, 0x44, 0x01, 0x18, 0x73, 0x65, + 0x65, 0x6b, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x3a, 0x20, 0x01, 0x08, 0x72, 0x65, 0x61, 0x64, + 0x01, 0x40, 0x63, 0x6f, 0x72, 0x72, 0x75, 0x70, + 0x74, 0x65, 0x64, 0x20, 0x62, 0x69, 0x6e, 0x61, + 0x72, 0x79, 0x2c, 0x20, 0x6d, 0x61, 0x67, 0x69, + 0x63, 0x20, 0x6d, 0x69, 0x73, 0x6d, 0x61, 0x74, + 0x63, 0x68, 0x01, 0x12, 0x67, 0x65, 0x74, 0x55, + 0x69, 0x6e, 0x74, 0x33, 0x32, 0x01, 0x14, 0x72, + 0x65, 0x61, 0x64, 0x20, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x01, 0x16, 0x65, 0x76, 0x61, 0x6c, 0x5f, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x01, 0x10, + 0x71, 0x75, 0x69, 0x63, 0x6b, 0x6a, 0x73, 0x32, + 0x0d, 0xe2, 0x03, 0x03, 0xe4, 0x03, 0xe6, 0x03, + 0xe8, 0x03, 0x02, 0x00, 0x0b, 0xea, 0x03, 0x00, + 0x0c, 0xec, 0x03, 0x00, 0x03, 0x00, 0x8c, 0x02, + 0x00, 0x01, 0x8c, 0x02, 0x01, 0x02, 0x8c, 0x02, + 0x02, 0x00, 0x0c, 0x20, 0x02, 0x01, 0xa8, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x0d, 0x04, 0x58, + 0x00, 0xee, 0x03, 0x00, 0x1e, 0xf0, 0x03, 0x01, + 0x1e, 0xf2, 0x03, 0x02, 0x1e, 0xf4, 0x03, 0x00, + 0x1e, 0xf6, 0x03, 0x01, 0x1e, 0xf8, 0x03, 0x02, + 0x1e, 0xfa, 0x03, 0x03, 0x1e, 0xfc, 0x03, 0x04, + 0x1e, 0xfe, 0x03, 0x05, 0x1e, 0x80, 0x04, 0x06, + 0x06, 0x82, 0x04, 0x07, 0x06, 0xea, 0x03, 0x08, + 0x06, 0xec, 0x03, 0x09, 0x06, 0x0c, 0x43, 0x02, + 0x01, 0x80, 0x04, 0x01, 0x00, 0x01, 0x05, 0x00, + 0x00, 0x01, 0x1e, 0x01, 0x84, 0x04, 0x00, 0x01, + 0x00, 0x0c, 0x42, 0x02, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x03, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x86, + 0x04, 0x00, 0x01, 0x00, 0xd7, 0x41, 0x04, 0x01, + 0x00, 0x00, 0xba, 0x25, 0x01, 0x00, 0x38, 0xb0, + 0x00, 0x00, 0x00, 0x11, 0xd7, 0x41, 0x64, 0x00, + 0x00, 0x00, 0xc6, 0x24, 0x01, 0x00, 0x41, 0x05, + 0x01, 0x00, 0x00, 0xc5, 0x00, 0x24, 0x01, 0x00, + 0x21, 0x01, 0x00, 0x28, 0x0c, 0x43, 0x02, 0x01, + 0x82, 0x04, 0x01, 0x00, 0x01, 0x03, 0x00, 0x00, + 0x01, 0x21, 0x01, 0x8c, 0x04, 0x00, 0x01, 0x00, + 0x0c, 0x42, 0x02, 0x01, 0x00, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x00, 0x00, 0x0e, 0x01, 0x86, 0x04, + 0x00, 0x01, 0x00, 0x38, 0xa1, 0x00, 0x00, 0x00, + 0x41, 0x07, 0x01, 0x00, 0x00, 0xd7, 0x25, 0x01, + 0x00, 0x38, 0x9e, 0x00, 0x00, 0x00, 0x41, 0x82, + 0x00, 0x00, 0x00, 0xd7, 0x24, 0x01, 0x00, 0x41, + 0x05, 0x01, 0x00, 0x00, 0xc5, 0x00, 0x24, 0x01, + 0x00, 0x41, 0x63, 0x00, 0x00, 0x00, 0xc6, 0x25, + 0x01, 0x00, 0x0c, 0x43, 0x02, 0x01, 0xea, 0x03, + 0x03, 0x0a, 0x03, 0x07, 0x00, 0x08, 0x00, 0x83, + 0x04, 0x0d, 0x90, 0x04, 0x00, 0x01, 0x00, 0x92, + 0x04, 0x00, 0x01, 0x00, 0x94, 0x04, 0x00, 0x01, + 0x00, 0x96, 0x04, 0x01, 0x00, 0x30, 0x98, 0x04, + 0x01, 0x01, 0x30, 0x9a, 0x04, 0x01, 0x02, 0x30, + 0x9c, 0x04, 0x01, 0x03, 0x30, 0x9e, 0x04, 0x01, + 0x04, 0x30, 0xa0, 0x04, 0x01, 0x05, 0x30, 0xa2, + 0x04, 0x01, 0x06, 0x30, 0xa4, 0x04, 0x01, 0x07, + 0x30, 0xa6, 0x04, 0x01, 0x08, 0x30, 0xa8, 0x04, + 0x01, 0x09, 0x30, 0xee, 0x03, 0x00, 0x1a, 0xf2, + 0x03, 0x02, 0x1a, 0xf8, 0x03, 0x05, 0x1a, 0xfa, + 0x03, 0x06, 0x1a, 0xfc, 0x03, 0x07, 0x1a, 0xf0, + 0x03, 0x01, 0x1a, 0xfe, 0x03, 0x08, 0x1a, 0x80, + 0x04, 0x09, 0x02, 0x60, 0x09, 0x00, 0x60, 0x08, + 0x00, 0x60, 0x07, 0x00, 0x60, 0x06, 0x00, 0x60, + 0x05, 0x00, 0x60, 0x04, 0x00, 0x60, 0x03, 0x00, + 0x60, 0x02, 0x00, 0x60, 0x01, 0x00, 0x60, 0x00, + 0x00, 0x64, 0x00, 0x00, 0x41, 0x15, 0x01, 0x00, + 0x00, 0xd7, 0x24, 0x01, 0x00, 0xcf, 0x61, 0x00, + 0x00, 0xf1, 0x13, 0x38, 0x9f, 0x00, 0x00, 0x00, + 0x11, 0x04, 0x16, 0x01, 0x00, 0x00, 0xd7, 0x71, + 0x9c, 0x21, 0x01, 0x00, 0x30, 0x64, 0x00, 0x00, + 0x41, 0x17, 0x01, 0x00, 0x00, 0x61, 0x00, 0x00, + 0x0b, 0x0a, 0x4b, 0x18, 0x01, 0x00, 0x00, 0x0a, + 0x4b, 0x19, 0x01, 0x00, 0x00, 0x24, 0x02, 0x00, + 0xd0, 0x38, 0xb0, 0x00, 0x00, 0x00, 0x11, 0x64, + 0x01, 0x00, 0x41, 0x1a, 0x01, 0x00, 0x00, 0x61, + 0x01, 0x00, 0x64, 0x02, 0x00, 0x64, 0x03, 0x00, + 0xa3, 0x64, 0x04, 0x00, 0xa3, 0x24, 0x02, 0x00, + 0x21, 0x01, 0x00, 0xd1, 0xd9, 0x11, 0xaf, 0xf0, + 0x1c, 0x0e, 0x64, 0x05, 0x00, 0x41, 0x1b, 0x01, + 0x00, 0x00, 0x24, 0x00, 0x00, 0x11, 0xaf, 0xf0, + 0x0c, 0x0e, 0x38, 0x94, 0x00, 0x00, 0x00, 0x40, + 0x1c, 0x01, 0x00, 0x00, 0xd2, 0x64, 0x00, 0x00, + 0x41, 0x15, 0x01, 0x00, 0x00, 0x61, 0x03, 0x00, + 0x0b, 0x0a, 0x4b, 0x1d, 0x01, 0x00, 0x00, 0x24, + 0x02, 0x00, 0xc8, 0x04, 0x61, 0x04, 0x00, 0xf1, + 0x15, 0x38, 0x9f, 0x00, 0x00, 0x00, 0x11, 0x04, + 0x1e, 0x01, 0x00, 0x00, 0x61, 0x03, 0x00, 0x71, + 0x9c, 0x21, 0x01, 0x00, 0x30, 0x61, 0x04, 0x00, + 0xef, 0xc8, 0x05, 0x61, 0x04, 0x00, 0x40, 0x1f, + 0x01, 0x00, 0x00, 0x41, 0x20, 0x01, 0x00, 0x00, + 0x61, 0x05, 0x00, 0x61, 0x02, 0x00, 0xef, 0x9c, + 0x64, 0x06, 0x00, 0x40, 0x21, 0x01, 0x00, 0x00, + 0x9c, 0x24, 0x01, 0x00, 0xc8, 0x06, 0x38, 0xb0, + 0x00, 0x00, 0x00, 0x11, 0x61, 0x06, 0x00, 0x21, + 0x01, 0x00, 0xc8, 0x07, 0x61, 0x07, 0x00, 0x41, + 0x46, 0x00, 0x00, 0x00, 0x61, 0x02, 0x00, 0x61, + 0x05, 0x00, 0x24, 0x02, 0x00, 0x0e, 0x61, 0x07, + 0x00, 0x41, 0x46, 0x00, 0x00, 0x00, 0x5d, 0x07, + 0x00, 0x64, 0x06, 0x00, 0x40, 0x22, 0x01, 0x00, + 0x00, 0xf5, 0x61, 0x05, 0x00, 0x61, 0x02, 0x00, + 0xef, 0x9c, 0x24, 0x02, 0x00, 0x0e, 0x38, 0xba, + 0x00, 0x00, 0x00, 0x11, 0x61, 0x06, 0x00, 0x61, + 0x05, 0x00, 0x61, 0x02, 0x00, 0xef, 0x9c, 0x64, + 0x06, 0x00, 0x40, 0x23, 0x01, 0x00, 0x00, 0x9c, + 0x64, 0x06, 0x00, 0x40, 0x24, 0x01, 0x00, 0x00, + 0x21, 0x03, 0x00, 0xc8, 0x08, 0x61, 0x08, 0x00, + 0x41, 0x25, 0x01, 0x00, 0x00, 0xba, 0x61, 0x02, + 0x00, 0xef, 0x0a, 0x24, 0x03, 0x00, 0x0e, 0x64, + 0x05, 0x00, 0x41, 0x26, 0x01, 0x00, 0x00, 0xd8, + 0x64, 0x05, 0x00, 0x40, 0x27, 0x01, 0x00, 0x00, + 0x64, 0x05, 0x00, 0x40, 0x28, 0x01, 0x00, 0x00, + 0xa3, 0x64, 0x05, 0x00, 0x40, 0x29, 0x01, 0x00, + 0x00, 0xa3, 0xc3, 0xed, 0x01, 0x24, 0x03, 0x00, + 0xc8, 0x09, 0x61, 0x09, 0x00, 0xba, 0xa5, 0xf0, + 0x13, 0x38, 0x9f, 0x00, 0x00, 0x00, 0x11, 0x04, + 0x2a, 0x01, 0x00, 0x00, 0xd8, 0x71, 0x9c, 0x21, + 0x01, 0x00, 0x30, 0x64, 0x05, 0x00, 0x41, 0x1a, + 0x01, 0x00, 0x00, 0x61, 0x09, 0x00, 0x61, 0x06, + 0x00, 0xba, 0x61, 0x06, 0x00, 0x40, 0x2b, 0x01, + 0x00, 0x00, 0x24, 0x04, 0x00, 0xba, 0xa5, 0xf0, + 0x1f, 0x64, 0x05, 0x00, 0x41, 0x2c, 0x01, 0x00, + 0x00, 0x61, 0x09, 0x00, 0x24, 0x01, 0x00, 0x0e, + 0x38, 0x9f, 0x00, 0x00, 0x00, 0x11, 0x04, 0x2d, + 0x01, 0x00, 0x00, 0x21, 0x01, 0x00, 0x30, 0x64, + 0x05, 0x00, 0x41, 0x2c, 0x01, 0x00, 0x00, 0x61, + 0x09, 0x00, 0x24, 0x01, 0x00, 0x29, 0x0c, 0x43, + 0x02, 0x01, 0xec, 0x03, 0x00, 0x09, 0x00, 0x07, + 0x00, 0x07, 0x00, 0xa2, 0x04, 0x09, 0xdc, 0x04, + 0x01, 0x00, 0x30, 0x9e, 0x04, 0x01, 0x01, 0x30, + 0xde, 0x04, 0x01, 0x02, 0x20, 0xe0, 0x04, 0x01, + 0x03, 0x30, 0xe2, 0x04, 0x01, 0x04, 0x30, 0xa6, + 0x04, 0x01, 0x05, 0x30, 0xe4, 0x04, 0x01, 0x06, + 0x30, 0x9a, 0x04, 0x01, 0x07, 0x30, 0x98, 0x04, + 0x01, 0x08, 0x30, 0xf0, 0x03, 0x01, 0x1a, 0xee, + 0x03, 0x00, 0x1a, 0xfe, 0x03, 0x08, 0x1a, 0x82, + 0x04, 0x0a, 0x02, 0xf2, 0x03, 0x02, 0x1a, 0xf4, + 0x03, 0x03, 0x1a, 0xf6, 0x03, 0x04, 0x1a, 0x60, + 0x08, 0x00, 0x60, 0x07, 0x00, 0x60, 0x06, 0x00, + 0x60, 0x05, 0x00, 0x60, 0x04, 0x00, 0x60, 0x03, + 0x00, 0x60, 0x02, 0x00, 0x60, 0x01, 0x00, 0x60, + 0x00, 0x00, 0x64, 0x00, 0x00, 0x41, 0x1b, 0x01, + 0x00, 0x00, 0x24, 0x00, 0x00, 0x11, 0xaf, 0xf0, + 0x0c, 0x0e, 0x38, 0x94, 0x00, 0x00, 0x00, 0x40, + 0x1c, 0x01, 0x00, 0x00, 0xcf, 0x64, 0x01, 0x00, + 0x41, 0x26, 0x01, 0x00, 0x00, 0x61, 0x00, 0x00, + 0x04, 0x33, 0x01, 0x00, 0x00, 0x24, 0x02, 0x00, + 0xd0, 0x61, 0x01, 0x00, 0xf1, 0x15, 0x38, 0x9f, + 0x00, 0x00, 0x00, 0x11, 0x04, 0x1e, 0x01, 0x00, + 0x00, 0x61, 0x00, 0x00, 0x71, 0x9c, 0x21, 0x01, + 0x00, 0x30, 0x61, 0x01, 0x00, 0x41, 0x34, 0x01, + 0x00, 0x00, 0x64, 0x02, 0x00, 0x40, 0x21, 0x01, + 0x00, 0x00, 0x8b, 0x64, 0x01, 0x00, 0x40, 0x35, + 0x01, 0x00, 0x00, 0x24, 0x02, 0x00, 0xd1, 0x61, + 0x02, 0x00, 0xba, 0xa5, 0xf0, 0x16, 0x38, 0x9f, + 0x00, 0x00, 0x00, 0x11, 0x04, 0x36, 0x01, 0x00, + 0x00, 0x61, 0x02, 0x00, 0x8b, 0x71, 0x9c, 0x21, + 0x01, 0x00, 0x30, 0x38, 0xb0, 0x00, 0x00, 0x00, + 0x11, 0x64, 0x02, 0x00, 0x40, 0x21, 0x01, 0x00, + 0x00, 0x21, 0x01, 0x00, 0xd2, 0x61, 0x01, 0x00, + 0x41, 0x37, 0x01, 0x00, 0x00, 0x61, 0x03, 0x00, + 0x40, 0x1f, 0x01, 0x00, 0x00, 0xba, 0x64, 0x02, + 0x00, 0x40, 0x21, 0x01, 0x00, 0x00, 0x24, 0x03, + 0x00, 0x0e, 0x38, 0xb0, 0x00, 0x00, 0x00, 0x11, + 0x61, 0x03, 0x00, 0x40, 0x1f, 0x01, 0x00, 0x00, + 0xba, 0x64, 0x02, 0x00, 0x40, 0x23, 0x01, 0x00, + 0x00, 0x21, 0x03, 0x00, 0xc8, 0x04, 0xe6, 0x61, + 0x04, 0x00, 0xf5, 0x64, 0x02, 0x00, 0x40, 0x22, + 0x01, 0x00, 0x00, 0xae, 0xf0, 0x1c, 0x61, 0x01, + 0x00, 0x41, 0x2c, 0x01, 0x00, 0x00, 0x24, 0x00, + 0x00, 0x0e, 0x38, 0x9f, 0x00, 0x00, 0x00, 0x11, + 0x04, 0x38, 0x01, 0x00, 0x00, 0x21, 0x01, 0x00, + 0x30, 0x38, 0xba, 0x00, 0x00, 0x00, 0x11, 0x61, + 0x03, 0x00, 0x40, 0x1f, 0x01, 0x00, 0x00, 0x64, + 0x02, 0x00, 0x40, 0x23, 0x01, 0x00, 0x00, 0x64, + 0x02, 0x00, 0x40, 0x24, 0x01, 0x00, 0x00, 0x21, + 0x03, 0x00, 0xc8, 0x05, 0x61, 0x05, 0x00, 0x41, + 0x39, 0x01, 0x00, 0x00, 0xba, 0x0a, 0x24, 0x02, + 0x00, 0xc8, 0x06, 0x38, 0xb0, 0x00, 0x00, 0x00, + 0x11, 0x61, 0x06, 0x00, 0x21, 0x01, 0x00, 0xc8, + 0x07, 0x61, 0x01, 0x00, 0x41, 0x34, 0x01, 0x00, + 0x00, 0x61, 0x06, 0x00, 0x64, 0x02, 0x00, 0x40, + 0x21, 0x01, 0x00, 0x00, 0x9c, 0x8b, 0x64, 0x01, + 0x00, 0x40, 0x35, 0x01, 0x00, 0x00, 0x24, 0x02, + 0x00, 0x11, 0x62, 0x02, 0x00, 0x0e, 0x61, 0x02, + 0x00, 0xba, 0xa5, 0xf0, 0x22, 0x61, 0x01, 0x00, + 0x41, 0x2c, 0x01, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x0e, 0x38, 0x9f, 0x00, 0x00, 0x00, 0x11, 0x04, + 0x36, 0x01, 0x00, 0x00, 0x61, 0x02, 0x00, 0x8b, + 0x71, 0x9c, 0x21, 0x01, 0x00, 0x30, 0x61, 0x01, + 0x00, 0x41, 0x37, 0x01, 0x00, 0x00, 0x61, 0x07, + 0x00, 0x40, 0x1f, 0x01, 0x00, 0x00, 0xba, 0x61, + 0x07, 0x00, 0xef, 0x24, 0x03, 0x00, 0x0e, 0x61, + 0x01, 0x00, 0x41, 0x37, 0x00, 0x00, 0x00, 0x24, + 0x00, 0x00, 0xf0, 0x1c, 0x61, 0x01, 0x00, 0x41, + 0x2c, 0x01, 0x00, 0x00, 0x24, 0x00, 0x00, 0x0e, + 0x38, 0x9f, 0x00, 0x00, 0x00, 0x11, 0x04, 0x3a, + 0x01, 0x00, 0x00, 0x21, 0x01, 0x00, 0x30, 0x61, + 0x01, 0x00, 0x41, 0x2c, 0x01, 0x00, 0x00, 0x24, + 0x00, 0x00, 0x0e, 0x64, 0x04, 0x00, 0x41, 0x37, + 0x01, 0x00, 0x00, 0x61, 0x07, 0x00, 0x40, 0x1f, + 0x01, 0x00, 0x00, 0xba, 0x61, 0x07, 0x00, 0xef, + 0x64, 0x05, 0x00, 0x64, 0x06, 0x00, 0xa3, 0x24, + 0x04, 0x00, 0xc8, 0x08, 0x64, 0x01, 0x00, 0x41, + 0x17, 0x01, 0x00, 0x00, 0x61, 0x08, 0x00, 0x0b, + 0x0a, 0x4b, 0x3b, 0x01, 0x00, 0x00, 0x25, 0x02, + 0x00, 0x08, 0xf0, 0x16, 0xc5, 0x00, 0x5e, 0x09, + 0x00, 0xc5, 0x01, 0x5e, 0x0a, 0x00, 0xc5, 0x02, + 0x5e, 0x0b, 0x00, 0xc5, 0x03, 0x5e, 0x0c, 0x00, + 0x29, 0xbb, 0xba, 0x9e, 0xea, 0xbb, 0xbd, 0x9e, + 0x5e, 0x04, 0x00, 0xbb, 0xba, 0x9e, 0x5e, 0x05, + 0x00, 0xbb, 0xbd, 0x9e, 0x5e, 0x06, 0x00, 0xbb, + 0xbe, 0x9e, 0x5e, 0x07, 0x00, 0x0b, 0x04, 0x3c, + 0x01, 0x00, 0x00, 0x4b, 0x22, 0x01, 0x00, 0x00, + 0xc2, 0x08, 0x4b, 0x23, 0x01, 0x00, 0x00, 0xbe, + 0x4b, 0x24, 0x01, 0x00, 0x00, 0xc2, 0x0c, 0x4b, + 0x21, 0x01, 0x00, 0x00, 0x5e, 0x08, 0x00, 0x06, + 0x2f, +}; + diff --git a/userland/qjs/source/gen/test_fib.c b/userland/qjs/source/gen/test_fib.c new file mode 100644 index 0000000..908312c --- /dev/null +++ b/userland/qjs/source/gen/test_fib.c @@ -0,0 +1,81 @@ +/* File generated automatically by the QuickJS-ng compiler. */ + +#include "quickjs-libc.h" + +const uint32_t qjsc_test_fib_size = 298; + +const uint8_t qjsc_test_fib[298] = { + 0x1d, 0xd1, 0xe5, 0x84, 0x0c, 0x0e, 0x01, 0x28, + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, + 0x2f, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x66, 0x69, + 0x62, 0x2e, 0x6a, 0x73, 0x01, 0x0c, 0x71, 0x6a, + 0x73, 0x3a, 0x6f, 0x73, 0x01, 0x04, 0x6f, 0x73, + 0x01, 0x0a, 0x69, 0x73, 0x57, 0x69, 0x6e, 0x01, + 0x06, 0x66, 0x69, 0x62, 0x01, 0x10, 0x70, 0x6c, + 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x01, 0x0a, + 0x77, 0x69, 0x6e, 0x33, 0x32, 0x01, 0x0c, 0x2e, + 0x2f, 0x66, 0x69, 0x62, 0x2e, 0x01, 0x06, 0x64, + 0x6c, 0x6c, 0x01, 0x04, 0x73, 0x6f, 0x01, 0x0e, + 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x01, + 0x06, 0x6c, 0x6f, 0x67, 0x01, 0x16, 0x48, 0x65, + 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, + 0x64, 0x01, 0x10, 0x66, 0x69, 0x62, 0x28, 0x31, + 0x30, 0x29, 0x3d, 0x0d, 0xe2, 0x03, 0x01, 0xe4, + 0x03, 0x00, 0x00, 0x01, 0x00, 0x8c, 0x02, 0x00, + 0x01, 0x0c, 0x20, 0x0a, 0x01, 0xa8, 0x01, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x6e, 0x00, + 0xe6, 0x03, 0x00, 0x1e, 0xe8, 0x03, 0x00, 0x1e, + 0xea, 0x03, 0x01, 0x1e, 0x08, 0xf0, 0x02, 0x29, + 0x64, 0x00, 0x00, 0x40, 0xf6, 0x00, 0x00, 0x00, + 0x04, 0xf7, 0x00, 0x00, 0x00, 0xad, 0xe8, 0x06, + 0x11, 0xf8, 0xf1, 0x0b, 0x70, 0x41, 0xf5, 0x00, + 0x00, 0x00, 0xe9, 0x0e, 0xf2, 0x1f, 0x0e, 0x04, + 0xf8, 0x00, 0x00, 0x00, 0x64, 0x01, 0x00, 0xf0, + 0x08, 0x04, 0xf9, 0x00, 0x00, 0x00, 0xf2, 0x06, + 0x04, 0xfa, 0x00, 0x00, 0x00, 0x71, 0x9c, 0x06, + 0x36, 0x8a, 0xf2, 0xd9, 0x38, 0xfb, 0x00, 0x00, + 0x00, 0x41, 0xfc, 0x00, 0x00, 0x00, 0x04, 0xfd, + 0x00, 0x00, 0x00, 0x24, 0x01, 0x00, 0x0e, 0x38, + 0xfb, 0x00, 0x00, 0x00, 0x41, 0xfc, 0x00, 0x00, + 0x00, 0x04, 0xfe, 0x00, 0x00, 0x00, 0x64, 0x02, + 0x00, 0xc2, 0x0a, 0xf5, 0x24, 0x02, 0x00, 0x0e, + 0x06, 0x2f, 0xe2, 0x03, 0x01, 0x01, 0x12, 0x19, + 0x1c, 0x2a, 0x20, 0x8f, 0x10, 0x66, 0x1f, 0x18, + 0x2b, 0x34, 0x10, 0x30, 0x0f, 0x34, 0x10, 0x1b, + 0x20, 0x00, +}; + +static JSContext *JS_NewCustomContext(JSRuntime *rt) +{ + JSContext *ctx = JS_NewContext(rt); + if (!ctx) + return NULL; + { + extern JSModuleDef *js_init_module_os(JSContext *ctx, const char *name); + js_init_module_os(ctx, "qjs:os"); + } + return ctx; +} + +int main(int argc, char **argv) +{ + int r; + JSRuntime *rt; + JSContext *ctx; + r = 0; + rt = JS_NewRuntime(); + js_std_set_worker_new_context_func(JS_NewCustomContext); + js_std_init_handlers(rt); + JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader, js_module_check_attributes, NULL); + ctx = JS_NewCustomContext(rt); + js_std_add_helpers(ctx, argc, argv); + js_std_eval_binary(ctx, qjsc_test_fib, qjsc_test_fib_size, 0); + r = js_std_loop(ctx); + if (r) { + js_std_dump_error(ctx); + } + js_std_free_handlers(rt); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + return r; +} diff --git a/userland/qjs/source/libregexp-opcode.h b/userland/qjs/source/libregexp-opcode.h new file mode 100644 index 0000000..b3d7b6f --- /dev/null +++ b/userland/qjs/source/libregexp-opcode.h @@ -0,0 +1,73 @@ +/* + * Regular Expression Engine + * + * Copyright (c) 2017-2018 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifdef DEF + +DEF(invalid, 1) /* never used */ +DEF(char, 3) +DEF(char_i, 3) +DEF(char32, 5) +DEF(char32_i, 5) +DEF(dot, 1) +DEF(any, 1) /* same as dot but match any character including line terminator */ +DEF(space, 1) +DEF(not_space, 1) /* must come after */ +DEF(line_start, 1) +DEF(line_start_m, 1) +DEF(line_end, 1) +DEF(line_end_m, 1) +DEF(goto, 5) +DEF(split_goto_first, 5) +DEF(split_next_first, 5) +DEF(match, 1) +DEF(lookahead_match, 1) +DEF(negative_lookahead_match, 1) /* must come after */ +DEF(save_start, 2) /* save start position */ +DEF(save_end, 2) /* save end position, must come after saved_start */ +DEF(save_reset, 3) /* reset save positions */ +DEF(loop, 6) /* decrement the top the stack and goto if != 0 */ +DEF(loop_split_goto_first, 10) /* loop and then split */ +DEF(loop_split_next_first, 10) +DEF(loop_check_adv_split_goto_first, 10) /* loop and then check advance and split */ +DEF(loop_check_adv_split_next_first, 10) +DEF(set_i32, 6) /* store the immediate value to a register */ +DEF(word_boundary, 1) +DEF(word_boundary_i, 1) +DEF(not_word_boundary, 1) +DEF(not_word_boundary_i, 1) +DEF(back_reference, 2) /* variable length */ +DEF(back_reference_i, 2) /* must come after */ +DEF(backward_back_reference, 2) /* must come after */ +DEF(backward_back_reference_i, 2) /* must come after */ +DEF(range, 3) /* variable length */ +DEF(range_i, 3) /* variable length */ +DEF(range32, 3) /* variable length */ +DEF(range32_i, 3) /* variable length */ +DEF(lookahead, 5) +DEF(negative_lookahead, 5) /* must come after */ +DEF(set_char_pos, 2) /* store the character position to a register */ +DEF(check_advance, 2) /* check that the register is different from the character position */ +DEF(prev, 1) /* go to the previous char */ + +#endif /* DEF */ diff --git a/userland/qjs/source/libregexp.c b/userland/qjs/source/libregexp.c new file mode 100644 index 0000000..49c474c --- /dev/null +++ b/userland/qjs/source/libregexp.c @@ -0,0 +1,3522 @@ +/* + * Regular Expression Engine + * + * Copyright (c) 2017-2018 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include "cutils.h" +#include "libregexp.h" +#include "libunicode.h" + +/* ASCII identifier tables, used by lre_js_is_ident_first/next in libregexp.h + and by quickjs.c. */ +uint32_t const lre_id_start_table_ascii[4] = { + /* $ A-Z _ a-z */ + 0x00000000, 0x00000010, 0x87FFFFFE, 0x07FFFFFE +}; + +uint32_t const lre_id_continue_table_ascii[4] = { + /* $ 0-9 A-Z _ a-z */ + 0x00000000, 0x03FF0010, 0x87FFFFFE, 0x07FFFFFE +}; + +/* + TODO: + - remove REOP_char_i and REOP_range_i by precomputing the case folding. + - add specific opcodes for simple unicode property tests so that the + generated bytecode is smaller. + - Add a lock step execution mode (=linear time execution guaranteed) + when the regular expression is "simple" i.e. no backreference nor + complicated lookahead. The opcodes are designed for this execution + model. +*/ + +#if defined(TEST) +#define DUMP_REOP +#endif +//#define DUMP_REOP +//#define DUMP_EXEC + +typedef enum { +#define DEF(id, size) REOP_ ## id, +#include "libregexp-opcode.h" +#undef DEF + REOP_COUNT, +} REOPCodeEnum; + +#define CAPTURE_COUNT_MAX 255 +#define REGISTER_COUNT_MAX 255 +#define GROUP_NAME_SCOPE_MAX 255 +/* must be large enough to have a negligible runtime cost and small + enough to call the interrupt callback often. */ +#define INTERRUPT_COUNTER_INIT 10000 + +/* unicode code points */ +#define CP_LS 0x2028 +#define CP_PS 0x2029 + +#define TMP_BUF_SIZE 128 + +typedef struct { + DynBuf byte_code; + const uint8_t *buf_ptr; + const uint8_t *buf_end; + const uint8_t *buf_start; + int re_flags; + bool is_unicode; + bool unicode_sets; /* if set, is_unicode is also set */ + bool ignore_case; + bool multi_line; + bool dotall; + uint8_t group_name_scope; + int capture_count; + int total_capture_count; /* -1 = not computed yet */ + int has_named_captures; /* -1 = don't know, 0 = no, 1 = yes */ + void *opaque; + DynBuf group_names; + union { + char error_msg[TMP_BUF_SIZE]; + char tmp_buf[TMP_BUF_SIZE]; + } u; +} REParseState; + +typedef struct { +#ifdef DUMP_REOP + const char *name; +#endif + uint8_t size; +} REOpCode; + +static const REOpCode reopcode_info[REOP_COUNT] = { +#ifdef DUMP_REOP +#define DEF(id, size) { #id, size }, +#else +#define DEF(id, size) { size }, +#endif +#include "libregexp-opcode.h" +#undef DEF +}; + +#define RE_HEADER_FLAGS 0 +#define RE_HEADER_CAPTURE_COUNT 2 +#define RE_HEADER_REGISTER_COUNT 3 +#define RE_HEADER_BYTECODE_LEN 4 + +#define RE_HEADER_LEN 8 + +static inline int lre_is_digit(int c) { + return c >= '0' && c <= '9'; +} + +/* insert 'len' bytes at position 'pos'. Return < 0 if error. */ +static int dbuf_insert(DynBuf *s, int pos, int len) +{ + if (dbuf_claim(s, len)) + return -1; + memmove(s->buf + pos + len, s->buf + pos, s->size - pos); + s->size += len; + return 0; +} + +typedef struct REString { + struct REString *next; + uint32_t hash; + uint32_t len; + uint32_t buf[]; +} REString; + +typedef struct { + /* the string list is the union of 'char_range' and of the strings + in hash_table[]. The strings in hash_table[] have a length != + 1. */ + CharRange cr; + uint32_t n_strings; + uint32_t hash_size; + int hash_bits; + REString **hash_table; +} REStringList; + +static uint32_t re_string_hash(int len, const uint32_t *buf) +{ + int i; + uint32_t h; + h = 1; + for(i = 0; i < len; i++) + h = h * 263 + buf[i]; + return hash32(h); +} + +static void re_string_list_init(REParseState *s1, REStringList *s) +{ + cr_init(&s->cr, s1->opaque, lre_realloc); + s->n_strings = 0; + s->hash_size = 0; + s->hash_bits = 0; + s->hash_table = NULL; +} + +static void re_string_list_free(REStringList *s) +{ + REString *p, *p_next; + int i; + for(i = 0; i < s->hash_size; i++) { + for(p = s->hash_table[i]; p != NULL; p = p_next) { + p_next = p->next; + lre_realloc(s->cr.mem_opaque, p, 0); + } + } + lre_realloc(s->cr.mem_opaque, s->hash_table, 0); + + cr_free(&s->cr); +} + +#ifdef DUMP_REOP +static void lre_print_char(int c, bool is_range) +{ + if (c == '\'' || c == '\\' || + (is_range && (c == '-' || c == ']'))) { + printf("\\%c", c); + } else if (c >= ' ' && c <= 126) { + printf("%c", c); + } else { + printf("\\u{%04x}", c); + } +} + +static __maybe_unused void re_string_list_dump(const char *str, const REStringList *s) +{ + REString *p; + const CharRange *cr; + int i, j, k; + + printf("%s:\n", str); + printf(" ranges: ["); + cr = &s->cr; + for(i = 0; i < cr->len; i += 2) { + lre_print_char(cr->points[i], true); + if (cr->points[i] != cr->points[i + 1] - 1) { + printf("-"); + lre_print_char(cr->points[i + 1] - 1, true); + } + } + printf("]\n"); + + j = 0; + for(i = 0; i < s->hash_size; i++) { + for(p = s->hash_table[i]; p != NULL; p = p->next) { + printf(" %d/%d: '", j, s->n_strings); + for(k = 0; k < p->len; k++) { + lre_print_char(p->buf[k], false); + } + printf("'\n"); + j++; + } + } +} +#endif /* DUMP_REOP */ + +/* 'buf' is NULL if 'len' is zero: the empty string is a valid member of a + string set, e.g. /[\q{}]/v */ +static int re_string_find2(REStringList *s, int len, const uint32_t *buf, + uint32_t h0, bool add_flag) +{ + uint32_t h = 0; /* avoid warning */ + REString *p; + if (s->n_strings != 0) { + h = h0 >> (32 - s->hash_bits); + for(p = s->hash_table[h]; p != NULL; p = p->next) { + if (p->hash == h0 && p->len == len && + (len == 0 || + !memcmp(p->buf, buf, len * sizeof(buf[0])))) { + return 1; + } + } + } + /* not found */ + if (!add_flag) + return 0; + /* increase the size of the hash table if needed */ + if (unlikely((s->n_strings + 1) > s->hash_size)) { + REString **new_hash_table, *p_next; + int new_hash_bits, i; + uint32_t new_hash_size; + new_hash_bits = max_int(s->hash_bits + 1, 4); + new_hash_size = 1 << new_hash_bits; + new_hash_table = lre_realloc(s->cr.mem_opaque, NULL, + sizeof(new_hash_table[0]) * new_hash_size); + if (!new_hash_table) + return -1; + memset(new_hash_table, 0, sizeof(new_hash_table[0]) * new_hash_size); + for(i = 0; i < s->hash_size; i++) { + for(p = s->hash_table[i]; p != NULL; p = p_next) { + p_next = p->next; + h = p->hash >> (32 - new_hash_bits); + p->next = new_hash_table[h]; + new_hash_table[h] = p; + } + } + lre_realloc(s->cr.mem_opaque, s->hash_table, 0); + s->hash_bits = new_hash_bits; + s->hash_size = new_hash_size; + s->hash_table = new_hash_table; + h = h0 >> (32 - s->hash_bits); + } + + p = lre_realloc(s->cr.mem_opaque, NULL, sizeof(REString) + len * sizeof(buf[0])); + if (!p) + return -1; + p->next = s->hash_table[h]; + s->hash_table[h] = p; + s->n_strings++; + p->hash = h0; + p->len = len; + if (len != 0) + memcpy(p->buf, buf, sizeof(buf[0]) * len); + return 1; +} + +static int re_string_find(REStringList *s, int len, const uint32_t *buf, + bool add_flag) +{ + uint32_t h0; + h0 = re_string_hash(len, buf); + return re_string_find2(s, len, buf, h0, add_flag); +} + +/* return -1 if memory error, 0 if OK */ +static int re_string_add(REStringList *s, int len, const uint32_t *buf) +{ + if (len == 1) { + return cr_union_interval(&s->cr, buf[0], buf[0]); + } + if (re_string_find(s, len, buf, true) < 0) + return -1; + return 0; +} + +/* a = a op b */ +static int re_string_list_op(REStringList *a, REStringList *b, int op) +{ + int i, ret; + REString *p, **pp; + + if (cr_op1(&a->cr, b->cr.points, b->cr.len, op)) + return -1; + + switch(op) { + case CR_OP_UNION: + if (b->n_strings != 0) { + for(i = 0; i < b->hash_size; i++) { + for(p = b->hash_table[i]; p != NULL; p = p->next) { + if (re_string_find2(a, p->len, p->buf, p->hash, true) < 0) + return -1; + } + } + } + break; + case CR_OP_INTER: + case CR_OP_SUB: + for(i = 0; i < a->hash_size; i++) { + pp = &a->hash_table[i]; + for(;;) { + p = *pp; + if (p == NULL) + break; + ret = re_string_find2(b, p->len, p->buf, p->hash, false); + if (op == CR_OP_SUB) + ret = !ret; + if (!ret) { + /* remove it */ + *pp = p->next; + a->n_strings--; + lre_realloc(a->cr.mem_opaque, p, 0); + } else { + /* keep it */ + pp = &p->next; + } + } + } + break; + default: + abort(); + } + return 0; +} + +static int re_string_list_canonicalize(REParseState *s1, + REStringList *s, bool is_unicode) +{ + if (cr_regexp_canonicalize(&s->cr, is_unicode)) + return -1; + if (s->n_strings != 0) { + REStringList a_s, *a = &a_s; + int i, j; + REString *p; + + /* XXX: simplify */ + re_string_list_init(s1, a); + + a->n_strings = s->n_strings; + a->hash_size = s->hash_size; + a->hash_bits = s->hash_bits; + a->hash_table = s->hash_table; + + s->n_strings = 0; + s->hash_size = 0; + s->hash_bits = 0; + s->hash_table = NULL; + + for(i = 0; i < a->hash_size; i++) { + for(p = a->hash_table[i]; p != NULL; p = p->next) { + for(j = 0; j < p->len; j++) { + p->buf[j] = lre_canonicalize(p->buf[j], is_unicode); + } + if (re_string_add(s, p->len, p->buf)) { + re_string_list_free(a); + return -1; + } + } + } + re_string_list_free(a); + } + return 0; +} + +static const uint16_t char_range_d[] = { + 1, + 0x0030, 0x0039 + 1, +}; + +/* code point ranges for Zs,Zl or Zp property */ +static const uint16_t char_range_s[] = { + 10, + 0x0009, 0x000D + 1, + 0x0020, 0x0020 + 1, + 0x00A0, 0x00A0 + 1, + 0x1680, 0x1680 + 1, + 0x2000, 0x200A + 1, + /* 2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;; */ + /* 2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;; */ + 0x2028, 0x2029 + 1, + 0x202F, 0x202F + 1, + 0x205F, 0x205F + 1, + 0x3000, 0x3000 + 1, + /* FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; */ + 0xFEFF, 0xFEFF + 1, +}; + +static const uint16_t char_range_w[] = { + 4, + 0x0030, 0x0039 + 1, + 0x0041, 0x005A + 1, + 0x005F, 0x005F + 1, + 0x0061, 0x007A + 1, +}; + +#define CLASS_RANGE_BASE 0x40000000 + +typedef enum { + CHAR_RANGE_d, + CHAR_RANGE_D, + CHAR_RANGE_s, + CHAR_RANGE_S, + CHAR_RANGE_w, + CHAR_RANGE_W, +} CharRangeEnum; + +static const uint16_t * const char_range_table[] = { + char_range_d, + char_range_s, + char_range_w, +}; + +static int cr_init_char_range(REParseState *s, REStringList *cr, uint32_t c) +{ + bool invert; + const uint16_t *c_pt; + int len, i; + + invert = c & 1; + c_pt = char_range_table[c >> 1]; + len = *c_pt++; + re_string_list_init(s, cr); + for(i = 0; i < len * 2; i++) { + if (cr_add_point(&cr->cr, c_pt[i])) + goto fail; + } + if (invert) { + if (cr_invert(&cr->cr)) + goto fail; + } + return 0; + fail: + re_string_list_free(cr); + return -1; +} + +#ifdef DUMP_REOP +static __maybe_unused void lre_dump_bytecode(const uint8_t *buf, + int buf_len) +{ + int pos, len, opcode, bc_len, re_flags, i; + uint32_t val, val2; + + assert(buf_len >= RE_HEADER_LEN); + + re_flags = lre_get_flags(buf); + bc_len = get_u32(buf + RE_HEADER_BYTECODE_LEN); + assert(bc_len + RE_HEADER_LEN <= buf_len); + printf("flags: 0x%x capture_count=%d reg_count=%d\n", + re_flags, buf[RE_HEADER_CAPTURE_COUNT], buf[RE_HEADER_REGISTER_COUNT]); + if (re_flags & LRE_FLAG_NAMED_GROUPS) { + const char *p; + p = (char *)buf + RE_HEADER_LEN + bc_len; + printf("named groups: "); + for(i = 1; i < buf[RE_HEADER_CAPTURE_COUNT]; i++) { + if (i != 1) + printf(","); + printf("<%s>", p); + p += strlen(p) + LRE_GROUP_NAME_TRAILER_LEN; + } + printf("\n"); + assert(p == (char *)(buf + buf_len)); + } + printf("bytecode_len=%d\n", bc_len); + + buf += RE_HEADER_LEN; + pos = 0; + while (pos < bc_len) { + printf("%5u: ", pos); + opcode = buf[pos]; + len = reopcode_info[opcode].size; + if (opcode >= REOP_COUNT) { + printf(" invalid opcode=0x%02x\n", opcode); + break; + } + if ((pos + len) > bc_len) { + printf(" buffer overflow (opcode=0x%02x)\n", opcode); + break; + } + printf("%s", reopcode_info[opcode].name); + switch(opcode) { + case REOP_char: + case REOP_char_i: + val = get_u16(buf + pos + 1); + if (val >= ' ' && val <= 126) + printf(" '%c'", val); + else + printf(" 0x%04x", val); + break; + case REOP_char32: + case REOP_char32_i: + val = get_u32(buf + pos + 1); + if (val >= ' ' && val <= 126) + printf(" '%c'", val); + else + printf(" 0x%08x", val); + break; + case REOP_goto: + case REOP_split_goto_first: + case REOP_split_next_first: + case REOP_lookahead: + case REOP_negative_lookahead: + val = get_u32(buf + pos + 1); + val += (pos + 5); + printf(" %u", val); + break; + case REOP_loop: + val2 = buf[pos + 1]; + val = get_u32(buf + pos + 2); + val += (pos + 6); + printf(" r%u, %u", val2, val); + break; + case REOP_loop_split_goto_first: + case REOP_loop_split_next_first: + case REOP_loop_check_adv_split_goto_first: + case REOP_loop_check_adv_split_next_first: + { + uint32_t limit; + val2 = buf[pos + 1]; + limit = get_u32(buf + pos + 2); + val = get_u32(buf + pos + 6); + val += (pos + 10); + printf(" r%u, %u, %u", val2, limit, val); + } + break; + case REOP_save_start: + case REOP_save_end: + printf(" %u", buf[pos + 1]); + break; + case REOP_back_reference: + case REOP_back_reference_i: + case REOP_backward_back_reference: + case REOP_backward_back_reference_i: + { + int n, i; + n = buf[pos + 1]; + len += n; + for(i = 0; i < n; i++) { + if (i != 0) + printf(","); + printf(" %u", buf[pos + 2 + i]); + } + } + break; + case REOP_save_reset: + printf(" %u %u", buf[pos + 1], buf[pos + 2]); + break; + case REOP_set_i32: + val = buf[pos + 1]; + val2 = get_u32(buf + pos + 2); + printf(" r%u, %d", val, val2); + break; + case REOP_set_char_pos: + case REOP_check_advance: + val = buf[pos + 1]; + printf(" r%u", val); + break; + case REOP_range: + case REOP_range_i: + { + int n, i; + n = get_u16(buf + pos + 1); + len += n * 4; + for(i = 0; i < n * 2; i++) { + val = get_u16(buf + pos + 3 + i * 2); + printf(" 0x%04x", val); + } + } + break; + case REOP_range32: + case REOP_range32_i: + { + int n, i; + n = get_u16(buf + pos + 1); + len += n * 8; + for(i = 0; i < n * 2; i++) { + val = get_u32(buf + pos + 3 + i * 4); + printf(" 0x%08x", val); + } + } + break; + default: + break; + } + printf("\n"); + pos += len; + } +} +#endif + +static void re_emit_op(REParseState *s, int op) +{ + dbuf_putc(&s->byte_code, op); +} + +/* return the offset of the u32 value */ +static int re_emit_op_u32(REParseState *s, int op, uint32_t val) +{ + int pos; + dbuf_putc(&s->byte_code, op); + pos = s->byte_code.size; + dbuf_put_u32(&s->byte_code, val); + return pos; +} + +static int re_emit_goto(REParseState *s, int op, uint32_t val) +{ + int pos; + dbuf_putc(&s->byte_code, op); + pos = s->byte_code.size; + dbuf_put_u32(&s->byte_code, val - (pos + 4)); + return pos; +} + +static int re_emit_goto_u8(REParseState *s, int op, uint32_t arg, uint32_t val) +{ + int pos; + dbuf_putc(&s->byte_code, op); + dbuf_putc(&s->byte_code, arg); + pos = s->byte_code.size; + dbuf_put_u32(&s->byte_code, val - (pos + 4)); + return pos; +} + +static int re_emit_goto_u8_u32(REParseState *s, int op, uint32_t arg0, uint32_t arg1, uint32_t val) +{ + int pos; + dbuf_putc(&s->byte_code, op); + dbuf_putc(&s->byte_code, arg0); + dbuf_put_u32(&s->byte_code, arg1); + pos = s->byte_code.size; + dbuf_put_u32(&s->byte_code, val - (pos + 4)); + return pos; +} + +static void re_emit_op_u8(REParseState *s, int op, uint32_t val) +{ + dbuf_putc(&s->byte_code, op); + dbuf_putc(&s->byte_code, val); +} + +static void re_emit_op_u16(REParseState *s, int op, uint32_t val) +{ + dbuf_putc(&s->byte_code, op); + dbuf_put_u16(&s->byte_code, val); +} + +static int JS_PRINTF_FORMAT_ATTR(2, 3) re_parse_error(REParseState *s, JS_PRINTF_FORMAT const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vsnprintf(s->u.error_msg, sizeof(s->u.error_msg), fmt, ap); + va_end(ap); + return -1; +} + +static int re_parse_out_of_memory(REParseState *s) +{ + return re_parse_error(s, "out of memory"); +} + +/* If allow_overflow is false, return -1 in case of + overflow. Otherwise return INT32_MAX. */ +static int parse_digits(const uint8_t **pp, bool allow_overflow) +{ + const uint8_t *p; + uint64_t v; + int c; + + p = *pp; + v = 0; + for(;;) { + c = *p; + if (c < '0' || c > '9') + break; + v = v * 10 + c - '0'; + if (v >= INT32_MAX) { + if (allow_overflow) + v = INT32_MAX; + else + return -1; + } + p++; + } + *pp = p; + return v; +} + +static int re_parse_expect(REParseState *s, const uint8_t **pp, int c) +{ + const uint8_t *p; + p = *pp; + if (*p != c) + return re_parse_error(s, "expecting '%c'", c); + p++; + *pp = p; + return 0; +} + +/* Parse an escape sequence, *pp points after the '\': + allow_utf16 value: + 0 : no UTF-16 escapes allowed + 1 : UTF-16 escapes allowed + 2 : UTF-16 escapes allowed and escapes of surrogate pairs are + converted to a unicode character (unicode regexp case). + + Return the unicode char and update *pp if recognized, + return -1 if malformed escape, + return -2 otherwise. */ +int lre_parse_escape(const uint8_t **pp, int allow_utf16) +{ + const uint8_t *p; + uint32_t c; + + p = *pp; + c = *p++; + switch(c) { + case 'b': + c = '\b'; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'v': + c = '\v'; + break; + case 'x': + { + int h0, h1; + + h0 = from_hex(*p++); + if (h0 < 0) + return -1; + h1 = from_hex(*p++); + if (h1 < 0) + return -1; + c = (h0 << 4) | h1; + } + break; + case 'u': + { + int h, i; + uint32_t c1; + + if (*p == '{' && allow_utf16) { + p++; + c = 0; + for(;;) { + h = from_hex(*p++); + if (h < 0) + return -1; + c = (c << 4) | h; + if (c > 0x10FFFF) + return -1; + if (*p == '}') + break; + } + p++; + } else { + c = 0; + for(i = 0; i < 4; i++) { + h = from_hex(*p++); + if (h < 0) { + return -1; + } + c = (c << 4) | h; + } + if (is_hi_surrogate(c) && + allow_utf16 == 2 && p[0] == '\\' && p[1] == 'u') { + /* convert an escaped surrogate pair into a + unicode char */ + c1 = 0; + for(i = 0; i < 4; i++) { + h = from_hex(p[2 + i]); + if (h < 0) + break; + c1 = (c1 << 4) | h; + } + if (i == 4 && is_lo_surrogate(c1)) { + p += 6; + c = from_surrogate(c, c1); + } + } + } + } + break; + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + c -= '0'; + if (allow_utf16 == 2) { + /* only accept \0 not followed by digit */ + if (c != 0 || lre_is_digit(*p)) + return -1; + } else { + /* parse a legacy octal sequence */ + uint32_t v; + v = *p - '0'; + if (v > 7) + break; + c = (c << 3) | v; + p++; + if (c >= 32) + break; + v = *p - '0'; + if (v > 7) + break; + c = (c << 3) | v; + p++; + } + break; + default: + return -2; + } + *pp = p; + return c; +} + +/* XXX: we use the same chars for name and value */ +static bool is_unicode_char(int c) +{ + return ((c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + (c == '_')); +} + +/* XXX: memory error test */ +static void seq_prop_cb(void *opaque, const uint32_t *seq, int seq_len) +{ + REStringList *sl = opaque; + re_string_add(sl, seq_len, seq); +} + +static int parse_unicode_property(REParseState *s, REStringList *cr, + const uint8_t **pp, bool is_inv, + bool allow_sequence_prop) +{ + const uint8_t *p; + char name[64], value[64]; + char *q; + bool script_ext; + int ret; + + p = *pp; + if (*p != '{') + return re_parse_error(s, "expecting '{' after \\p"); + p++; + q = name; + while (is_unicode_char(*p)) { + if ((q - name) >= sizeof(name) - 1) + goto unknown_property_name; + *q++ = *p++; + } + *q = '\0'; + q = value; + if (*p == '=') { + p++; + while (is_unicode_char(*p)) { + if ((q - value) >= sizeof(value) - 1) + return re_parse_error(s, "unknown unicode property value"); + *q++ = *p++; + } + } + *q = '\0'; + if (*p != '}') + return re_parse_error(s, "expecting '}'"); + p++; + // printf("name=%s value=%s\n", name, value); + + if (!strcmp(name, "Script") || !strcmp(name, "sc")) { + script_ext = false; + goto do_script; + } else if (!strcmp(name, "Script_Extensions") || !strcmp(name, "scx")) { + script_ext = true; + do_script: + re_string_list_init(s, cr); + ret = unicode_script(&cr->cr, value, script_ext); + if (ret) { + re_string_list_free(cr); + if (ret == -2) + return re_parse_error(s, "unknown unicode script"); + else + goto out_of_memory; + } + } else if (!strcmp(name, "General_Category") || !strcmp(name, "gc")) { + re_string_list_init(s, cr); + ret = unicode_general_category(&cr->cr, value); + if (ret) { + re_string_list_free(cr); + if (ret == -2) + return re_parse_error(s, "unknown unicode general category"); + else + goto out_of_memory; + } + } else if (value[0] == '\0') { + re_string_list_init(s, cr); + ret = unicode_general_category(&cr->cr, name); + if (ret == -1) { + re_string_list_free(cr); + goto out_of_memory; + } + if (ret < 0) { + ret = unicode_prop(&cr->cr, name); + if (ret == -1) { + re_string_list_free(cr); + goto out_of_memory; + } + } + if (ret < 0 && !is_inv && allow_sequence_prop) { + CharRange cr_tmp; + cr_init(&cr_tmp, s->opaque, lre_realloc); + ret = unicode_sequence_prop(name, seq_prop_cb, cr, &cr_tmp); + cr_free(&cr_tmp); + if (ret == -1) { + re_string_list_free(cr); + goto out_of_memory; + } + } + if (ret < 0) + goto unknown_property_name; + } else { + unknown_property_name: + return re_parse_error(s, "unknown unicode property name"); + } + + /* the ordering of case folding and inversion differs with + unicode_sets. 'unicode_sets' ordering is more consistent */ + /* XXX: the spec seems incorrect, we do it as the other engines + seem to do it. */ + if (s->ignore_case && s->unicode_sets) { + if (re_string_list_canonicalize(s, cr, s->is_unicode)) { + re_string_list_free(cr); + goto out_of_memory; + } + } + if (is_inv) { + if (cr_invert(&cr->cr)) { + re_string_list_free(cr); + goto out_of_memory; + } + } + if (s->ignore_case && !s->unicode_sets) { + if (re_string_list_canonicalize(s, cr, s->is_unicode)) { + re_string_list_free(cr); + goto out_of_memory; + } + } + *pp = p; + return 0; + out_of_memory: + return re_parse_out_of_memory(s); +} + +static int get_class_atom(REParseState *s, REStringList *cr, + const uint8_t **pp, bool inclass); + +static int parse_class_string_disjunction(REParseState *s, REStringList *cr, + const uint8_t **pp) +{ + const uint8_t *p; + DynBuf str; + int c; + + p = *pp; + if (*p != '{') + return re_parse_error(s, "expecting '{' after \\q"); + + dbuf_init2(&str, s->opaque, lre_realloc); + re_string_list_init(s, cr); + + p++; + for(;;) { + str.size = 0; + while (*p != '}' && *p != '|') { + c = get_class_atom(s, NULL, &p, true); + if (c < 0) + goto fail; + if (dbuf_put_u32(&str, c)) { + re_parse_out_of_memory(s); + goto fail; + } + } + if (re_string_add(cr, str.size / 4, (uint32_t *)str.buf)) { + re_parse_out_of_memory(s); + goto fail; + } + if (*p == '}') + break; + p++; + } + if (s->ignore_case) { + if (re_string_list_canonicalize(s, cr, true)) + goto fail; + } + p++; /* skip the '}' */ + dbuf_free(&str); + *pp = p; + return 0; + fail: + dbuf_free(&str); + re_string_list_free(cr); + return -1; +} + +/* return -1 if error otherwise the character or a class range + (CLASS_RANGE_BASE) if cr != NULL. In case of class range, 'cr' is + initialized. Otherwise, it is ignored. */ +static int get_class_atom(REParseState *s, REStringList *cr, + const uint8_t **pp, bool inclass) +{ + const uint8_t *p; + uint32_t c; + int ret; + + p = *pp; + + c = *p; + switch(c) { + case '\\': + p++; + if (p >= s->buf_end) + goto unexpected_end; + c = *p++; + switch(c) { + case 'd': + c = CHAR_RANGE_d; + goto class_range; + case 'D': + c = CHAR_RANGE_D; + goto class_range; + case 's': + c = CHAR_RANGE_s; + goto class_range; + case 'S': + c = CHAR_RANGE_S; + goto class_range; + case 'w': + c = CHAR_RANGE_w; + goto class_range; + case 'W': + c = CHAR_RANGE_W; + class_range: + if (!cr) + goto default_escape; + if (cr_init_char_range(s, cr, c)) + return -1; + c += CLASS_RANGE_BASE; + break; + case 'c': + c = *p; + if ((c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (((c >= '0' && c <= '9') || c == '_') && + inclass && !s->is_unicode)) { /* Annex B.1.4 */ + c &= 0x1f; + p++; + } else if (s->is_unicode) { + goto invalid_escape; + } else { + /* otherwise return '\' and 'c' */ + p--; + c = '\\'; + } + break; + case '-': + if (!inclass && s->is_unicode) + goto invalid_escape; + break; + case '&': + case '!': + case '#': + case '%': + case ',': + case ':': + case ';': + case '<': + case '=': + case '>': + case '@': + case '`': + case '~': + if (s->is_unicode && (!inclass || !s->unicode_sets)) + /* Only illegal if in unicode mode and not in a class */ + goto invalid_escape; + break; + case '^': + case '$': + case '\\': + case '.': + case '*': + case '+': + case '?': + case '(': + case ')': + case '[': + case ']': + case '{': + case '}': + case '|': + case '/': + /* always valid to escape these characters */ + break; + case 'p': + case 'P': + if (s->is_unicode && cr) { + if (parse_unicode_property(s, cr, &p, (c == 'P'), s->unicode_sets)) + return -1; + c = CLASS_RANGE_BASE; + break; + } + goto default_escape; + case 'q': + if (s->unicode_sets && cr && inclass) { + if (parse_class_string_disjunction(s, cr, &p)) + return -1; + c = CLASS_RANGE_BASE; + break; + } + goto default_escape; + default: + default_escape: + p--; + ret = lre_parse_escape(&p, s->is_unicode * 2); + if (ret >= 0) { + c = ret; + } else { + if (s->is_unicode) { + invalid_escape: + return re_parse_error(s, "invalid escape sequence in regular expression"); + } else { + /* just ignore the '\' */ + goto normal_char; + } + } + break; + } + break; + case '\0': + if (p >= s->buf_end) { + unexpected_end: + return re_parse_error(s, "unexpected end"); + } + /* fall thru */ + goto normal_char; + + case '&': + case '!': + case '#': + case '$': + case '%': + case '*': + case '+': + case ',': + case '.': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case '^': + case '`': + case '~': + if (s->unicode_sets && p[1] == c) { + /* forbidden double characters */ + return re_parse_error(s, "invalid class set operation in regular expression"); + } + goto normal_char; + + case '(': + case ')': + case '[': + case ']': + case '{': + case '}': + case '/': + case '-': + case '|': + if (s->unicode_sets) { + /* invalid characters in unicode sets */ + return re_parse_error(s, "invalid character in class in regular expression"); + } + goto normal_char; + + default: + normal_char: + /* normal char */ + if (c >= 128) { + c = utf8_decode_len(p, UTF8_CHAR_LEN_MAX, &p); + if ((unsigned)c > 0xffff && !s->is_unicode) { + /* XXX: should handle non BMP-1 code points */ + return re_parse_error(s, "malformed unicode char"); + } + } else { + p++; + } + break; + } + *pp = p; + return c; +} + +static int re_emit_range(REParseState *s, const CharRange *cr) +{ + int len, i; + uint32_t high; + + len = (unsigned)cr->len / 2; + if (len >= 65535) + return re_parse_error(s, "too many ranges"); + if (len == 0) { + re_emit_op_u32(s, REOP_char32, -1); + } else { + high = cr->points[cr->len - 1]; + if (high == UINT32_MAX) + high = cr->points[cr->len - 2]; + if (high <= 0xffff) { + /* can use 16 bit ranges with the conversion that 0xffff = + infinity */ + re_emit_op_u16(s, s->ignore_case ? REOP_range_i : REOP_range, len); + for(i = 0; i < cr->len; i += 2) { + dbuf_put_u16(&s->byte_code, cr->points[i]); + high = cr->points[i + 1] - 1; + if (high == UINT32_MAX - 1) + high = 0xffff; + dbuf_put_u16(&s->byte_code, high); + } + } else { + re_emit_op_u16(s, s->ignore_case ? REOP_range32_i : REOP_range32, len); + for(i = 0; i < cr->len; i += 2) { + dbuf_put_u32(&s->byte_code, cr->points[i]); + dbuf_put_u32(&s->byte_code, cr->points[i + 1] - 1); + } + } + } + return 0; +} + +static int re_string_cmp_len(const void *a, const void *b, void *arg) +{ + REString *p1 = *(REString **)a; + REString *p2 = *(REString **)b; + return (p1->len < p2->len) - (p1->len > p2->len); +} + +static void re_emit_char(REParseState *s, int c) +{ + if (c <= 0xffff) + re_emit_op_u16(s, s->ignore_case ? REOP_char_i : REOP_char, c); + else + re_emit_op_u32(s, s->ignore_case ? REOP_char32_i : REOP_char32, c); +} + +static int re_emit_string_list(REParseState *s, const REStringList *sl) +{ + REString **tab, *p; + int i, j, split_pos, last_match_pos, n; + bool has_empty_string, is_last; + + // re_string_list_dump("sl", sl); + if (sl->n_strings == 0) { + /* simple case: only characters */ + if (re_emit_range(s, &sl->cr)) + return -1; + } else { + /* at least one string list is present : match the longest ones first */ + /* XXX: add a new op_switch opcode to compile as a trie */ + tab = lre_realloc(s->opaque, NULL, sizeof(tab[0]) * sl->n_strings); + if (!tab) { + re_parse_out_of_memory(s); + return -1; + } + has_empty_string = false; + n = 0; + for(i = 0; i < sl->hash_size; i++) { + for(p = sl->hash_table[i]; p != NULL; p = p->next) { + if (p->len == 0) { + has_empty_string = true; + } else { + tab[n++] = p; + } + } + } + assert(n <= sl->n_strings); + + rqsort(tab, n, sizeof(tab[0]), re_string_cmp_len, NULL); + + last_match_pos = -1; + for(i = 0; i < n; i++) { + p = tab[i]; + is_last = !has_empty_string && sl->cr.len == 0 && i == (n - 1); + if (!is_last) + split_pos = re_emit_op_u32(s, REOP_split_next_first, 0); + else + split_pos = 0; + for(j = 0; j < p->len; j++) { + re_emit_char(s, p->buf[j]); + } + if (!is_last) { + last_match_pos = re_emit_op_u32(s, REOP_goto, last_match_pos); + /* the positions to patch are only valid if all the byte code + could be emitted */ + if (dbuf_error(&s->byte_code)) + goto out_of_memory; + put_u32(s->byte_code.buf + split_pos, s->byte_code.size - (split_pos + 4)); + } + } + + if (sl->cr.len != 0) { + /* char range */ + is_last = !has_empty_string; + if (!is_last) + split_pos = re_emit_op_u32(s, REOP_split_next_first, 0); + else + split_pos = 0; /* not used */ + if (re_emit_range(s, &sl->cr)) + goto fail; + if (!is_last) { + if (dbuf_error(&s->byte_code)) + goto out_of_memory; + put_u32(s->byte_code.buf + split_pos, s->byte_code.size - (split_pos + 4)); + } + } + + /* patch the 'goto match' */ + if (dbuf_error(&s->byte_code)) + goto out_of_memory; + while (last_match_pos != -1) { + int next_pos = get_u32(s->byte_code.buf + last_match_pos); + put_u32(s->byte_code.buf + last_match_pos, s->byte_code.size - (last_match_pos + 4)); + last_match_pos = next_pos; + } + + lre_realloc(s->opaque, tab, 0); + } + return 0; + out_of_memory: + re_parse_out_of_memory(s); + fail: + lre_realloc(s->opaque, tab, 0); + return -1; +} + +static int re_parse_nested_class(REParseState *s, REStringList *cr, const uint8_t **pp); + +static int re_parse_class_set_operand(REParseState *s, REStringList *cr, const uint8_t **pp) +{ + int c1; + const uint8_t *p = *pp; + + if (*p == '[') { + if (re_parse_nested_class(s, cr, pp)) + return -1; + } else { + c1 = get_class_atom(s, cr, pp, true); + if (c1 < 0) + return -1; + if (c1 < CLASS_RANGE_BASE) { + /* create a range with a single character */ + re_string_list_init(s, cr); + if (s->ignore_case) + c1 = lre_canonicalize(c1, s->is_unicode); + if (cr_union_interval(&cr->cr, c1, c1)) { + re_string_list_free(cr); + return -1; + } + } + } + return 0; +} + +static int re_parse_nested_class(REParseState *s, REStringList *cr, const uint8_t **pp) +{ + const uint8_t *p; + uint32_t c1, c2; + int ret; + REStringList cr1_s, *cr1 = &cr1_s; + bool invert, is_first; + + if (lre_check_stack_overflow(s->opaque, 0)) + return re_parse_error(s, "stack overflow"); + + re_string_list_init(s, cr); + p = *pp; + p++; /* skip '[' */ + + invert = false; + if (*p == '^') { + p++; + invert = true; + } + + /* handle unions */ + is_first = true; + for(;;) { + if (*p == ']') + break; + if (*p == '[' && s->unicode_sets) { + if (re_parse_nested_class(s, cr1, &p)) + goto fail; + goto class_union; + } else { + c1 = get_class_atom(s, cr1, &p, true); + if ((int)c1 < 0) + goto fail; + if (*p == '-' && p[1] != ']') { + const uint8_t *p0 = p + 1; + if (p[1] == '-' && s->unicode_sets && is_first) + goto class_atom; /* first character class followed by '--' */ + if (c1 >= CLASS_RANGE_BASE) { + if (s->is_unicode) { + re_string_list_free(cr1); + goto invalid_class_range; + } + /* Annex B: match '-' character */ + goto class_atom; + } + c2 = get_class_atom(s, cr1, &p0, true); + if ((int)c2 < 0) + goto fail; + if (c2 >= CLASS_RANGE_BASE) { + re_string_list_free(cr1); + if (s->is_unicode) { + goto invalid_class_range; + } + /* Annex B: match '-' character */ + goto class_atom; + } + p = p0; + if (c2 < c1) { + invalid_class_range: + re_parse_error(s, "invalid class range"); + goto fail; + } + if (s->ignore_case) { + CharRange cr2_s, *cr2 = &cr2_s; + cr_init(cr2, s->opaque, lre_realloc); + if (cr_add_interval(cr2, c1, c2 + 1) || + cr_regexp_canonicalize(cr2, s->is_unicode) || + cr_op1(&cr->cr, cr2->points, cr2->len, CR_OP_UNION)) { + cr_free(cr2); + goto memory_error; + } + cr_free(cr2); + } else { + if (cr_union_interval(&cr->cr, c1, c2)) + goto memory_error; + } + is_first = false; /* union operation */ + } else { + class_atom: + if (c1 >= CLASS_RANGE_BASE) { + class_union: + ret = re_string_list_op(cr, cr1, CR_OP_UNION); + re_string_list_free(cr1); + if (ret) + goto memory_error; + } else { + if (s->ignore_case) + c1 = lre_canonicalize(c1, s->is_unicode); + if (cr_union_interval(&cr->cr, c1, c1)) + goto memory_error; + } + } + } + if (s->unicode_sets && is_first) { + if (*p == '&' && p[1] == '&' && p[2] != '&') { + /* handle '&&' */ + for(;;) { + if (*p == ']') { + break; + } else if (*p == '&' && p[1] == '&' && p[2] != '&') { + p += 2; + } else { + goto invalid_operation; + } + if (re_parse_class_set_operand(s, cr1, &p)) + goto fail; + ret = re_string_list_op(cr, cr1, CR_OP_INTER); + re_string_list_free(cr1); + if (ret) + goto memory_error; + } + } else if (*p == '-' && p[1] == '-') { + /* handle '--' */ + for(;;) { + if (*p == ']') { + break; + } else if (*p == '-' && p[1] == '-') { + p += 2; + } else { + invalid_operation: + re_parse_error(s, "invalid operation in regular expression"); + goto fail; + } + if (re_parse_class_set_operand(s, cr1, &p)) + goto fail; + ret = re_string_list_op(cr, cr1, CR_OP_SUB); + re_string_list_free(cr1); + if (ret) + goto memory_error; + } + } + } + is_first = false; + } + + p++; /* skip ']' */ + *pp = p; + if (invert) { + /* XXX: add may_contain_string syntax check to be fully + compliant. The test here accepts more input than the + spec. */ + if (cr->n_strings != 0) { + re_parse_error(s, "negated character class with strings in regular expression debugger eval code"); + goto fail; + } + if (cr_invert(&cr->cr)) + goto memory_error; + } + return 0; + memory_error: + re_parse_out_of_memory(s); + fail: + re_string_list_free(cr); + return -1; +} + +static int re_parse_char_class(REParseState *s, const uint8_t **pp) +{ + REStringList cr_s, *cr = &cr_s; + + if (re_parse_nested_class(s, cr, pp)) + return -1; + if (re_emit_string_list(s, cr)) + goto fail; + re_string_list_free(cr); + return 0; + fail: + re_string_list_free(cr); + return -1; +} + +/* need_check_adv: false if the opcodes always advance the char pointer + need_capture_init: true if all the captures in the atom are not set +*/ +static bool re_need_check_adv_and_capture_init(bool *pneed_capture_init, + const uint8_t *bc_buf, int bc_buf_len) +{ + int pos, opcode, len; + uint32_t val; + bool need_check_adv, need_capture_init; + + need_check_adv = true; + need_capture_init = false; + pos = 0; + while (pos < bc_buf_len) { + opcode = bc_buf[pos]; + len = reopcode_info[opcode].size; + switch(opcode) { + case REOP_range: + case REOP_range_i: + val = get_u16(bc_buf + pos + 1); + len += val * 4; + need_check_adv = false; + break; + case REOP_range32: + case REOP_range32_i: + val = get_u16(bc_buf + pos + 1); + len += val * 8; + need_check_adv = false; + break; + case REOP_char: + case REOP_char_i: + case REOP_char32: + case REOP_char32_i: + case REOP_dot: + case REOP_any: + case REOP_space: + case REOP_not_space: + need_check_adv = false; + break; + case REOP_line_start: + case REOP_line_start_m: + case REOP_line_end: + case REOP_line_end_m: + case REOP_set_i32: + case REOP_set_char_pos: + case REOP_word_boundary: + case REOP_word_boundary_i: + case REOP_not_word_boundary: + case REOP_not_word_boundary_i: + case REOP_prev: + /* no effect */ + break; + case REOP_save_start: + case REOP_save_end: + case REOP_save_reset: + break; + case REOP_back_reference: + case REOP_back_reference_i: + case REOP_backward_back_reference: + case REOP_backward_back_reference_i: + val = bc_buf[pos + 1]; + len += val; + need_capture_init = true; + break; + default: + /* safe behavior: we cannot predict the outcome */ + need_capture_init = true; + goto done; + } + pos += len; + } + done: + *pneed_capture_init = need_capture_init; + return need_check_adv; +} + +/* '*pp' is the first char after '<' */ +static int re_parse_group_name(char *buf, int buf_size, const uint8_t **pp) +{ + const uint8_t *p, *p1; + uint32_t c, d; + char *q; + + p = *pp; + q = buf; + for(;;) { + c = *p; + if (c == '\\') { + p++; + if (*p != 'u') + return -1; + c = lre_parse_escape(&p, 2); // accept surrogate pairs + } else if (c == '>') { + break; + } else if (c >= 128) { + c = utf8_decode_len(p, UTF8_CHAR_LEN_MAX, &p); + if (is_hi_surrogate(c)) { + d = utf8_decode_len(p, UTF8_CHAR_LEN_MAX, &p1); + if (is_lo_surrogate(d)) { + c = from_surrogate(c, d); + p = p1; + } + } + } else { + p++; + } + if (c > 0x10FFFF) + return -1; + if (q == buf) { + if (!lre_js_is_ident_first(c)) + return -1; + } else { + if (!lre_js_is_ident_next(c)) + return -1; + } + if ((q - buf + UTF8_CHAR_LEN_MAX + 1) > buf_size) + return -1; + if (c < 128) { + *q++ = c; + } else { + q += utf8_encode((uint8_t*)q, c); + } + } + if (q == buf) + return -1; + *q = '\0'; + p++; + *pp = p; + return 0; +} + +/* if capture_name = NULL: return the number of captures + 1. + Otherwise, return the number of matching capture groups */ +static int re_parse_captures(REParseState *s, int *phas_named_captures, + const char *capture_name, bool emit_group_index) +{ + const uint8_t *p; + int capture_index, n; + char name[TMP_BUF_SIZE]; + + capture_index = 1; + n = 0; + *phas_named_captures = 0; + for (p = s->buf_start; p < s->buf_end; p++) { + switch (*p) { + case '(': + if (p[1] == '?') { + if (p[2] == '<' && p[3] != '=' && p[3] != '!') { + *phas_named_captures = 1; + /* potential named capture */ + if (capture_name) { + p += 3; + if (re_parse_group_name(name, sizeof(name), &p) == 0) { + if (!strcmp(name, capture_name)) { + if (emit_group_index) + dbuf_putc(&s->byte_code, capture_index); + n++; + } + } + } + capture_index++; + if (capture_index >= CAPTURE_COUNT_MAX) + goto done; + } + } else { + capture_index++; + if (capture_index >= CAPTURE_COUNT_MAX) + goto done; + } + break; + case '\\': + p++; + break; + case '[': + for (p += 1 + (*p == ']'); p < s->buf_end && *p != ']'; p++) { + if (*p == '\\') + p++; + } + break; + } + } + done: + if (capture_name) { + return n; + } else { + return capture_index; + } +} + +static int re_count_captures(REParseState *s) +{ + if (s->total_capture_count < 0) { + s->total_capture_count = re_parse_captures(s, &s->has_named_captures, + NULL, false); + } + return s->total_capture_count; +} + +static bool re_has_named_captures(REParseState *s) +{ + if (s->has_named_captures < 0) + re_count_captures(s); + return s->has_named_captures; +} + +static int find_group_name(REParseState *s, const char *name, bool emit_group_index) +{ + const char *p, *buf_end; + size_t len, name_len; + int capture_index, n; + + p = (char *)s->group_names.buf; + if (!p) + return 0; + buf_end = (char *)s->group_names.buf + s->group_names.size; + name_len = strlen(name); + capture_index = 1; + n = 0; + while (p < buf_end) { + len = strlen(p); + if (len == name_len && memcmp(name, p, name_len) == 0) { + if (emit_group_index) + dbuf_putc(&s->byte_code, capture_index); + n++; + } + p += len + LRE_GROUP_NAME_TRAILER_LEN; + capture_index++; + } + return n; +} + +static bool is_duplicate_group_name(REParseState *s, const char *name, int scope) +{ + const char *p, *buf_end; + size_t len, name_len; + int scope1; + + p = (char *)s->group_names.buf; + if (!p) + return 0; + buf_end = (char *)s->group_names.buf + s->group_names.size; + name_len = strlen(name); + while (p < buf_end) { + len = strlen(p); + if (len == name_len && memcmp(name, p, name_len) == 0) { + scope1 = (uint8_t)p[len + 1]; + if (scope == scope1) + return true; + } + p += len + LRE_GROUP_NAME_TRAILER_LEN; + } + return false; +} + +static int re_parse_disjunction(REParseState *s, bool is_backward_dir); + +static int re_parse_modifiers(REParseState *s, const uint8_t **pp) +{ + const uint8_t *p = *pp; + int mask = 0; + int val; + + for(;;) { + if (*p == 'i') { + val = LRE_FLAG_IGNORECASE; + } else if (*p == 'm') { + val = LRE_FLAG_MULTILINE; + } else if (*p == 's') { + val = LRE_FLAG_DOTALL; + } else { + break; + } + if (mask & val) + return re_parse_error(s, "duplicate modifier: '%c'", *p); + mask |= val; + p++; + } + *pp = p; + return mask; +} + +static bool update_modifier(bool val, int add_mask, int remove_mask, + int mask) +{ + if (add_mask & mask) + val = true; + if (remove_mask & mask) + val = false; + return val; +} + +static int re_parse_term(REParseState *s, bool is_backward_dir) +{ + const uint8_t *p; + int c, last_atom_start, quant_min, quant_max, last_capture_count; + bool greedy, is_neg, is_backward_lookahead; + REStringList cr_s, *cr = &cr_s; + + /* after a failed allocation the byte code is incomplete and 'buf' may + still be NULL: stop before computing positions inside it */ + if (dbuf_error(&s->byte_code)) + return re_parse_out_of_memory(s); + + last_atom_start = -1; + last_capture_count = 0; + p = s->buf_ptr; + c = *p; + switch(c) { + case '^': + p++; + re_emit_op(s, s->multi_line ? REOP_line_start_m : REOP_line_start); + break; + case '$': + p++; + re_emit_op(s, s->multi_line ? REOP_line_end_m : REOP_line_end); + break; + case '.': + p++; + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + if (is_backward_dir) + re_emit_op(s, REOP_prev); + re_emit_op(s, s->dotall ? REOP_any : REOP_dot); + if (is_backward_dir) + re_emit_op(s, REOP_prev); + break; + case '{': + if (s->is_unicode) { + return re_parse_error(s, "syntax error"); + } else if (!lre_is_digit(p[1])) { + /* Annex B: we accept '{' not followed by digits as a + normal atom */ + goto parse_class_atom; + } else { + const uint8_t *p1 = p + 1; + /* Annex B: error if it is like a repetition count */ + parse_digits(&p1, true); + if (*p1 == ',') { + p1++; + if (lre_is_digit(*p1)) { + parse_digits(&p1, true); + } + } + if (*p1 != '}') { + goto parse_class_atom; + } + } + /* fall thru */ + case '*': + case '+': + case '?': + return re_parse_error(s, "nothing to repeat"); + case '(': + if (p[1] == '?') { + if (p[2] == ':') { + p += 3; + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + s->buf_ptr = p; + if (re_parse_disjunction(s, is_backward_dir)) + return -1; + p = s->buf_ptr; + if (re_parse_expect(s, &p, ')')) + return -1; + } else if (p[2] == 'i' || p[2] == 'm' || p[2] == 's' || p[2] == '-') { + bool saved_ignore_case, saved_multi_line, saved_dotall; + int add_mask, remove_mask; + p += 2; + remove_mask = 0; + add_mask = re_parse_modifiers(s, &p); + if (add_mask < 0) + return -1; + if (*p == '-') { + p++; + remove_mask = re_parse_modifiers(s, &p); + if (remove_mask < 0) + return -1; + } + if ((add_mask == 0 && remove_mask == 0) || + (add_mask & remove_mask) != 0) { + return re_parse_error(s, "invalid modifiers"); + } + if (re_parse_expect(s, &p, ':')) + return -1; + saved_ignore_case = s->ignore_case; + saved_multi_line = s->multi_line; + saved_dotall = s->dotall; + s->ignore_case = update_modifier(s->ignore_case, add_mask, remove_mask, LRE_FLAG_IGNORECASE); + s->multi_line = update_modifier(s->multi_line, add_mask, remove_mask, LRE_FLAG_MULTILINE); + s->dotall = update_modifier(s->dotall, add_mask, remove_mask, LRE_FLAG_DOTALL); + + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + s->buf_ptr = p; + if (re_parse_disjunction(s, is_backward_dir)) + return -1; + p = s->buf_ptr; + if (re_parse_expect(s, &p, ')')) + return -1; + s->ignore_case = saved_ignore_case; + s->multi_line = saved_multi_line; + s->dotall = saved_dotall; + } else if ((p[2] == '=' || p[2] == '!')) { + is_neg = (p[2] == '!'); + is_backward_lookahead = false; + p += 3; + goto lookahead; + } else if (p[2] == '<' && + (p[3] == '=' || p[3] == '!')) { + int pos; + is_neg = (p[3] == '!'); + is_backward_lookahead = true; + p += 4; + /* lookahead */ + lookahead: + /* Annex B allows lookahead to be used as an atom for + the quantifiers */ + if (!s->is_unicode && !is_backward_lookahead) { + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + } + pos = re_emit_op_u32(s, REOP_lookahead + is_neg, 0); + s->buf_ptr = p; + if (re_parse_disjunction(s, is_backward_lookahead)) + return -1; + p = s->buf_ptr; + if (re_parse_expect(s, &p, ')')) + return -1; + re_emit_op(s, REOP_lookahead_match + is_neg); + /* jump after the 'match' after the lookahead is successful */ + if (dbuf_error(&s->byte_code)) + return re_parse_out_of_memory(s); + put_u32(s->byte_code.buf + pos, s->byte_code.size - (pos + 4)); + } else if (p[2] == '<') { + p += 3; + if (re_parse_group_name(s->u.tmp_buf, sizeof(s->u.tmp_buf), + &p)) { + return re_parse_error(s, "invalid group name"); + } + /* poor's man method to test duplicate group + names. */ + /* XXX: this method does not catch all the errors*/ + if (is_duplicate_group_name(s, s->u.tmp_buf, s->group_name_scope)) { + return re_parse_error(s, "duplicate group name"); + } + /* group name with a trailing zero */ + dbuf_put(&s->group_names, (uint8_t *)s->u.tmp_buf, + strlen(s->u.tmp_buf) + 1); + dbuf_putc(&s->group_names, s->group_name_scope); + s->has_named_captures = 1; + goto parse_capture; + } else { + return re_parse_error(s, "invalid group"); + } + } else { + int capture_index; + p++; + /* capture without group name */ + dbuf_putc(&s->group_names, 0); + dbuf_putc(&s->group_names, 0); + parse_capture: + if (s->capture_count >= CAPTURE_COUNT_MAX) + return re_parse_error(s, "too many captures"); + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + capture_index = s->capture_count++; + re_emit_op_u8(s, REOP_save_start + is_backward_dir, + capture_index); + + s->buf_ptr = p; + if (re_parse_disjunction(s, is_backward_dir)) + return -1; + p = s->buf_ptr; + + re_emit_op_u8(s, REOP_save_start + 1 - is_backward_dir, + capture_index); + + if (re_parse_expect(s, &p, ')')) + return -1; + } + break; + case '\\': + switch(p[1]) { + case 'b': + case 'B': + if (p[1] != 'b') { + re_emit_op(s, s->ignore_case && s->is_unicode ? REOP_not_word_boundary_i : REOP_not_word_boundary); + } else { + re_emit_op(s, s->ignore_case && s->is_unicode ? REOP_word_boundary_i : REOP_word_boundary); + } + p += 2; + break; + case 'k': + { + const uint8_t *p1; + int dummy_res, n; + bool is_forward; + + p1 = p; + if (p1[2] != '<') { + /* annex B: we tolerate invalid group names in non + unicode mode if there is no named capture + definition */ + if (s->is_unicode || re_has_named_captures(s)) + return re_parse_error(s, "expecting group name"); + else + goto parse_class_atom; + } + p1 += 3; + if (re_parse_group_name(s->u.tmp_buf, sizeof(s->u.tmp_buf), + &p1)) { + if (s->is_unicode || re_has_named_captures(s)) + return re_parse_error(s, "invalid group name"); + else + goto parse_class_atom; + } + is_forward = false; + n = find_group_name(s, s->u.tmp_buf, false); + if (n == 0) { + /* no capture name parsed before, try to look + after (inefficient, but hopefully not common */ + n = re_parse_captures(s, &dummy_res, s->u.tmp_buf, false); + if (n == 0) { + if (s->is_unicode || re_has_named_captures(s)) + return re_parse_error(s, "group name not defined"); + else + goto parse_class_atom; + } + is_forward = true; + } + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + + /* emit back references to all the captures indexes matching the group name */ + re_emit_op_u8(s, REOP_back_reference + 2 * is_backward_dir + s->ignore_case, n); + if (is_forward) { + re_parse_captures(s, &dummy_res, s->u.tmp_buf, true); + } else { + find_group_name(s, s->u.tmp_buf, true); + } + p = p1; + } + break; + case '0': + p += 2; + c = 0; + if (s->is_unicode) { + if (lre_is_digit(*p)) { + return re_parse_error(s, "invalid decimal escape in regular expression"); + } + } else { + /* Annex B.1.4: accept legacy octal */ + if (*p >= '0' && *p <= '7') { + c = *p++ - '0'; + if (*p >= '0' && *p <= '7') { + c = (c << 3) + *p++ - '0'; + } + } + } + goto normal_char; + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': + case '9': + { + const uint8_t *q = ++p; + + c = parse_digits(&p, false); + if (c < 0 || (c >= s->capture_count && c >= re_count_captures(s))) { + if (!s->is_unicode) { + /* Annex B.1.4: accept legacy octal */ + p = q; + if (*p <= '7') { + c = 0; + if (*p <= '3') + c = *p++ - '0'; + if (*p >= '0' && *p <= '7') { + c = (c << 3) + *p++ - '0'; + if (*p >= '0' && *p <= '7') { + c = (c << 3) + *p++ - '0'; + } + } + } else { + c = *p++; + } + goto normal_char; + } + return re_parse_error(s, "back reference out of range in regular expression"); + } + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + + re_emit_op_u8(s, REOP_back_reference + 2 * is_backward_dir + s->ignore_case, 1); + dbuf_putc(&s->byte_code, c); + } + break; + default: + goto parse_class_atom; + } + break; + case '[': + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + if (is_backward_dir) + re_emit_op(s, REOP_prev); + if (re_parse_char_class(s, &p)) + return -1; + if (is_backward_dir) + re_emit_op(s, REOP_prev); + break; + case ']': + case '}': + if (s->is_unicode) + return re_parse_error(s, "syntax error"); + goto parse_class_atom; + default: + parse_class_atom: + c = get_class_atom(s, cr, &p, false); + if ((int)c < 0) + return -1; + normal_char: + last_atom_start = s->byte_code.size; + last_capture_count = s->capture_count; + if (is_backward_dir) + re_emit_op(s, REOP_prev); + if (c >= CLASS_RANGE_BASE) { + int ret = 0; + /* optimize the common 'space' tests */ + if (c == (CLASS_RANGE_BASE + CHAR_RANGE_s)) { + re_emit_op(s, REOP_space); + } else if (c == (CLASS_RANGE_BASE + CHAR_RANGE_S)) { + re_emit_op(s, REOP_not_space); + } else { + ret = re_emit_string_list(s, cr); + } + re_string_list_free(cr); + if (ret) + return -1; + } else { + if (s->ignore_case) + c = lre_canonicalize(c, s->is_unicode); + re_emit_char(s, c); + } + if (is_backward_dir) + re_emit_op(s, REOP_prev); + break; + } + + /* quantifier */ + if (last_atom_start >= 0) { + c = *p; + switch(c) { + case '*': + p++; + quant_min = 0; + quant_max = INT32_MAX; + goto quantifier; + case '+': + p++; + quant_min = 1; + quant_max = INT32_MAX; + goto quantifier; + case '?': + p++; + quant_min = 0; + quant_max = 1; + goto quantifier; + case '{': + { + const uint8_t *p1 = p; + /* As an extension (see ES6 annex B), we accept '{' not + followed by digits as a normal atom */ + if (!lre_is_digit(p[1])) { + if (s->is_unicode) + goto invalid_quant_count; + break; + } + p++; + quant_min = parse_digits(&p, true); + quant_max = quant_min; + if (*p == ',') { + p++; + if (lre_is_digit(*p)) { + quant_max = parse_digits(&p, true); + if (quant_max < quant_min) { + invalid_quant_count: + return re_parse_error(s, "invalid repetition count"); + } + } else { + quant_max = INT32_MAX; /* infinity */ + } + } + if (*p != '}' && !s->is_unicode) { + /* Annex B: normal atom if invalid '{' syntax */ + p = p1; + break; + } + if (re_parse_expect(s, &p, '}')) + return -1; + } + quantifier: + greedy = true; + if (*p == '?') { + p++; + greedy = false; + } + if (last_atom_start < 0) { + return re_parse_error(s, "nothing to repeat"); + } + { + bool need_capture_init, add_zero_advance_check; + int len, pos; + + /* the spec tells that if there is no advance when + running the atom after the first quant_min times, + then there is no match. We remove this test when we + are sure the atom always advances the position. */ + add_zero_advance_check = + re_need_check_adv_and_capture_init(&need_capture_init, + s->byte_code.buf + last_atom_start, + s->byte_code.size - last_atom_start); + + /* general case: need to reset the capture at each + iteration. We don't do it if there are no captures + in the atom or if we are sure all captures are + initialized in the atom. If quant_min = 0, we still + need to reset once the captures in case the atom + does not match. */ + if (need_capture_init && last_capture_count != s->capture_count) { + if (dbuf_insert(&s->byte_code, last_atom_start, 3)) + goto out_of_memory; + int pos = last_atom_start; + s->byte_code.buf[pos++] = REOP_save_reset; + s->byte_code.buf[pos++] = last_capture_count; + s->byte_code.buf[pos++] = s->capture_count - 1; + } + + len = s->byte_code.size - last_atom_start; + if (quant_min == 0) { + /* need to reset the capture in case the atom is + not executed */ + if (!need_capture_init && last_capture_count != s->capture_count) { + if (dbuf_insert(&s->byte_code, last_atom_start, 3)) + goto out_of_memory; + s->byte_code.buf[last_atom_start++] = REOP_save_reset; + s->byte_code.buf[last_atom_start++] = last_capture_count; + s->byte_code.buf[last_atom_start++] = s->capture_count - 1; + } + if (quant_max == 0) { + s->byte_code.size = last_atom_start; + } else if (quant_max == 1 || quant_max == INT32_MAX) { + bool has_goto = (quant_max == INT32_MAX); + if (dbuf_insert(&s->byte_code, last_atom_start, 5 + add_zero_advance_check * 2)) + goto out_of_memory; + s->byte_code.buf[last_atom_start] = REOP_split_goto_first + + greedy; + put_u32(s->byte_code.buf + last_atom_start + 1, + len + 5 * has_goto + add_zero_advance_check * 2 * 2); + if (add_zero_advance_check) { + s->byte_code.buf[last_atom_start + 1 + 4] = REOP_set_char_pos; + s->byte_code.buf[last_atom_start + 1 + 4 + 1] = 0; + re_emit_op_u8(s, REOP_check_advance, 0); + } + if (has_goto) + re_emit_goto(s, REOP_goto, last_atom_start); + } else { + if (dbuf_insert(&s->byte_code, last_atom_start, 11 + add_zero_advance_check * 2)) + goto out_of_memory; + pos = last_atom_start; + s->byte_code.buf[pos++] = REOP_split_goto_first + greedy; + put_u32(s->byte_code.buf + pos, 6 + add_zero_advance_check * 2 + len + 10); + pos += 4; + + s->byte_code.buf[pos++] = REOP_set_i32; + s->byte_code.buf[pos++] = 0; + put_u32(s->byte_code.buf + pos, quant_max); + pos += 4; + last_atom_start = pos; + if (add_zero_advance_check) { + s->byte_code.buf[pos++] = REOP_set_char_pos; + s->byte_code.buf[pos++] = 0; + } + re_emit_goto_u8_u32(s, (add_zero_advance_check ? REOP_loop_check_adv_split_next_first : REOP_loop_split_next_first) - greedy, 0, quant_max, last_atom_start); + } + } else if (quant_min == 1 && quant_max == INT32_MAX && + !add_zero_advance_check) { + re_emit_goto(s, REOP_split_next_first - greedy, + last_atom_start); + } else { + if (quant_min == quant_max) + add_zero_advance_check = false; + if (dbuf_insert(&s->byte_code, last_atom_start, 6 + add_zero_advance_check * 2)) + goto out_of_memory; + /* Note: we assume the string length is < INT32_MAX */ + pos = last_atom_start; + s->byte_code.buf[pos++] = REOP_set_i32; + s->byte_code.buf[pos++] = 0; + put_u32(s->byte_code.buf + pos, quant_max); + pos += 4; + last_atom_start = pos; + if (add_zero_advance_check) { + s->byte_code.buf[pos++] = REOP_set_char_pos; + s->byte_code.buf[pos++] = 0; + } + if (quant_min == quant_max) { + /* a simple loop is enough */ + re_emit_goto_u8(s, REOP_loop, 0, last_atom_start); + } else { + re_emit_goto_u8_u32(s, (add_zero_advance_check ? REOP_loop_check_adv_split_next_first : REOP_loop_split_next_first) - greedy, 0, quant_max - quant_min, last_atom_start); + } + } + last_atom_start = -1; + } + break; + default: + break; + } + } + s->buf_ptr = p; + return 0; + out_of_memory: + return re_parse_out_of_memory(s); +} + +static int re_parse_alternative(REParseState *s, bool is_backward_dir) +{ + const uint8_t *p; + int ret; + size_t start, term_start, end, term_size; + + start = s->byte_code.size; + for(;;) { + p = s->buf_ptr; + if (p >= s->buf_end) + break; + if (*p == '|' || *p == ')') + break; + term_start = s->byte_code.size; + ret = re_parse_term(s, is_backward_dir); + if (ret) + return ret; + if (is_backward_dir) { + /* reverse the order of the terms (XXX: inefficient, but + speed is not really critical here) */ + end = s->byte_code.size; + term_size = end - term_start; + if (dbuf_claim(&s->byte_code, term_size)) + return re_parse_out_of_memory(s); + memmove(s->byte_code.buf + start + term_size, + s->byte_code.buf + start, + end - start); + memcpy(s->byte_code.buf + start, s->byte_code.buf + end, + term_size); + } + } + return 0; +} + +static int re_parse_disjunction(REParseState *s, bool is_backward_dir) +{ + int start, len, pos; + + if (lre_check_stack_overflow(s->opaque, 0)) + return re_parse_error(s, "stack overflow"); + + start = s->byte_code.size; + if (re_parse_alternative(s, is_backward_dir)) + return -1; + while (*s->buf_ptr == '|') { + s->buf_ptr++; + + len = s->byte_code.size - start; + + /* insert a split before the first alternative */ + if (dbuf_insert(&s->byte_code, start, 5)) { + return re_parse_out_of_memory(s); + } + s->byte_code.buf[start] = REOP_split_next_first; + put_u32(s->byte_code.buf + start + 1, len + 5); + + pos = re_emit_op_u32(s, REOP_goto, 0); + + if (re_has_named_captures(s) && s->group_name_scope == GROUP_NAME_SCOPE_MAX) + return re_parse_error(s, "too many named groups"); + + s->group_name_scope++; + + if (re_parse_alternative(s, is_backward_dir)) + return -1; + + /* patch the goto ('pos' is only valid if the placeholder for the + offset could be emitted) */ + if (dbuf_error(&s->byte_code)) + return re_parse_out_of_memory(s); + len = s->byte_code.size - (pos + 4); + put_u32(s->byte_code.buf + pos, len); + } + return 0; +} + +/* Allocate the registers as a stack. The control flow is recursive so + the analysis can be linear. */ +static int compute_register_count(uint8_t *bc_buf, int bc_buf_len) +{ + int stack_size, stack_size_max, pos, opcode, len; + uint32_t val; + + stack_size = 0; + stack_size_max = 0; + bc_buf += RE_HEADER_LEN; + bc_buf_len -= RE_HEADER_LEN; + pos = 0; + while (pos < bc_buf_len) { + opcode = bc_buf[pos]; + len = reopcode_info[opcode].size; + assert(opcode < REOP_COUNT); + assert((pos + len) <= bc_buf_len); + switch(opcode) { + case REOP_set_i32: + case REOP_set_char_pos: + bc_buf[pos + 1] = stack_size; + stack_size++; + if (stack_size > stack_size_max) { + if (stack_size > REGISTER_COUNT_MAX) + return -1; + stack_size_max = stack_size; + } + break; + case REOP_check_advance: + case REOP_loop: + case REOP_loop_split_goto_first: + case REOP_loop_split_next_first: + assert(stack_size > 0); + stack_size--; + bc_buf[pos + 1] = stack_size; + break; + case REOP_loop_check_adv_split_goto_first: + case REOP_loop_check_adv_split_next_first: + assert(stack_size >= 2); + stack_size -= 2; + bc_buf[pos + 1] = stack_size; + break; + case REOP_range: + case REOP_range_i: + val = get_u16(bc_buf + pos + 1); + len += val * 4; + break; + case REOP_range32: + case REOP_range32_i: + val = get_u16(bc_buf + pos + 1); + len += val * 8; + break; + case REOP_back_reference: + case REOP_back_reference_i: + case REOP_backward_back_reference: + case REOP_backward_back_reference_i: + val = bc_buf[pos + 1]; + len += val; + break; + } + pos += len; + } + return stack_size_max; +} + +static void *lre_bytecode_realloc(void *opaque, void *ptr, size_t size) +{ + if (size > (INT32_MAX / 2)) { + /* the bytecode cannot be larger than 2G. Leave some slack to + avoid some overflows. */ + return NULL; + } else { + return lre_realloc(opaque, ptr, size); + } +} + +/* 'buf' must be a zero terminated UTF-8 string of length buf_len. + Return NULL if error and allocate an error message in *perror_msg, + otherwise the compiled bytecode and its length in plen. +*/ +uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size, + const char *buf, size_t buf_len, int re_flags, + void *opaque) +{ + REParseState s_s, *s = &s_s; + int register_count; + bool is_sticky; + + memset(s, 0, sizeof(*s)); + s->opaque = opaque; + s->buf_ptr = (const uint8_t *)buf; + s->buf_end = s->buf_ptr + buf_len; + s->buf_start = s->buf_ptr; + s->re_flags = re_flags; + s->is_unicode = ((re_flags & (LRE_FLAG_UNICODE | LRE_FLAG_UNICODE_SETS)) != 0); + is_sticky = ((re_flags & LRE_FLAG_STICKY) != 0); + s->ignore_case = ((re_flags & LRE_FLAG_IGNORECASE) != 0); + s->multi_line = ((re_flags & LRE_FLAG_MULTILINE) != 0); + s->dotall = ((re_flags & LRE_FLAG_DOTALL) != 0); + s->unicode_sets = ((re_flags & LRE_FLAG_UNICODE_SETS) != 0); + s->capture_count = 1; + s->total_capture_count = -1; + s->has_named_captures = -1; + + dbuf_init2(&s->byte_code, opaque, lre_bytecode_realloc); + dbuf_init2(&s->group_names, opaque, lre_realloc); + + dbuf_put_u16(&s->byte_code, re_flags); /* first element is the flags */ + dbuf_putc(&s->byte_code, 0); /* second element is the number of captures */ + dbuf_putc(&s->byte_code, 0); /* stack size */ + dbuf_put_u32(&s->byte_code, 0); /* bytecode length */ + + if (!is_sticky) { + /* iterate thru all positions (about the same as .*?( ... ) ) + . We do it without an explicit loop so that lock step + thread execution will be possible in an optimized + implementation */ + re_emit_op_u32(s, REOP_split_goto_first, 1 + 5); + re_emit_op(s, REOP_any); + re_emit_op_u32(s, REOP_goto, -(5 + 1 + 5)); + } + re_emit_op_u8(s, REOP_save_start, 0); + + if (re_parse_disjunction(s, false)) { + error: + dbuf_free(&s->byte_code); + dbuf_free(&s->group_names); + js__pstrcpy(error_msg, error_msg_size, s->u.error_msg); + *plen = 0; + return NULL; + } + + re_emit_op_u8(s, REOP_save_end, 0); + + re_emit_op(s, REOP_match); + + if (*s->buf_ptr != '\0') { + re_parse_error(s, "extraneous characters at the end"); + goto error; + } + + if (dbuf_error(&s->byte_code)) { + re_parse_out_of_memory(s); + goto error; + } + + register_count = compute_register_count(s->byte_code.buf, s->byte_code.size); + if (register_count < 0) { + re_parse_error(s, "too many imbricated quantifiers"); + goto error; + } + + s->byte_code.buf[RE_HEADER_CAPTURE_COUNT] = s->capture_count; + s->byte_code.buf[RE_HEADER_REGISTER_COUNT] = register_count; + put_u32(s->byte_code.buf + RE_HEADER_BYTECODE_LEN, + s->byte_code.size - RE_HEADER_LEN); + + /* add the named groups if needed */ + if (s->group_names.size > (s->capture_count - 1) * LRE_GROUP_NAME_TRAILER_LEN) { + if (dbuf_put(&s->byte_code, s->group_names.buf, s->group_names.size)) { + re_parse_out_of_memory(s); + goto error; + } + put_u16(s->byte_code.buf + RE_HEADER_FLAGS, + lre_get_flags(s->byte_code.buf) | LRE_FLAG_NAMED_GROUPS); + } + dbuf_free(&s->group_names); + +#ifdef DUMP_REOP + lre_dump_bytecode(s->byte_code.buf, s->byte_code.size); +#endif + + error_msg[0] = '\0'; + *plen = s->byte_code.size; + return s->byte_code.buf; +} + +static bool is_line_terminator(uint32_t c) +{ + return (c == '\n' || c == '\r' || c == CP_LS || c == CP_PS); +} + +#define GET_CHAR(c, cptr, cbuf_end, cbuf_type) \ + do { \ + if (cbuf_type == 0) { \ + c = *cptr++; \ + } else { \ + const uint16_t *_p = (const uint16_t *)cptr; \ + const uint16_t *_end = (const uint16_t *)cbuf_end; \ + c = *_p++; \ + if (is_hi_surrogate(c) && cbuf_type == 2) { \ + if (_p < _end && is_lo_surrogate(*_p)) { \ + c = from_surrogate(c, *_p++); \ + } \ + } \ + cptr = (const void *)_p; \ + } \ + } while (0) + +#define PEEK_CHAR(c, cptr, cbuf_end, cbuf_type) \ + do { \ + if (cbuf_type == 0) { \ + c = cptr[0]; \ + } else { \ + const uint16_t *_p = (const uint16_t *)cptr; \ + const uint16_t *_end = (const uint16_t *)cbuf_end; \ + c = *_p++; \ + if (is_hi_surrogate(c) && cbuf_type == 2) { \ + if (_p < _end && is_lo_surrogate(*_p)) { \ + c = from_surrogate(c, *_p); \ + } \ + } \ + } \ + } while (0) + +#define PEEK_PREV_CHAR(c, cptr, cbuf_start, cbuf_type) \ + do { \ + if (cbuf_type == 0) { \ + c = cptr[-1]; \ + } else { \ + const uint16_t *_p = (const uint16_t *)cptr - 1; \ + const uint16_t *_start = (const uint16_t *)cbuf_start; \ + c = *_p; \ + if (is_lo_surrogate(c) && cbuf_type == 2) { \ + if (_p > _start && is_hi_surrogate(_p[-1])) { \ + c = from_surrogate(*--_p, c); \ + } \ + } \ + } \ + } while (0) + +#define GET_PREV_CHAR(c, cptr, cbuf_start, cbuf_type) \ + do { \ + if (cbuf_type == 0) { \ + cptr--; \ + c = cptr[0]; \ + } else { \ + const uint16_t *_p = (const uint16_t *)cptr - 1; \ + const uint16_t *_start = (const uint16_t *)cbuf_start; \ + c = *_p; \ + if (is_lo_surrogate(c) && cbuf_type == 2) { \ + if (_p > _start && is_hi_surrogate(_p[-1])) { \ + c = from_surrogate(*--_p, c); \ + } \ + } \ + cptr = (const void *)_p; \ + } \ + } while (0) + +#define PREV_CHAR(cptr, cbuf_start, cbuf_type) \ + do { \ + if (cbuf_type == 0) { \ + cptr--; \ + } else { \ + const uint16_t *_p = (const uint16_t *)cptr - 1; \ + const uint16_t *_start = (const uint16_t *)cbuf_start; \ + if (is_lo_surrogate(*_p) && cbuf_type == 2) { \ + if (_p > _start && is_hi_surrogate(_p[-1])) { \ + --_p; \ + } \ + } \ + cptr = (const void *)_p; \ + } \ + } while (0) + +typedef enum { + RE_EXEC_STATE_SPLIT, + RE_EXEC_STATE_LOOKAHEAD, + RE_EXEC_STATE_NEGATIVE_LOOKAHEAD, +} REExecStateEnum; + +#if INTPTR_MAX >= INT64_MAX +#define BP_TYPE_BITS 3 +#else +#define BP_TYPE_BITS 2 +#endif + +typedef union { + uint8_t *ptr; + intptr_t val; /* for bp, the low BP_SHIFT bits store REExecStateEnum */ + struct { + uintptr_t val : sizeof(uintptr_t) * 8 - BP_TYPE_BITS; + uintptr_t type : BP_TYPE_BITS; + } bp; +} StackElem; + +typedef struct { + const uint8_t *cbuf; + const uint8_t *cbuf_end; + /* 0 = 8 bit chars, 1 = 16 bit chars, 2 = 16 bit chars, UTF-16 */ + int cbuf_type; + int capture_count; + bool is_unicode; + int interrupt_counter; + void *opaque; /* used for stack overflow check */ + + StackElem *stack_buf; + size_t stack_size; + StackElem static_stack_buf[32]; /* static stack to avoid allocation in most cases */ +} REExecContext; + +static int lre_poll_timeout(REExecContext *s) +{ + if (unlikely(--s->interrupt_counter <= 0)) { + s->interrupt_counter = INTERRUPT_COUNTER_INIT; + if (lre_check_timeout(s->opaque)) + return LRE_RET_TIMEOUT; + } + return 0; +} + +static no_inline int stack_realloc(REExecContext *s, size_t n) +{ + StackElem *new_stack; + size_t new_size; + new_size = s->stack_size * 3 / 2; + if (new_size < n) + new_size = n; + if (s->stack_buf == s->static_stack_buf) { + new_stack = lre_realloc(s->opaque, NULL, new_size * sizeof(StackElem)); + if (!new_stack) + return -1; + /* XXX: could use correct size */ + memcpy(new_stack, s->stack_buf, s->stack_size * sizeof(StackElem)); + } else { + new_stack = lre_realloc(s->opaque, s->stack_buf, new_size * sizeof(StackElem)); + if (!new_stack) + return -1; + } + s->stack_size = new_size; + s->stack_buf = new_stack; + return 0; +} + +/* return 1 if match, 0 if not match or < 0 if error. */ +static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture, + const uint8_t *pc, const uint8_t *cptr) +{ + int opcode; + int cbuf_type; + uint32_t val, c, idx; + const uint8_t *cbuf_end; + StackElem *sp, *bp, *stack_end; +#ifdef DUMP_EXEC + const uint8_t *pc_start = pc; /* TEST */ +#endif + cbuf_type = s->cbuf_type; + cbuf_end = s->cbuf_end; + + sp = s->stack_buf; + bp = s->stack_buf; + stack_end = s->stack_buf + s->stack_size; + +#define CHECK_STACK_SPACE(n) \ + if (unlikely((stack_end - sp) < (n))) { \ + size_t saved_sp = sp - s->stack_buf; \ + size_t saved_bp = bp - s->stack_buf; \ + if (stack_realloc(s, sp - s->stack_buf + (n))) \ + return LRE_RET_MEMORY_ERROR; \ + stack_end = s->stack_buf + s->stack_size; \ + sp = s->stack_buf + saved_sp; \ + bp = s->stack_buf + saved_bp; \ + } + + /* XXX: could test if the value was saved to reduce the stack size + but slower */ +#define SAVE_CAPTURE(idx, value) \ + { \ + CHECK_STACK_SPACE(2); \ + sp[0].val = idx; \ + sp[1].ptr = capture[idx]; \ + sp += 2; \ + capture[idx] = (value); \ + } + + /* avoid saving the previous value if already saved */ +#define SAVE_CAPTURE_CHECK(idx, value) \ + { \ + StackElem *sp1; \ + sp1 = sp; \ + for(;;) { \ + if (sp1 > bp) { \ + if (sp1[-2].val == idx) \ + break; \ + sp1 -= 2; \ + } else { \ + CHECK_STACK_SPACE(2); \ + sp[0].val = idx; \ + sp[1].ptr = capture[idx]; \ + sp += 2; \ + break; \ + } \ + } \ + capture[idx] = (value); \ + } + + +#ifdef DUMP_EXEC + printf("%5s %5s %5s %5s %s\n", "PC", "CP", "BP", "SP", "OPCODE"); +#endif + for(;;) { + opcode = *pc++; +#ifdef DUMP_EXEC + printf("%5ld %5ld %5ld %5ld %s\n", + pc - 1 - pc_start, + cbuf_type == 0 ? cptr - s->cbuf : (cptr - s->cbuf) / 2, + bp - s->stack_buf, + sp - s->stack_buf, + reopcode_info[opcode].name); +#endif + switch(opcode) { + case REOP_match: + return 1; + no_match: + for(;;) { + REExecStateEnum type; + if (bp == s->stack_buf) + return 0; + /* undo the modifications to capture[] */ + while (sp > bp) { + capture[sp[-2].val] = sp[-1].ptr; + sp -= 2; + } + + pc = sp[-3].ptr; + cptr = sp[-2].ptr; + type = sp[-1].bp.type; + bp = s->stack_buf + sp[-1].bp.val; + sp -= 3; + if (type != RE_EXEC_STATE_LOOKAHEAD) + break; + } + if (lre_poll_timeout(s)) + return LRE_RET_TIMEOUT; + break; + case REOP_lookahead_match: + /* pop all the saved states until reaching the start of + the lookahead and keep the updated captures and + variables and the corresponding undo info. */ + { + StackElem *sp1, *sp_top, *next_sp; + REExecStateEnum type; + + sp_top = sp; + for(;;) { + sp1 = sp; + sp = bp; + pc = sp[-3].ptr; + cptr = sp[-2].ptr; + type = sp[-1].bp.type; + bp = s->stack_buf + sp[-1].bp.val; + sp[-1].ptr = (void *)sp1; /* save the next value for the copy step */ + sp -= 3; + if (type == RE_EXEC_STATE_LOOKAHEAD) + break; + } + if (sp != s->stack_buf) { + /* keep the undo info if there is a saved state */ + sp1 = sp; + while (sp1 < sp_top) { + next_sp = (void *)sp1[2].ptr; + sp1 += 3; + while (sp1 < next_sp) + *sp++ = *sp1++; + } + } + } + break; + case REOP_negative_lookahead_match: + /* pop all the saved states until reaching start of the negative lookahead */ + for(;;) { + REExecStateEnum type; + type = bp[-1].bp.type; + /* undo the modifications to capture[] */ + while (sp > bp) { + capture[sp[-2].val] = sp[-1].ptr; + sp -= 2; + } + pc = sp[-3].ptr; + cptr = sp[-2].ptr; + type = sp[-1].bp.type; + bp = s->stack_buf + sp[-1].bp.val; + sp -= 3; + if (type == RE_EXEC_STATE_NEGATIVE_LOOKAHEAD) + break; + } + goto no_match; + case REOP_char32: + case REOP_char32_i: + val = get_u32(pc); + pc += 4; + goto test_char; + case REOP_char: + case REOP_char_i: + val = get_u16(pc); + pc += 2; + test_char: + if (cptr >= cbuf_end) + goto no_match; + GET_CHAR(c, cptr, cbuf_end, cbuf_type); + if (opcode == REOP_char_i || opcode == REOP_char32_i) { + c = lre_canonicalize(c, s->is_unicode); + } + if (val != c) + goto no_match; + break; + case REOP_split_goto_first: + case REOP_split_next_first: + { + const uint8_t *pc1; + + val = get_u32(pc); + pc += 4; + if (opcode == REOP_split_next_first) { + pc1 = pc + (int)val; + } else { + pc1 = pc; + pc = pc + (int)val; + } + CHECK_STACK_SPACE(3); + sp[0].ptr = (uint8_t *)pc1; + sp[1].ptr = (uint8_t *)cptr; + sp[2].bp.val = bp - s->stack_buf; + sp[2].bp.type = RE_EXEC_STATE_SPLIT; + sp += 3; + bp = sp; + } + break; + case REOP_lookahead: + case REOP_negative_lookahead: + val = get_u32(pc); + pc += 4; + CHECK_STACK_SPACE(3); + sp[0].ptr = (uint8_t *)(pc + (int)val); + sp[1].ptr = (uint8_t *)cptr; + sp[2].bp.val = bp - s->stack_buf; + sp[2].bp.type = RE_EXEC_STATE_LOOKAHEAD + opcode - REOP_lookahead; + sp += 3; + bp = sp; + break; + case REOP_goto: + val = get_u32(pc); + pc += 4 + (int)val; + if (lre_poll_timeout(s)) + return LRE_RET_TIMEOUT; + break; + case REOP_line_start: + case REOP_line_start_m: + if (cptr == s->cbuf) + break; + if (opcode == REOP_line_start) + goto no_match; + PEEK_PREV_CHAR(c, cptr, s->cbuf, cbuf_type); + if (!is_line_terminator(c)) + goto no_match; + break; + case REOP_line_end: + case REOP_line_end_m: + if (cptr == cbuf_end) + break; + if (opcode == REOP_line_end) + goto no_match; + PEEK_CHAR(c, cptr, cbuf_end, cbuf_type); + if (!is_line_terminator(c)) + goto no_match; + break; + case REOP_dot: + if (cptr == cbuf_end) + goto no_match; + GET_CHAR(c, cptr, cbuf_end, cbuf_type); + if (is_line_terminator(c)) + goto no_match; + break; + case REOP_any: + if (cptr == cbuf_end) + goto no_match; + GET_CHAR(c, cptr, cbuf_end, cbuf_type); + break; + case REOP_space: + if (cptr == cbuf_end) + goto no_match; + GET_CHAR(c, cptr, cbuf_end, cbuf_type); + if (!lre_is_space(c)) + goto no_match; + break; + case REOP_not_space: + if (cptr == cbuf_end) + goto no_match; + GET_CHAR(c, cptr, cbuf_end, cbuf_type); + if (lre_is_space(c)) + goto no_match; + break; + case REOP_save_start: + case REOP_save_end: + val = *pc++; + if (val >= (uint32_t)s->capture_count) + return LRE_RET_BYTECODE_ERROR; + idx = 2 * val + opcode - REOP_save_start; + SAVE_CAPTURE(idx, (uint8_t *)cptr); + break; + case REOP_save_reset: + { + uint32_t val2; + val = pc[0]; + val2 = pc[1]; + pc += 2; + if (val2 >= (uint32_t)s->capture_count) + return LRE_RET_BYTECODE_ERROR; + CHECK_STACK_SPACE(2 * (val2 - val + 1)); + while (val <= val2) { + idx = 2 * val; + SAVE_CAPTURE(idx, NULL); + idx = 2 * val + 1; + SAVE_CAPTURE(idx, NULL); + val++; + } + } + break; + case REOP_set_i32: + idx = 2 * s->capture_count + pc[0]; + val = get_u32(pc + 1); + pc += 5; + SAVE_CAPTURE_CHECK(idx, (void *)(uintptr_t)val); + break; + case REOP_loop: + { + uint32_t val2; + idx = 2 * s->capture_count + pc[0]; + val = get_u32(pc + 1); + pc += 5; + + val2 = (uintptr_t)capture[idx] - 1; + SAVE_CAPTURE_CHECK(idx, (void *)(uintptr_t)val2); + if (val2 != 0) { + pc += (int)val; + if (lre_poll_timeout(s)) + return LRE_RET_TIMEOUT; + } + } + break; + case REOP_loop_split_goto_first: + case REOP_loop_split_next_first: + case REOP_loop_check_adv_split_goto_first: + case REOP_loop_check_adv_split_next_first: + { + const uint8_t *pc1; + uint32_t val2, limit; + idx = 2 * s->capture_count + pc[0]; + limit = get_u32(pc + 1); + val = get_u32(pc + 5); + pc += 9; + + /* decrement the counter */ + val2 = (uintptr_t)capture[idx] - 1; + SAVE_CAPTURE_CHECK(idx, (void *)(uintptr_t)val2); + + if (val2 > limit) { + /* normal loop if counter > limit */ + pc += (int)val; + if (lre_poll_timeout(s)) + return LRE_RET_TIMEOUT; + } else { + /* check advance */ + if ((opcode == REOP_loop_check_adv_split_goto_first || + opcode == REOP_loop_check_adv_split_next_first) && + capture[idx + 1] == cptr && + val2 != limit) { + goto no_match; + } + + /* otherwise conditional split */ + if (val2 != 0) { + if (opcode == REOP_loop_split_next_first || + opcode == REOP_loop_check_adv_split_next_first) { + pc1 = pc + (int)val; + } else { + pc1 = pc; + pc = pc + (int)val; + } + CHECK_STACK_SPACE(3); + sp[0].ptr = (uint8_t *)pc1; + sp[1].ptr = (uint8_t *)cptr; + sp[2].bp.val = bp - s->stack_buf; + sp[2].bp.type = RE_EXEC_STATE_SPLIT; + sp += 3; + bp = sp; + } + } + } + break; + case REOP_set_char_pos: + idx = 2 * s->capture_count + pc[0]; + pc++; + SAVE_CAPTURE_CHECK(idx, (uint8_t *)cptr); + break; + case REOP_check_advance: + idx = 2 * s->capture_count + pc[0]; + pc++; + if (capture[idx] == cptr) + goto no_match; + break; + case REOP_word_boundary: + case REOP_word_boundary_i: + case REOP_not_word_boundary: + case REOP_not_word_boundary_i: + { + bool v1, v2; + int ignore_case = (opcode == REOP_word_boundary_i || opcode == REOP_not_word_boundary_i); + bool is_boundary = (opcode == REOP_word_boundary || opcode == REOP_word_boundary_i); + /* char before */ + if (cptr == s->cbuf) { + v1 = false; + } else { + PEEK_PREV_CHAR(c, cptr, s->cbuf, cbuf_type); + if (c < 256) { + v1 = (lre_is_word_byte(c) != 0); + } else { + v1 = ignore_case && (c == 0x017f || c == 0x212a); + } + } + /* current char */ + if (cptr >= cbuf_end) { + v2 = false; + } else { + PEEK_CHAR(c, cptr, cbuf_end, cbuf_type); + if (c < 256) { + v2 = (lre_is_word_byte(c) != 0); + } else { + v2 = ignore_case && (c == 0x017f || c == 0x212a); + } + } + if (v1 ^ v2 ^ is_boundary) + goto no_match; + } + break; + case REOP_back_reference: + case REOP_back_reference_i: + case REOP_backward_back_reference: + case REOP_backward_back_reference_i: + { + const uint8_t *cptr1, *cptr1_end, *cptr1_start; + const uint8_t *pc1; + uint32_t c1, c2; + int i, n; + + n = *pc++; + pc1 = pc; + pc += n; + + for(i = 0; i < n; i++) { + val = pc1[i]; + if (val >= s->capture_count) + goto no_match; + cptr1_start = capture[2 * val]; + cptr1_end = capture[2 * val + 1]; + /* test the first not empty capture */ + if (cptr1_start && cptr1_end) { + if (opcode == REOP_back_reference || + opcode == REOP_back_reference_i) { + cptr1 = cptr1_start; + while (cptr1 < cptr1_end) { + if (cptr >= cbuf_end) + goto no_match; + GET_CHAR(c1, cptr1, cptr1_end, cbuf_type); + GET_CHAR(c2, cptr, cbuf_end, cbuf_type); + if (opcode == REOP_back_reference_i) { + c1 = lre_canonicalize(c1, s->is_unicode); + c2 = lre_canonicalize(c2, s->is_unicode); + } + if (c1 != c2) + goto no_match; + } + } else { + cptr1 = cptr1_end; + while (cptr1 > cptr1_start) { + if (cptr == s->cbuf) + goto no_match; + GET_PREV_CHAR(c1, cptr1, cptr1_start, cbuf_type); + GET_PREV_CHAR(c2, cptr, s->cbuf, cbuf_type); + if (opcode == REOP_backward_back_reference_i) { + c1 = lre_canonicalize(c1, s->is_unicode); + c2 = lre_canonicalize(c2, s->is_unicode); + } + if (c1 != c2) + goto no_match; + } + } + break; + } + } + } + break; + case REOP_range: + case REOP_range_i: + { + int n; + uint32_t low, high, idx_min, idx_max, idx; + + n = get_u16(pc); /* n must be >= 1 */ + pc += 2; + if (cptr >= cbuf_end) + goto no_match; + GET_CHAR(c, cptr, cbuf_end, cbuf_type); + if (opcode == REOP_range_i) { + c = lre_canonicalize(c, s->is_unicode); + } + idx_min = 0; + low = get_u16(pc + 0 * 4); + if (c < low) + goto no_match; + idx_max = n - 1; + high = get_u16(pc + idx_max * 4 + 2); + /* 0xffff in for last value means +infinity */ + if (unlikely(c >= 0xffff) && high == 0xffff) + goto range_match; + if (c > high) + goto no_match; + while (idx_min <= idx_max) { + idx = (idx_min + idx_max) / 2; + low = get_u16(pc + idx * 4); + high = get_u16(pc + idx * 4 + 2); + if (c < low) + idx_max = idx - 1; + else if (c > high) + idx_min = idx + 1; + else + goto range_match; + } + goto no_match; + range_match: + pc += 4 * n; + } + break; + case REOP_range32: + case REOP_range32_i: + { + int n; + uint32_t low, high, idx_min, idx_max, idx; + + n = get_u16(pc); /* n must be >= 1 */ + pc += 2; + if (cptr >= cbuf_end) + goto no_match; + GET_CHAR(c, cptr, cbuf_end, cbuf_type); + if (opcode == REOP_range32_i) { + c = lre_canonicalize(c, s->is_unicode); + } + idx_min = 0; + low = get_u32(pc + 0 * 8); + if (c < low) + goto no_match; + idx_max = n - 1; + high = get_u32(pc + idx_max * 8 + 4); + if (c > high) + goto no_match; + while (idx_min <= idx_max) { + idx = (idx_min + idx_max) / 2; + low = get_u32(pc + idx * 8); + high = get_u32(pc + idx * 8 + 4); + if (c < low) + idx_max = idx - 1; + else if (c > high) + idx_min = idx + 1; + else + goto range32_match; + } + goto no_match; + range32_match: + pc += 8 * n; + } + break; + case REOP_prev: + /* go to the previous char */ + if (cptr == s->cbuf) + goto no_match; + PREV_CHAR(cptr, s->cbuf, cbuf_type); + break; + default: +#ifdef DUMP_EXEC + printf("unknown opcode pc=%ld\n", pc - 1 - pc_start); +#endif + abort(); + } + } +} + +/* Return 1 if match, 0 if not match or < 0 if error (see LRE_RET_x). cindex is the + starting position of the match and must be such as 0 <= cindex <= + clen. */ +int lre_exec(uint8_t **capture, + const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen, + int cbuf_type, void *opaque) +{ + REExecContext s_s, *s = &s_s; + int re_flags, i, ret; + const uint8_t *cptr; + + re_flags = lre_get_flags(bc_buf); + s->is_unicode = (re_flags & (LRE_FLAG_UNICODE | LRE_FLAG_UNICODE_SETS)) != 0; + s->capture_count = bc_buf[RE_HEADER_CAPTURE_COUNT]; + s->cbuf = cbuf; + s->cbuf_end = cbuf + (clen << cbuf_type); + s->cbuf_type = cbuf_type; + if (s->cbuf_type == 1 && s->is_unicode) + s->cbuf_type = 2; + s->interrupt_counter = INTERRUPT_COUNTER_INIT; + s->opaque = opaque; + + s->stack_buf = s->static_stack_buf; + s->stack_size = countof(s->static_stack_buf); + + for(i = 0; i < s->capture_count * 2; i++) + capture[i] = NULL; + + cptr = cbuf + (cindex << cbuf_type); + if (0 < cindex && cindex < clen && s->cbuf_type == 2) { + const uint16_t *p = (const uint16_t *)cptr; + if (is_lo_surrogate(*p) && is_hi_surrogate(p[-1])) { + cptr = (const uint8_t *)(p - 1); + } + } + + ret = lre_exec_backtrack(s, capture, bc_buf + RE_HEADER_LEN, cptr); + + if (s->stack_buf != s->static_stack_buf) + lre_realloc(s->opaque, s->stack_buf, 0); + return ret; +} + +int lre_get_alloc_count(const uint8_t *bc_buf) +{ + return bc_buf[RE_HEADER_CAPTURE_COUNT] * 2 + + bc_buf[RE_HEADER_REGISTER_COUNT]; +} + +/* Structurally validate serialized regexp bytecode (e.g. from JS_ReadObject) + before it is executed: a present header and a body length that fits within + the buffer. Returns 0 on success, -1 if the bytecode is malformed. */ +int lre_check_bytecode(const uint8_t *bc_buf, int bc_buf_len) +{ + uint32_t re_bytecode_len; + if (bc_buf_len < RE_HEADER_LEN) + return -1; + re_bytecode_len = get_u32(bc_buf + RE_HEADER_BYTECODE_LEN); + if (re_bytecode_len > (uint32_t)(bc_buf_len - RE_HEADER_LEN)) + return -1; + return 0; +} + +int lre_get_capture_count(const uint8_t *bc_buf) +{ + return bc_buf[RE_HEADER_CAPTURE_COUNT]; +} + +int lre_get_flags(const uint8_t *bc_buf) +{ + return get_u16(bc_buf + RE_HEADER_FLAGS); +} + +/* Return NULL if no group names. Otherwise, return a pointer to + 'capture_count - 1' zero terminated UTF-8 strings. */ +const char *lre_get_groupnames(const uint8_t *bc_buf) +{ + uint32_t re_bytecode_len; + if ((lre_get_flags(bc_buf) & LRE_FLAG_NAMED_GROUPS) == 0) + return NULL; + re_bytecode_len = get_u32(bc_buf + RE_HEADER_BYTECODE_LEN); + return (const char *)(bc_buf + RE_HEADER_LEN + re_bytecode_len); +} + +#ifdef TEST + +bool lre_check_stack_overflow(void *opaque, size_t alloca_size) +{ + return false; +} + +void *lre_realloc(void *opaque, void *ptr, size_t size) +{ + return realloc(ptr, size); +} + +int main(int argc, char **argv) +{ + int len, flags, ret, i; + uint8_t *bc; + char error_msg[64]; + uint8_t *capture; + const char *input; + int input_len, capture_count; + + if (argc < 4) { + printf("usage: %s regexp flags input\n", argv[0]); + return 1; + } + flags = atoi(argv[2]); + bc = lre_compile(&len, error_msg, sizeof(error_msg), argv[1], + strlen(argv[1]), flags, NULL); + if (!bc) { + fprintf(stderr, "error: %s\n", error_msg); + exit(1); + } + + input = argv[3]; + input_len = strlen(input); + + capture = malloc(sizeof(capture[0]) * lre_get_alloc_count(bc)); + ret = lre_exec(capture, bc, (uint8_t *)input, 0, input_len, 0, NULL); + printf("ret=%d\n", ret); + if (ret == 1) { + capture_count = lre_get_capture_count(bc); + for(i = 0; i < 2 * capture_count; i++) { + uint8_t *ptr; + ptr = capture[i]; + printf("%d: ", i); + if (!ptr) + printf(""); + else + printf("%u", (int)(ptr - (uint8_t *)input)); + printf("\n"); + } + } + free(capture); + return 0; +} +#endif diff --git a/userland/qjs/source/libregexp.h b/userland/qjs/source/libregexp.h new file mode 100644 index 0000000..44eded3 --- /dev/null +++ b/userland/qjs/source/libregexp.h @@ -0,0 +1,101 @@ +/* + * Regular Expression Engine + * + * Copyright (c) 2017-2018 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef LIBREGEXP_H +#define LIBREGEXP_H + +#include +#include + +#include "libunicode.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LRE_FLAG_GLOBAL (1 << 0) +#define LRE_FLAG_IGNORECASE (1 << 1) +#define LRE_FLAG_MULTILINE (1 << 2) +#define LRE_FLAG_DOTALL (1 << 3) +#define LRE_FLAG_UNICODE (1 << 4) +#define LRE_FLAG_STICKY (1 << 5) +#define LRE_FLAG_INDICES (1 << 6) /* Unused by libregexp, just recorded. */ +#define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */ +#define LRE_FLAG_UNICODE_SETS (1 << 8) + +#define LRE_RET_MEMORY_ERROR (-1) +#define LRE_RET_TIMEOUT (-2) +#define LRE_RET_BYTECODE_ERROR (-3) + +/* trailer length after the group name including the trailing '\0' */ +#define LRE_GROUP_NAME_TRAILER_LEN 2 + +uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size, + const char *buf, size_t buf_len, int re_flags, + void *opaque); +int lre_get_alloc_count(const uint8_t *bc_buf); +int lre_check_bytecode(const uint8_t *bc_buf, int bc_buf_len); +int lre_get_capture_count(const uint8_t *bc_buf); +int lre_get_flags(const uint8_t *bc_buf); +const char *lre_get_groupnames(const uint8_t *bc_buf); +int lre_exec(uint8_t **capture, + const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen, + int cbuf_type, void *opaque); + +int lre_parse_escape(const uint8_t **pp, int allow_utf16); +/* lre_is_space() is provided as an inline in libunicode.h */ + +/* must be provided by the user */ +bool lre_check_stack_overflow(void *opaque, size_t alloca_size); +/* must be provided by the user, return non zero if time out */ +int lre_check_timeout(void *opaque); +void *lre_realloc(void *opaque, void *ptr, size_t size); + +/* JS identifier test */ +extern uint32_t const lre_id_start_table_ascii[4]; +extern uint32_t const lre_id_continue_table_ascii[4]; + +static inline int lre_js_is_ident_first(int c) +{ + if ((uint32_t)c < 128) { + return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1; + } else { + return lre_is_id_start(c); + } +} + +static inline int lre_js_is_ident_next(int c) +{ + if ((uint32_t)c < 128) { + return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1; + } else { + /* ZWNJ and ZWJ are accepted in identifiers */ + return lre_is_id_continue(c) || c == 0x200C || c == 0x200D; + } +} + +#ifdef __cplusplus +} /* extern "C" { */ +#endif + +#endif /* LIBREGEXP_H */ diff --git a/userland/qjs/source/libunicode-table.h b/userland/qjs/source/libunicode-table.h new file mode 100644 index 0000000..f1cf304 --- /dev/null +++ b/userland/qjs/source/libunicode-table.h @@ -0,0 +1,5160 @@ +/* Compressed unicode tables */ +/* Automatically generated file - do not edit */ + +/* +UNICODE LICENSE V3 + +COPYRIGHT AND PERMISSION NOTICE + +Copyright © 1991-2026 Unicode, Inc. + +NOTICE TO USER: Carefully read the following legal agreement. BY +DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR +SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT +DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of data files and any associated documentation (the "Data Files") or +software and any associated documentation (the "Software") to deal in the +Data Files or Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, and/or sell +copies of the Data Files or Software, and to permit persons to whom the +Data Files or Software are furnished to do so, provided that either (a) +this copyright and permission notice appear with all copies of the Data +Files or Software, or (b) this copyright and permission notice appear in +associated Documentation. + +THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF +THIRD PARTY RIGHTS. + +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE +BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA +FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in these Data Files or Software without prior written +authorization of the copyright holder. +*/ + +#include + +static const uint32_t case_conv_table1[378] = { + 0x00209a30, 0x00309a00, 0x005a8173, 0x00601730, + 0x006c0730, 0x006f81b3, 0x00701700, 0x007c0700, + 0x007f8100, 0x00803040, 0x009801c3, 0x00988190, + 0x00990640, 0x009c9040, 0x00a481b4, 0x00a52e40, + 0x00bc0130, 0x00bc8640, 0x00bf8170, 0x00c00100, + 0x00c08130, 0x00c10440, 0x00c30130, 0x00c38240, + 0x00c48230, 0x00c58240, 0x00c70130, 0x00c78130, + 0x00c80130, 0x00c88240, 0x00c98130, 0x00ca0130, + 0x00ca8100, 0x00cb0130, 0x00cb8130, 0x00cc0240, + 0x00cd0100, 0x00cd8101, 0x00ce0130, 0x00ce8130, + 0x00cf0100, 0x00cf8130, 0x00d00640, 0x00d30130, + 0x00d38240, 0x00d48130, 0x00d60240, 0x00d70130, + 0x00d78240, 0x00d88230, 0x00d98440, 0x00db8130, + 0x00dc0240, 0x00de0240, 0x00df8100, 0x00e20350, + 0x00e38350, 0x00e50350, 0x00e69040, 0x00ee8100, + 0x00ef1240, 0x00f801b4, 0x00f88350, 0x00fa0240, + 0x00fb0130, 0x00fb8130, 0x00fc2840, 0x01100130, + 0x01111240, 0x011d0131, 0x011d8240, 0x011e8130, + 0x011f0131, 0x011f8201, 0x01208240, 0x01218130, + 0x01220130, 0x01228130, 0x01230a40, 0x01280101, + 0x01288101, 0x01290101, 0x01298100, 0x012a0100, + 0x012b0200, 0x012c8100, 0x012d8100, 0x012e0101, + 0x01300100, 0x01308101, 0x01318100, 0x01320101, + 0x01328101, 0x01330101, 0x01340100, 0x01348100, + 0x01350101, 0x01358101, 0x01360101, 0x01378100, + 0x01388101, 0x01390100, 0x013a8100, 0x013e8101, + 0x01400100, 0x01410101, 0x01418100, 0x01438101, + 0x01440100, 0x01448100, 0x01450200, 0x01460100, + 0x01490100, 0x014e8101, 0x014f0101, 0x01a28173, + 0x01b80440, 0x01bb0240, 0x01bd8300, 0x01bf8130, + 0x01c30130, 0x01c40330, 0x01c60130, 0x01c70230, + 0x01c801d0, 0x01c89130, 0x01d18930, 0x01d60100, + 0x01d68300, 0x01d801d3, 0x01d89100, 0x01e10173, + 0x01e18900, 0x01e60100, 0x01e68200, 0x01e78130, + 0x01e80173, 0x01e88173, 0x01ea8173, 0x01eb0173, + 0x01eb8100, 0x01ec1840, 0x01f80173, 0x01f88173, + 0x01f90100, 0x01f98100, 0x01fa01a0, 0x01fa8173, + 0x01fb8240, 0x01fc8130, 0x01fd0240, 0x01fe8330, + 0x02001030, 0x02082030, 0x02182000, 0x02281000, + 0x02302240, 0x02453640, 0x02600130, 0x02608e40, + 0x02678100, 0x02686040, 0x0298a630, 0x02b0a600, + 0x02c381b5, 0x08502631, 0x08638131, 0x08668131, + 0x08682b00, 0x087e8300, 0x09d05011, 0x09f80610, + 0x09fc0620, 0x0e400174, 0x0e408174, 0x0e410174, + 0x0e418174, 0x0e420174, 0x0e428174, 0x0e430174, + 0x0e438180, 0x0e440180, 0x0e448240, 0x0e482b30, + 0x0e5e8330, 0x0ebc8101, 0x0ebe8101, 0x0ec70101, + 0x0f007e40, 0x0f3f1840, 0x0f4b01b5, 0x0f4b81b6, + 0x0f4c01b6, 0x0f4c81b6, 0x0f4d01b7, 0x0f4d8180, + 0x0f4f0130, 0x0f506040, 0x0f800800, 0x0f840830, + 0x0f880600, 0x0f8c0630, 0x0f900800, 0x0f940830, + 0x0f980800, 0x0f9c0830, 0x0fa00600, 0x0fa40630, + 0x0fa801b0, 0x0fa88100, 0x0fa901d3, 0x0fa98100, + 0x0faa01d3, 0x0faa8100, 0x0fab01d3, 0x0fab8100, + 0x0fac8130, 0x0fad8130, 0x0fae8130, 0x0faf8130, + 0x0fb00800, 0x0fb40830, 0x0fb80200, 0x0fb90400, + 0x0fbb0201, 0x0fbc0201, 0x0fbd0201, 0x0fbe0201, + 0x0fc008b7, 0x0fc40867, 0x0fc808b8, 0x0fcc0868, + 0x0fd008b8, 0x0fd40868, 0x0fd80200, 0x0fd901b9, + 0x0fd981b1, 0x0fda01b9, 0x0fdb01b1, 0x0fdb81d7, + 0x0fdc0230, 0x0fdd0230, 0x0fde0161, 0x0fdf0173, + 0x0fe101b9, 0x0fe181b2, 0x0fe201ba, 0x0fe301b2, + 0x0fe381d8, 0x0fe40430, 0x0fe60162, 0x0fe80201, + 0x0fe901d0, 0x0fe981d0, 0x0feb01b0, 0x0feb81d0, + 0x0fec0230, 0x0fed0230, 0x0ff00201, 0x0ff101d3, + 0x0ff181d3, 0x0ff201ba, 0x0ff28101, 0x0ff301b0, + 0x0ff381d3, 0x0ff40231, 0x0ff50230, 0x0ff60131, + 0x0ff901ba, 0x0ff981b2, 0x0ffa01bb, 0x0ffb01b2, + 0x0ffb81d9, 0x0ffc0230, 0x0ffd0230, 0x0ffe0162, + 0x109301a0, 0x109501a0, 0x109581a0, 0x10990131, + 0x10a70101, 0x10b01031, 0x10b81001, 0x10c18240, + 0x125b1a31, 0x12681a01, 0x16003031, 0x16183001, + 0x16300240, 0x16310130, 0x16318130, 0x16320130, + 0x16328100, 0x16330100, 0x16338640, 0x16368130, + 0x16370130, 0x16378130, 0x16380130, 0x16390240, + 0x163a8240, 0x163f0230, 0x16406440, 0x16758440, + 0x16790240, 0x16802600, 0x16938100, 0x16968100, + 0x53202e40, 0x53401c40, 0x53910e40, 0x53993e40, + 0x53bc8440, 0x53be8130, 0x53bf0a40, 0x53c58240, + 0x53c68130, 0x53c80440, 0x53ca0101, 0x53cb1440, + 0x53d50130, 0x53d58130, 0x53d60130, 0x53d68130, + 0x53d70130, 0x53d80130, 0x53d88130, 0x53d90130, + 0x53d98131, 0x53da1040, 0x53e20131, 0x53e28130, + 0x53e30130, 0x53e38440, 0x53e58130, 0x53e61040, + 0x53ee0130, 0x53fa8240, 0x55a98101, 0x55b85020, + 0x7d8001b2, 0x7d8081b2, 0x7d8101b2, 0x7d8181da, + 0x7d8201da, 0x7d8281b3, 0x7d8301b3, 0x7d8981bb, + 0x7d8a01bb, 0x7d8a81bb, 0x7d8b01bc, 0x7d8b81bb, + 0x7f909a31, 0x7fa09a01, 0x82002831, 0x82142801, + 0x82582431, 0x826c2401, 0x82b80b31, 0x82be0f31, + 0x82c60731, 0x82ca0231, 0x82cb8b01, 0x82d18f01, + 0x82d98701, 0x82dd8201, 0x86403331, 0x86603301, + 0x86a81631, 0x86b81601, 0x8c502031, 0x8c602001, + 0xb7202031, 0xb7302001, 0xb7501931, 0xb75d9901, + 0xf4802231, 0xf4912201, +}; + +static const uint8_t case_conv_table2[378] = { + 0x01, 0x00, 0x9c, 0x06, 0x07, 0x4d, 0x03, 0x04, + 0x10, 0x00, 0x8f, 0x0b, 0x00, 0x00, 0x11, 0x00, + 0x08, 0x00, 0x53, 0x4b, 0x52, 0x00, 0x53, 0x00, + 0x54, 0x00, 0x3b, 0x55, 0x56, 0x00, 0x58, 0x5a, + 0x40, 0x5f, 0x5e, 0x00, 0x47, 0x50, 0x63, 0x65, + 0x43, 0x66, 0x00, 0x68, 0x00, 0x6a, 0x00, 0x6c, + 0x00, 0x6e, 0x00, 0x70, 0x00, 0x00, 0x41, 0x00, + 0x00, 0x00, 0x00, 0x1a, 0x00, 0x93, 0x00, 0x00, + 0x20, 0x36, 0x00, 0x28, 0x00, 0x24, 0x00, 0x24, + 0x25, 0x2d, 0x00, 0x13, 0x6d, 0x6f, 0x00, 0x29, + 0x27, 0x2a, 0x14, 0x16, 0x18, 0x1b, 0x1c, 0x41, + 0x1e, 0x42, 0x1f, 0x4e, 0x3c, 0x40, 0x22, 0x21, + 0x44, 0x21, 0x43, 0x26, 0x28, 0x27, 0x29, 0x23, + 0x2b, 0x4b, 0x2d, 0x46, 0x2f, 0x4c, 0x31, 0x4d, + 0x33, 0x47, 0x45, 0x99, 0x00, 0x00, 0x97, 0x91, + 0x7f, 0x80, 0x85, 0x86, 0x12, 0x82, 0x84, 0x78, + 0x79, 0x12, 0x7d, 0xa3, 0x7e, 0x7a, 0x7b, 0x8c, + 0x92, 0x98, 0xa6, 0xa0, 0x87, 0x00, 0x9a, 0xa1, + 0x95, 0x77, 0x33, 0x95, 0x00, 0x90, 0x00, 0x76, + 0x9b, 0x9a, 0x99, 0x98, 0x00, 0x00, 0xa0, 0x00, + 0x9e, 0x00, 0xa3, 0xa2, 0x15, 0x31, 0x32, 0x33, + 0xb7, 0xb8, 0x53, 0xac, 0xab, 0x12, 0x14, 0x1e, + 0x21, 0x22, 0x22, 0x2a, 0x34, 0x35, 0x00, 0xa8, + 0xa9, 0x39, 0x22, 0x4c, 0x00, 0x00, 0x97, 0x01, + 0x5a, 0xda, 0x1d, 0x36, 0x05, 0x00, 0xc7, 0xc6, + 0xc9, 0xc8, 0xcb, 0xca, 0xcd, 0xcc, 0xcf, 0xce, + 0xc4, 0xd8, 0x45, 0xd9, 0x42, 0xda, 0x46, 0xdb, + 0xd1, 0xd3, 0xd5, 0xd7, 0xdd, 0xdc, 0xf1, 0xf9, + 0x01, 0x11, 0x0a, 0x12, 0x80, 0x9f, 0x00, 0x21, + 0x80, 0xa3, 0xf0, 0x00, 0xc0, 0x40, 0xc6, 0x60, + 0xea, 0xde, 0xe6, 0x99, 0xc0, 0x00, 0x00, 0x06, + 0x60, 0xdf, 0x29, 0x00, 0x15, 0x12, 0x06, 0x16, + 0xfb, 0xe0, 0x09, 0x15, 0x12, 0x84, 0x0b, 0xc6, + 0x16, 0x02, 0xe2, 0x06, 0xc0, 0x40, 0x00, 0x46, + 0x60, 0xe1, 0xe3, 0x6d, 0x37, 0x38, 0x39, 0x18, + 0x17, 0x1a, 0x19, 0x00, 0x1d, 0x1c, 0x1f, 0x1e, + 0x00, 0x61, 0xba, 0x67, 0x45, 0x48, 0x00, 0x50, + 0x64, 0x4f, 0x51, 0x00, 0x00, 0x49, 0x00, 0x00, + 0x00, 0xa5, 0xa6, 0xa7, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb9, 0x00, 0x00, 0x5c, 0x00, 0x4a, 0x00, + 0x5d, 0x57, 0x59, 0x62, 0x60, 0x72, 0x6b, 0x71, + 0x52, 0x00, 0x3e, 0x69, 0xbb, 0x00, 0x5b, 0x00, + 0x25, 0x00, 0x48, 0xaa, 0x8a, 0x8b, 0x8c, 0xab, + 0xac, 0x58, 0x58, 0xaf, 0x94, 0xb0, 0x6f, 0xb2, + 0x61, 0x60, 0x63, 0x62, 0x65, 0x64, 0x6a, 0x6b, + 0x6c, 0x6d, 0x66, 0x67, 0x68, 0x69, 0x6f, 0x6e, + 0x71, 0x70, 0x73, 0x72, 0x75, 0x74, 0x77, 0x76, + 0x79, 0x78, +}; + +static const uint16_t case_conv_ext[58] = { + 0x0399, 0x0308, 0x0301, 0x03a5, 0x0313, 0x0300, 0x0342, 0x0391, + 0x0397, 0x03a9, 0x0046, 0x0049, 0x004c, 0x0053, 0x0069, 0x0307, + 0x02bc, 0x004e, 0x004a, 0x030c, 0x0535, 0x0552, 0x0048, 0x0331, + 0x0054, 0x0057, 0x030a, 0x0059, 0x0041, 0x02be, 0x1f08, 0x1f80, + 0x1f28, 0x1f90, 0x1f68, 0x1fa0, 0x1fba, 0x0386, 0x1fb3, 0x1fca, + 0x0389, 0x1fc3, 0x03a1, 0x1ffa, 0x038f, 0x1ff3, 0x0544, 0x0546, + 0x053b, 0x054e, 0x053d, 0x03b8, 0x0462, 0xa64a, 0x1e60, 0x03c9, + 0x006b, 0x00e5, +}; + +static const uint8_t unicode_prop_Cased1_table[190] = { + 0x40, 0xa9, 0x80, 0x8e, 0x80, 0xfc, 0x80, 0xd3, + 0x80, 0x9b, 0x81, 0x8d, 0x02, 0x80, 0xe1, 0x80, + 0x91, 0x85, 0x9a, 0x01, 0x00, 0x01, 0x11, 0x03, + 0x04, 0x08, 0x01, 0x08, 0x30, 0x08, 0x01, 0x15, + 0x20, 0x01, 0x31, 0x99, 0x31, 0x9d, 0x84, 0x40, + 0x94, 0x80, 0xd6, 0x82, 0xa6, 0x80, 0x41, 0x62, + 0x80, 0xa6, 0x80, 0x4b, 0x72, 0x80, 0x4c, 0x02, + 0xf8, 0x02, 0x80, 0x8f, 0x80, 0xb0, 0x40, 0xdb, + 0x08, 0x80, 0x41, 0xd0, 0x80, 0x8c, 0x80, 0x8f, + 0x8c, 0xe4, 0x03, 0x01, 0x89, 0x00, 0x14, 0x28, + 0x10, 0x11, 0x02, 0x01, 0x18, 0x0b, 0x24, 0x4b, + 0x26, 0x01, 0x01, 0x86, 0xe5, 0x80, 0x60, 0x79, + 0xb6, 0x81, 0x40, 0x91, 0x81, 0xbd, 0x88, 0x94, + 0x05, 0x80, 0x98, 0x80, 0xc0, 0x1a, 0x82, 0x43, + 0x34, 0xa2, 0x06, 0x80, 0x8d, 0x60, 0x5c, 0x15, + 0x01, 0x10, 0xa9, 0x80, 0x88, 0x60, 0xcc, 0x44, + 0xd4, 0x80, 0xc6, 0x01, 0x08, 0x09, 0x0b, 0x80, + 0x8b, 0x00, 0x06, 0x80, 0xc0, 0x03, 0x0f, 0x06, + 0x80, 0x9b, 0x03, 0x04, 0x00, 0x16, 0x80, 0x41, + 0x53, 0x81, 0x98, 0x80, 0x98, 0x80, 0x9e, 0x80, + 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, + 0x98, 0x80, 0x9e, 0x80, 0x98, 0x07, 0x47, 0x33, + 0x89, 0x80, 0x93, 0x2d, 0x41, 0x04, 0xbd, 0x50, + 0xc1, 0x99, 0x85, 0x99, 0x85, 0x99, +}; + +static const uint8_t unicode_prop_Cased1_index[18] = { + 0xb9, 0x02, 0x80, 0xa0, 0x1e, 0x40, 0x9e, 0xa6, + 0x40, 0x55, 0xd4, 0x21, 0x15, 0xd7, 0x21, 0x8a, + 0xf1, 0x01, +}; + +static const uint8_t unicode_prop_Case_Ignorable_table[785] = { + 0xa6, 0x05, 0x80, 0x8a, 0x80, 0xa2, 0x00, 0x80, + 0xc6, 0x03, 0x00, 0x03, 0x01, 0x81, 0x41, 0xf6, + 0x40, 0xbf, 0x19, 0x18, 0x88, 0x08, 0x80, 0x40, + 0xfa, 0x86, 0x40, 0xce, 0x04, 0x80, 0xb0, 0xac, + 0x00, 0x01, 0x01, 0x00, 0xab, 0x80, 0x8a, 0x85, + 0x89, 0x8a, 0x00, 0xa2, 0x80, 0x89, 0x94, 0x8f, + 0x80, 0xe4, 0x38, 0x89, 0x03, 0xa0, 0x00, 0x80, + 0x9d, 0x9a, 0xda, 0x8a, 0xb9, 0x8a, 0x18, 0x08, + 0x97, 0x97, 0xaa, 0x82, 0xab, 0x06, 0x0c, 0x88, + 0xa8, 0xb9, 0xb6, 0x00, 0x03, 0x3b, 0x02, 0x86, + 0x89, 0x81, 0x8c, 0x80, 0x8e, 0x80, 0xb9, 0x03, + 0x1f, 0x80, 0x93, 0x81, 0x99, 0x01, 0x81, 0xb8, + 0x03, 0x0b, 0x09, 0x12, 0x80, 0x9d, 0x0a, 0x80, + 0x8a, 0x81, 0xb8, 0x03, 0x20, 0x0b, 0x80, 0x93, + 0x81, 0x95, 0x28, 0x80, 0xb9, 0x01, 0x00, 0x1f, + 0x06, 0x81, 0x8a, 0x81, 0x9d, 0x80, 0xbc, 0x80, + 0x8b, 0x80, 0xb1, 0x02, 0x80, 0xb6, 0x00, 0x14, + 0x10, 0x1e, 0x81, 0x8a, 0x81, 0x9c, 0x80, 0xb9, + 0x01, 0x05, 0x04, 0x81, 0x93, 0x81, 0x9b, 0x81, + 0xb8, 0x0b, 0x1f, 0x80, 0x93, 0x81, 0x9c, 0x80, + 0xc7, 0x06, 0x10, 0x80, 0xd9, 0x01, 0x86, 0x8a, + 0x88, 0xe1, 0x01, 0x88, 0x88, 0x00, 0x86, 0xc8, + 0x81, 0x9a, 0x00, 0x00, 0x80, 0xb6, 0x8d, 0x04, + 0x01, 0x84, 0x8a, 0x80, 0xa3, 0x88, 0x80, 0xe5, + 0x18, 0x28, 0x09, 0x81, 0x98, 0x0b, 0x82, 0x8f, + 0x83, 0x8c, 0x01, 0x0d, 0x80, 0x8e, 0x80, 0xdd, + 0x80, 0x42, 0x5f, 0x82, 0x43, 0xb1, 0x82, 0x9c, + 0x81, 0x9d, 0x81, 0x9d, 0x81, 0xbf, 0x08, 0x37, + 0x01, 0x8a, 0x10, 0x20, 0xac, 0x84, 0xb2, 0x80, + 0xc0, 0x81, 0xa1, 0x80, 0xf5, 0x13, 0x81, 0x88, + 0x05, 0x82, 0x40, 0xda, 0x09, 0x80, 0xb9, 0x00, + 0x30, 0x00, 0x01, 0x3d, 0x89, 0x08, 0xa6, 0x07, + 0xad, 0x81, 0x8b, 0x93, 0x83, 0xaf, 0x00, 0x20, + 0x04, 0x80, 0xa7, 0x88, 0x8b, 0x81, 0x9f, 0x19, + 0x08, 0x82, 0xb7, 0x00, 0x0a, 0x00, 0x82, 0xb9, + 0x39, 0x81, 0xbf, 0x85, 0xd1, 0x10, 0x8c, 0x06, + 0x18, 0x28, 0x11, 0xb1, 0xbe, 0x8c, 0x80, 0xa1, + 0xe4, 0x41, 0xbc, 0x00, 0x82, 0x8a, 0x82, 0x8c, + 0x82, 0x8c, 0x82, 0x8c, 0x81, 0x8b, 0x27, 0x81, + 0x89, 0x01, 0x01, 0x84, 0xb0, 0x20, 0x89, 0x00, + 0x8c, 0x80, 0x8f, 0x8c, 0xb2, 0xa0, 0x4b, 0x8a, + 0x81, 0xf0, 0x82, 0xfc, 0x80, 0x8e, 0x80, 0xdf, + 0x9f, 0xae, 0x80, 0x41, 0xd4, 0x80, 0xa3, 0x1a, + 0x24, 0x80, 0xdc, 0x85, 0xdc, 0x82, 0x60, 0x6f, + 0x15, 0x80, 0x44, 0xe1, 0x85, 0x41, 0x0d, 0x80, + 0xe1, 0x18, 0x89, 0x00, 0x9b, 0x83, 0xcf, 0x81, + 0x8d, 0xa1, 0xcd, 0x80, 0x96, 0x82, 0xe5, 0x1a, + 0x0f, 0x02, 0x03, 0x80, 0x98, 0x0c, 0x80, 0x40, + 0x96, 0x81, 0x99, 0x91, 0x8c, 0x80, 0xa5, 0x87, + 0x98, 0x8a, 0xad, 0x82, 0xaf, 0x01, 0x19, 0x81, + 0x90, 0x80, 0x94, 0x81, 0xc1, 0x29, 0x09, 0x81, + 0x8b, 0x07, 0x80, 0xa2, 0x80, 0x8a, 0x80, 0xb2, + 0x00, 0x11, 0x0c, 0x08, 0x80, 0x9a, 0x80, 0x8d, + 0x0c, 0x08, 0x80, 0xe3, 0x84, 0x88, 0x82, 0xf8, + 0x01, 0x03, 0x80, 0x60, 0x4f, 0x2f, 0x80, 0x40, + 0x92, 0x90, 0x42, 0x3c, 0x8f, 0x10, 0x8b, 0x8f, + 0xa1, 0x01, 0x80, 0x40, 0xa8, 0x06, 0x05, 0x80, + 0x8a, 0x80, 0xa2, 0x00, 0x80, 0xae, 0x80, 0xac, + 0x81, 0xc2, 0x80, 0x94, 0x82, 0x42, 0x00, 0x80, + 0x40, 0xe1, 0x80, 0x40, 0x94, 0x84, 0x44, 0x04, + 0x28, 0xa9, 0x80, 0x88, 0x42, 0x45, 0x10, 0x0c, + 0x83, 0xa7, 0x13, 0x80, 0x40, 0xa4, 0x81, 0x42, + 0x3c, 0x83, 0xa5, 0x80, 0x99, 0x20, 0x80, 0x41, + 0x3a, 0x81, 0x97, 0x80, 0xb3, 0x85, 0xc5, 0x8a, + 0xb0, 0x83, 0xfa, 0x80, 0xb5, 0x8e, 0xa8, 0x01, + 0x81, 0x89, 0x82, 0xb0, 0x19, 0x09, 0x03, 0x80, + 0x89, 0x80, 0xb1, 0x82, 0xa3, 0x20, 0x87, 0xbd, + 0x80, 0x8b, 0x81, 0xb3, 0x88, 0x89, 0x19, 0x80, + 0xde, 0x11, 0x00, 0x0d, 0x01, 0x80, 0x40, 0x9c, + 0x02, 0x87, 0x94, 0x81, 0xb8, 0x0a, 0x80, 0xa4, + 0x32, 0x84, 0xc5, 0x85, 0x8c, 0x00, 0x00, 0x80, + 0x8d, 0x81, 0xd4, 0x39, 0x10, 0x80, 0x96, 0x80, + 0xd3, 0x28, 0x03, 0x08, 0x81, 0x40, 0xed, 0x1d, + 0x08, 0x81, 0x9a, 0x81, 0xd4, 0x39, 0x00, 0x81, + 0xe9, 0x00, 0x01, 0x28, 0x80, 0xe4, 0x00, 0x01, + 0x18, 0x84, 0x41, 0x02, 0x88, 0x01, 0x40, 0xff, + 0x08, 0x03, 0x80, 0x40, 0x8f, 0x19, 0x0b, 0x80, + 0x9f, 0x89, 0xa7, 0x29, 0x1f, 0x80, 0x88, 0x29, + 0x82, 0xad, 0x8c, 0x01, 0x40, 0xc5, 0x00, 0x10, + 0x80, 0x40, 0xc8, 0x30, 0x28, 0x80, 0xd1, 0x95, + 0x0e, 0x01, 0x01, 0xf9, 0x2a, 0x00, 0x08, 0x30, + 0x80, 0xc7, 0x0a, 0x00, 0x80, 0xc0, 0x80, 0x41, + 0x18, 0x81, 0x8a, 0x81, 0xb3, 0x24, 0x00, 0x80, + 0x96, 0x80, 0x54, 0xd4, 0x90, 0x85, 0x8e, 0x60, + 0x2c, 0xc7, 0x8b, 0x12, 0x49, 0xbf, 0x84, 0xba, + 0x86, 0x88, 0x83, 0x41, 0xfb, 0x82, 0xa7, 0x81, + 0x41, 0xe1, 0x80, 0xbe, 0x90, 0xbf, 0x08, 0x81, + 0x8c, 0x81, 0x60, 0x3f, 0xfb, 0x18, 0x30, 0x81, + 0x4c, 0x9d, 0x08, 0x83, 0x52, 0x5b, 0xad, 0x81, + 0x96, 0x42, 0x1f, 0x82, 0x88, 0x8f, 0x0e, 0x9d, + 0x83, 0x40, 0x93, 0x82, 0x47, 0xba, 0xb6, 0x83, + 0xb1, 0x38, 0x8d, 0x80, 0x95, 0x20, 0x8e, 0x45, + 0x4f, 0x30, 0x90, 0x0e, 0x01, 0x04, 0x84, 0xbd, + 0xa0, 0x80, 0x40, 0x9f, 0x8d, 0x41, 0x6f, 0x80, + 0xbc, 0x83, 0x41, 0xfa, 0x84, 0x40, 0xfd, 0x81, + 0x40, 0xf2, 0x01, 0x06, 0x0c, 0x80, 0x88, 0x80, + 0x41, 0xcf, 0x86, 0xec, 0x87, 0x4a, 0xae, 0x84, + 0x6c, 0x0c, 0x00, 0x80, 0x9d, 0xdf, 0xff, 0x40, + 0xef, +}; + +static const uint8_t unicode_prop_Case_Ignorable_index[75] = { + 0xbe, 0x05, 0x00, 0xfe, 0x07, 0x00, 0x52, 0x0a, + 0xa0, 0xc1, 0x0b, 0x00, 0x82, 0x0d, 0x00, 0x3f, + 0x10, 0x80, 0xd4, 0x17, 0x40, 0xde, 0x1a, 0x20, + 0xe9, 0x1c, 0x00, 0x72, 0x20, 0x00, 0x16, 0xa0, + 0x40, 0xc6, 0xa8, 0x40, 0xc2, 0xaa, 0xa0, 0x30, + 0xfe, 0x00, 0xb1, 0x07, 0x41, 0x51, 0x0f, 0x01, + 0xd0, 0x11, 0x01, 0x5f, 0x14, 0x01, 0x44, 0x19, + 0x61, 0xa8, 0x1c, 0x01, 0x2a, 0x61, 0x61, 0xff, + 0xaf, 0x01, 0x19, 0xe0, 0x61, 0x00, 0xe7, 0x01, + 0xf0, 0x01, 0x0e, +}; + +static const uint8_t unicode_prop_ID_Start_table[1146] = { + 0xc0, 0x99, 0x85, 0x99, 0xae, 0x80, 0x89, 0x03, + 0x04, 0x96, 0x80, 0x9e, 0x80, 0x41, 0xc9, 0x83, + 0x8b, 0x8d, 0x26, 0x00, 0x80, 0x40, 0x80, 0x20, + 0x09, 0x18, 0x05, 0x00, 0x10, 0x00, 0x93, 0x80, + 0xd2, 0x80, 0x40, 0x8a, 0x87, 0x40, 0xa5, 0x80, + 0xa5, 0x08, 0x85, 0xa8, 0xc6, 0x9a, 0x1b, 0xac, + 0xaa, 0xa2, 0x08, 0xe2, 0x00, 0x8e, 0x0e, 0x81, + 0x89, 0x11, 0x80, 0x8f, 0x00, 0x9d, 0x9c, 0xd8, + 0x8a, 0x80, 0x97, 0xa0, 0x88, 0x0b, 0x04, 0x95, + 0x18, 0x88, 0x02, 0x80, 0x96, 0x98, 0x86, 0x8a, + 0x84, 0x97, 0x06, 0x8f, 0xa9, 0xb9, 0xb5, 0x10, + 0x91, 0x06, 0x89, 0x8e, 0x8f, 0x1f, 0x09, 0x81, + 0x95, 0x06, 0x00, 0x13, 0x10, 0x8f, 0x80, 0x8c, + 0x08, 0x82, 0x8d, 0x81, 0x89, 0x07, 0x2b, 0x09, + 0x95, 0x06, 0x01, 0x01, 0x01, 0x9e, 0x18, 0x80, + 0x92, 0x82, 0x8f, 0x88, 0x02, 0x80, 0x95, 0x06, + 0x01, 0x04, 0x10, 0x91, 0x80, 0x8e, 0x81, 0x96, + 0x80, 0x8a, 0x39, 0x09, 0x95, 0x06, 0x01, 0x04, + 0x10, 0x9d, 0x08, 0x82, 0x8e, 0x80, 0x90, 0x00, + 0x2a, 0x10, 0x1a, 0x08, 0x00, 0x0a, 0x0a, 0x12, + 0x8b, 0x95, 0x80, 0xb3, 0x38, 0x10, 0x96, 0x80, + 0x8f, 0x10, 0x99, 0x10, 0x09, 0x81, 0x9d, 0x03, + 0x38, 0x10, 0x96, 0x80, 0x89, 0x04, 0x10, 0x9d, + 0x10, 0x81, 0x8e, 0x81, 0x90, 0x88, 0x02, 0x80, + 0xa8, 0x08, 0x8f, 0x04, 0x17, 0x82, 0x97, 0x2c, + 0x91, 0x82, 0x97, 0x80, 0x88, 0x00, 0x0e, 0xb9, + 0xaf, 0x01, 0x8b, 0x86, 0xb9, 0x08, 0x00, 0x20, + 0x97, 0x00, 0x80, 0x89, 0x01, 0x88, 0x01, 0x20, + 0x80, 0x94, 0x83, 0x9f, 0x80, 0xbe, 0x38, 0xa3, + 0x9a, 0x84, 0xf2, 0xaa, 0x93, 0x80, 0x8f, 0x2b, + 0x1a, 0x02, 0x0e, 0x13, 0x8c, 0x8b, 0x80, 0x90, + 0xa5, 0x00, 0x20, 0x81, 0xaa, 0x80, 0x41, 0x4c, + 0x03, 0x0e, 0x00, 0x03, 0x81, 0xa8, 0x03, 0x81, + 0xa0, 0x03, 0x0e, 0x00, 0x03, 0x81, 0x8e, 0x80, + 0xb8, 0x03, 0x81, 0xc2, 0xa4, 0x8f, 0x8f, 0xd5, + 0x0d, 0x82, 0x42, 0x6b, 0x81, 0x90, 0x80, 0x99, + 0x84, 0xca, 0x82, 0x8a, 0x86, 0x91, 0x8c, 0x92, + 0x8d, 0x91, 0x8d, 0x8c, 0x02, 0x8e, 0xb3, 0xa2, + 0x03, 0x80, 0xc2, 0xd8, 0x86, 0xa8, 0x00, 0x84, + 0xc5, 0x89, 0x9e, 0xb0, 0x9d, 0x0c, 0x8a, 0xab, + 0x83, 0x99, 0xb5, 0x96, 0x88, 0xb4, 0xd1, 0x80, + 0xdc, 0xae, 0x90, 0x87, 0xb5, 0x9d, 0x8c, 0x81, + 0x89, 0xab, 0x99, 0xa3, 0xa8, 0x82, 0x89, 0xa3, + 0x81, 0x8a, 0x84, 0xaa, 0x0a, 0xa8, 0x18, 0x28, + 0x0a, 0x04, 0x40, 0xbf, 0xbf, 0x41, 0x15, 0x0d, + 0x81, 0xa5, 0x0d, 0x0f, 0x00, 0x00, 0x00, 0x80, + 0x9e, 0x81, 0xb4, 0x06, 0x00, 0x12, 0x06, 0x13, + 0x0d, 0x83, 0x8c, 0x22, 0x06, 0xf3, 0x80, 0x8c, + 0x80, 0x8f, 0x8c, 0xe4, 0x03, 0x01, 0x89, 0x00, + 0x0d, 0x28, 0x00, 0x00, 0x80, 0x8f, 0x0b, 0x24, + 0x18, 0x90, 0xa8, 0x4a, 0x76, 0x40, 0xe4, 0x2b, + 0x11, 0x8b, 0xa5, 0x00, 0x20, 0x81, 0xb7, 0x30, + 0x8f, 0x96, 0x88, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x86, 0x42, 0x25, 0x82, 0x98, 0x88, + 0x34, 0x0c, 0x83, 0xd5, 0x1c, 0x80, 0xd9, 0x03, + 0x84, 0xaa, 0x80, 0xdd, 0x90, 0x9f, 0xaf, 0x8f, + 0x41, 0xff, 0x59, 0xbf, 0xbf, 0x60, 0x56, 0x8c, + 0xc2, 0xad, 0x81, 0x41, 0x0c, 0x82, 0x8f, 0x89, + 0x81, 0x93, 0xae, 0x8f, 0x9e, 0x81, 0xcf, 0xa6, + 0x88, 0x81, 0xe6, 0x81, 0xd1, 0x93, 0x90, 0x02, + 0x03, 0x80, 0x96, 0x9c, 0xb3, 0x8d, 0xb1, 0xbd, + 0x2a, 0x00, 0x81, 0x8a, 0x9b, 0x89, 0x96, 0x98, + 0x9c, 0x86, 0xae, 0x9b, 0x80, 0x8f, 0x20, 0x89, + 0x89, 0x20, 0xa8, 0x96, 0x10, 0x87, 0x93, 0x96, + 0x10, 0x82, 0xb1, 0x00, 0x11, 0x0c, 0x08, 0x00, + 0x97, 0x11, 0x8a, 0x32, 0x8b, 0x29, 0x29, 0x85, + 0x88, 0x30, 0x30, 0xaa, 0x80, 0x8d, 0x85, 0xf2, + 0x9c, 0x60, 0x2b, 0xa3, 0x8b, 0x96, 0x83, 0xb0, + 0x60, 0x21, 0x03, 0x41, 0x6d, 0x81, 0xe9, 0xa5, + 0x86, 0x8b, 0x24, 0x00, 0x89, 0x80, 0x8c, 0x04, + 0x00, 0x01, 0x01, 0x80, 0xeb, 0xa0, 0x41, 0x6a, + 0x91, 0xbf, 0x81, 0xb5, 0xa7, 0x8b, 0xf3, 0x20, + 0x40, 0x86, 0xa3, 0x99, 0x85, 0x99, 0x8a, 0xd8, + 0x15, 0x0d, 0x0d, 0x0a, 0xa2, 0x8b, 0x80, 0x99, + 0x80, 0x92, 0x01, 0x80, 0x8e, 0x81, 0x8d, 0xa1, + 0xfa, 0xc4, 0xb4, 0x41, 0x0a, 0x9c, 0x82, 0xb0, + 0xae, 0x9f, 0x8c, 0x9d, 0x84, 0xa5, 0x89, 0x9d, + 0x81, 0xa3, 0x1f, 0x04, 0xa9, 0x40, 0x9d, 0x91, + 0xa3, 0x83, 0xa3, 0x83, 0xa7, 0x87, 0xb3, 0x8b, + 0x8a, 0x80, 0x8e, 0x06, 0x01, 0x80, 0x8a, 0x80, + 0x8e, 0x06, 0x01, 0x82, 0xb3, 0x8b, 0x41, 0x36, + 0x88, 0x95, 0x89, 0x87, 0x97, 0x28, 0xa9, 0x80, + 0x88, 0xc4, 0x29, 0x00, 0xab, 0x01, 0x10, 0x81, + 0x96, 0x89, 0x96, 0x88, 0x9e, 0xc0, 0x92, 0x01, + 0x89, 0x95, 0x89, 0x99, 0x85, 0x99, 0xa5, 0xb7, + 0x29, 0xbf, 0x80, 0x8e, 0x18, 0x10, 0x9c, 0xa9, + 0x9c, 0x82, 0x9c, 0xa2, 0x38, 0x9b, 0x9a, 0xb5, + 0x89, 0x95, 0x89, 0x92, 0x8c, 0x91, 0xed, 0xc8, + 0xb6, 0xb2, 0x8c, 0xb2, 0x8c, 0xa3, 0xa5, 0x9b, + 0x88, 0x96, 0x40, 0xf9, 0xa9, 0x29, 0x8f, 0x85, + 0xb7, 0x9c, 0x89, 0x07, 0x95, 0xa9, 0x91, 0xad, + 0x94, 0x9a, 0x96, 0x8b, 0xb4, 0xb8, 0x09, 0x80, + 0x8c, 0xac, 0x9f, 0x98, 0x99, 0xa3, 0x9c, 0x01, + 0x07, 0xa2, 0x10, 0x8b, 0xaf, 0x8d, 0x83, 0x94, + 0x00, 0x80, 0xa2, 0x91, 0x80, 0x98, 0x92, 0x81, + 0xbe, 0x30, 0x00, 0x18, 0x8e, 0x80, 0x89, 0x86, + 0xae, 0xa5, 0x39, 0x09, 0x95, 0x06, 0x01, 0x04, + 0x10, 0x91, 0x80, 0x8b, 0x84, 0x9d, 0x89, 0x00, + 0x08, 0x80, 0xa5, 0x00, 0x98, 0x00, 0x80, 0xab, + 0xb4, 0x91, 0x83, 0x93, 0x82, 0x9d, 0xaf, 0x93, + 0x08, 0x80, 0x40, 0xb7, 0xae, 0xa8, 0x83, 0xa3, + 0xaf, 0x93, 0x80, 0xba, 0xaa, 0x8c, 0x80, 0xc6, + 0x9a, 0xa4, 0x86, 0x40, 0xb8, 0xab, 0xf3, 0xbf, + 0x9e, 0x39, 0x01, 0x38, 0x08, 0x97, 0x8e, 0x00, + 0x80, 0xdd, 0x39, 0xa6, 0x8f, 0x00, 0x80, 0x9b, + 0x80, 0x89, 0xa7, 0x30, 0x94, 0x80, 0x8a, 0xad, + 0x92, 0x80, 0x91, 0xc8, 0x40, 0xc6, 0xa0, 0x9e, + 0x88, 0x80, 0xa4, 0x90, 0x80, 0xb0, 0x9d, 0xef, + 0x30, 0x08, 0xa5, 0x94, 0x80, 0x98, 0x28, 0x08, + 0x9f, 0x8d, 0x80, 0x96, 0xab, 0x41, 0x03, 0x92, + 0x8e, 0x00, 0x8c, 0x80, 0xa1, 0xfb, 0x80, 0xce, + 0x43, 0x99, 0xe5, 0xee, 0x90, 0x40, 0xc3, 0x4a, + 0x4b, 0xe0, 0x8e, 0x44, 0x2f, 0x90, 0x85, 0x98, + 0x4f, 0x9a, 0x84, 0x42, 0x46, 0x5a, 0xb8, 0x9d, + 0x46, 0xe1, 0x42, 0x38, 0x86, 0x9e, 0x90, 0xce, + 0x90, 0x9d, 0x91, 0xaf, 0x8f, 0x83, 0x9e, 0x94, + 0x84, 0x92, 0x41, 0xaf, 0xac, 0x40, 0xd2, 0xbf, + 0x9f, 0x98, 0x81, 0x98, 0xab, 0xca, 0x20, 0xc1, + 0x8c, 0xbf, 0x08, 0x80, 0x8d, 0x84, 0x88, 0x5c, + 0xd5, 0xa8, 0x9f, 0xe0, 0xf2, 0x60, 0x21, 0xfc, + 0x18, 0x30, 0x08, 0x41, 0x22, 0x8e, 0x80, 0x9c, + 0x11, 0x80, 0x8d, 0x1f, 0x41, 0x8b, 0x49, 0x03, + 0xea, 0x84, 0x8c, 0x82, 0x88, 0x86, 0x89, 0x57, + 0x65, 0xd4, 0x80, 0xc6, 0x01, 0x08, 0x09, 0x0b, + 0x80, 0x8b, 0x00, 0x06, 0x80, 0xc0, 0x03, 0x0f, + 0x06, 0x80, 0x9b, 0x03, 0x04, 0x00, 0x16, 0x80, + 0x41, 0x53, 0x81, 0x98, 0x80, 0x98, 0x80, 0x9e, + 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, 0x9e, + 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x07, 0x47, + 0x33, 0x9e, 0x2d, 0x41, 0x04, 0xbd, 0x40, 0x91, + 0xac, 0x89, 0x86, 0x8f, 0x80, 0x41, 0x40, 0x9d, + 0x91, 0xab, 0x41, 0xe3, 0x9b, 0x40, 0xe3, 0x9d, + 0x08, 0x40, 0xce, 0x9e, 0x02, 0x01, 0x06, 0x0c, + 0x88, 0x81, 0x40, 0xdf, 0x30, 0x18, 0x08, 0x8e, + 0x80, 0x40, 0xc4, 0xba, 0xc3, 0x30, 0x44, 0xb3, + 0x18, 0x9a, 0x01, 0x00, 0x08, 0x80, 0x89, 0x03, + 0x00, 0x00, 0x28, 0x18, 0x00, 0x00, 0x02, 0x01, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x0b, 0x06, 0x03, 0x03, 0x00, 0x80, 0x89, 0x80, + 0x90, 0x22, 0x04, 0x80, 0x90, 0x51, 0x43, 0x60, + 0xa6, 0xdf, 0x9f, 0x51, 0x1d, 0x81, 0x56, 0x8d, + 0x81, 0x5d, 0x30, 0x8e, 0x42, 0x6d, 0x49, 0xa1, + 0x42, 0x1d, 0x45, 0xe1, 0x53, 0x4a, 0x84, 0x60, + 0x21, 0x29, +}; + +static const uint8_t unicode_prop_ID_Start_index[108] = { + 0xf6, 0x03, 0x20, 0xa6, 0x07, 0x00, 0xa9, 0x09, + 0x20, 0xb1, 0x0a, 0x00, 0xba, 0x0b, 0x20, 0x3b, + 0x0d, 0x20, 0xc7, 0x0e, 0x20, 0x49, 0x12, 0x00, + 0x9b, 0x16, 0x00, 0xac, 0x19, 0x00, 0xc0, 0x1d, + 0x80, 0x80, 0x20, 0x20, 0x70, 0x2d, 0x00, 0x00, + 0x32, 0x00, 0x06, 0xa8, 0x00, 0x77, 0xaa, 0x00, + 0xfc, 0xd7, 0x00, 0xfd, 0xfe, 0x40, 0xd1, 0x02, + 0x01, 0xb2, 0x05, 0x21, 0xf6, 0x08, 0x01, 0x49, + 0x0c, 0x01, 0x76, 0x10, 0x01, 0xdf, 0x12, 0x21, + 0xc8, 0x14, 0x41, 0x42, 0x19, 0x21, 0x31, 0x1d, + 0x61, 0xf1, 0x2f, 0x41, 0x78, 0x6b, 0x01, 0x23, + 0xb1, 0xa1, 0xad, 0xd4, 0x01, 0x6f, 0xd7, 0x01, + 0xee, 0xe5, 0x01, 0x38, 0xee, 0x01, 0xe0, 0xa6, + 0x42, 0x7a, 0x34, 0x03, +}; + +static const uint8_t unicode_prop_ID_Continue1_table[708] = { + 0xaf, 0x89, 0xa4, 0x80, 0xd6, 0x80, 0x42, 0x47, + 0xef, 0x96, 0x80, 0x40, 0xfa, 0x84, 0x41, 0x08, + 0xac, 0x00, 0x01, 0x01, 0x00, 0xc7, 0x8a, 0xaf, + 0x9e, 0x28, 0xe4, 0x31, 0x29, 0x08, 0x19, 0x89, + 0x96, 0x80, 0x9d, 0x9a, 0xda, 0x8a, 0x8e, 0x89, + 0xa0, 0x88, 0x88, 0x80, 0x97, 0x18, 0x88, 0x02, + 0x04, 0xaa, 0x82, 0xba, 0x88, 0xa9, 0x97, 0x80, + 0xa0, 0xb5, 0x10, 0x91, 0x06, 0x89, 0x09, 0x89, + 0x90, 0x82, 0xb7, 0x00, 0x31, 0x09, 0x82, 0x88, + 0x80, 0x89, 0x09, 0x89, 0x8d, 0x01, 0x82, 0xb7, + 0x00, 0x23, 0x09, 0x12, 0x80, 0x93, 0x8b, 0x10, + 0x8a, 0x82, 0xb7, 0x00, 0x38, 0x10, 0x82, 0x93, + 0x09, 0x89, 0x89, 0x28, 0x82, 0xb7, 0x00, 0x31, + 0x09, 0x16, 0x82, 0x89, 0x09, 0x89, 0x91, 0x80, + 0xba, 0x22, 0x10, 0x83, 0x88, 0x80, 0x8d, 0x89, + 0x8f, 0x84, 0xb6, 0x00, 0x30, 0x10, 0x1e, 0x81, + 0x8a, 0x09, 0x89, 0x90, 0x82, 0xb7, 0x00, 0x30, + 0x10, 0x1e, 0x81, 0x8a, 0x09, 0x89, 0x10, 0x8b, + 0x83, 0xb6, 0x08, 0x30, 0x10, 0x83, 0x88, 0x80, + 0x89, 0x09, 0x89, 0x90, 0x82, 0xc5, 0x03, 0x28, + 0x00, 0x3d, 0x89, 0x09, 0xbc, 0x01, 0x86, 0x8b, + 0x38, 0x89, 0xd6, 0x01, 0x88, 0x8a, 0x30, 0x89, + 0xbd, 0x0d, 0x89, 0x8a, 0x00, 0x00, 0x03, 0x81, + 0xb0, 0x93, 0x01, 0x84, 0x8a, 0x80, 0xa3, 0x88, + 0x80, 0xe3, 0x93, 0x80, 0x89, 0x8b, 0x1b, 0x10, + 0x11, 0x32, 0x83, 0x8c, 0x8b, 0x80, 0x8e, 0x42, + 0xbe, 0x82, 0x88, 0x88, 0x43, 0x9f, 0x83, 0x9b, + 0x82, 0x9c, 0x81, 0x9d, 0x81, 0xbf, 0x9f, 0x88, + 0x01, 0x89, 0xa0, 0x10, 0x8a, 0x40, 0x8e, 0x80, + 0xf5, 0x8b, 0x83, 0x8b, 0x89, 0x89, 0xff, 0x8a, + 0xbb, 0x84, 0xb8, 0x89, 0x80, 0x9c, 0x81, 0x8a, + 0x85, 0x89, 0x95, 0x8d, 0x80, 0x9e, 0x81, 0x8b, + 0x93, 0x84, 0xae, 0x90, 0x8a, 0x89, 0x90, 0x88, + 0x8b, 0x82, 0x9d, 0x8c, 0x81, 0x89, 0xab, 0x8d, + 0xaf, 0x93, 0x87, 0x89, 0x85, 0x89, 0xf5, 0x10, + 0x94, 0x18, 0x28, 0x0a, 0x40, 0xc5, 0xbf, 0x42, + 0x0b, 0x81, 0xb0, 0x81, 0x92, 0x80, 0xfa, 0x8c, + 0x18, 0x82, 0x8b, 0x4b, 0xfd, 0x82, 0x40, 0x8c, + 0x80, 0xdf, 0x9f, 0x42, 0x29, 0x85, 0xe8, 0x81, + 0xdf, 0x80, 0x60, 0x75, 0x23, 0x89, 0xc4, 0x03, + 0x89, 0x9f, 0x81, 0xcf, 0x81, 0x41, 0x0f, 0x02, + 0x03, 0x80, 0x96, 0x23, 0x80, 0xd2, 0x81, 0xb1, + 0x91, 0x89, 0x89, 0x85, 0x91, 0x8c, 0x8a, 0x9b, + 0x87, 0x98, 0x8c, 0xab, 0x83, 0xae, 0x8d, 0x8e, + 0x89, 0x8a, 0x80, 0x89, 0x89, 0xae, 0x8d, 0x8b, + 0x07, 0x09, 0x89, 0xa0, 0x82, 0xb1, 0x00, 0x11, + 0x0c, 0x08, 0x80, 0xa8, 0x24, 0x81, 0x40, 0xeb, + 0x38, 0x09, 0x89, 0x60, 0x4f, 0x23, 0x80, 0x42, + 0xe0, 0x8f, 0x8f, 0x8f, 0x11, 0x97, 0x82, 0x40, + 0xbf, 0x89, 0xa4, 0x80, 0xa4, 0x80, 0x42, 0x96, + 0x80, 0x40, 0xe1, 0x80, 0x40, 0x94, 0x84, 0x41, + 0x24, 0x89, 0x45, 0x56, 0x10, 0x0c, 0x83, 0xa7, + 0x13, 0x80, 0x40, 0xa4, 0x81, 0x42, 0x3c, 0x1f, + 0x89, 0x85, 0x89, 0x9e, 0x84, 0x41, 0x3c, 0x81, + 0xcc, 0x85, 0xc5, 0x8a, 0xb0, 0x83, 0xf9, 0x82, + 0xb4, 0x8e, 0x9e, 0x8a, 0x09, 0x89, 0x83, 0xac, + 0x8a, 0x30, 0xac, 0x89, 0x2a, 0xa3, 0x8d, 0x80, + 0x89, 0x21, 0xab, 0x80, 0x8b, 0x82, 0xaf, 0x8d, + 0x3b, 0x80, 0x8b, 0xd1, 0x8b, 0x28, 0x08, 0x40, + 0x9c, 0x8b, 0x84, 0x89, 0x2b, 0xb6, 0x08, 0x31, + 0x09, 0x82, 0x88, 0x80, 0x89, 0x09, 0x32, 0x84, + 0xc2, 0x88, 0x00, 0x08, 0x03, 0x04, 0x00, 0x8d, + 0x81, 0xd1, 0x91, 0x88, 0x89, 0x18, 0xd0, 0x93, + 0x8b, 0x89, 0x40, 0xd4, 0x31, 0x88, 0x9a, 0x81, + 0xd1, 0x90, 0x8e, 0x89, 0xd0, 0x8c, 0x87, 0x89, + 0x85, 0x93, 0xb8, 0x8e, 0x83, 0x89, 0x40, 0xf1, + 0x8e, 0x40, 0xa4, 0x89, 0xc5, 0x28, 0x09, 0x18, + 0x00, 0x81, 0x8b, 0x89, 0xf6, 0x31, 0x32, 0x80, + 0x9b, 0x89, 0xa7, 0x30, 0x1f, 0x80, 0x88, 0x8a, + 0xad, 0x8f, 0x40, 0xc5, 0x87, 0x40, 0x87, 0x89, + 0xb4, 0x38, 0x87, 0x8f, 0x89, 0xb7, 0x95, 0x80, + 0x8d, 0xf9, 0x2a, 0x00, 0x08, 0x30, 0x07, 0x89, + 0xaf, 0x20, 0x08, 0x27, 0x89, 0xb5, 0x89, 0x41, + 0x08, 0x83, 0x88, 0x08, 0x80, 0xaf, 0x32, 0x84, + 0x8c, 0x8a, 0x54, 0xe4, 0x05, 0x8e, 0x60, 0x2c, + 0xc7, 0x9b, 0x49, 0x25, 0x89, 0xd5, 0x89, 0xa5, + 0x84, 0xba, 0x86, 0x98, 0x89, 0x42, 0x15, 0x89, + 0x41, 0xd4, 0x00, 0xb6, 0x33, 0xd0, 0x80, 0x8a, + 0x81, 0x60, 0x4c, 0xaa, 0x81, 0x50, 0x50, 0x89, + 0x42, 0x05, 0xad, 0x81, 0x96, 0x42, 0x1d, 0x22, + 0x2f, 0x39, 0x86, 0x9d, 0x83, 0x40, 0x93, 0x82, + 0x45, 0x88, 0xb1, 0x41, 0xff, 0xb6, 0x83, 0xb1, + 0x38, 0x8d, 0x80, 0x95, 0x20, 0x8e, 0x45, 0x4f, + 0x30, 0x90, 0x0e, 0x01, 0x04, 0xe3, 0x80, 0x40, + 0x9f, 0x86, 0x88, 0x89, 0x41, 0x63, 0x80, 0xbc, + 0x8d, 0x41, 0xf1, 0x8d, 0x40, 0xf3, 0x08, 0x89, + 0x40, 0xe7, 0x01, 0x06, 0x0c, 0x80, 0x41, 0xd9, + 0x86, 0xec, 0x34, 0x89, 0x52, 0x95, 0x89, 0x6c, + 0x05, 0x05, 0x40, 0xef, +}; + +static const uint8_t unicode_prop_ID_Continue1_index[66] = { + 0xfa, 0x06, 0x00, 0x70, 0x09, 0x00, 0xf0, 0x0a, + 0x40, 0x57, 0x0c, 0x00, 0xf0, 0x0d, 0x60, 0xc7, + 0x0f, 0x20, 0xea, 0x17, 0x40, 0xec, 0x1a, 0x00, + 0x0e, 0x20, 0x40, 0x7e, 0xa6, 0x20, 0xda, 0xa9, + 0x20, 0x10, 0xfe, 0x40, 0x40, 0x0a, 0x41, 0xbb, + 0x10, 0x21, 0x4e, 0x13, 0x41, 0xde, 0x15, 0x01, + 0xe5, 0x19, 0x01, 0x5a, 0x1d, 0x01, 0xf5, 0x6a, + 0x21, 0x8c, 0xd1, 0x61, 0x37, 0xe1, 0x41, 0xf0, + 0x01, 0x0e, +}; + +static const uint8_t unicode_prop_White_Space_table[22] = { + 0x88, 0x84, 0x91, 0x80, 0xe3, 0x80, 0x99, 0x80, + 0x55, 0xde, 0x80, 0x49, 0x7e, 0x8a, 0x9c, 0x0c, + 0x80, 0xae, 0x80, 0x4f, 0x9f, 0x80, +}; + +static const uint8_t unicode_prop_White_Space_index[3] = { + 0x01, 0x30, 0x00, +}; + +static const uint8_t unicode_cc_table[937] = { + 0xb2, 0xcf, 0xd4, 0x00, 0xe8, 0x03, 0xdc, 0x00, + 0xe8, 0x00, 0xd8, 0x04, 0xdc, 0x01, 0xca, 0x03, + 0xdc, 0x01, 0xca, 0x0a, 0xdc, 0x04, 0x01, 0x03, + 0xdc, 0xc7, 0x00, 0xf0, 0xc0, 0x02, 0xdc, 0xc2, + 0x01, 0xdc, 0x80, 0xc2, 0x03, 0xdc, 0xc0, 0x00, + 0xe8, 0x01, 0xdc, 0xc0, 0x41, 0xe9, 0x00, 0xea, + 0x41, 0xe9, 0x00, 0xea, 0x00, 0xe9, 0xcc, 0xb0, + 0xe2, 0xc4, 0xb0, 0xd8, 0x00, 0xdc, 0xc3, 0x00, + 0xdc, 0xc2, 0x00, 0xde, 0x00, 0xdc, 0xc5, 0x05, + 0xdc, 0xc1, 0x00, 0xdc, 0xc1, 0x00, 0xde, 0x00, + 0xe4, 0xc0, 0x49, 0x0a, 0x43, 0x13, 0x80, 0x00, + 0x17, 0x80, 0x41, 0x18, 0x80, 0xc0, 0x00, 0xdc, + 0x80, 0x00, 0x12, 0xb0, 0x17, 0xc7, 0x42, 0x1e, + 0xaf, 0x47, 0x1b, 0xc1, 0x01, 0xdc, 0xc4, 0x00, + 0xdc, 0xc1, 0x00, 0xdc, 0x8f, 0x00, 0x23, 0xb0, + 0x34, 0xc6, 0x81, 0xc3, 0x00, 0xdc, 0xc0, 0x81, + 0xc1, 0x80, 0x00, 0xdc, 0xc1, 0x00, 0xdc, 0xa2, + 0x00, 0x24, 0x9d, 0xc0, 0x00, 0xdc, 0xc1, 0x00, + 0xdc, 0xc1, 0x02, 0xdc, 0xc0, 0x01, 0xdc, 0xc0, + 0x00, 0xdc, 0xc2, 0x00, 0xdc, 0xc0, 0x00, 0xdc, + 0xc0, 0x00, 0xdc, 0xc0, 0x00, 0xdc, 0xc1, 0xb0, + 0x6f, 0xc6, 0x00, 0xdc, 0xc0, 0x88, 0x00, 0xdc, + 0x97, 0xc3, 0x80, 0xc8, 0x80, 0xc2, 0x80, 0xc4, + 0xaa, 0x02, 0xdc, 0xb0, 0x0a, 0xc1, 0x02, 0xdc, + 0xc3, 0xa9, 0xc4, 0x04, 0xdc, 0xcd, 0x80, 0x00, + 0xdc, 0xc1, 0x00, 0xdc, 0xc1, 0x00, 0xdc, 0xc2, + 0x02, 0xdc, 0x42, 0x1b, 0xc2, 0x00, 0xdc, 0xc1, + 0x01, 0xdc, 0xc4, 0xb0, 0x0b, 0x00, 0x07, 0x8f, + 0x00, 0x09, 0x82, 0xc0, 0x00, 0xdc, 0xc1, 0xb0, + 0x36, 0x00, 0x07, 0x8f, 0x00, 0x09, 0xaf, 0xc0, + 0xb0, 0x0c, 0x00, 0x07, 0x8f, 0x00, 0x09, 0xb0, + 0x3d, 0x00, 0x07, 0x8f, 0x00, 0x09, 0xb0, 0x3d, + 0x00, 0x07, 0x8f, 0x00, 0x09, 0xb0, 0x4e, 0x00, + 0x09, 0xb0, 0x3d, 0x00, 0x07, 0x8f, 0x00, 0x09, + 0x86, 0x00, 0x54, 0x00, 0x5b, 0xb0, 0x34, 0x00, + 0x07, 0x8f, 0x00, 0x09, 0xb0, 0x3c, 0x01, 0x09, + 0x8f, 0x00, 0x09, 0xb0, 0x4b, 0x00, 0x09, 0xb0, + 0x3c, 0x01, 0x67, 0x00, 0x09, 0x8c, 0x03, 0x6b, + 0xb0, 0x3b, 0x01, 0x76, 0x00, 0x09, 0x8c, 0x03, + 0x7a, 0xb0, 0x1b, 0x01, 0xdc, 0x9a, 0x00, 0xdc, + 0x80, 0x00, 0xdc, 0x80, 0x00, 0xd8, 0xb0, 0x06, + 0x41, 0x81, 0x80, 0x00, 0x84, 0x84, 0x03, 0x82, + 0x81, 0x00, 0x82, 0x80, 0xc1, 0x00, 0x09, 0x80, + 0xc1, 0xb0, 0x0d, 0x00, 0xdc, 0xb0, 0x3f, 0x00, + 0x07, 0x80, 0x01, 0x09, 0xb0, 0x21, 0x00, 0xdc, + 0xb2, 0x9e, 0xc2, 0xb3, 0x83, 0x01, 0x09, 0x9d, + 0x00, 0x09, 0xb0, 0x6c, 0x00, 0x09, 0x89, 0xc0, + 0xb0, 0x9a, 0x00, 0xe4, 0xb0, 0x5e, 0x00, 0xde, + 0xc0, 0x00, 0xdc, 0xb0, 0xaa, 0xc0, 0x00, 0xdc, + 0xb0, 0x16, 0x00, 0x09, 0x93, 0xc7, 0x81, 0x00, + 0xdc, 0xaf, 0xc4, 0x05, 0xdc, 0xc1, 0x00, 0xdc, + 0x80, 0x01, 0xdc, 0xc1, 0x01, 0xdc, 0xc4, 0x00, + 0xdc, 0xd1, 0x00, 0xdc, 0x81, 0xc5, 0x00, 0xdc, + 0xc3, 0x00, 0xea, 0xb0, 0x17, 0x00, 0x07, 0x8e, + 0x00, 0x09, 0xa5, 0xc0, 0x00, 0xdc, 0xc6, 0xb0, + 0x05, 0x01, 0x09, 0xb0, 0x09, 0x00, 0x07, 0x8a, + 0x01, 0x09, 0xb0, 0x12, 0x00, 0x07, 0xb0, 0x67, + 0xc2, 0x41, 0x00, 0x04, 0xdc, 0xc1, 0x03, 0xdc, + 0xc0, 0x41, 0x00, 0x05, 0x01, 0x83, 0x00, 0xdc, + 0x85, 0xc0, 0x82, 0xc1, 0xb0, 0x95, 0xc1, 0x00, + 0xdc, 0xc6, 0x00, 0xdc, 0xc1, 0x00, 0xea, 0x00, + 0xd6, 0x00, 0xdc, 0x00, 0xca, 0xe4, 0x00, 0xe8, + 0x01, 0xe4, 0x00, 0xdc, 0x00, 0xda, 0xc0, 0x00, + 0xe9, 0x00, 0xdc, 0xc0, 0x00, 0xdc, 0xb2, 0x9f, + 0xc1, 0x01, 0x01, 0xc3, 0x02, 0x01, 0xc1, 0x83, + 0xc0, 0x82, 0x01, 0x01, 0xc0, 0x00, 0xdc, 0xc0, + 0x01, 0x01, 0x03, 0xdc, 0xc0, 0xb8, 0x03, 0xcd, + 0xc2, 0xb0, 0x5c, 0x00, 0x09, 0xb0, 0x2f, 0xdf, + 0xb1, 0xf9, 0x00, 0xda, 0x00, 0xe4, 0x00, 0xe8, + 0x00, 0xde, 0x01, 0xe0, 0xb0, 0x38, 0x01, 0x08, + 0xb8, 0x6d, 0xa3, 0xc0, 0x83, 0xc9, 0x9f, 0xc1, + 0xb0, 0x1f, 0xc1, 0xb0, 0xe3, 0x00, 0x09, 0xa4, + 0x00, 0x09, 0xb0, 0x66, 0x00, 0x09, 0x9a, 0xd1, + 0xb0, 0x08, 0x02, 0xdc, 0xa4, 0x00, 0x09, 0xb0, + 0x2e, 0x00, 0x07, 0x8b, 0x00, 0x09, 0xb0, 0xbe, + 0xc0, 0x80, 0xc1, 0x00, 0xdc, 0x81, 0xc1, 0x84, + 0xc1, 0x80, 0xc0, 0xb0, 0x03, 0x00, 0x09, 0xb0, + 0xc5, 0x00, 0x09, 0xb8, 0x46, 0xff, 0x00, 0x1a, + 0xb2, 0xd0, 0xc6, 0x06, 0xdc, 0xc1, 0xb3, 0x9c, + 0x00, 0xdc, 0xb0, 0xb1, 0x00, 0xdc, 0xb0, 0x64, + 0xc4, 0xb6, 0x61, 0x00, 0xdc, 0x80, 0xc0, 0xa7, + 0xc0, 0x00, 0x01, 0x00, 0xdc, 0x83, 0x00, 0x09, + 0xb0, 0x74, 0xc0, 0x00, 0xdc, 0xb2, 0x0c, 0xc3, + 0xb0, 0x10, 0xc4, 0xb1, 0x0c, 0xc1, 0xb0, 0x1c, + 0x01, 0xdc, 0x80, 0x02, 0xdc, 0xb0, 0x15, 0x01, + 0xdc, 0xc2, 0x00, 0xdc, 0xc0, 0x03, 0xdc, 0xb0, + 0x00, 0xc0, 0x00, 0xdc, 0xc0, 0x00, 0xdc, 0xb0, + 0x8f, 0x00, 0x09, 0xa8, 0x00, 0x09, 0x8d, 0x00, + 0x09, 0xb0, 0x08, 0x00, 0x09, 0x00, 0x07, 0xb0, + 0x14, 0xc2, 0xaf, 0x01, 0x09, 0xb0, 0x0d, 0x00, + 0x07, 0xb0, 0x1b, 0x00, 0x09, 0x88, 0x00, 0x07, + 0xb0, 0x39, 0x00, 0x09, 0x00, 0x07, 0xb0, 0x81, + 0x00, 0x07, 0x00, 0x09, 0xb0, 0x1f, 0x01, 0x07, + 0x8f, 0x00, 0x09, 0x97, 0xc6, 0x82, 0xc4, 0xb0, + 0x28, 0x02, 0x09, 0xb0, 0x40, 0x00, 0x09, 0x82, + 0x00, 0x07, 0x96, 0xc0, 0xb0, 0x32, 0x00, 0x09, + 0x00, 0x07, 0xb0, 0xca, 0x00, 0x09, 0x00, 0x07, + 0xb0, 0x4d, 0x00, 0x09, 0xb0, 0x45, 0x00, 0x09, + 0x00, 0x07, 0xb0, 0x42, 0x00, 0x09, 0xb0, 0xdc, + 0x00, 0x09, 0x00, 0x07, 0xb0, 0xd1, 0x01, 0x09, + 0x83, 0x00, 0x07, 0xb0, 0x6b, 0x00, 0x09, 0xb0, + 0x22, 0x00, 0x09, 0x91, 0x00, 0x09, 0xb0, 0x20, + 0x00, 0x09, 0xb1, 0x74, 0x00, 0x09, 0xb0, 0xd1, + 0x00, 0x07, 0x80, 0x01, 0x09, 0xb0, 0x20, 0x00, + 0x09, 0xb1, 0x78, 0x01, 0x09, 0xb8, 0x39, 0xbb, + 0x00, 0x09, 0xb8, 0x01, 0x8f, 0x04, 0x01, 0xb0, + 0x0a, 0xc6, 0xb4, 0x88, 0x01, 0x06, 0xb8, 0x44, + 0x7b, 0x00, 0x01, 0xb8, 0x0c, 0x95, 0x01, 0xd8, + 0x02, 0x01, 0x82, 0x00, 0xe2, 0x04, 0xd8, 0x87, + 0x07, 0xdc, 0x81, 0xc4, 0x01, 0xdc, 0x9d, 0xc3, + 0xb0, 0x63, 0xc2, 0xb8, 0x05, 0x8a, 0xc6, 0x80, + 0xd0, 0x81, 0xc6, 0x80, 0xc1, 0x80, 0xc4, 0xb0, + 0x33, 0xc0, 0xb0, 0x6f, 0xc6, 0xb1, 0x46, 0xc0, + 0xb0, 0x0c, 0xc3, 0xb1, 0xcb, 0x01, 0xe8, 0x00, + 0xdc, 0xc0, 0xb0, 0xcd, 0xc0, 0x00, 0xdc, 0xb0, + 0xc2, 0xc0, 0x81, 0xc0, 0x86, 0xc1, 0x84, 0xc0, + 0xb1, 0xa9, 0x06, 0xdc, 0xb0, 0x3c, 0xc5, 0x00, + 0x07, +}; + +static const uint8_t unicode_cc_index[90] = { + 0x4d, 0x03, 0x00, 0x97, 0x05, 0x20, 0xc6, 0x05, + 0x00, 0xe7, 0x06, 0x00, 0x45, 0x07, 0x00, 0x9c, + 0x08, 0x00, 0x4d, 0x09, 0x00, 0x3c, 0x0b, 0x00, + 0x3d, 0x0d, 0x00, 0x36, 0x0f, 0x00, 0x38, 0x10, + 0x20, 0x3a, 0x19, 0x00, 0xcb, 0x1a, 0x20, 0xf2, + 0x1b, 0x00, 0xc3, 0x1d, 0x20, 0xd0, 0x20, 0x00, + 0x00, 0x2e, 0x00, 0x2c, 0xa8, 0x00, 0xbe, 0xaa, + 0x00, 0x76, 0x03, 0x01, 0xfa, 0x0e, 0x01, 0x80, + 0x10, 0x21, 0xe9, 0x12, 0x01, 0xc3, 0x14, 0x01, + 0x3f, 0x19, 0x01, 0x98, 0x1d, 0x21, 0x67, 0xd1, + 0x01, 0x8f, 0xe0, 0x21, 0xf6, 0xe6, 0x01, 0x4b, + 0xe9, 0x01, +}; + +static const uint32_t unicode_decomp_table1[709] = { + 0x00280081, 0x002a0097, 0x002a8081, 0x002bc097, + 0x002c8115, 0x002d0097, 0x002d4081, 0x002e0097, + 0x002e4115, 0x002f0199, 0x00302016, 0x00400842, + 0x00448a42, 0x004a0442, 0x004c0096, 0x004c8117, + 0x004d0242, 0x004e4342, 0x004fc12f, 0x0050c342, + 0x005240bf, 0x00530342, 0x00550942, 0x005a0842, + 0x005e0096, 0x005e4342, 0x005fc081, 0x00680142, + 0x006bc142, 0x00710185, 0x0071c317, 0x00734844, + 0x00778344, 0x00798342, 0x007b02be, 0x007c4197, + 0x007d0142, 0x007e0444, 0x00800e42, 0x00878142, + 0x00898744, 0x00ac0483, 0x00b60317, 0x00b80283, + 0x00d00214, 0x00d10096, 0x00dd0080, 0x00de8097, + 0x00df8080, 0x00e10097, 0x00e1413e, 0x00e1c080, + 0x00e204be, 0x00ea83ae, 0x00f282ae, 0x00f401ad, + 0x00f4c12e, 0x00f54103, 0x00fc0303, 0x00fe4081, + 0x0100023e, 0x0101c0be, 0x010301be, 0x010640be, + 0x010e40be, 0x0114023e, 0x0115c0be, 0x011701be, + 0x011d8144, 0x01304144, 0x01340244, 0x01358144, + 0x01368344, 0x01388344, 0x013a8644, 0x013e0144, + 0x0161c085, 0x018882ae, 0x019d422f, 0x01b00184, + 0x01b4c084, 0x024a4084, 0x024c4084, 0x024d0084, + 0x0256042e, 0x0272c12e, 0x02770120, 0x0277c084, + 0x028cc084, 0x028d8084, 0x029641ae, 0x02978084, + 0x02d20084, 0x02d2c12e, 0x02d70120, 0x02e50084, + 0x02f281ae, 0x03120084, 0x03300084, 0x0331c122, + 0x0332812e, 0x035281ae, 0x03768084, 0x037701ae, + 0x038cc085, 0x03acc085, 0x03b7012f, 0x03c30081, + 0x03d0c084, 0x03d34084, 0x03d48084, 0x03d5c084, + 0x03d70084, 0x03da4084, 0x03dcc084, 0x03dd412e, + 0x03ddc085, 0x03de0084, 0x03de4085, 0x03e04084, + 0x03e4c084, 0x03e74084, 0x03e88084, 0x03e9c084, + 0x03eb0084, 0x03ee4084, 0x04098084, 0x043f0081, + 0x06c18484, 0x06c48084, 0x06cec184, 0x06d00120, + 0x06d0c084, 0x074b0383, 0x074cc41f, 0x074f1783, + 0x075e0081, 0x0766d283, 0x07801d44, 0x078e8942, + 0x07931844, 0x079f0d42, 0x07a58216, 0x07a68085, + 0x07a6c0be, 0x07a80d44, 0x07aea044, 0x07c00122, + 0x07c08344, 0x07c20122, 0x07c28344, 0x07c40122, + 0x07c48244, 0x07c60122, 0x07c68244, 0x07c8113e, + 0x07d08244, 0x07d20122, 0x07d28244, 0x07d40122, + 0x07d48344, 0x07d64c3e, 0x07dc4080, 0x07dc80be, + 0x07dcc080, 0x07dd00be, 0x07dd4080, 0x07dd80be, + 0x07ddc080, 0x07de00be, 0x07de4080, 0x07de80be, + 0x07dec080, 0x07df00be, 0x07df4080, 0x07e00820, + 0x07e40820, 0x07e80820, 0x07ec05be, 0x07eec080, + 0x07ef00be, 0x07ef4097, 0x07ef8080, 0x07efc117, + 0x07f0443e, 0x07f24080, 0x07f280be, 0x07f2c080, + 0x07f303be, 0x07f4c080, 0x07f582ae, 0x07f6c080, + 0x07f7433e, 0x07f8c080, 0x07f903ae, 0x07fac080, + 0x07fb013e, 0x07fb8102, 0x07fc83be, 0x07fe4080, + 0x07fe80be, 0x07fec080, 0x07ff00be, 0x07ff4080, + 0x07ff8097, 0x0800011e, 0x08008495, 0x08044081, + 0x0805c097, 0x08090081, 0x08094097, 0x08098099, + 0x080bc081, 0x080cc085, 0x080d00b1, 0x080d8085, + 0x080dc0b1, 0x080f0197, 0x0811c197, 0x0815c0b3, + 0x0817c081, 0x081c0595, 0x081ec081, 0x081f0215, + 0x0820051f, 0x08228583, 0x08254415, 0x082a0097, + 0x08400119, 0x08408081, 0x0840c0bf, 0x08414119, + 0x0841c081, 0x084240bf, 0x0842852d, 0x08454081, + 0x08458097, 0x08464295, 0x08480097, 0x08484099, + 0x08488097, 0x08490081, 0x08498080, 0x084a0081, + 0x084a8102, 0x084b0495, 0x084d421f, 0x084e4081, + 0x084ec099, 0x084f0283, 0x08514295, 0x08540119, + 0x0854809b, 0x0854c619, 0x0857c097, 0x08580081, + 0x08584097, 0x08588099, 0x0858c097, 0x08590081, + 0x08594097, 0x08598099, 0x0859c09b, 0x085a0097, + 0x085a4081, 0x085a8097, 0x085ac099, 0x085b0295, + 0x085c4097, 0x085c8099, 0x085cc097, 0x085d0081, + 0x085d4097, 0x085d8099, 0x085dc09b, 0x085e0097, + 0x085e4081, 0x085e8097, 0x085ec099, 0x085f0215, + 0x08624099, 0x0866813e, 0x086b80be, 0x087341be, + 0x088100be, 0x088240be, 0x088300be, 0x088901be, + 0x088b0085, 0x088b40b1, 0x088bc085, 0x088c00b1, + 0x089040be, 0x089100be, 0x0891c1be, 0x089801be, + 0x089b42be, 0x089d0144, 0x089e0144, 0x08a00144, + 0x08a10144, 0x08a20144, 0x08ab023e, 0x08b80244, + 0x08ba8220, 0x08ca411e, 0x0918049f, 0x091a4523, + 0x091cc097, 0x091d04a5, 0x091f452b, 0x0921c09b, + 0x092204a1, 0x09244525, 0x0926c099, 0x09270d25, + 0x092d8d1f, 0x09340d1f, 0x093a8081, 0x0a8300b3, + 0x0a9d0099, 0x0a9d4097, 0x0a9d8099, 0x0ab700be, + 0x0b1f0115, 0x0b5bc081, 0x0ba7c081, 0x0bbcc081, + 0x0bc004ad, 0x0bc244ad, 0x0bc484ad, 0x0bc6f383, + 0x0be0852d, 0x0be31d03, 0x0bf1882d, 0x0c000081, + 0x0c0d8283, 0x0c130b84, 0x0c194284, 0x0c1c0122, + 0x0c1cc122, 0x0c1d8122, 0x0c1e4122, 0x0c1f0122, + 0x0c250084, 0x0c26c123, 0x0c278084, 0x0c27c085, + 0x0c2b0b84, 0x0c314284, 0x0c340122, 0x0c34c122, + 0x0c358122, 0x0c364122, 0x0c370122, 0x0c3d0084, + 0x0c3dc220, 0x0c3f8084, 0x0c3fc085, 0x0c4c4a2d, + 0x0c51451f, 0x0c53ca9f, 0x0c5915ad, 0x0c648703, + 0x0c800741, 0x0c838089, 0x0c83c129, 0x0c8441a9, + 0x0c850089, 0x0c854129, 0x0c85c2a9, 0x0c870089, + 0x0c87408f, 0x0c87808d, 0x0c881241, 0x0c910203, + 0x0c940099, 0x0c9444a3, 0x0c968323, 0x0c98072d, + 0x0c9b84af, 0x0c9dc2a1, 0x0c9f00b5, 0x0c9f40b3, + 0x0c9f8085, 0x0ca01883, 0x0cac4223, 0x0cad4523, + 0x0cafc097, 0x0cb004a1, 0x0cb241a5, 0x0cb30097, + 0x0cb34099, 0x0cb38097, 0x0cb3c099, 0x0cb417ad, + 0x0cbfc085, 0x0cc001b3, 0x0cc0c0b1, 0x0cc100b3, + 0x0cc14131, 0x0cc1c0b5, 0x0cc200b3, 0x0cc241b1, + 0x0cc30133, 0x0cc38131, 0x0cc40085, 0x0cc440b1, + 0x0cc48133, 0x0cc50085, 0x0cc540b5, 0x0cc580b7, + 0x0cc5c0b5, 0x0cc600b1, 0x0cc64135, 0x0cc6c0b3, + 0x0cc701b1, 0x0cc7c0b3, 0x0cc800b5, 0x0cc840b3, + 0x0cc881b1, 0x0cc9422f, 0x0cca4131, 0x0ccac0b5, + 0x0ccb00b1, 0x0ccb40b3, 0x0ccb80b5, 0x0ccbc0b1, + 0x0ccc012f, 0x0ccc80b5, 0x0cccc0b3, 0x0ccd00b5, + 0x0ccd40b1, 0x0ccd80b5, 0x0ccdc085, 0x0cce02b1, + 0x0ccf40b3, 0x0ccf80b1, 0x0ccfc085, 0x0cd001b1, + 0x0cd0c0b3, 0x0cd101b1, 0x0cd1c0b5, 0x0cd200b3, + 0x0cd24085, 0x0cd280b5, 0x0cd2c085, 0x0cd30133, + 0x0cd381b1, 0x0cd440b3, 0x0cd48085, 0x0cd4c0b1, + 0x0cd500b3, 0x0cd54085, 0x0cd580b5, 0x0cd5c0b1, + 0x0cd60521, 0x0cd88525, 0x0cdb02a5, 0x0cdc4099, + 0x0cdc8117, 0x0cdd0099, 0x0cdd4197, 0x0cde0127, + 0x0cde8285, 0x0cdfc089, 0x0ce0043f, 0x0ce20099, + 0x0ce2409b, 0x0ce283bf, 0x0ce44219, 0x0ce54205, + 0x0ce6433f, 0x0ce7c131, 0x0ce84085, 0x0ce881b1, + 0x0ce94085, 0x0ce98107, 0x0cea0089, 0x0cea4097, + 0x0cea8219, 0x0ceb809d, 0x0cebc08d, 0x0cec083f, + 0x0cf00105, 0x0cf0809b, 0x0cf0c197, 0x0cf1809b, + 0x0cf1c099, 0x0cf20517, 0x0cf48099, 0x0cf4c117, + 0x0cf54119, 0x0cf5c097, 0x0cf6009b, 0x0cf64099, + 0x0cf68217, 0x0cf78119, 0x0cf804a1, 0x0cfa4525, + 0x0cfcc525, 0x0cff4125, 0x0cffc099, 0x29a70103, + 0x29dc0081, 0x29fc4215, 0x29fe0103, 0x2ad70203, + 0x2ada4081, 0x3e401482, 0x3e4a7f82, 0x3e6a3f82, + 0x3e8aa102, 0x3e9b0110, 0x3e9c2f82, 0x3eb3c590, + 0x3ec00197, 0x3ec0c119, 0x3ec1413f, 0x3ec4c2af, + 0x3ec74184, 0x3ec804ad, 0x3eca4081, 0x3eca8304, + 0x3ecc03a0, 0x3ece02a0, 0x3ecf8084, 0x3ed00120, + 0x3ed0c120, 0x3ed184ae, 0x3ed3c085, 0x3ed4312d, + 0x3ef4cbad, 0x3efa892f, 0x3eff022d, 0x3f002f2f, + 0x3f1782a5, 0x3f18c0b1, 0x3f1907af, 0x3f1cffaf, + 0x3f3c81a5, 0x3f3d64af, 0x3f542031, 0x3f649b31, + 0x3f7c0131, 0x3f7c83b3, 0x3f7e40b1, 0x3f7e80bd, + 0x3f7ec0bb, 0x3f7f00b3, 0x3f840503, 0x3f8c01ad, + 0x3f8cc315, 0x3f8e462d, 0x3f91cc03, 0x3f97c695, + 0x3f9c01af, 0x3f9d0085, 0x3f9d852f, 0x3fa03aad, + 0x3fbd442f, 0x3fc06f1f, 0x3fd7c11f, 0x3fd85fad, + 0x3fe80081, 0x3fe84f1f, 0x3ff0831f, 0x3ff2831f, + 0x3ff4831f, 0x3ff6819f, 0x3ff80783, 0x41724092, + 0x41790092, 0x41e04d83, 0x41e70f91, 0x44268192, + 0x442ac092, 0x444b8112, 0x44d2c112, 0x44e0c192, + 0x44e38092, 0x44e44092, 0x44f14212, 0x452ec212, + 0x456e8112, 0x464e0092, 0x58484412, 0x5b5a0192, + 0x73358d1f, 0x733c051f, 0x74578392, 0x746ec312, + 0x75000d1f, 0x75068d1f, 0x750d0d1f, 0x7513839f, + 0x7515891f, 0x751a0d1f, 0x75208d1f, 0x75271015, + 0x752f439f, 0x7531459f, 0x75340d1f, 0x753a8d1f, + 0x75410395, 0x7543441f, 0x7545839f, 0x75478d1f, + 0x754e0795, 0x7552839f, 0x75548d1f, 0x755b0d1f, + 0x75618d1f, 0x75680d1f, 0x756e8d1f, 0x75750d1f, + 0x757b8d1f, 0x75820d1f, 0x75888d1f, 0x758f0d1f, + 0x75958d1f, 0x759c0d1f, 0x75a28d1f, 0x75a90103, + 0x75aa089f, 0x75ae4081, 0x75ae839f, 0x75b04081, + 0x75b08c9f, 0x75b6c081, 0x75b7032d, 0x75b8889f, + 0x75bcc081, 0x75bd039f, 0x75bec081, 0x75bf0c9f, + 0x75c54081, 0x75c5832d, 0x75c7089f, 0x75cb4081, + 0x75cb839f, 0x75cd4081, 0x75cd8c9f, 0x75d3c081, + 0x75d4032d, 0x75d5889f, 0x75d9c081, 0x75da039f, + 0x75dbc081, 0x75dc0c9f, 0x75e24081, 0x75e2832d, + 0x75e4089f, 0x75e84081, 0x75e8839f, 0x75ea4081, + 0x75ea8c9f, 0x75f0c081, 0x75f1042d, 0x75f3851f, + 0x75f6051f, 0x75f8851f, 0x75fb051f, 0x75fd851f, + 0x780c049f, 0x780e419f, 0x780f059f, 0x7811c203, + 0x7812d0ad, 0x781b0103, 0x7b80022d, 0x7b814dad, + 0x7b884203, 0x7b89c081, 0x7b8a452d, 0x7b8d0403, + 0x7b908081, 0x7b91dc03, 0x7ba0052d, 0x7ba2c8ad, + 0x7ba84483, 0x7baac8ad, 0x7c400097, 0x7c404521, + 0x7c440d25, 0x7c4a8087, 0x7c4ac115, 0x7c4b4117, + 0x7c4c0d1f, 0x7c528217, 0x7c538099, 0x7c53c097, + 0x7c5a8197, 0x7c640097, 0x7c80012f, 0x7c808081, + 0x7c841603, 0x7c9004c1, 0x7c940103, 0x7efc051f, + 0xbe0001ac, 0xbe00d110, 0xbe0947ac, 0xbe0d3910, + 0xbe29872c, 0xbe2d022c, 0xbe2e3790, 0xbe49ff90, + 0xbe69bc10, +}; + +static const uint16_t unicode_decomp_table2[709] = { + 0x0020, 0x0000, 0x0061, 0x0002, 0x0004, 0x0006, 0x03bc, 0x0008, + 0x000a, 0x000c, 0x0015, 0x0095, 0x00a5, 0x00b9, 0x00c1, 0x00c3, + 0x00c7, 0x00cb, 0x00d1, 0x00d7, 0x00dd, 0x00e0, 0x00e6, 0x00f8, + 0x0108, 0x010a, 0x0073, 0x0110, 0x0112, 0x0114, 0x0120, 0x012c, + 0x0144, 0x014d, 0x0153, 0x0162, 0x0168, 0x016a, 0x0176, 0x0192, + 0x0194, 0x01a9, 0x01bb, 0x01c7, 0x01d1, 0x01d5, 0x02b9, 0x01d7, + 0x003b, 0x01d9, 0x01db, 0x00b7, 0x01e1, 0x01fc, 0x020c, 0x0218, + 0x021d, 0x0223, 0x0227, 0x03a3, 0x0233, 0x023f, 0x0242, 0x024b, + 0x024e, 0x0251, 0x025d, 0x0260, 0x0269, 0x026c, 0x026f, 0x0275, + 0x0278, 0x0281, 0x028a, 0x029c, 0x029f, 0x02a3, 0x02af, 0x02b9, + 0x02c5, 0x02c9, 0x02cd, 0x02d1, 0x02d5, 0x02e7, 0x02ed, 0x02f1, + 0x02f5, 0x02f9, 0x02fd, 0x0305, 0x0309, 0x030d, 0x0313, 0x0317, + 0x031b, 0x0323, 0x0327, 0x032b, 0x032f, 0x0335, 0x033d, 0x0341, + 0x0349, 0x034d, 0x0351, 0x0f0b, 0x0357, 0x035b, 0x035f, 0x0363, + 0x0367, 0x036b, 0x036f, 0x0373, 0x0379, 0x037d, 0x0381, 0x0385, + 0x0389, 0x038d, 0x0391, 0x0395, 0x0399, 0x039d, 0x03a1, 0x10dc, + 0x03a5, 0x03c9, 0x03cd, 0x03d9, 0x03dd, 0x03e1, 0x03ef, 0x03f1, + 0x043d, 0x044f, 0x0499, 0x04f0, 0x0502, 0x054a, 0x0564, 0x056c, + 0x0570, 0x0573, 0x059a, 0x05fa, 0x05fe, 0x0607, 0x060b, 0x0614, + 0x0618, 0x061e, 0x0622, 0x0628, 0x068e, 0x0694, 0x0698, 0x069e, + 0x06a2, 0x06ab, 0x03ac, 0x06f3, 0x03ad, 0x06f6, 0x03ae, 0x06f9, + 0x03af, 0x06fc, 0x03cc, 0x06ff, 0x03cd, 0x0702, 0x03ce, 0x0705, + 0x0709, 0x070d, 0x0711, 0x0386, 0x0732, 0x0735, 0x03b9, 0x0737, + 0x073b, 0x0388, 0x0753, 0x0389, 0x0756, 0x0390, 0x076b, 0x038a, + 0x0777, 0x03b0, 0x0789, 0x038e, 0x0799, 0x079f, 0x07a3, 0x038c, + 0x07b8, 0x038f, 0x07bb, 0x00b4, 0x07be, 0x07c0, 0x07c2, 0x2010, + 0x07cb, 0x002e, 0x07cd, 0x07cf, 0x0020, 0x07d2, 0x07d6, 0x07db, + 0x07df, 0x07e4, 0x07ea, 0x07f0, 0x0020, 0x07f6, 0x2212, 0x0801, + 0x0805, 0x0807, 0x081d, 0x0825, 0x0827, 0x0043, 0x082d, 0x0830, + 0x0190, 0x0836, 0x0839, 0x004e, 0x0845, 0x0847, 0x084c, 0x084e, + 0x0851, 0x005a, 0x03a9, 0x005a, 0x0853, 0x0857, 0x0860, 0x0069, + 0x0862, 0x0865, 0x086f, 0x0874, 0x087a, 0x087e, 0x08a2, 0x0049, + 0x08a4, 0x08a6, 0x08a9, 0x0056, 0x08ab, 0x08ad, 0x08b0, 0x08b4, + 0x0058, 0x08b6, 0x08b8, 0x08bb, 0x08c0, 0x08c2, 0x08c5, 0x0076, + 0x08c7, 0x08c9, 0x08cc, 0x08d0, 0x0078, 0x08d2, 0x08d4, 0x08d7, + 0x08db, 0x08de, 0x08e4, 0x08e7, 0x08f0, 0x08f3, 0x08f6, 0x08f9, + 0x0902, 0x0906, 0x090b, 0x090f, 0x0914, 0x0917, 0x091a, 0x0923, + 0x092c, 0x093b, 0x093e, 0x0941, 0x0944, 0x0947, 0x094a, 0x0956, + 0x095c, 0x0960, 0x0962, 0x0964, 0x0968, 0x096a, 0x0970, 0x0978, + 0x097c, 0x0980, 0x0986, 0x0989, 0x098f, 0x0991, 0x0030, 0x0993, + 0x0999, 0x099c, 0x099e, 0x09a1, 0x09a4, 0x2d61, 0x6bcd, 0x9f9f, + 0x09a6, 0x09b1, 0x09bc, 0x09c7, 0x0a95, 0x0aa1, 0x0b15, 0x0020, + 0x0b27, 0x0b31, 0x0b8d, 0x0ba1, 0x0ba5, 0x0ba9, 0x0bad, 0x0bb1, + 0x0bb5, 0x0bb9, 0x0bbd, 0x0bc1, 0x0bc5, 0x0c21, 0x0c35, 0x0c39, + 0x0c3d, 0x0c41, 0x0c45, 0x0c49, 0x0c4d, 0x0c51, 0x0c55, 0x0c59, + 0x0c6f, 0x0c71, 0x0c73, 0x0ca0, 0x0cbc, 0x0cdc, 0x0ce4, 0x0cec, + 0x0cf4, 0x0cfc, 0x0d04, 0x0d0c, 0x0d14, 0x0d22, 0x0d2e, 0x0d7a, + 0x0d82, 0x0d85, 0x0d89, 0x0d8d, 0x0d9d, 0x0db1, 0x0db5, 0x0dbc, + 0x0dc2, 0x0dc6, 0x0e28, 0x0e2c, 0x0e30, 0x0e32, 0x0e36, 0x0e3c, + 0x0e3e, 0x0e41, 0x0e43, 0x0e46, 0x0e77, 0x0e7b, 0x0e89, 0x0e8e, + 0x0e94, 0x0e9c, 0x0ea3, 0x0ea9, 0x0eb4, 0x0ebe, 0x0ec6, 0x0eca, + 0x0ecf, 0x0ed9, 0x0edd, 0x0ee4, 0x0eec, 0x0ef3, 0x0ef8, 0x0f04, + 0x0f0a, 0x0f15, 0x0f1b, 0x0f22, 0x0f28, 0x0f33, 0x0f3d, 0x0f45, + 0x0f4c, 0x0f51, 0x0f57, 0x0f5e, 0x0f63, 0x0f69, 0x0f70, 0x0f76, + 0x0f7d, 0x0f82, 0x0f89, 0x0f8d, 0x0f9e, 0x0fa4, 0x0fa9, 0x0fad, + 0x0fb8, 0x0fbe, 0x0fc9, 0x0fd0, 0x0fd6, 0x0fda, 0x0fe1, 0x0fe5, + 0x0fef, 0x0ffa, 0x1000, 0x1004, 0x1009, 0x100f, 0x1013, 0x101a, + 0x101f, 0x1023, 0x1029, 0x102f, 0x1032, 0x1036, 0x1039, 0x103f, + 0x1045, 0x1059, 0x1061, 0x1079, 0x107c, 0x1080, 0x1095, 0x10a1, + 0x10b1, 0x10c3, 0x10cb, 0x10cf, 0x10da, 0x10de, 0x10ea, 0x10f2, + 0x10f4, 0x1100, 0x1105, 0x1111, 0x1141, 0x1149, 0x114d, 0x1153, + 0x1157, 0x115a, 0x116e, 0x1171, 0x1175, 0x117b, 0x117d, 0x1181, + 0x1184, 0x118c, 0x1192, 0x1196, 0x119c, 0x11a2, 0x11a8, 0x11ab, + 0xa76f, 0x11af, 0x11b3, 0x11b7, 0x028d, 0x11bf, 0x1211, 0x130f, + 0x140d, 0x1491, 0x1496, 0x1554, 0x156d, 0x1573, 0x1579, 0x157f, + 0x158b, 0x1597, 0x002b, 0x15a2, 0x15ba, 0x15be, 0x15c2, 0x15c6, + 0x15ca, 0x15ce, 0x15e2, 0x15e6, 0x164a, 0x1663, 0x1689, 0x168f, + 0x174d, 0x1753, 0x1758, 0x1778, 0x1878, 0x187e, 0x1912, 0x19d4, + 0x1a78, 0x1a80, 0x1a9e, 0x1aa3, 0x1ab7, 0x1ac1, 0x1ac7, 0x1adb, + 0x1ae0, 0x1ae6, 0x1af4, 0x1b24, 0x1b31, 0x1b39, 0x1b3d, 0x1b53, + 0x1bca, 0x1bdc, 0x1bde, 0x1be0, 0x3164, 0x1c21, 0x1c23, 0x1c25, + 0x1c27, 0x1c29, 0x1c2b, 0x1c49, 0x1c4e, 0x1c53, 0x1c89, 0x1ccf, + 0x1cdd, 0x1ce2, 0x1ceb, 0x1cf4, 0x1d02, 0x1d07, 0x1d0c, 0x1d1e, + 0x1d30, 0x1d39, 0x1d3e, 0x1d62, 0x1d70, 0x1d72, 0x1d74, 0x1d94, + 0x1daf, 0x1db1, 0x1db3, 0x1db5, 0x1db7, 0x1db9, 0x1dbb, 0x1dbd, + 0x1ddd, 0x1ddf, 0x1de1, 0x1de3, 0x1de5, 0x1dec, 0x1dee, 0x1df0, + 0x1df2, 0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09, 0x1e0b, 0x1e0d, + 0x1e0f, 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b, 0x1e1d, + 0x1e21, 0x03f4, 0x1e23, 0x2207, 0x1e25, 0x2202, 0x1e27, 0x1e2f, + 0x03f4, 0x1e31, 0x2207, 0x1e33, 0x2202, 0x1e35, 0x1e3d, 0x03f4, + 0x1e3f, 0x2207, 0x1e41, 0x2202, 0x1e43, 0x1e4b, 0x03f4, 0x1e4d, + 0x2207, 0x1e4f, 0x2202, 0x1e51, 0x1e59, 0x03f4, 0x1e5b, 0x2207, + 0x1e5d, 0x2202, 0x1e5f, 0x1e69, 0x1e6b, 0x1e6d, 0x1e6f, 0x1e71, + 0x1e73, 0x1e75, 0x1e77, 0x1e79, 0x1e81, 0x1ea4, 0x1ea8, 0x1eae, + 0x1ecb, 0x062d, 0x1ed3, 0x1edf, 0x062c, 0x1eef, 0x1f5f, 0x1f6b, + 0x1f7e, 0x1f90, 0x1fa3, 0x1fa5, 0x1fa9, 0x1faf, 0x1fb5, 0x1fb7, + 0x1fbb, 0x1fbd, 0x1fc5, 0x1fc8, 0x1fca, 0x1fd0, 0x1fd2, 0x30b5, + 0x1fd8, 0x2030, 0x2046, 0x204a, 0x204c, 0x2051, 0x209e, 0x20af, + 0x21b0, 0x21c0, 0x21c6, 0x22c0, 0x23de, +}; + +static const uint8_t unicode_decomp_data[9452] = { + 0x20, 0x88, 0x20, 0x84, 0x32, 0x33, 0x20, 0x81, + 0x20, 0xa7, 0x31, 0x6f, 0x31, 0xd0, 0x34, 0x31, + 0xd0, 0x32, 0x33, 0xd0, 0x34, 0x41, 0x80, 0x41, + 0x81, 0x41, 0x82, 0x41, 0x83, 0x41, 0x88, 0x41, + 0x8a, 0x00, 0x00, 0x43, 0xa7, 0x45, 0x80, 0x45, + 0x81, 0x45, 0x82, 0x45, 0x88, 0x49, 0x80, 0x49, + 0x81, 0x49, 0x82, 0x49, 0x88, 0x00, 0x00, 0x4e, + 0x83, 0x4f, 0x80, 0x4f, 0x81, 0x4f, 0x82, 0x4f, + 0x83, 0x4f, 0x88, 0x00, 0x00, 0x00, 0x00, 0x55, + 0x80, 0x55, 0x81, 0x55, 0x82, 0x55, 0x88, 0x59, + 0x81, 0x00, 0x00, 0x00, 0x00, 0x61, 0x80, 0x61, + 0x81, 0x61, 0x82, 0x61, 0x83, 0x61, 0x88, 0x61, + 0x8a, 0x00, 0x00, 0x63, 0xa7, 0x65, 0x80, 0x65, + 0x81, 0x65, 0x82, 0x65, 0x88, 0x69, 0x80, 0x69, + 0x81, 0x69, 0x82, 0x69, 0x88, 0x00, 0x00, 0x6e, + 0x83, 0x6f, 0x80, 0x6f, 0x81, 0x6f, 0x82, 0x6f, + 0x83, 0x6f, 0x88, 0x00, 0x00, 0x00, 0x00, 0x75, + 0x80, 0x75, 0x81, 0x75, 0x82, 0x75, 0x88, 0x79, + 0x81, 0x00, 0x00, 0x79, 0x88, 0x41, 0x84, 0x41, + 0x86, 0x41, 0xa8, 0x43, 0x81, 0x43, 0x82, 0x43, + 0x87, 0x43, 0x8c, 0x44, 0x8c, 0x45, 0x84, 0x45, + 0x86, 0x45, 0x87, 0x45, 0xa8, 0x45, 0x8c, 0x47, + 0x82, 0x47, 0x86, 0x47, 0x87, 0x47, 0xa7, 0x48, + 0x82, 0x49, 0x83, 0x49, 0x84, 0x49, 0x86, 0x49, + 0xa8, 0x49, 0x87, 0x49, 0x4a, 0x69, 0x6a, 0x4a, + 0x82, 0x4b, 0xa7, 0x4c, 0x81, 0x4c, 0xa7, 0x4c, + 0x8c, 0x4c, 0x00, 0x00, 0x6b, 0x20, 0x6b, 0x4e, + 0x81, 0x4e, 0xa7, 0x4e, 0x8c, 0xbc, 0x02, 0x6e, + 0x4f, 0x84, 0x4f, 0x86, 0x4f, 0x8b, 0x52, 0x81, + 0x52, 0xa7, 0x52, 0x8c, 0x53, 0x81, 0x53, 0x82, + 0x53, 0xa7, 0x53, 0x8c, 0x54, 0xa7, 0x54, 0x8c, + 0x55, 0x83, 0x55, 0x84, 0x55, 0x86, 0x55, 0x8a, + 0x55, 0x8b, 0x55, 0xa8, 0x57, 0x82, 0x59, 0x82, + 0x59, 0x88, 0x5a, 0x81, 0x5a, 0x87, 0x5a, 0x8c, + 0x4f, 0x9b, 0x55, 0x9b, 0x44, 0x00, 0x7d, 0x01, + 0x44, 0x00, 0x7e, 0x01, 0x64, 0x00, 0x7e, 0x01, + 0x4c, 0x4a, 0x4c, 0x6a, 0x6c, 0x6a, 0x4e, 0x4a, + 0x4e, 0x6a, 0x6e, 0x6a, 0x41, 0x00, 0x8c, 0x49, + 0x00, 0x8c, 0x4f, 0x00, 0x8c, 0x55, 0x00, 0x8c, + 0xdc, 0x00, 0x84, 0xdc, 0x00, 0x81, 0xdc, 0x00, + 0x8c, 0xdc, 0x00, 0x80, 0xc4, 0x00, 0x84, 0x26, + 0x02, 0x84, 0xc6, 0x00, 0x84, 0x47, 0x8c, 0x4b, + 0x8c, 0x4f, 0xa8, 0xea, 0x01, 0x84, 0xeb, 0x01, + 0x84, 0xb7, 0x01, 0x8c, 0x92, 0x02, 0x8c, 0x6a, + 0x00, 0x8c, 0x44, 0x5a, 0x44, 0x7a, 0x64, 0x7a, + 0x47, 0x81, 0x4e, 0x00, 0x80, 0xc5, 0x00, 0x81, + 0xc6, 0x00, 0x81, 0xd8, 0x00, 0x81, 0x41, 0x8f, + 0x41, 0x91, 0x45, 0x8f, 0x45, 0x91, 0x49, 0x8f, + 0x49, 0x91, 0x4f, 0x8f, 0x4f, 0x91, 0x52, 0x8f, + 0x52, 0x91, 0x55, 0x8f, 0x55, 0x91, 0x53, 0xa6, + 0x54, 0xa6, 0x48, 0x8c, 0x41, 0x00, 0x87, 0x45, + 0x00, 0xa7, 0xd6, 0x00, 0x84, 0xd5, 0x00, 0x84, + 0x4f, 0x00, 0x87, 0x2e, 0x02, 0x84, 0x59, 0x00, + 0x84, 0x68, 0x00, 0x66, 0x02, 0x6a, 0x00, 0x72, + 0x00, 0x79, 0x02, 0x7b, 0x02, 0x81, 0x02, 0x77, + 0x00, 0x79, 0x00, 0x20, 0x86, 0x20, 0x87, 0x20, + 0x8a, 0x20, 0xa8, 0x20, 0x83, 0x20, 0x8b, 0x63, + 0x02, 0x6c, 0x00, 0x73, 0x00, 0x78, 0x00, 0x95, + 0x02, 0x80, 0x81, 0x00, 0x93, 0x88, 0x81, 0x20, + 0xc5, 0x20, 0x81, 0xa8, 0x00, 0x81, 0x91, 0x03, + 0x81, 0x95, 0x03, 0x81, 0x97, 0x03, 0x81, 0x99, + 0x03, 0x81, 0x00, 0x00, 0x00, 0x9f, 0x03, 0x81, + 0x00, 0x00, 0x00, 0xa5, 0x03, 0x81, 0xa9, 0x03, + 0x81, 0xca, 0x03, 0x81, 0x01, 0x03, 0x98, 0x07, + 0xa4, 0x07, 0xb0, 0x00, 0xb4, 0x00, 0xb6, 0x00, + 0xb8, 0x00, 0xca, 0x00, 0x01, 0x03, 0xb8, 0x07, + 0xc4, 0x07, 0xbe, 0x00, 0xc4, 0x00, 0xc8, 0x00, + 0xa5, 0x03, 0x0d, 0x13, 0x00, 0x01, 0x03, 0xd1, + 0x00, 0xd1, 0x07, 0xc6, 0x03, 0xc0, 0x03, 0xba, + 0x03, 0xc1, 0x03, 0xc2, 0x03, 0x00, 0x00, 0x98, + 0x03, 0xb5, 0x03, 0x15, 0x04, 0x80, 0x15, 0x04, + 0x88, 0x00, 0x00, 0x00, 0x13, 0x04, 0x81, 0x06, + 0x04, 0x88, 0x1a, 0x04, 0x81, 0x18, 0x04, 0x80, + 0x23, 0x04, 0x86, 0x18, 0x04, 0x86, 0x38, 0x04, + 0x86, 0x35, 0x04, 0x80, 0x35, 0x04, 0x88, 0x00, + 0x00, 0x00, 0x33, 0x04, 0x81, 0x56, 0x04, 0x88, + 0x3a, 0x04, 0x81, 0x38, 0x04, 0x80, 0x43, 0x04, + 0x86, 0x74, 0x04, 0x8f, 0x16, 0x04, 0x86, 0x10, + 0x04, 0x86, 0x10, 0x04, 0x88, 0x15, 0x04, 0x86, + 0xd8, 0x04, 0x88, 0x16, 0x04, 0x88, 0x17, 0x04, + 0x88, 0x18, 0x04, 0x84, 0x18, 0x04, 0x88, 0x1e, + 0x04, 0x88, 0xe8, 0x04, 0x88, 0x2d, 0x04, 0x88, + 0x23, 0x04, 0x84, 0x23, 0x04, 0x88, 0x23, 0x04, + 0x8b, 0x27, 0x04, 0x88, 0x2b, 0x04, 0x88, 0x65, + 0x05, 0x82, 0x05, 0x27, 0x06, 0x00, 0x2c, 0x00, + 0x2d, 0x21, 0x2d, 0x00, 0x2e, 0x23, 0x2d, 0x27, + 0x06, 0x00, 0x4d, 0x21, 0x4d, 0xa0, 0x4d, 0x23, + 0x4d, 0xd5, 0x06, 0x54, 0x06, 0x00, 0x00, 0x00, + 0x00, 0xc1, 0x06, 0x54, 0x06, 0xd2, 0x06, 0x54, + 0x06, 0x28, 0x09, 0x3c, 0x09, 0x30, 0x09, 0x3c, + 0x09, 0x33, 0x09, 0x3c, 0x09, 0x15, 0x09, 0x00, + 0x27, 0x01, 0x27, 0x02, 0x27, 0x07, 0x27, 0x0c, + 0x27, 0x0d, 0x27, 0x16, 0x27, 0x1a, 0x27, 0xbe, + 0x09, 0x09, 0x00, 0x09, 0x19, 0xa1, 0x09, 0xbc, + 0x09, 0xaf, 0x09, 0xbc, 0x09, 0x32, 0x0a, 0x3c, + 0x0a, 0x38, 0x0a, 0x3c, 0x0a, 0x16, 0x0a, 0x00, + 0x26, 0x01, 0x26, 0x06, 0x26, 0x2b, 0x0a, 0x3c, + 0x0a, 0x47, 0x0b, 0x56, 0x0b, 0x3e, 0x0b, 0x09, + 0x00, 0x09, 0x19, 0x21, 0x0b, 0x3c, 0x0b, 0x92, + 0x0b, 0xd7, 0x0b, 0xbe, 0x0b, 0x08, 0x00, 0x09, + 0x00, 0x08, 0x19, 0x46, 0x0c, 0x56, 0x0c, 0xbf, + 0x0c, 0xd5, 0x0c, 0xc6, 0x0c, 0xd5, 0x0c, 0xc2, + 0x0c, 0x04, 0x00, 0x08, 0x13, 0x3e, 0x0d, 0x08, + 0x00, 0x09, 0x00, 0x08, 0x19, 0xd9, 0x0d, 0xca, + 0x0d, 0xca, 0x0d, 0x0f, 0x05, 0x12, 0x00, 0x0f, + 0x15, 0x4d, 0x0e, 0x32, 0x0e, 0xcd, 0x0e, 0xb2, + 0x0e, 0x99, 0x0e, 0x12, 0x00, 0x12, 0x08, 0x42, + 0x0f, 0xb7, 0x0f, 0x4c, 0x0f, 0xb7, 0x0f, 0x51, + 0x0f, 0xb7, 0x0f, 0x56, 0x0f, 0xb7, 0x0f, 0x5b, + 0x0f, 0xb7, 0x0f, 0x40, 0x0f, 0xb5, 0x0f, 0x71, + 0x0f, 0x72, 0x0f, 0x71, 0x0f, 0x00, 0x03, 0x41, + 0x0f, 0xb2, 0x0f, 0x81, 0x0f, 0xb3, 0x0f, 0x80, + 0x0f, 0xb3, 0x0f, 0x81, 0x0f, 0x71, 0x0f, 0x80, + 0x0f, 0x92, 0x0f, 0xb7, 0x0f, 0x9c, 0x0f, 0xb7, + 0x0f, 0xa1, 0x0f, 0xb7, 0x0f, 0xa6, 0x0f, 0xb7, + 0x0f, 0xab, 0x0f, 0xb7, 0x0f, 0x90, 0x0f, 0xb5, + 0x0f, 0x25, 0x10, 0x2e, 0x10, 0x05, 0x1b, 0x35, + 0x1b, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1b, 0x35, + 0x1b, 0x00, 0x00, 0x00, 0x00, 0x09, 0x1b, 0x35, + 0x1b, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0x35, + 0x1b, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x1b, 0x35, + 0x1b, 0x11, 0x1b, 0x35, 0x1b, 0x3a, 0x1b, 0x35, + 0x1b, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x1b, 0x35, + 0x1b, 0x3e, 0x1b, 0x35, 0x1b, 0x42, 0x1b, 0x35, + 0x1b, 0x41, 0x00, 0xc6, 0x00, 0x42, 0x00, 0x00, + 0x00, 0x44, 0x00, 0x45, 0x00, 0x8e, 0x01, 0x47, + 0x00, 0x4f, 0x00, 0x22, 0x02, 0x50, 0x00, 0x52, + 0x00, 0x54, 0x00, 0x55, 0x00, 0x57, 0x00, 0x61, + 0x00, 0x50, 0x02, 0x51, 0x02, 0x02, 0x1d, 0x62, + 0x00, 0x64, 0x00, 0x65, 0x00, 0x59, 0x02, 0x5b, + 0x02, 0x5c, 0x02, 0x67, 0x00, 0x00, 0x00, 0x6b, + 0x00, 0x6d, 0x00, 0x4b, 0x01, 0x6f, 0x00, 0x54, + 0x02, 0x16, 0x1d, 0x17, 0x1d, 0x70, 0x00, 0x74, + 0x00, 0x75, 0x00, 0x1d, 0x1d, 0x6f, 0x02, 0x76, + 0x00, 0x25, 0x1d, 0xb2, 0x03, 0xb3, 0x03, 0xb4, + 0x03, 0xc6, 0x03, 0xc7, 0x03, 0x69, 0x00, 0x72, + 0x00, 0x75, 0x00, 0x76, 0x00, 0xb2, 0x03, 0xb3, + 0x03, 0xc1, 0x03, 0xc6, 0x03, 0xc7, 0x03, 0x52, + 0x02, 0x63, 0x00, 0x55, 0x02, 0xf0, 0x00, 0x5c, + 0x02, 0x66, 0x00, 0x5f, 0x02, 0x61, 0x02, 0x65, + 0x02, 0x68, 0x02, 0x69, 0x02, 0x6a, 0x02, 0x7b, + 0x1d, 0x9d, 0x02, 0x6d, 0x02, 0x85, 0x1d, 0x9f, + 0x02, 0x71, 0x02, 0x70, 0x02, 0x72, 0x02, 0x73, + 0x02, 0x74, 0x02, 0x75, 0x02, 0x78, 0x02, 0x82, + 0x02, 0x83, 0x02, 0xab, 0x01, 0x89, 0x02, 0x8a, + 0x02, 0x1c, 0x1d, 0x8b, 0x02, 0x8c, 0x02, 0x7a, + 0x00, 0x90, 0x02, 0x91, 0x02, 0x92, 0x02, 0xb8, + 0x03, 0x41, 0x00, 0xa5, 0x42, 0x00, 0x87, 0x42, + 0x00, 0xa3, 0x42, 0x00, 0xb1, 0xc7, 0x00, 0x81, + 0x44, 0x00, 0x87, 0x44, 0x00, 0xa3, 0x44, 0x00, + 0xb1, 0x44, 0x00, 0xa7, 0x44, 0x00, 0xad, 0x12, + 0x01, 0x80, 0x12, 0x01, 0x81, 0x45, 0x00, 0xad, + 0x45, 0x00, 0xb0, 0x28, 0x02, 0x86, 0x46, 0x00, + 0x87, 0x47, 0x00, 0x84, 0x48, 0x00, 0x87, 0x48, + 0x00, 0xa3, 0x48, 0x00, 0x88, 0x48, 0x00, 0xa7, + 0x48, 0x00, 0xae, 0x49, 0x00, 0xb0, 0xcf, 0x00, + 0x81, 0x4b, 0x00, 0x81, 0x4b, 0x00, 0xa3, 0x4b, + 0x00, 0xb1, 0x4c, 0x00, 0xa3, 0x36, 0x1e, 0x84, + 0x4c, 0xb1, 0x4c, 0xad, 0x4d, 0x81, 0x4d, 0x87, + 0x4d, 0xa3, 0x4e, 0x87, 0x4e, 0xa3, 0x4e, 0xb1, + 0x4e, 0xad, 0xd5, 0x00, 0x81, 0xd5, 0x00, 0x88, + 0x4c, 0x01, 0x80, 0x4c, 0x01, 0x81, 0x50, 0x00, + 0x81, 0x50, 0x00, 0x87, 0x52, 0x00, 0x87, 0x52, + 0x00, 0xa3, 0x5a, 0x1e, 0x84, 0x52, 0x00, 0xb1, + 0x53, 0x00, 0x87, 0x53, 0x00, 0xa3, 0x5a, 0x01, + 0x87, 0x60, 0x01, 0x87, 0x62, 0x1e, 0x87, 0x54, + 0x00, 0x87, 0x54, 0x00, 0xa3, 0x54, 0x00, 0xb1, + 0x54, 0x00, 0xad, 0x55, 0x00, 0xa4, 0x55, 0x00, + 0xb0, 0x55, 0x00, 0xad, 0x68, 0x01, 0x81, 0x6a, + 0x01, 0x88, 0x56, 0x83, 0x56, 0xa3, 0x57, 0x80, + 0x57, 0x81, 0x57, 0x88, 0x57, 0x87, 0x57, 0xa3, + 0x58, 0x87, 0x58, 0x88, 0x59, 0x87, 0x5a, 0x82, + 0x5a, 0xa3, 0x5a, 0xb1, 0x68, 0xb1, 0x74, 0x88, + 0x77, 0x8a, 0x79, 0x8a, 0x61, 0x00, 0xbe, 0x02, + 0x7f, 0x01, 0x87, 0x41, 0x00, 0xa3, 0x41, 0x00, + 0x89, 0xc2, 0x00, 0x81, 0xc2, 0x00, 0x80, 0xc2, + 0x00, 0x89, 0xc2, 0x00, 0x83, 0xa0, 0x1e, 0x82, + 0x02, 0x01, 0x81, 0x02, 0x01, 0x80, 0x02, 0x01, + 0x89, 0x02, 0x01, 0x83, 0xa0, 0x1e, 0x86, 0x45, + 0x00, 0xa3, 0x45, 0x00, 0x89, 0x45, 0x00, 0x83, + 0xca, 0x00, 0x81, 0xca, 0x00, 0x80, 0xca, 0x00, + 0x89, 0xca, 0x00, 0x83, 0xb8, 0x1e, 0x82, 0x49, + 0x00, 0x89, 0x49, 0x00, 0xa3, 0x4f, 0x00, 0xa3, + 0x4f, 0x00, 0x89, 0xd4, 0x00, 0x81, 0xd4, 0x00, + 0x80, 0xd4, 0x00, 0x89, 0xd4, 0x00, 0x83, 0xcc, + 0x1e, 0x82, 0xa0, 0x01, 0x81, 0xa0, 0x01, 0x80, + 0xa0, 0x01, 0x89, 0xa0, 0x01, 0x83, 0xa0, 0x01, + 0xa3, 0x55, 0x00, 0xa3, 0x55, 0x00, 0x89, 0xaf, + 0x01, 0x81, 0xaf, 0x01, 0x80, 0xaf, 0x01, 0x89, + 0xaf, 0x01, 0x83, 0xaf, 0x01, 0xa3, 0x59, 0x00, + 0x80, 0x59, 0x00, 0xa3, 0x59, 0x00, 0x89, 0x59, + 0x00, 0x83, 0xb1, 0x03, 0x13, 0x03, 0x00, 0x1f, + 0x80, 0x00, 0x1f, 0x81, 0x00, 0x1f, 0xc2, 0x91, + 0x03, 0x13, 0x03, 0x08, 0x1f, 0x80, 0x08, 0x1f, + 0x81, 0x08, 0x1f, 0xc2, 0xb5, 0x03, 0x13, 0x03, + 0x10, 0x1f, 0x80, 0x10, 0x1f, 0x81, 0x95, 0x03, + 0x13, 0x03, 0x18, 0x1f, 0x80, 0x18, 0x1f, 0x81, + 0xb7, 0x03, 0x93, 0xb7, 0x03, 0x94, 0x20, 0x1f, + 0x80, 0x21, 0x1f, 0x80, 0x20, 0x1f, 0x81, 0x21, + 0x1f, 0x81, 0x20, 0x1f, 0xc2, 0x21, 0x1f, 0xc2, + 0x97, 0x03, 0x93, 0x97, 0x03, 0x94, 0x28, 0x1f, + 0x80, 0x29, 0x1f, 0x80, 0x28, 0x1f, 0x81, 0x29, + 0x1f, 0x81, 0x28, 0x1f, 0xc2, 0x29, 0x1f, 0xc2, + 0xb9, 0x03, 0x93, 0xb9, 0x03, 0x94, 0x30, 0x1f, + 0x80, 0x31, 0x1f, 0x80, 0x30, 0x1f, 0x81, 0x31, + 0x1f, 0x81, 0x30, 0x1f, 0xc2, 0x31, 0x1f, 0xc2, + 0x99, 0x03, 0x93, 0x99, 0x03, 0x94, 0x38, 0x1f, + 0x80, 0x39, 0x1f, 0x80, 0x38, 0x1f, 0x81, 0x39, + 0x1f, 0x81, 0x38, 0x1f, 0xc2, 0x39, 0x1f, 0xc2, + 0xbf, 0x03, 0x93, 0xbf, 0x03, 0x94, 0x40, 0x1f, + 0x80, 0x40, 0x1f, 0x81, 0x9f, 0x03, 0x13, 0x03, + 0x48, 0x1f, 0x80, 0x48, 0x1f, 0x81, 0xc5, 0x03, + 0x13, 0x03, 0x50, 0x1f, 0x80, 0x50, 0x1f, 0x81, + 0x50, 0x1f, 0xc2, 0xa5, 0x03, 0x94, 0x00, 0x00, + 0x00, 0x59, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x59, + 0x1f, 0x81, 0x00, 0x00, 0x00, 0x59, 0x1f, 0xc2, + 0xc9, 0x03, 0x93, 0xc9, 0x03, 0x94, 0x60, 0x1f, + 0x80, 0x61, 0x1f, 0x80, 0x60, 0x1f, 0x81, 0x61, + 0x1f, 0x81, 0x60, 0x1f, 0xc2, 0x61, 0x1f, 0xc2, + 0xa9, 0x03, 0x93, 0xa9, 0x03, 0x94, 0x68, 0x1f, + 0x80, 0x69, 0x1f, 0x80, 0x68, 0x1f, 0x81, 0x69, + 0x1f, 0x81, 0x68, 0x1f, 0xc2, 0x69, 0x1f, 0xc2, + 0xb1, 0x03, 0x80, 0xb5, 0x03, 0x80, 0xb7, 0x03, + 0x80, 0xb9, 0x03, 0x80, 0xbf, 0x03, 0x80, 0xc5, + 0x03, 0x80, 0xc9, 0x03, 0x80, 0x00, 0x1f, 0x45, + 0x03, 0x20, 0x1f, 0x45, 0x03, 0x60, 0x1f, 0x45, + 0x03, 0xb1, 0x03, 0x86, 0xb1, 0x03, 0x84, 0x70, + 0x1f, 0xc5, 0xb1, 0x03, 0xc5, 0xac, 0x03, 0xc5, + 0x00, 0x00, 0x00, 0xb1, 0x03, 0xc2, 0xb6, 0x1f, + 0xc5, 0x91, 0x03, 0x86, 0x91, 0x03, 0x84, 0x91, + 0x03, 0x80, 0x91, 0x03, 0xc5, 0x20, 0x93, 0x20, + 0x93, 0x20, 0xc2, 0xa8, 0x00, 0xc2, 0x74, 0x1f, + 0xc5, 0xb7, 0x03, 0xc5, 0xae, 0x03, 0xc5, 0x00, + 0x00, 0x00, 0xb7, 0x03, 0xc2, 0xc6, 0x1f, 0xc5, + 0x95, 0x03, 0x80, 0x97, 0x03, 0x80, 0x97, 0x03, + 0xc5, 0xbf, 0x1f, 0x80, 0xbf, 0x1f, 0x81, 0xbf, + 0x1f, 0xc2, 0xb9, 0x03, 0x86, 0xb9, 0x03, 0x84, + 0xca, 0x03, 0x80, 0x00, 0x03, 0xb9, 0x42, 0xca, + 0x42, 0x99, 0x06, 0x99, 0x04, 0x99, 0x00, 0xfe, + 0x1f, 0x80, 0xfe, 0x1f, 0x81, 0xfe, 0x1f, 0xc2, + 0xc5, 0x03, 0x86, 0xc5, 0x03, 0x84, 0xcb, 0x03, + 0x80, 0x00, 0x03, 0xc1, 0x13, 0xc1, 0x14, 0xc5, + 0x42, 0xcb, 0x42, 0xa5, 0x06, 0xa5, 0x04, 0xa5, + 0x00, 0xa1, 0x03, 0x94, 0xa8, 0x00, 0x80, 0x85, + 0x03, 0x60, 0x00, 0x7c, 0x1f, 0xc5, 0xc9, 0x03, + 0xc5, 0xce, 0x03, 0xc5, 0x00, 0x00, 0x00, 0xc9, + 0x03, 0xc2, 0xf6, 0x1f, 0xc5, 0x9f, 0x03, 0x80, + 0xa9, 0x03, 0x80, 0xa9, 0x03, 0xc5, 0x20, 0x94, + 0x02, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0xb3, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x32, 0x20, 0x32, 0x20, 0x32, 0x20, + 0x00, 0x00, 0x00, 0x35, 0x20, 0x35, 0x20, 0x35, + 0x20, 0x00, 0x00, 0x00, 0x21, 0x21, 0x00, 0x00, + 0x20, 0x85, 0x3f, 0x3f, 0x3f, 0x21, 0x21, 0x3f, + 0x32, 0x20, 0x00, 0x00, 0x00, 0x00, 0x30, 0x69, + 0x00, 0x00, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x2b, 0x3d, 0x28, 0x29, 0x6e, 0x30, 0x00, 0x2b, + 0x00, 0x12, 0x22, 0x3d, 0x00, 0x28, 0x00, 0x29, + 0x00, 0x00, 0x00, 0x61, 0x00, 0x65, 0x00, 0x6f, + 0x00, 0x78, 0x00, 0x59, 0x02, 0x68, 0x6b, 0x6c, + 0x6d, 0x6e, 0x70, 0x73, 0x74, 0x52, 0x73, 0x61, + 0x2f, 0x63, 0x61, 0x2f, 0x73, 0xb0, 0x00, 0x43, + 0x63, 0x2f, 0x6f, 0x63, 0x2f, 0x75, 0xb0, 0x00, + 0x46, 0x48, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x20, + 0xdf, 0x01, 0x01, 0x04, 0x24, 0x4e, 0x6f, 0x50, + 0x51, 0x52, 0x52, 0x52, 0x53, 0x4d, 0x54, 0x45, + 0x4c, 0x54, 0x4d, 0x4b, 0x00, 0xc5, 0x00, 0x42, + 0x43, 0x00, 0x65, 0x45, 0x46, 0x00, 0x4d, 0x6f, + 0xd0, 0x05, 0x46, 0x41, 0x58, 0xc0, 0x03, 0xb3, + 0x03, 0x93, 0x03, 0xa0, 0x03, 0x11, 0x22, 0x44, + 0x64, 0x65, 0x69, 0x6a, 0x31, 0xd0, 0x37, 0x31, + 0xd0, 0x39, 0x31, 0xd0, 0x31, 0x30, 0x31, 0xd0, + 0x33, 0x32, 0xd0, 0x33, 0x31, 0xd0, 0x35, 0x32, + 0xd0, 0x35, 0x33, 0xd0, 0x35, 0x34, 0xd0, 0x35, + 0x31, 0xd0, 0x36, 0x35, 0xd0, 0x36, 0x31, 0xd0, + 0x38, 0x33, 0xd0, 0x38, 0x35, 0xd0, 0x38, 0x37, + 0xd0, 0x38, 0x31, 0xd0, 0x49, 0x49, 0x49, 0x49, + 0x49, 0x49, 0x56, 0x56, 0x49, 0x56, 0x49, 0x49, + 0x56, 0x49, 0x49, 0x49, 0x49, 0x58, 0x58, 0x49, + 0x58, 0x49, 0x49, 0x4c, 0x43, 0x44, 0x4d, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x76, 0x76, + 0x69, 0x76, 0x69, 0x69, 0x76, 0x69, 0x69, 0x69, + 0x69, 0x78, 0x78, 0x69, 0x78, 0x69, 0x69, 0x6c, + 0x63, 0x64, 0x6d, 0x30, 0xd0, 0x33, 0x90, 0x21, + 0xb8, 0x92, 0x21, 0xb8, 0x94, 0x21, 0xb8, 0xd0, + 0x21, 0xb8, 0xd4, 0x21, 0xb8, 0xd2, 0x21, 0xb8, + 0x03, 0x22, 0xb8, 0x08, 0x22, 0xb8, 0x0b, 0x22, + 0xb8, 0x23, 0x22, 0xb8, 0x00, 0x00, 0x00, 0x25, + 0x22, 0xb8, 0x2b, 0x22, 0x2b, 0x22, 0x2b, 0x22, + 0x00, 0x00, 0x00, 0x2e, 0x22, 0x2e, 0x22, 0x2e, + 0x22, 0x00, 0x00, 0x00, 0x3c, 0x22, 0xb8, 0x43, + 0x22, 0xb8, 0x45, 0x22, 0xb8, 0x00, 0x00, 0x00, + 0x48, 0x22, 0xb8, 0x3d, 0x00, 0xb8, 0x00, 0x00, + 0x00, 0x61, 0x22, 0xb8, 0x4d, 0x22, 0xb8, 0x3c, + 0x00, 0xb8, 0x3e, 0x00, 0xb8, 0x64, 0x22, 0xb8, + 0x65, 0x22, 0xb8, 0x72, 0x22, 0xb8, 0x76, 0x22, + 0xb8, 0x7a, 0x22, 0xb8, 0x82, 0x22, 0xb8, 0x86, + 0x22, 0xb8, 0xa2, 0x22, 0xb8, 0xa8, 0x22, 0xb8, + 0xa9, 0x22, 0xb8, 0xab, 0x22, 0xb8, 0x7c, 0x22, + 0xb8, 0x91, 0x22, 0xb8, 0xb2, 0x22, 0x38, 0x03, + 0x08, 0x30, 0x31, 0x00, 0x31, 0x00, 0x30, 0x00, + 0x32, 0x30, 0x28, 0x00, 0x31, 0x00, 0x29, 0x00, + 0x28, 0x00, 0x31, 0x00, 0x30, 0x00, 0x29, 0x00, + 0x28, 0x32, 0x30, 0x29, 0x31, 0x00, 0x2e, 0x00, + 0x31, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x32, 0x30, + 0x2e, 0x28, 0x00, 0x61, 0x00, 0x29, 0x00, 0x41, + 0x00, 0x61, 0x00, 0x2b, 0x22, 0x00, 0x00, 0x00, + 0x00, 0x3a, 0x3a, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, + 0x3d, 0xdd, 0x2a, 0xb8, 0x6a, 0x56, 0x00, 0x4e, + 0x00, 0x28, 0x36, 0x3f, 0x59, 0x85, 0x8c, 0xa0, + 0xba, 0x3f, 0x51, 0x00, 0x26, 0x2c, 0x43, 0x57, + 0x6c, 0xa1, 0xb6, 0xc1, 0x9b, 0x52, 0x00, 0x5e, + 0x7a, 0x7f, 0x9d, 0xa6, 0xc1, 0xce, 0xe7, 0xb6, + 0x53, 0xc8, 0x53, 0xe3, 0x53, 0xd7, 0x56, 0x1f, + 0x57, 0xeb, 0x58, 0x02, 0x59, 0x0a, 0x59, 0x15, + 0x59, 0x27, 0x59, 0x73, 0x59, 0x50, 0x5b, 0x80, + 0x5b, 0xf8, 0x5b, 0x0f, 0x5c, 0x22, 0x5c, 0x38, + 0x5c, 0x6e, 0x5c, 0x71, 0x5c, 0xdb, 0x5d, 0xe5, + 0x5d, 0xf1, 0x5d, 0xfe, 0x5d, 0x72, 0x5e, 0x7a, + 0x5e, 0x7f, 0x5e, 0xf4, 0x5e, 0xfe, 0x5e, 0x0b, + 0x5f, 0x13, 0x5f, 0x50, 0x5f, 0x61, 0x5f, 0x73, + 0x5f, 0xc3, 0x5f, 0x08, 0x62, 0x36, 0x62, 0x4b, + 0x62, 0x2f, 0x65, 0x34, 0x65, 0x87, 0x65, 0x97, + 0x65, 0xa4, 0x65, 0xb9, 0x65, 0xe0, 0x65, 0xe5, + 0x65, 0xf0, 0x66, 0x08, 0x67, 0x28, 0x67, 0x20, + 0x6b, 0x62, 0x6b, 0x79, 0x6b, 0xb3, 0x6b, 0xcb, + 0x6b, 0xd4, 0x6b, 0xdb, 0x6b, 0x0f, 0x6c, 0x14, + 0x6c, 0x34, 0x6c, 0x6b, 0x70, 0x2a, 0x72, 0x36, + 0x72, 0x3b, 0x72, 0x3f, 0x72, 0x47, 0x72, 0x59, + 0x72, 0x5b, 0x72, 0xac, 0x72, 0x84, 0x73, 0x89, + 0x73, 0xdc, 0x74, 0xe6, 0x74, 0x18, 0x75, 0x1f, + 0x75, 0x28, 0x75, 0x30, 0x75, 0x8b, 0x75, 0x92, + 0x75, 0x76, 0x76, 0x7d, 0x76, 0xae, 0x76, 0xbf, + 0x76, 0xee, 0x76, 0xdb, 0x77, 0xe2, 0x77, 0xf3, + 0x77, 0x3a, 0x79, 0xb8, 0x79, 0xbe, 0x79, 0x74, + 0x7a, 0xcb, 0x7a, 0xf9, 0x7a, 0x73, 0x7c, 0xf8, + 0x7c, 0x36, 0x7f, 0x51, 0x7f, 0x8a, 0x7f, 0xbd, + 0x7f, 0x01, 0x80, 0x0c, 0x80, 0x12, 0x80, 0x33, + 0x80, 0x7f, 0x80, 0x89, 0x80, 0xe3, 0x81, 0x00, + 0x07, 0x10, 0x19, 0x29, 0x38, 0x3c, 0x8b, 0x8f, + 0x95, 0x4d, 0x86, 0x6b, 0x86, 0x40, 0x88, 0x4c, + 0x88, 0x63, 0x88, 0x7e, 0x89, 0x8b, 0x89, 0xd2, + 0x89, 0x00, 0x8a, 0x37, 0x8c, 0x46, 0x8c, 0x55, + 0x8c, 0x78, 0x8c, 0x9d, 0x8c, 0x64, 0x8d, 0x70, + 0x8d, 0xb3, 0x8d, 0xab, 0x8e, 0xca, 0x8e, 0x9b, + 0x8f, 0xb0, 0x8f, 0xb5, 0x8f, 0x91, 0x90, 0x49, + 0x91, 0xc6, 0x91, 0xcc, 0x91, 0xd1, 0x91, 0x77, + 0x95, 0x80, 0x95, 0x1c, 0x96, 0xb6, 0x96, 0xb9, + 0x96, 0xe8, 0x96, 0x51, 0x97, 0x5e, 0x97, 0x62, + 0x97, 0x69, 0x97, 0xcb, 0x97, 0xed, 0x97, 0xf3, + 0x97, 0x01, 0x98, 0xa8, 0x98, 0xdb, 0x98, 0xdf, + 0x98, 0x96, 0x99, 0x99, 0x99, 0xac, 0x99, 0xa8, + 0x9a, 0xd8, 0x9a, 0xdf, 0x9a, 0x25, 0x9b, 0x2f, + 0x9b, 0x32, 0x9b, 0x3c, 0x9b, 0x5a, 0x9b, 0xe5, + 0x9c, 0x75, 0x9e, 0x7f, 0x9e, 0xa5, 0x9e, 0x00, + 0x16, 0x1e, 0x28, 0x2c, 0x54, 0x58, 0x69, 0x6e, + 0x7b, 0x96, 0xa5, 0xad, 0xe8, 0xf7, 0xfb, 0x12, + 0x30, 0x00, 0x00, 0x41, 0x53, 0x44, 0x53, 0x45, + 0x53, 0x4b, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x4d, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x4f, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x51, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x53, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x55, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x57, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x59, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x5b, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x5d, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x5f, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x61, 0x30, 0x99, 0x30, 0x64, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x66, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x68, 0x30, 0x99, + 0x30, 0x6f, 0x30, 0x99, 0x30, 0x72, 0x30, 0x99, + 0x30, 0x75, 0x30, 0x99, 0x30, 0x78, 0x30, 0x99, + 0x30, 0x7b, 0x30, 0x99, 0x30, 0x46, 0x30, 0x99, + 0x30, 0x20, 0x00, 0x99, 0x30, 0x9d, 0x30, 0x99, + 0x30, 0x88, 0x30, 0x8a, 0x30, 0xab, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xad, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xb3, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x30, 0x99, + 0x30, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x30, 0x99, + 0x30, 0xc4, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, + 0x00, 0xc8, 0x30, 0x99, 0x30, 0xcf, 0x30, 0x99, + 0x30, 0xd2, 0x30, 0x99, 0x30, 0xd5, 0x30, 0x99, + 0x30, 0xd8, 0x30, 0x99, 0x30, 0xdb, 0x30, 0x99, + 0x30, 0xa6, 0x30, 0x99, 0x30, 0xef, 0x30, 0x99, + 0x30, 0xfd, 0x30, 0x99, 0x30, 0xb3, 0x30, 0xc8, + 0x30, 0x00, 0x11, 0x00, 0x01, 0xaa, 0x02, 0xac, + 0xad, 0x03, 0x04, 0x05, 0xb0, 0xb1, 0xb2, 0xb3, + 0xb4, 0xb5, 0x1a, 0x06, 0x07, 0x08, 0x21, 0x09, + 0x11, 0x61, 0x11, 0x14, 0x11, 0x4c, 0x00, 0x01, + 0xb3, 0xb4, 0xb8, 0xba, 0xbf, 0xc3, 0xc5, 0x08, + 0xc9, 0xcb, 0x09, 0x0a, 0x0c, 0x0e, 0x0f, 0x13, + 0x15, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1e, 0x22, + 0x2c, 0x33, 0x38, 0xdd, 0xde, 0x43, 0x44, 0x45, + 0x70, 0x71, 0x74, 0x7d, 0x7e, 0x80, 0x8a, 0x8d, + 0x00, 0x4e, 0x8c, 0x4e, 0x09, 0x4e, 0xdb, 0x56, + 0x0a, 0x4e, 0x2d, 0x4e, 0x0b, 0x4e, 0x32, 0x75, + 0x59, 0x4e, 0x19, 0x4e, 0x01, 0x4e, 0x29, 0x59, + 0x30, 0x57, 0xba, 0x4e, 0x28, 0x00, 0x29, 0x00, + 0x00, 0x11, 0x02, 0x11, 0x03, 0x11, 0x05, 0x11, + 0x06, 0x11, 0x07, 0x11, 0x09, 0x11, 0x0b, 0x11, + 0x0c, 0x11, 0x0e, 0x11, 0x0f, 0x11, 0x10, 0x11, + 0x11, 0x11, 0x12, 0x11, 0x28, 0x00, 0x00, 0x11, + 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x02, 0x11, + 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x05, 0x11, + 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x09, 0x11, + 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x0b, 0x11, + 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x0e, 0x11, + 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x0c, 0x11, + 0x6e, 0x11, 0x29, 0x00, 0x28, 0x00, 0x0b, 0x11, + 0x69, 0x11, 0x0c, 0x11, 0x65, 0x11, 0xab, 0x11, + 0x29, 0x00, 0x28, 0x00, 0x0b, 0x11, 0x69, 0x11, + 0x12, 0x11, 0x6e, 0x11, 0x29, 0x00, 0x28, 0x00, + 0x29, 0x00, 0x00, 0x4e, 0x8c, 0x4e, 0x09, 0x4e, + 0xdb, 0x56, 0x94, 0x4e, 0x6d, 0x51, 0x03, 0x4e, + 0x6b, 0x51, 0x5d, 0x4e, 0x41, 0x53, 0x08, 0x67, + 0x6b, 0x70, 0x34, 0x6c, 0x28, 0x67, 0xd1, 0x91, + 0x1f, 0x57, 0xe5, 0x65, 0x2a, 0x68, 0x09, 0x67, + 0x3e, 0x79, 0x0d, 0x54, 0x79, 0x72, 0xa1, 0x8c, + 0x5d, 0x79, 0xb4, 0x52, 0xe3, 0x4e, 0x7c, 0x54, + 0x66, 0x5b, 0xe3, 0x76, 0x01, 0x4f, 0xc7, 0x8c, + 0x54, 0x53, 0x6d, 0x79, 0x11, 0x4f, 0xea, 0x81, + 0xf3, 0x81, 0x4f, 0x55, 0x7c, 0x5e, 0x87, 0x65, + 0x8f, 0x7b, 0x50, 0x54, 0x45, 0x32, 0x00, 0x31, + 0x00, 0x33, 0x00, 0x30, 0x00, 0x00, 0x11, 0x00, + 0x02, 0x03, 0x05, 0x06, 0x07, 0x09, 0x0b, 0x0c, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x00, 0x11, 0x00, + 0x61, 0x02, 0x61, 0x03, 0x61, 0x05, 0x61, 0x06, + 0x61, 0x07, 0x61, 0x09, 0x61, 0x0b, 0x61, 0x0c, + 0x61, 0x0e, 0x11, 0x61, 0x11, 0x00, 0x11, 0x0e, + 0x61, 0xb7, 0x00, 0x69, 0x0b, 0x11, 0x01, 0x63, + 0x00, 0x69, 0x0b, 0x11, 0x6e, 0x11, 0x00, 0x4e, + 0x8c, 0x4e, 0x09, 0x4e, 0xdb, 0x56, 0x94, 0x4e, + 0x6d, 0x51, 0x03, 0x4e, 0x6b, 0x51, 0x5d, 0x4e, + 0x41, 0x53, 0x08, 0x67, 0x6b, 0x70, 0x34, 0x6c, + 0x28, 0x67, 0xd1, 0x91, 0x1f, 0x57, 0xe5, 0x65, + 0x2a, 0x68, 0x09, 0x67, 0x3e, 0x79, 0x0d, 0x54, + 0x79, 0x72, 0xa1, 0x8c, 0x5d, 0x79, 0xb4, 0x52, + 0xd8, 0x79, 0x37, 0x75, 0x73, 0x59, 0x69, 0x90, + 0x2a, 0x51, 0x70, 0x53, 0xe8, 0x6c, 0x05, 0x98, + 0x11, 0x4f, 0x99, 0x51, 0x63, 0x6b, 0x0a, 0x4e, + 0x2d, 0x4e, 0x0b, 0x4e, 0xe6, 0x5d, 0xf3, 0x53, + 0x3b, 0x53, 0x97, 0x5b, 0x66, 0x5b, 0xe3, 0x76, + 0x01, 0x4f, 0xc7, 0x8c, 0x54, 0x53, 0x1c, 0x59, + 0x33, 0x00, 0x36, 0x00, 0x34, 0x00, 0x30, 0x00, + 0x35, 0x30, 0x31, 0x00, 0x08, 0x67, 0x31, 0x00, + 0x30, 0x00, 0x08, 0x67, 0x48, 0x67, 0x65, 0x72, + 0x67, 0x65, 0x56, 0x4c, 0x54, 0x44, 0xa2, 0x30, + 0x00, 0x02, 0x04, 0x06, 0x08, 0x09, 0x0b, 0x0d, + 0x0f, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, + 0x1f, 0x22, 0x24, 0x26, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x30, 0x33, 0x36, 0x39, 0x3c, 0x3d, + 0x3e, 0x3f, 0x40, 0x42, 0x44, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0xe4, + 0x4e, 0x8c, 0x54, 0xa1, 0x30, 0x01, 0x30, 0x5b, + 0x27, 0x01, 0x4a, 0x34, 0x00, 0x01, 0x52, 0x39, + 0x01, 0xa2, 0x30, 0x00, 0x5a, 0x49, 0xa4, 0x30, + 0x00, 0x27, 0x4f, 0x0c, 0xa4, 0x30, 0x00, 0x4f, + 0x1d, 0x02, 0x05, 0x4f, 0xa8, 0x30, 0x00, 0x11, + 0x07, 0x54, 0x21, 0xa8, 0x30, 0x00, 0x54, 0x03, + 0x54, 0xa4, 0x30, 0x06, 0x4f, 0x15, 0x06, 0x58, + 0x3c, 0x07, 0x00, 0x46, 0xab, 0x30, 0x00, 0x3e, + 0x18, 0x1d, 0x00, 0x42, 0x3f, 0x51, 0xac, 0x30, + 0x00, 0x41, 0x47, 0x00, 0x47, 0x32, 0xae, 0x30, + 0xac, 0x30, 0xae, 0x30, 0x00, 0x1d, 0x4e, 0xad, + 0x30, 0x00, 0x38, 0x3d, 0x4f, 0x01, 0x3e, 0x13, + 0x4f, 0xad, 0x30, 0xed, 0x30, 0xad, 0x30, 0x00, + 0x40, 0x03, 0x3c, 0x33, 0xad, 0x30, 0x00, 0x40, + 0x34, 0x4f, 0x1b, 0x3e, 0xad, 0x30, 0x00, 0x40, + 0x42, 0x16, 0x1b, 0xb0, 0x30, 0x00, 0x39, 0x30, + 0xa4, 0x30, 0x0c, 0x45, 0x3c, 0x24, 0x4f, 0x0b, + 0x47, 0x18, 0x00, 0x49, 0xaf, 0x30, 0x00, 0x3e, + 0x4d, 0x1e, 0xb1, 0x30, 0x00, 0x4b, 0x08, 0x02, + 0x3a, 0x19, 0x02, 0x4b, 0x2c, 0xa4, 0x30, 0x11, + 0x00, 0x0b, 0x47, 0xb5, 0x30, 0x00, 0x3e, 0x0c, + 0x47, 0x2b, 0xb0, 0x30, 0x07, 0x3a, 0x43, 0x00, + 0xb9, 0x30, 0x02, 0x3a, 0x08, 0x02, 0x3a, 0x0f, + 0x07, 0x43, 0x00, 0xb7, 0x30, 0x10, 0x00, 0x12, + 0x34, 0x11, 0x3c, 0x13, 0x17, 0xa4, 0x30, 0x2a, + 0x1f, 0x24, 0x2b, 0x00, 0x20, 0xbb, 0x30, 0x16, + 0x41, 0x00, 0x38, 0x0d, 0xc4, 0x30, 0x0d, 0x38, + 0x00, 0xd0, 0x30, 0x00, 0x2c, 0x1c, 0x1b, 0xa2, + 0x30, 0x32, 0x00, 0x17, 0x26, 0x49, 0xaf, 0x30, + 0x25, 0x00, 0x3c, 0xb3, 0x30, 0x21, 0x00, 0x20, + 0x38, 0xa1, 0x30, 0x34, 0x00, 0x48, 0x22, 0x28, + 0xa3, 0x30, 0x32, 0x00, 0x59, 0x25, 0xa7, 0x30, + 0x2f, 0x1c, 0x10, 0x00, 0x44, 0xd5, 0x30, 0x00, + 0x14, 0x1e, 0xaf, 0x30, 0x29, 0x00, 0x10, 0x4d, + 0x3c, 0xda, 0x30, 0xbd, 0x30, 0xb8, 0x30, 0x22, + 0x13, 0x1a, 0x20, 0x33, 0x0c, 0x22, 0x3b, 0x01, + 0x22, 0x44, 0x00, 0x21, 0x44, 0x07, 0xa4, 0x30, + 0x39, 0x00, 0x4f, 0x24, 0xc8, 0x30, 0x14, 0x23, + 0x00, 0xdb, 0x30, 0xf3, 0x30, 0xc9, 0x30, 0x14, + 0x2a, 0x00, 0x12, 0x33, 0x22, 0x12, 0x33, 0x2a, + 0xa4, 0x30, 0x3a, 0x00, 0x0b, 0x49, 0xa4, 0x30, + 0x3a, 0x00, 0x47, 0x3a, 0x1f, 0x2b, 0x3a, 0x47, + 0x0b, 0xb7, 0x30, 0x27, 0x3c, 0x00, 0x30, 0x3c, + 0xaf, 0x30, 0x30, 0x00, 0x3e, 0x44, 0xdf, 0x30, + 0xea, 0x30, 0xd0, 0x30, 0x0f, 0x1a, 0x00, 0x2c, + 0x1b, 0xe1, 0x30, 0xac, 0x30, 0xac, 0x30, 0x35, + 0x00, 0x1c, 0x47, 0x35, 0x50, 0x1c, 0x3f, 0xa2, + 0x30, 0x42, 0x5a, 0x27, 0x42, 0x5a, 0x49, 0x44, + 0x00, 0x51, 0xc3, 0x30, 0x27, 0x00, 0x05, 0x28, + 0xea, 0x30, 0xe9, 0x30, 0xd4, 0x30, 0x17, 0x00, + 0x28, 0xd6, 0x30, 0x15, 0x26, 0x00, 0x15, 0xec, + 0x30, 0xe0, 0x30, 0xb2, 0x30, 0x3a, 0x41, 0x16, + 0x00, 0x41, 0xc3, 0x30, 0x2c, 0x00, 0x05, 0x30, + 0x00, 0xb9, 0x70, 0x31, 0x00, 0x30, 0x00, 0xb9, + 0x70, 0x32, 0x00, 0x30, 0x00, 0xb9, 0x70, 0x68, + 0x50, 0x61, 0x64, 0x61, 0x41, 0x55, 0x62, 0x61, + 0x72, 0x6f, 0x56, 0x70, 0x63, 0x64, 0x6d, 0x64, + 0x00, 0x6d, 0x00, 0xb2, 0x00, 0x49, 0x00, 0x55, + 0x00, 0x73, 0x5e, 0x10, 0x62, 0x2d, 0x66, 0x8c, + 0x54, 0x27, 0x59, 0x63, 0x6b, 0x0e, 0x66, 0xbb, + 0x6c, 0x2a, 0x68, 0x0f, 0x5f, 0x1a, 0x4f, 0x3e, + 0x79, 0x70, 0x00, 0x41, 0x6e, 0x00, 0x41, 0xbc, + 0x03, 0x41, 0x6d, 0x00, 0x41, 0x6b, 0x00, 0x41, + 0x4b, 0x00, 0x42, 0x4d, 0x00, 0x42, 0x47, 0x00, + 0x42, 0x63, 0x61, 0x6c, 0x6b, 0x63, 0x61, 0x6c, + 0x70, 0x00, 0x46, 0x6e, 0x00, 0x46, 0xbc, 0x03, + 0x46, 0xbc, 0x03, 0x67, 0x6d, 0x00, 0x67, 0x6b, + 0x00, 0x67, 0x48, 0x00, 0x7a, 0x6b, 0x48, 0x7a, + 0x4d, 0x48, 0x7a, 0x47, 0x48, 0x7a, 0x54, 0x48, + 0x7a, 0xbc, 0x03, 0x13, 0x21, 0x6d, 0x00, 0x13, + 0x21, 0x64, 0x00, 0x13, 0x21, 0x6b, 0x00, 0x13, + 0x21, 0x66, 0x00, 0x6d, 0x6e, 0x00, 0x6d, 0xbc, + 0x03, 0x6d, 0x6d, 0x00, 0x6d, 0x63, 0x00, 0x6d, + 0x6b, 0x00, 0x6d, 0x63, 0x00, 0x0a, 0x0a, 0x4f, + 0x00, 0x0a, 0x4f, 0x6d, 0x00, 0xb2, 0x00, 0x63, + 0x00, 0x08, 0x0a, 0x4f, 0x0a, 0x0a, 0x50, 0x00, + 0x0a, 0x50, 0x6d, 0x00, 0xb3, 0x00, 0x6b, 0x00, + 0x6d, 0x00, 0xb3, 0x00, 0x6d, 0x00, 0x15, 0x22, + 0x73, 0x00, 0x6d, 0x00, 0x15, 0x22, 0x73, 0x00, + 0xb2, 0x00, 0x50, 0x61, 0x6b, 0x50, 0x61, 0x4d, + 0x50, 0x61, 0x47, 0x50, 0x61, 0x72, 0x61, 0x64, + 0x72, 0x61, 0x64, 0xd1, 0x73, 0x72, 0x00, 0x61, + 0x00, 0x64, 0x00, 0x15, 0x22, 0x73, 0x00, 0xb2, + 0x00, 0x70, 0x00, 0x73, 0x6e, 0x00, 0x73, 0xbc, + 0x03, 0x73, 0x6d, 0x00, 0x73, 0x70, 0x00, 0x56, + 0x6e, 0x00, 0x56, 0xbc, 0x03, 0x56, 0x6d, 0x00, + 0x56, 0x6b, 0x00, 0x56, 0x4d, 0x00, 0x56, 0x70, + 0x00, 0x57, 0x6e, 0x00, 0x57, 0xbc, 0x03, 0x57, + 0x6d, 0x00, 0x57, 0x6b, 0x00, 0x57, 0x4d, 0x00, + 0x57, 0x6b, 0x00, 0xa9, 0x03, 0x4d, 0x00, 0xa9, + 0x03, 0x61, 0x2e, 0x6d, 0x2e, 0x42, 0x71, 0x63, + 0x63, 0x63, 0x64, 0x43, 0xd1, 0x6b, 0x67, 0x43, + 0x6f, 0x2e, 0x64, 0x42, 0x47, 0x79, 0x68, 0x61, + 0x48, 0x50, 0x69, 0x6e, 0x4b, 0x4b, 0x4b, 0x4d, + 0x6b, 0x74, 0x6c, 0x6d, 0x6c, 0x6e, 0x6c, 0x6f, + 0x67, 0x6c, 0x78, 0x6d, 0x62, 0x6d, 0x69, 0x6c, + 0x6d, 0x6f, 0x6c, 0x50, 0x48, 0x70, 0x2e, 0x6d, + 0x2e, 0x50, 0x50, 0x4d, 0x50, 0x52, 0x73, 0x72, + 0x53, 0x76, 0x57, 0x62, 0x56, 0xd1, 0x6d, 0x41, + 0xd1, 0x6d, 0x31, 0x00, 0xe5, 0x65, 0x31, 0x00, + 0x30, 0x00, 0xe5, 0x65, 0x32, 0x00, 0x30, 0x00, + 0xe5, 0x65, 0x33, 0x00, 0x30, 0x00, 0xe5, 0x65, + 0x67, 0x61, 0x6c, 0x4a, 0x04, 0x4c, 0x04, 0x53, + 0x43, 0x46, 0x51, 0x26, 0x01, 0x53, 0x01, 0x27, + 0xa7, 0x37, 0xab, 0x6b, 0x02, 0x52, 0xab, 0x48, + 0x8c, 0xf4, 0x66, 0xca, 0x8e, 0xc8, 0x8c, 0xd1, + 0x6e, 0x32, 0x4e, 0xe5, 0x53, 0x9c, 0x9f, 0x9c, + 0x9f, 0x51, 0x59, 0xd1, 0x91, 0x87, 0x55, 0x48, + 0x59, 0xf6, 0x61, 0x69, 0x76, 0x85, 0x7f, 0x3f, + 0x86, 0xba, 0x87, 0xf8, 0x88, 0x8f, 0x90, 0x02, + 0x6a, 0x1b, 0x6d, 0xd9, 0x70, 0xde, 0x73, 0x3d, + 0x84, 0x6a, 0x91, 0xf1, 0x99, 0x82, 0x4e, 0x75, + 0x53, 0x04, 0x6b, 0x1b, 0x72, 0x2d, 0x86, 0x1e, + 0x9e, 0x50, 0x5d, 0xeb, 0x6f, 0xcd, 0x85, 0x64, + 0x89, 0xc9, 0x62, 0xd8, 0x81, 0x1f, 0x88, 0xca, + 0x5e, 0x17, 0x67, 0x6a, 0x6d, 0xfc, 0x72, 0xce, + 0x90, 0x86, 0x4f, 0xb7, 0x51, 0xde, 0x52, 0xc4, + 0x64, 0xd3, 0x6a, 0x10, 0x72, 0xe7, 0x76, 0x01, + 0x80, 0x06, 0x86, 0x5c, 0x86, 0xef, 0x8d, 0x32, + 0x97, 0x6f, 0x9b, 0xfa, 0x9d, 0x8c, 0x78, 0x7f, + 0x79, 0xa0, 0x7d, 0xc9, 0x83, 0x04, 0x93, 0x7f, + 0x9e, 0xd6, 0x8a, 0xdf, 0x58, 0x04, 0x5f, 0x60, + 0x7c, 0x7e, 0x80, 0x62, 0x72, 0xca, 0x78, 0xc2, + 0x8c, 0xf7, 0x96, 0xd8, 0x58, 0x62, 0x5c, 0x13, + 0x6a, 0xda, 0x6d, 0x0f, 0x6f, 0x2f, 0x7d, 0x37, + 0x7e, 0x4b, 0x96, 0xd2, 0x52, 0x8b, 0x80, 0xdc, + 0x51, 0xcc, 0x51, 0x1c, 0x7a, 0xbe, 0x7d, 0xf1, + 0x83, 0x75, 0x96, 0x80, 0x8b, 0xcf, 0x62, 0x02, + 0x6a, 0xfe, 0x8a, 0x39, 0x4e, 0xe7, 0x5b, 0x12, + 0x60, 0x87, 0x73, 0x70, 0x75, 0x17, 0x53, 0xfb, + 0x78, 0xbf, 0x4f, 0xa9, 0x5f, 0x0d, 0x4e, 0xcc, + 0x6c, 0x78, 0x65, 0x22, 0x7d, 0xc3, 0x53, 0x5e, + 0x58, 0x01, 0x77, 0x49, 0x84, 0xaa, 0x8a, 0xba, + 0x6b, 0xb0, 0x8f, 0x88, 0x6c, 0xfe, 0x62, 0xe5, + 0x82, 0xa0, 0x63, 0x65, 0x75, 0xae, 0x4e, 0x69, + 0x51, 0xc9, 0x51, 0x81, 0x68, 0xe7, 0x7c, 0x6f, + 0x82, 0xd2, 0x8a, 0xcf, 0x91, 0xf5, 0x52, 0x42, + 0x54, 0x73, 0x59, 0xec, 0x5e, 0xc5, 0x65, 0xfe, + 0x6f, 0x2a, 0x79, 0xad, 0x95, 0x6a, 0x9a, 0x97, + 0x9e, 0xce, 0x9e, 0x9b, 0x52, 0xc6, 0x66, 0x77, + 0x6b, 0x62, 0x8f, 0x74, 0x5e, 0x90, 0x61, 0x00, + 0x62, 0x9a, 0x64, 0x23, 0x6f, 0x49, 0x71, 0x89, + 0x74, 0xca, 0x79, 0xf4, 0x7d, 0x6f, 0x80, 0x26, + 0x8f, 0xee, 0x84, 0x23, 0x90, 0x4a, 0x93, 0x17, + 0x52, 0xa3, 0x52, 0xbd, 0x54, 0xc8, 0x70, 0xc2, + 0x88, 0xaa, 0x8a, 0xc9, 0x5e, 0xf5, 0x5f, 0x7b, + 0x63, 0xae, 0x6b, 0x3e, 0x7c, 0x75, 0x73, 0xe4, + 0x4e, 0xf9, 0x56, 0xe7, 0x5b, 0xba, 0x5d, 0x1c, + 0x60, 0xb2, 0x73, 0x69, 0x74, 0x9a, 0x7f, 0x46, + 0x80, 0x34, 0x92, 0xf6, 0x96, 0x48, 0x97, 0x18, + 0x98, 0x8b, 0x4f, 0xae, 0x79, 0xb4, 0x91, 0xb8, + 0x96, 0xe1, 0x60, 0x86, 0x4e, 0xda, 0x50, 0xee, + 0x5b, 0x3f, 0x5c, 0x99, 0x65, 0x02, 0x6a, 0xce, + 0x71, 0x42, 0x76, 0xfc, 0x84, 0x7c, 0x90, 0x8d, + 0x9f, 0x88, 0x66, 0x2e, 0x96, 0x89, 0x52, 0x7b, + 0x67, 0xf3, 0x67, 0x41, 0x6d, 0x9c, 0x6e, 0x09, + 0x74, 0x59, 0x75, 0x6b, 0x78, 0x10, 0x7d, 0x5e, + 0x98, 0x6d, 0x51, 0x2e, 0x62, 0x78, 0x96, 0x2b, + 0x50, 0x19, 0x5d, 0xea, 0x6d, 0x2a, 0x8f, 0x8b, + 0x5f, 0x44, 0x61, 0x17, 0x68, 0x87, 0x73, 0x86, + 0x96, 0x29, 0x52, 0x0f, 0x54, 0x65, 0x5c, 0x13, + 0x66, 0x4e, 0x67, 0xa8, 0x68, 0xe5, 0x6c, 0x06, + 0x74, 0xe2, 0x75, 0x79, 0x7f, 0xcf, 0x88, 0xe1, + 0x88, 0xcc, 0x91, 0xe2, 0x96, 0x3f, 0x53, 0xba, + 0x6e, 0x1d, 0x54, 0xd0, 0x71, 0x98, 0x74, 0xfa, + 0x85, 0xa3, 0x96, 0x57, 0x9c, 0x9f, 0x9e, 0x97, + 0x67, 0xcb, 0x6d, 0xe8, 0x81, 0xcb, 0x7a, 0x20, + 0x7b, 0x92, 0x7c, 0xc0, 0x72, 0x99, 0x70, 0x58, + 0x8b, 0xc0, 0x4e, 0x36, 0x83, 0x3a, 0x52, 0x07, + 0x52, 0xa6, 0x5e, 0xd3, 0x62, 0xd6, 0x7c, 0x85, + 0x5b, 0x1e, 0x6d, 0xb4, 0x66, 0x3b, 0x8f, 0x4c, + 0x88, 0x4d, 0x96, 0x8b, 0x89, 0xd3, 0x5e, 0x40, + 0x51, 0xc0, 0x55, 0x00, 0x00, 0x00, 0x00, 0x5a, + 0x58, 0x00, 0x00, 0x74, 0x66, 0x00, 0x00, 0x00, + 0x00, 0xde, 0x51, 0x2a, 0x73, 0xca, 0x76, 0x3c, + 0x79, 0x5e, 0x79, 0x65, 0x79, 0x8f, 0x79, 0x56, + 0x97, 0xbe, 0x7c, 0xbd, 0x7f, 0x00, 0x00, 0x12, + 0x86, 0x00, 0x00, 0xf8, 0x8a, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x90, 0xfd, 0x90, 0xef, 0x98, 0xfc, + 0x98, 0x28, 0x99, 0xb4, 0x9d, 0xde, 0x90, 0xb7, + 0x96, 0xae, 0x4f, 0xe7, 0x50, 0x4d, 0x51, 0xc9, + 0x52, 0xe4, 0x52, 0x51, 0x53, 0x9d, 0x55, 0x06, + 0x56, 0x68, 0x56, 0x40, 0x58, 0xa8, 0x58, 0x64, + 0x5c, 0x6e, 0x5c, 0x94, 0x60, 0x68, 0x61, 0x8e, + 0x61, 0xf2, 0x61, 0x4f, 0x65, 0xe2, 0x65, 0x91, + 0x66, 0x85, 0x68, 0x77, 0x6d, 0x1a, 0x6e, 0x22, + 0x6f, 0x6e, 0x71, 0x2b, 0x72, 0x22, 0x74, 0x91, + 0x78, 0x3e, 0x79, 0x49, 0x79, 0x48, 0x79, 0x50, + 0x79, 0x56, 0x79, 0x5d, 0x79, 0x8d, 0x79, 0x8e, + 0x79, 0x40, 0x7a, 0x81, 0x7a, 0xc0, 0x7b, 0xf4, + 0x7d, 0x09, 0x7e, 0x41, 0x7e, 0x72, 0x7f, 0x05, + 0x80, 0xed, 0x81, 0x79, 0x82, 0x79, 0x82, 0x57, + 0x84, 0x10, 0x89, 0x96, 0x89, 0x01, 0x8b, 0x39, + 0x8b, 0xd3, 0x8c, 0x08, 0x8d, 0xb6, 0x8f, 0x38, + 0x90, 0xe3, 0x96, 0xff, 0x97, 0x3b, 0x98, 0x75, + 0x60, 0xee, 0x42, 0x18, 0x82, 0x02, 0x26, 0x4e, + 0xb5, 0x51, 0x68, 0x51, 0x80, 0x4f, 0x45, 0x51, + 0x80, 0x51, 0xc7, 0x52, 0xfa, 0x52, 0x9d, 0x55, + 0x55, 0x55, 0x99, 0x55, 0xe2, 0x55, 0x5a, 0x58, + 0xb3, 0x58, 0x44, 0x59, 0x54, 0x59, 0x62, 0x5a, + 0x28, 0x5b, 0xd2, 0x5e, 0xd9, 0x5e, 0x69, 0x5f, + 0xad, 0x5f, 0xd8, 0x60, 0x4e, 0x61, 0x08, 0x61, + 0x8e, 0x61, 0x60, 0x61, 0xf2, 0x61, 0x34, 0x62, + 0xc4, 0x63, 0x1c, 0x64, 0x52, 0x64, 0x56, 0x65, + 0x74, 0x66, 0x17, 0x67, 0x1b, 0x67, 0x56, 0x67, + 0x79, 0x6b, 0xba, 0x6b, 0x41, 0x6d, 0xdb, 0x6e, + 0xcb, 0x6e, 0x22, 0x6f, 0x1e, 0x70, 0x6e, 0x71, + 0xa7, 0x77, 0x35, 0x72, 0xaf, 0x72, 0x2a, 0x73, + 0x71, 0x74, 0x06, 0x75, 0x3b, 0x75, 0x1d, 0x76, + 0x1f, 0x76, 0xca, 0x76, 0xdb, 0x76, 0xf4, 0x76, + 0x4a, 0x77, 0x40, 0x77, 0xcc, 0x78, 0xb1, 0x7a, + 0xc0, 0x7b, 0x7b, 0x7c, 0x5b, 0x7d, 0xf4, 0x7d, + 0x3e, 0x7f, 0x05, 0x80, 0x52, 0x83, 0xef, 0x83, + 0x79, 0x87, 0x41, 0x89, 0x86, 0x89, 0x96, 0x89, + 0xbf, 0x8a, 0xf8, 0x8a, 0xcb, 0x8a, 0x01, 0x8b, + 0xfe, 0x8a, 0xed, 0x8a, 0x39, 0x8b, 0x8a, 0x8b, + 0x08, 0x8d, 0x38, 0x8f, 0x72, 0x90, 0x99, 0x91, + 0x76, 0x92, 0x7c, 0x96, 0xe3, 0x96, 0x56, 0x97, + 0xdb, 0x97, 0xff, 0x97, 0x0b, 0x98, 0x3b, 0x98, + 0x12, 0x9b, 0x9c, 0x9f, 0x4a, 0x28, 0x44, 0x28, + 0xd5, 0x33, 0x9d, 0x3b, 0x18, 0x40, 0x39, 0x40, + 0x49, 0x52, 0xd0, 0x5c, 0xd3, 0x7e, 0x43, 0x9f, + 0x8e, 0x9f, 0x2a, 0xa0, 0x02, 0x66, 0x66, 0x66, + 0x69, 0x66, 0x6c, 0x66, 0x66, 0x69, 0x66, 0x66, + 0x6c, 0x7f, 0x01, 0x74, 0x73, 0x00, 0x74, 0x65, + 0x05, 0x0f, 0x11, 0x0f, 0x00, 0x0f, 0x06, 0x19, + 0x11, 0x0f, 0x08, 0xd9, 0x05, 0xb4, 0x05, 0x00, + 0x00, 0x00, 0x00, 0xf2, 0x05, 0xb7, 0x05, 0xd0, + 0x05, 0x12, 0x00, 0x03, 0x04, 0x0b, 0x0c, 0x0d, + 0x18, 0x1a, 0xe9, 0x05, 0xc1, 0x05, 0xe9, 0x05, + 0xc2, 0x05, 0x49, 0xfb, 0xc1, 0x05, 0x49, 0xfb, + 0xc2, 0x05, 0xd0, 0x05, 0xb7, 0x05, 0xd0, 0x05, + 0xb8, 0x05, 0xd0, 0x05, 0xbc, 0x05, 0xd8, 0x05, + 0xbc, 0x05, 0xde, 0x05, 0xbc, 0x05, 0xe0, 0x05, + 0xbc, 0x05, 0xe3, 0x05, 0xbc, 0x05, 0xb9, 0x05, + 0x2d, 0x03, 0x2e, 0x03, 0x2f, 0x03, 0x30, 0x03, + 0x31, 0x03, 0x1c, 0x00, 0x18, 0x06, 0x22, 0x06, + 0x2b, 0x06, 0xd0, 0x05, 0xdc, 0x05, 0x71, 0x06, + 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0d, 0x0d, + 0x0d, 0x0d, 0x0f, 0x0f, 0x0f, 0x0f, 0x09, 0x09, + 0x09, 0x09, 0x0e, 0x0e, 0x0e, 0x0e, 0x08, 0x08, + 0x08, 0x08, 0x33, 0x33, 0x33, 0x33, 0x35, 0x35, + 0x35, 0x35, 0x13, 0x13, 0x13, 0x13, 0x12, 0x12, + 0x12, 0x12, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, + 0x16, 0x16, 0x1c, 0x1c, 0x1b, 0x1b, 0x1d, 0x1d, + 0x17, 0x17, 0x27, 0x27, 0x20, 0x20, 0x38, 0x38, + 0x38, 0x38, 0x3e, 0x3e, 0x3e, 0x3e, 0x42, 0x42, + 0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x49, 0x49, + 0x4a, 0x4a, 0x4a, 0x4a, 0x4f, 0x4f, 0x50, 0x50, + 0x50, 0x50, 0x4d, 0x4d, 0x4d, 0x4d, 0x61, 0x61, + 0x62, 0x62, 0x49, 0x06, 0x64, 0x64, 0x64, 0x64, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7f, 0x7f, 0x2e, 0x82, + 0x82, 0x7c, 0x7c, 0x80, 0x80, 0x87, 0x87, 0x87, + 0x87, 0x00, 0x00, 0x26, 0x06, 0x00, 0x01, 0x00, + 0x01, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0x22, 0x00, + 0x22, 0x00, 0xa1, 0x00, 0xa1, 0x00, 0xa0, 0x00, + 0xa0, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0xaa, 0x00, + 0xaa, 0x00, 0xaa, 0x00, 0x23, 0x00, 0x23, 0x00, + 0x23, 0xcc, 0x06, 0x00, 0x00, 0x00, 0x00, 0x26, + 0x06, 0x00, 0x06, 0x00, 0x07, 0x00, 0x1f, 0x00, + 0x23, 0x00, 0x24, 0x02, 0x06, 0x02, 0x07, 0x02, + 0x08, 0x02, 0x1f, 0x02, 0x23, 0x02, 0x24, 0x04, + 0x06, 0x04, 0x07, 0x04, 0x08, 0x04, 0x1f, 0x04, + 0x23, 0x04, 0x24, 0x05, 0x06, 0x05, 0x1f, 0x05, + 0x23, 0x05, 0x24, 0x06, 0x07, 0x06, 0x1f, 0x07, + 0x06, 0x07, 0x1f, 0x08, 0x06, 0x08, 0x07, 0x08, + 0x1f, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x08, 0x0d, + 0x1f, 0x0f, 0x07, 0x0f, 0x1f, 0x10, 0x06, 0x10, + 0x07, 0x10, 0x08, 0x10, 0x1f, 0x11, 0x07, 0x11, + 0x1f, 0x12, 0x1f, 0x13, 0x06, 0x13, 0x1f, 0x14, + 0x06, 0x14, 0x1f, 0x1b, 0x06, 0x1b, 0x07, 0x1b, + 0x08, 0x1b, 0x1f, 0x1b, 0x23, 0x1b, 0x24, 0x1c, + 0x07, 0x1c, 0x1f, 0x1c, 0x23, 0x1c, 0x24, 0x1d, + 0x01, 0x1d, 0x06, 0x1d, 0x07, 0x1d, 0x08, 0x1d, + 0x1e, 0x1d, 0x1f, 0x1d, 0x23, 0x1d, 0x24, 0x1e, + 0x06, 0x1e, 0x07, 0x1e, 0x08, 0x1e, 0x1f, 0x1e, + 0x23, 0x1e, 0x24, 0x1f, 0x06, 0x1f, 0x07, 0x1f, + 0x08, 0x1f, 0x1f, 0x1f, 0x23, 0x1f, 0x24, 0x20, + 0x06, 0x20, 0x07, 0x20, 0x08, 0x20, 0x1f, 0x20, + 0x23, 0x20, 0x24, 0x21, 0x06, 0x21, 0x1f, 0x21, + 0x23, 0x21, 0x24, 0x24, 0x06, 0x24, 0x07, 0x24, + 0x08, 0x24, 0x1f, 0x24, 0x23, 0x24, 0x24, 0x0a, + 0x4a, 0x0b, 0x4a, 0x23, 0x4a, 0x20, 0x00, 0x4c, + 0x06, 0x51, 0x06, 0x51, 0x06, 0xff, 0x00, 0x1f, + 0x26, 0x06, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x1f, + 0x00, 0x20, 0x00, 0x23, 0x00, 0x24, 0x02, 0x0b, + 0x02, 0x0c, 0x02, 0x1f, 0x02, 0x20, 0x02, 0x23, + 0x02, 0x24, 0x04, 0x0b, 0x04, 0x0c, 0x04, 0x1f, + 0x26, 0x06, 0x04, 0x20, 0x04, 0x23, 0x04, 0x24, + 0x05, 0x0b, 0x05, 0x0c, 0x05, 0x1f, 0x05, 0x20, + 0x05, 0x23, 0x05, 0x24, 0x1b, 0x23, 0x1b, 0x24, + 0x1c, 0x23, 0x1c, 0x24, 0x1d, 0x01, 0x1d, 0x1e, + 0x1d, 0x1f, 0x1d, 0x23, 0x1d, 0x24, 0x1e, 0x1f, + 0x1e, 0x23, 0x1e, 0x24, 0x1f, 0x01, 0x1f, 0x1f, + 0x20, 0x0b, 0x20, 0x0c, 0x20, 0x1f, 0x20, 0x20, + 0x20, 0x23, 0x20, 0x24, 0x23, 0x4a, 0x24, 0x0b, + 0x24, 0x0c, 0x24, 0x1f, 0x24, 0x20, 0x24, 0x23, + 0x24, 0x24, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, + 0x00, 0x1f, 0x00, 0x21, 0x02, 0x06, 0x02, 0x07, + 0x02, 0x08, 0x02, 0x1f, 0x02, 0x21, 0x04, 0x06, + 0x04, 0x07, 0x04, 0x08, 0x04, 0x1f, 0x04, 0x21, + 0x05, 0x1f, 0x06, 0x07, 0x06, 0x1f, 0x07, 0x06, + 0x07, 0x1f, 0x08, 0x06, 0x08, 0x1f, 0x0d, 0x06, + 0x0d, 0x07, 0x0d, 0x08, 0x0d, 0x1f, 0x0f, 0x07, + 0x0f, 0x08, 0x0f, 0x1f, 0x10, 0x06, 0x10, 0x07, + 0x10, 0x08, 0x10, 0x1f, 0x11, 0x07, 0x12, 0x1f, + 0x13, 0x06, 0x13, 0x1f, 0x14, 0x06, 0x14, 0x1f, + 0x1b, 0x06, 0x1b, 0x07, 0x1b, 0x08, 0x1b, 0x1f, + 0x1c, 0x07, 0x1c, 0x1f, 0x1d, 0x06, 0x1d, 0x07, + 0x1d, 0x08, 0x1d, 0x1e, 0x1d, 0x1f, 0x1e, 0x06, + 0x1e, 0x07, 0x1e, 0x08, 0x1e, 0x1f, 0x1e, 0x21, + 0x1f, 0x06, 0x1f, 0x07, 0x1f, 0x08, 0x1f, 0x1f, + 0x20, 0x06, 0x20, 0x07, 0x20, 0x08, 0x20, 0x1f, + 0x20, 0x21, 0x21, 0x06, 0x21, 0x1f, 0x21, 0x4a, + 0x24, 0x06, 0x24, 0x07, 0x24, 0x08, 0x24, 0x1f, + 0x24, 0x21, 0x00, 0x1f, 0x00, 0x21, 0x02, 0x1f, + 0x02, 0x21, 0x04, 0x1f, 0x04, 0x21, 0x05, 0x1f, + 0x05, 0x21, 0x0d, 0x1f, 0x0d, 0x21, 0x0e, 0x1f, + 0x0e, 0x21, 0x1d, 0x1e, 0x1d, 0x1f, 0x1e, 0x1f, + 0x20, 0x1f, 0x20, 0x21, 0x24, 0x1f, 0x24, 0x21, + 0x40, 0x06, 0x4e, 0x06, 0x51, 0x06, 0x27, 0x06, + 0x10, 0x22, 0x10, 0x23, 0x12, 0x22, 0x12, 0x23, + 0x13, 0x22, 0x13, 0x23, 0x0c, 0x22, 0x0c, 0x23, + 0x0d, 0x22, 0x0d, 0x23, 0x06, 0x22, 0x06, 0x23, + 0x05, 0x22, 0x05, 0x23, 0x07, 0x22, 0x07, 0x23, + 0x0e, 0x22, 0x0e, 0x23, 0x0f, 0x22, 0x0f, 0x23, + 0x0d, 0x05, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x1e, + 0x0d, 0x0a, 0x0c, 0x0a, 0x0e, 0x0a, 0x0f, 0x0a, + 0x10, 0x22, 0x10, 0x23, 0x12, 0x22, 0x12, 0x23, + 0x13, 0x22, 0x13, 0x23, 0x0c, 0x22, 0x0c, 0x23, + 0x0d, 0x22, 0x0d, 0x23, 0x06, 0x22, 0x06, 0x23, + 0x05, 0x22, 0x05, 0x23, 0x07, 0x22, 0x07, 0x23, + 0x0e, 0x22, 0x0e, 0x23, 0x0f, 0x22, 0x0f, 0x23, + 0x0d, 0x05, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x1e, + 0x0d, 0x0a, 0x0c, 0x0a, 0x0e, 0x0a, 0x0f, 0x0a, + 0x0d, 0x05, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x1e, + 0x0c, 0x20, 0x0d, 0x20, 0x10, 0x1e, 0x0c, 0x05, + 0x0c, 0x06, 0x0c, 0x07, 0x0d, 0x05, 0x0d, 0x06, + 0x0d, 0x07, 0x10, 0x1e, 0x11, 0x1e, 0x00, 0x24, + 0x00, 0x24, 0x2a, 0x06, 0x00, 0x02, 0x1b, 0x00, + 0x03, 0x02, 0x00, 0x03, 0x02, 0x00, 0x03, 0x1b, + 0x00, 0x04, 0x1b, 0x00, 0x1b, 0x02, 0x00, 0x1b, + 0x03, 0x00, 0x1b, 0x04, 0x02, 0x1b, 0x03, 0x02, + 0x1b, 0x03, 0x03, 0x1b, 0x20, 0x03, 0x1b, 0x1f, + 0x09, 0x03, 0x02, 0x09, 0x02, 0x03, 0x09, 0x02, + 0x1f, 0x09, 0x1b, 0x03, 0x09, 0x1b, 0x03, 0x09, + 0x1b, 0x02, 0x09, 0x1b, 0x1b, 0x09, 0x1b, 0x1b, + 0x0b, 0x03, 0x03, 0x0b, 0x03, 0x03, 0x0b, 0x1b, + 0x1b, 0x0a, 0x03, 0x1b, 0x0a, 0x03, 0x1b, 0x0a, + 0x02, 0x20, 0x0a, 0x1b, 0x04, 0x0a, 0x1b, 0x04, + 0x0a, 0x1b, 0x1b, 0x0a, 0x1b, 0x1b, 0x0c, 0x03, + 0x1f, 0x0c, 0x04, 0x1b, 0x0c, 0x04, 0x1b, 0x0d, + 0x1b, 0x03, 0x0d, 0x1b, 0x03, 0x0d, 0x1b, 0x1b, + 0x0d, 0x1b, 0x20, 0x0f, 0x02, 0x1b, 0x0f, 0x1b, + 0x1b, 0x0f, 0x1b, 0x1b, 0x0f, 0x1b, 0x1f, 0x10, + 0x1b, 0x1b, 0x10, 0x1b, 0x20, 0x10, 0x1b, 0x1f, + 0x17, 0x04, 0x1b, 0x17, 0x04, 0x1b, 0x18, 0x1b, + 0x03, 0x18, 0x1b, 0x1b, 0x1a, 0x03, 0x1b, 0x1a, + 0x03, 0x20, 0x1a, 0x03, 0x1f, 0x1a, 0x02, 0x02, + 0x1a, 0x02, 0x02, 0x1a, 0x04, 0x1b, 0x1a, 0x04, + 0x1b, 0x1a, 0x1b, 0x03, 0x1a, 0x1b, 0x03, 0x1b, + 0x03, 0x02, 0x1b, 0x03, 0x1b, 0x1b, 0x03, 0x20, + 0x1b, 0x02, 0x03, 0x1b, 0x02, 0x1b, 0x1b, 0x04, + 0x02, 0x1b, 0x04, 0x1b, 0x28, 0x06, 0x1d, 0x04, + 0x06, 0x1f, 0x1d, 0x04, 0x1f, 0x1d, 0x1d, 0x1e, + 0x05, 0x1d, 0x1e, 0x05, 0x21, 0x1e, 0x04, 0x1d, + 0x1e, 0x04, 0x1d, 0x1e, 0x04, 0x21, 0x1e, 0x1d, + 0x22, 0x1e, 0x1d, 0x21, 0x22, 0x1d, 0x1d, 0x22, + 0x1d, 0x1d, 0x00, 0x06, 0x22, 0x02, 0x04, 0x22, + 0x02, 0x04, 0x21, 0x02, 0x06, 0x22, 0x02, 0x06, + 0x21, 0x02, 0x1d, 0x22, 0x02, 0x1d, 0x21, 0x04, + 0x1d, 0x22, 0x04, 0x05, 0x21, 0x04, 0x1d, 0x21, + 0x0b, 0x06, 0x21, 0x0d, 0x05, 0x22, 0x0c, 0x05, + 0x22, 0x0e, 0x05, 0x22, 0x1c, 0x04, 0x22, 0x1c, + 0x1d, 0x22, 0x22, 0x05, 0x22, 0x22, 0x04, 0x22, + 0x22, 0x1d, 0x22, 0x1d, 0x1d, 0x22, 0x1a, 0x1d, + 0x22, 0x1e, 0x05, 0x22, 0x1a, 0x1d, 0x05, 0x1c, + 0x05, 0x1d, 0x11, 0x1d, 0x22, 0x1b, 0x1d, 0x22, + 0x1e, 0x04, 0x05, 0x1d, 0x06, 0x22, 0x1c, 0x04, + 0x1d, 0x1b, 0x1d, 0x1d, 0x1c, 0x04, 0x1d, 0x1e, + 0x04, 0x05, 0x04, 0x05, 0x22, 0x05, 0x04, 0x22, + 0x1d, 0x04, 0x22, 0x19, 0x1d, 0x22, 0x00, 0x05, + 0x22, 0x1b, 0x1d, 0x1d, 0x11, 0x04, 0x1d, 0x0d, + 0x1d, 0x1d, 0x0b, 0x06, 0x22, 0x1e, 0x04, 0x22, + 0x35, 0x06, 0x00, 0x0f, 0x9d, 0x0d, 0x0f, 0x9d, + 0x27, 0x06, 0x00, 0x1d, 0x1d, 0x20, 0x00, 0x1c, + 0x01, 0x0a, 0x1e, 0x06, 0x1e, 0x08, 0x0e, 0x1d, + 0x12, 0x1e, 0x0a, 0x0c, 0x21, 0x1d, 0x12, 0x1d, + 0x23, 0x20, 0x21, 0x0c, 0x1d, 0x1e, 0x35, 0x06, + 0x00, 0x0f, 0x14, 0x27, 0x06, 0x0e, 0x1d, 0x22, + 0xff, 0x00, 0x1d, 0x1d, 0x20, 0xff, 0x12, 0x1d, + 0x23, 0x20, 0xff, 0x21, 0x0c, 0x1d, 0x1e, 0x27, + 0x06, 0x05, 0x1d, 0xff, 0x05, 0x1d, 0x00, 0x1d, + 0x20, 0x27, 0x06, 0x0a, 0xa5, 0x00, 0x1d, 0x2c, + 0x00, 0x01, 0x30, 0x02, 0x30, 0x3a, 0x00, 0x3b, + 0x00, 0x21, 0x00, 0x3f, 0x00, 0x16, 0x30, 0x17, + 0x30, 0x26, 0x20, 0x13, 0x20, 0x12, 0x01, 0x00, + 0x5f, 0x5f, 0x28, 0x29, 0x7b, 0x7d, 0x08, 0x30, + 0x0c, 0x0d, 0x08, 0x09, 0x02, 0x03, 0x00, 0x01, + 0x04, 0x05, 0x06, 0x07, 0x5b, 0x00, 0x5d, 0x00, + 0x3e, 0x20, 0x3e, 0x20, 0x3e, 0x20, 0x3e, 0x20, + 0x5f, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x2c, 0x00, + 0x01, 0x30, 0x2e, 0x00, 0x00, 0x00, 0x3b, 0x00, + 0x3a, 0x00, 0x3f, 0x00, 0x21, 0x00, 0x14, 0x20, + 0x28, 0x00, 0x29, 0x00, 0x7b, 0x00, 0x7d, 0x00, + 0x14, 0x30, 0x15, 0x30, 0x23, 0x26, 0x2a, 0x2b, + 0x2d, 0x3c, 0x3e, 0x3d, 0x00, 0x5c, 0x24, 0x25, + 0x40, 0x40, 0x06, 0xff, 0x0b, 0x00, 0x0b, 0xff, + 0x0c, 0x20, 0x00, 0x4d, 0x06, 0x40, 0x06, 0xff, + 0x0e, 0x00, 0x0e, 0xff, 0x0f, 0x00, 0x0f, 0xff, + 0x10, 0x00, 0x10, 0xff, 0x11, 0x00, 0x11, 0xff, + 0x12, 0x00, 0x12, 0x21, 0x06, 0x00, 0x01, 0x01, + 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, + 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, + 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, + 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, + 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, + 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, + 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x20, 0x20, + 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x23, 0x23, 0x23, 0x24, 0x24, + 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26, + 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29, + 0x29, 0x29, 0x22, 0x06, 0x22, 0x00, 0x22, 0x00, + 0x22, 0x01, 0x22, 0x01, 0x22, 0x03, 0x22, 0x03, + 0x22, 0x05, 0x22, 0x05, 0x21, 0x00, 0x85, 0x29, + 0x01, 0x30, 0x01, 0x0b, 0x0c, 0x00, 0xfa, 0xf1, + 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xe2, 0xe4, 0xe6, + 0xc2, 0xfb, 0xa1, 0xa3, 0xa5, 0xa7, 0xa9, 0xaa, + 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, + 0xbc, 0xbe, 0xc0, 0xc3, 0xc5, 0xc7, 0xc9, 0xca, + 0xcb, 0xcc, 0xcd, 0xce, 0xd1, 0xd4, 0xd7, 0xda, + 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe3, 0xe5, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xee, 0xf2, 0x98, + 0x99, 0x31, 0x31, 0x4f, 0x31, 0x55, 0x31, 0x5b, + 0x31, 0x61, 0x31, 0xa2, 0x00, 0xa3, 0x00, 0xac, + 0x00, 0xaf, 0x00, 0xa6, 0x00, 0xa5, 0x00, 0xa9, + 0x20, 0x00, 0x00, 0x02, 0x25, 0x90, 0x21, 0x91, + 0x21, 0x92, 0x21, 0x93, 0x21, 0xa0, 0x25, 0xcb, + 0x25, 0xd2, 0x05, 0x07, 0x03, 0x01, 0xda, 0x05, + 0x07, 0x03, 0x01, 0xd0, 0x02, 0xd1, 0x02, 0xe6, + 0x00, 0x99, 0x02, 0x53, 0x02, 0x00, 0x00, 0xa3, + 0x02, 0x66, 0xab, 0xa5, 0x02, 0xa4, 0x02, 0x56, + 0x02, 0x57, 0x02, 0x91, 0x1d, 0x58, 0x02, 0x5e, + 0x02, 0xa9, 0x02, 0x64, 0x02, 0x62, 0x02, 0x60, + 0x02, 0x9b, 0x02, 0x27, 0x01, 0x9c, 0x02, 0x67, + 0x02, 0x84, 0x02, 0xaa, 0x02, 0xab, 0x02, 0x6c, + 0x02, 0x04, 0xdf, 0x8e, 0xa7, 0x6e, 0x02, 0x05, + 0xdf, 0x8e, 0x02, 0x06, 0xdf, 0xf8, 0x00, 0x76, + 0x02, 0x77, 0x02, 0x71, 0x00, 0x7a, 0x02, 0x08, + 0xdf, 0x7d, 0x02, 0x7e, 0x02, 0x80, 0x02, 0xa8, + 0x02, 0xa6, 0x02, 0x67, 0xab, 0xa7, 0x02, 0x88, + 0x02, 0x71, 0x2c, 0x00, 0x00, 0x8f, 0x02, 0xa1, + 0x02, 0xa2, 0x02, 0x98, 0x02, 0xc0, 0x01, 0xc1, + 0x01, 0xc2, 0x01, 0x0a, 0xdf, 0x1e, 0xdf, 0x41, + 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x14, 0x99, + 0x10, 0xba, 0x10, 0x00, 0x00, 0x00, 0x00, 0x9b, + 0x10, 0xba, 0x10, 0x05, 0x05, 0xa5, 0x10, 0xba, + 0x10, 0x05, 0x31, 0x11, 0x27, 0x11, 0x32, 0x11, + 0x27, 0x11, 0x55, 0x47, 0x13, 0x3e, 0x13, 0x47, + 0x13, 0x57, 0x13, 0x55, 0x82, 0x13, 0xc9, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x84, 0x13, 0xbb, 0x13, + 0x05, 0x05, 0x8b, 0x13, 0xc2, 0x13, 0x05, 0x90, + 0x13, 0xc9, 0x13, 0x05, 0xc2, 0x13, 0xc2, 0x13, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x13, 0xb8, 0x13, + 0xc2, 0x13, 0xc9, 0x13, 0x05, 0x55, 0xb9, 0x14, + 0xba, 0x14, 0xb9, 0x14, 0xb0, 0x14, 0x00, 0x00, + 0x00, 0x00, 0xb9, 0x14, 0xbd, 0x14, 0x55, 0x50, + 0xb8, 0x15, 0xaf, 0x15, 0xb9, 0x15, 0xaf, 0x15, + 0x55, 0x35, 0x19, 0x30, 0x19, 0x05, 0x1e, 0x61, + 0x1e, 0x61, 0x1e, 0x61, 0x29, 0x61, 0x1e, 0x61, + 0x1f, 0x61, 0x29, 0x61, 0x1f, 0x61, 0x1e, 0x61, + 0x20, 0x61, 0x21, 0x61, 0x1f, 0x61, 0x22, 0x61, + 0x1f, 0x61, 0x21, 0x61, 0x20, 0x61, 0x55, 0x55, + 0x55, 0x55, 0x67, 0x6d, 0x67, 0x6d, 0x63, 0x6d, + 0x67, 0x6d, 0x69, 0x6d, 0x67, 0x6d, 0x55, 0x05, + 0x41, 0x00, 0x30, 0x00, 0x57, 0xd1, 0x65, 0xd1, + 0x58, 0xd1, 0x65, 0xd1, 0x5f, 0xd1, 0x6e, 0xd1, + 0x5f, 0xd1, 0x6f, 0xd1, 0x5f, 0xd1, 0x70, 0xd1, + 0x5f, 0xd1, 0x71, 0xd1, 0x5f, 0xd1, 0x72, 0xd1, + 0x55, 0x55, 0x55, 0x05, 0xb9, 0xd1, 0x65, 0xd1, + 0xba, 0xd1, 0x65, 0xd1, 0xbb, 0xd1, 0x6e, 0xd1, + 0xbc, 0xd1, 0x6e, 0xd1, 0xbb, 0xd1, 0x6f, 0xd1, + 0xbc, 0xd1, 0x6f, 0xd1, 0x55, 0x55, 0x55, 0x41, + 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x69, + 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, 0x43, + 0x44, 0x00, 0x00, 0x47, 0x00, 0x00, 0x4a, 0x4b, + 0x00, 0x00, 0x4e, 0x4f, 0x50, 0x51, 0x00, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, + 0x62, 0x63, 0x64, 0x00, 0x66, 0x68, 0x00, 0x70, + 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x42, 0x00, + 0x44, 0x45, 0x46, 0x47, 0x4a, 0x00, 0x53, 0x00, + 0x61, 0x00, 0x41, 0x42, 0x00, 0x44, 0x45, 0x46, + 0x47, 0x00, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x00, + 0x4f, 0x53, 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, + 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, + 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, + 0x00, 0x41, 0x00, 0x61, 0x00, 0x31, 0x01, 0x37, + 0x02, 0x91, 0x03, 0xa3, 0x03, 0xb1, 0x03, 0xd1, + 0x03, 0x24, 0x00, 0x1f, 0x04, 0x20, 0x05, 0x91, + 0x03, 0xa3, 0x03, 0xb1, 0x03, 0xd1, 0x03, 0x24, + 0x00, 0x1f, 0x04, 0x20, 0x05, 0x91, 0x03, 0xa3, + 0x03, 0xb1, 0x03, 0xd1, 0x03, 0x24, 0x00, 0x1f, + 0x04, 0x20, 0x05, 0x91, 0x03, 0xa3, 0x03, 0xb1, + 0x03, 0xd1, 0x03, 0x24, 0x00, 0x1f, 0x04, 0x20, + 0x05, 0x91, 0x03, 0xa3, 0x03, 0xb1, 0x03, 0xd1, + 0x03, 0x24, 0x00, 0x1f, 0x04, 0x20, 0x05, 0x0b, + 0x0c, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, + 0x00, 0x30, 0x00, 0x30, 0x04, 0x3a, 0x04, 0x3e, + 0x04, 0x4b, 0x04, 0x4d, 0x04, 0x4e, 0x04, 0x89, + 0xa6, 0x30, 0x04, 0xa9, 0x26, 0x28, 0xb9, 0x7f, + 0x9f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x0a, 0x0b, 0x0e, 0x0f, 0x11, 0x13, + 0x14, 0x15, 0x16, 0x17, 0x18, 0x1a, 0x1b, 0x61, + 0x26, 0x25, 0x2f, 0x7b, 0x51, 0xa6, 0xb1, 0x04, + 0x27, 0x06, 0x00, 0x01, 0x05, 0x08, 0x2a, 0x06, + 0x1e, 0x08, 0x03, 0x0d, 0x20, 0x19, 0x1a, 0x1b, + 0x1c, 0x09, 0x0f, 0x17, 0x0b, 0x18, 0x07, 0x0a, + 0x00, 0x01, 0x04, 0x06, 0x0c, 0x0e, 0x10, 0x44, + 0x90, 0x77, 0x45, 0x28, 0x06, 0x2c, 0x06, 0x00, + 0x00, 0x47, 0x06, 0x33, 0x06, 0x17, 0x10, 0x11, + 0x12, 0x13, 0x00, 0x06, 0x0e, 0x02, 0x0f, 0x34, + 0x06, 0x2a, 0x06, 0x2b, 0x06, 0x2e, 0x06, 0x00, + 0x00, 0x36, 0x06, 0x00, 0x00, 0x3a, 0x06, 0x2d, + 0x06, 0x00, 0x00, 0x4a, 0x06, 0x00, 0x00, 0x44, + 0x06, 0x00, 0x00, 0x46, 0x06, 0x33, 0x06, 0x39, + 0x06, 0x00, 0x00, 0x35, 0x06, 0x42, 0x06, 0x00, + 0x00, 0x34, 0x06, 0x00, 0x00, 0x00, 0x00, 0x2e, + 0x06, 0x00, 0x00, 0x36, 0x06, 0x00, 0x00, 0x3a, + 0x06, 0x00, 0x00, 0xba, 0x06, 0x00, 0x00, 0x6f, + 0x06, 0x00, 0x00, 0x28, 0x06, 0x2c, 0x06, 0x00, + 0x00, 0x47, 0x06, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x06, 0x37, 0x06, 0x4a, 0x06, 0x43, 0x06, 0x00, + 0x00, 0x45, 0x06, 0x46, 0x06, 0x33, 0x06, 0x39, + 0x06, 0x41, 0x06, 0x35, 0x06, 0x42, 0x06, 0x00, + 0x00, 0x34, 0x06, 0x2a, 0x06, 0x2b, 0x06, 0x2e, + 0x06, 0x00, 0x00, 0x36, 0x06, 0x38, 0x06, 0x3a, + 0x06, 0x6e, 0x06, 0x00, 0x00, 0xa1, 0x06, 0x27, + 0x06, 0x00, 0x01, 0x05, 0x08, 0x20, 0x21, 0x0b, + 0x06, 0x10, 0x23, 0x2a, 0x06, 0x1a, 0x1b, 0x1c, + 0x09, 0x0f, 0x17, 0x0b, 0x18, 0x07, 0x0a, 0x00, + 0x01, 0x04, 0x06, 0x0c, 0x0e, 0x10, 0x28, 0x06, + 0x2c, 0x06, 0x2f, 0x06, 0x00, 0x00, 0x48, 0x06, + 0x32, 0x06, 0x2d, 0x06, 0x37, 0x06, 0x4a, 0x06, + 0x2a, 0x06, 0x1a, 0x1b, 0x1c, 0x09, 0x0f, 0x17, + 0x0b, 0x18, 0x07, 0x0a, 0x00, 0x01, 0x04, 0x06, + 0x0c, 0x0e, 0x10, 0x30, 0x2e, 0x30, 0x00, 0x2c, + 0x00, 0x28, 0x00, 0x41, 0x00, 0x29, 0x00, 0x14, + 0x30, 0x53, 0x00, 0x15, 0x30, 0x43, 0x52, 0x43, + 0x44, 0x57, 0x5a, 0x41, 0x00, 0x48, 0x56, 0x4d, + 0x56, 0x53, 0x44, 0x53, 0x53, 0x50, 0x50, 0x56, + 0x57, 0x43, 0x4d, 0x43, 0x4d, 0x44, 0x4d, 0x52, + 0x44, 0x4a, 0x4b, 0x30, 0x30, 0x00, 0x68, 0x68, + 0x4b, 0x62, 0x57, 0x5b, 0xcc, 0x53, 0xc7, 0x30, + 0x8c, 0x4e, 0x1a, 0x59, 0xe3, 0x89, 0x29, 0x59, + 0xa4, 0x4e, 0x20, 0x66, 0x21, 0x71, 0x99, 0x65, + 0x4d, 0x52, 0x8c, 0x5f, 0x8d, 0x51, 0xb0, 0x65, + 0x1d, 0x52, 0x42, 0x7d, 0x1f, 0x75, 0xa9, 0x8c, + 0xf0, 0x58, 0x39, 0x54, 0x14, 0x6f, 0x95, 0x62, + 0x55, 0x63, 0x00, 0x4e, 0x09, 0x4e, 0x4a, 0x90, + 0xe6, 0x5d, 0x2d, 0x4e, 0xf3, 0x53, 0x07, 0x63, + 0x70, 0x8d, 0x53, 0x62, 0x81, 0x79, 0x7a, 0x7a, + 0x08, 0x54, 0x80, 0x6e, 0x09, 0x67, 0x08, 0x67, + 0x33, 0x75, 0x72, 0x52, 0xb6, 0x55, 0x4d, 0x91, + 0x14, 0x30, 0x15, 0x30, 0x2c, 0x67, 0x09, 0x4e, + 0x8c, 0x4e, 0x89, 0x5b, 0xb9, 0x70, 0x53, 0x62, + 0xd7, 0x76, 0xdd, 0x52, 0x57, 0x65, 0x97, 0x5f, + 0xef, 0x53, 0x30, 0x00, 0x38, 0x4e, 0x05, 0x00, + 0x09, 0x22, 0x01, 0x60, 0x4f, 0xae, 0x4f, 0xbb, + 0x4f, 0x02, 0x50, 0x7a, 0x50, 0x99, 0x50, 0xe7, + 0x50, 0xcf, 0x50, 0x9e, 0x34, 0x3a, 0x06, 0x4d, + 0x51, 0x54, 0x51, 0x64, 0x51, 0x77, 0x51, 0x1c, + 0x05, 0xb9, 0x34, 0x67, 0x51, 0x8d, 0x51, 0x4b, + 0x05, 0x97, 0x51, 0xa4, 0x51, 0xcc, 0x4e, 0xac, + 0x51, 0xb5, 0x51, 0xdf, 0x91, 0xf5, 0x51, 0x03, + 0x52, 0xdf, 0x34, 0x3b, 0x52, 0x46, 0x52, 0x72, + 0x52, 0x77, 0x52, 0x15, 0x35, 0x02, 0x00, 0x20, + 0x80, 0x80, 0x00, 0x08, 0x00, 0x00, 0xc7, 0x52, + 0x00, 0x02, 0x1d, 0x33, 0x3e, 0x3f, 0x50, 0x82, + 0x8a, 0x93, 0xac, 0xb6, 0xb8, 0xb8, 0xb8, 0x2c, + 0x0a, 0x70, 0x70, 0xca, 0x53, 0xdf, 0x53, 0x63, + 0x0b, 0xeb, 0x53, 0xf1, 0x53, 0x06, 0x54, 0x9e, + 0x54, 0x38, 0x54, 0x48, 0x54, 0x68, 0x54, 0xa2, + 0x54, 0xf6, 0x54, 0x10, 0x55, 0x53, 0x55, 0x63, + 0x55, 0x84, 0x55, 0x84, 0x55, 0x99, 0x55, 0xab, + 0x55, 0xb3, 0x55, 0xc2, 0x55, 0x16, 0x57, 0x06, + 0x56, 0x17, 0x57, 0x51, 0x56, 0x74, 0x56, 0x07, + 0x52, 0xee, 0x58, 0xce, 0x57, 0xf4, 0x57, 0x0d, + 0x58, 0x8b, 0x57, 0x32, 0x58, 0x31, 0x58, 0xac, + 0x58, 0xe4, 0x14, 0xf2, 0x58, 0xf7, 0x58, 0x06, + 0x59, 0x1a, 0x59, 0x22, 0x59, 0x62, 0x59, 0xa8, + 0x16, 0xea, 0x16, 0xec, 0x59, 0x1b, 0x5a, 0x27, + 0x5a, 0xd8, 0x59, 0x66, 0x5a, 0xee, 0x36, 0xfc, + 0x36, 0x08, 0x5b, 0x3e, 0x5b, 0x3e, 0x5b, 0xc8, + 0x19, 0xc3, 0x5b, 0xd8, 0x5b, 0xe7, 0x5b, 0xf3, + 0x5b, 0x18, 0x1b, 0xff, 0x5b, 0x06, 0x5c, 0x53, + 0x5f, 0x22, 0x5c, 0x81, 0x37, 0x60, 0x5c, 0x6e, + 0x5c, 0xc0, 0x5c, 0x8d, 0x5c, 0xe4, 0x1d, 0x43, + 0x5d, 0xe6, 0x1d, 0x6e, 0x5d, 0x6b, 0x5d, 0x7c, + 0x5d, 0xe1, 0x5d, 0xe2, 0x5d, 0x2f, 0x38, 0xfd, + 0x5d, 0x28, 0x5e, 0x3d, 0x5e, 0x69, 0x5e, 0x62, + 0x38, 0x83, 0x21, 0x7c, 0x38, 0xb0, 0x5e, 0xb3, + 0x5e, 0xb6, 0x5e, 0xca, 0x5e, 0x92, 0xa3, 0xfe, + 0x5e, 0x31, 0x23, 0x31, 0x23, 0x01, 0x82, 0x22, + 0x5f, 0x22, 0x5f, 0xc7, 0x38, 0xb8, 0x32, 0xda, + 0x61, 0x62, 0x5f, 0x6b, 0x5f, 0xe3, 0x38, 0x9a, + 0x5f, 0xcd, 0x5f, 0xd7, 0x5f, 0xf9, 0x5f, 0x81, + 0x60, 0x3a, 0x39, 0x1c, 0x39, 0x94, 0x60, 0xd4, + 0x26, 0xc7, 0x60, 0x02, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, + 0x00, 0x02, 0x08, 0x00, 0x80, 0x08, 0x00, 0x00, + 0x08, 0x80, 0x28, 0x80, 0x02, 0x00, 0x00, 0x02, + 0x48, 0x61, 0x00, 0x04, 0x06, 0x04, 0x32, 0x46, + 0x6a, 0x5c, 0x67, 0x96, 0xaa, 0xae, 0xc8, 0xd3, + 0x5d, 0x62, 0x00, 0x54, 0x77, 0xf3, 0x0c, 0x2b, + 0x3d, 0x63, 0xfc, 0x62, 0x68, 0x63, 0x83, 0x63, + 0xe4, 0x63, 0xf1, 0x2b, 0x22, 0x64, 0xc5, 0x63, + 0xa9, 0x63, 0x2e, 0x3a, 0x69, 0x64, 0x7e, 0x64, + 0x9d, 0x64, 0x77, 0x64, 0x6c, 0x3a, 0x4f, 0x65, + 0x6c, 0x65, 0x0a, 0x30, 0xe3, 0x65, 0xf8, 0x66, + 0x49, 0x66, 0x19, 0x3b, 0x91, 0x66, 0x08, 0x3b, + 0xe4, 0x3a, 0x92, 0x51, 0x95, 0x51, 0x00, 0x67, + 0x9c, 0x66, 0xad, 0x80, 0xd9, 0x43, 0x17, 0x67, + 0x1b, 0x67, 0x21, 0x67, 0x5e, 0x67, 0x53, 0x67, + 0xc3, 0x33, 0x49, 0x3b, 0xfa, 0x67, 0x85, 0x67, + 0x52, 0x68, 0x85, 0x68, 0x6d, 0x34, 0x8e, 0x68, + 0x1f, 0x68, 0x14, 0x69, 0x9d, 0x3b, 0x42, 0x69, + 0xa3, 0x69, 0xea, 0x69, 0xa8, 0x6a, 0xa3, 0x36, + 0xdb, 0x6a, 0x18, 0x3c, 0x21, 0x6b, 0xa7, 0x38, + 0x54, 0x6b, 0x4e, 0x3c, 0x72, 0x6b, 0x9f, 0x6b, + 0xba, 0x6b, 0xbb, 0x6b, 0x8d, 0x3a, 0x0b, 0x1d, + 0xfa, 0x3a, 0x4e, 0x6c, 0xbc, 0x3c, 0xbf, 0x6c, + 0xcd, 0x6c, 0x67, 0x6c, 0x16, 0x6d, 0x3e, 0x6d, + 0x77, 0x6d, 0x41, 0x6d, 0x69, 0x6d, 0x78, 0x6d, + 0x85, 0x6d, 0x1e, 0x3d, 0x34, 0x6d, 0x2f, 0x6e, + 0x6e, 0x6e, 0x33, 0x3d, 0xcb, 0x6e, 0xc7, 0x6e, + 0xd1, 0x3e, 0xf9, 0x6d, 0x6e, 0x6f, 0x5e, 0x3f, + 0x8e, 0x3f, 0xc6, 0x6f, 0x39, 0x70, 0x1e, 0x70, + 0x1b, 0x70, 0x96, 0x3d, 0x4a, 0x70, 0x7d, 0x70, + 0x77, 0x70, 0xad, 0x70, 0x25, 0x05, 0x45, 0x71, + 0x63, 0x42, 0x9c, 0x71, 0xab, 0x43, 0x28, 0x72, + 0x35, 0x72, 0x50, 0x72, 0x08, 0x46, 0x80, 0x72, + 0x95, 0x72, 0x35, 0x47, 0x02, 0x20, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x00, + 0x00, 0x02, 0x02, 0x80, 0x8a, 0x00, 0x00, 0x20, + 0x00, 0x08, 0x0a, 0x00, 0x80, 0x88, 0x80, 0x20, + 0x14, 0x48, 0x7a, 0x73, 0x8b, 0x73, 0xac, 0x3e, + 0xa5, 0x73, 0xb8, 0x3e, 0xb8, 0x3e, 0x47, 0x74, + 0x5c, 0x74, 0x71, 0x74, 0x85, 0x74, 0xca, 0x74, + 0x1b, 0x3f, 0x24, 0x75, 0x36, 0x4c, 0x3e, 0x75, + 0x92, 0x4c, 0x70, 0x75, 0x9f, 0x21, 0x10, 0x76, + 0xa1, 0x4f, 0xb8, 0x4f, 0x44, 0x50, 0xfc, 0x3f, + 0x08, 0x40, 0xf4, 0x76, 0xf3, 0x50, 0xf2, 0x50, + 0x19, 0x51, 0x33, 0x51, 0x1e, 0x77, 0x1f, 0x77, + 0x1f, 0x77, 0x4a, 0x77, 0x39, 0x40, 0x8b, 0x77, + 0x46, 0x40, 0x96, 0x40, 0x1d, 0x54, 0x4e, 0x78, + 0x8c, 0x78, 0xcc, 0x78, 0xe3, 0x40, 0x26, 0x56, + 0x56, 0x79, 0x9a, 0x56, 0xc5, 0x56, 0x8f, 0x79, + 0xeb, 0x79, 0x2f, 0x41, 0x40, 0x7a, 0x4a, 0x7a, + 0x4f, 0x7a, 0x7c, 0x59, 0xa7, 0x5a, 0xa7, 0x5a, + 0xee, 0x7a, 0x02, 0x42, 0xab, 0x5b, 0xc6, 0x7b, + 0xc9, 0x7b, 0x27, 0x42, 0x80, 0x5c, 0xd2, 0x7c, + 0xa0, 0x42, 0xe8, 0x7c, 0xe3, 0x7c, 0x00, 0x7d, + 0x86, 0x5f, 0x63, 0x7d, 0x01, 0x43, 0xc7, 0x7d, + 0x02, 0x7e, 0x45, 0x7e, 0x34, 0x43, 0x28, 0x62, + 0x47, 0x62, 0x59, 0x43, 0xd9, 0x62, 0x7a, 0x7f, + 0x3e, 0x63, 0x95, 0x7f, 0xfa, 0x7f, 0x05, 0x80, + 0xda, 0x64, 0x23, 0x65, 0x60, 0x80, 0xa8, 0x65, + 0x70, 0x80, 0x5f, 0x33, 0xd5, 0x43, 0xb2, 0x80, + 0x03, 0x81, 0x0b, 0x44, 0x3e, 0x81, 0xb5, 0x5a, + 0xa7, 0x67, 0xb5, 0x67, 0x93, 0x33, 0x9c, 0x33, + 0x01, 0x82, 0x04, 0x82, 0x9e, 0x8f, 0x6b, 0x44, + 0x91, 0x82, 0x8b, 0x82, 0x9d, 0x82, 0xb3, 0x52, + 0xb1, 0x82, 0xb3, 0x82, 0xbd, 0x82, 0xe6, 0x82, + 0x3c, 0x6b, 0xe5, 0x82, 0x1d, 0x83, 0x63, 0x83, + 0xad, 0x83, 0x23, 0x83, 0xbd, 0x83, 0xe7, 0x83, + 0x57, 0x84, 0x53, 0x83, 0xca, 0x83, 0xcc, 0x83, + 0xdc, 0x83, 0x36, 0x6c, 0x6b, 0x6d, 0x02, 0x00, + 0x00, 0x20, 0x22, 0x2a, 0xa0, 0x0a, 0x00, 0x20, + 0x80, 0x28, 0x00, 0xa8, 0x20, 0x20, 0x00, 0x02, + 0x80, 0x22, 0x02, 0x8a, 0x08, 0x00, 0xaa, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x28, 0xd5, 0x6c, + 0x2b, 0x45, 0xf1, 0x84, 0xf3, 0x84, 0x16, 0x85, + 0xca, 0x73, 0x64, 0x85, 0x2c, 0x6f, 0x5d, 0x45, + 0x61, 0x45, 0xb1, 0x6f, 0xd2, 0x70, 0x6b, 0x45, + 0x50, 0x86, 0x5c, 0x86, 0x67, 0x86, 0x69, 0x86, + 0xa9, 0x86, 0x88, 0x86, 0x0e, 0x87, 0xe2, 0x86, + 0x79, 0x87, 0x28, 0x87, 0x6b, 0x87, 0x86, 0x87, + 0xd7, 0x45, 0xe1, 0x87, 0x01, 0x88, 0xf9, 0x45, + 0x60, 0x88, 0x63, 0x88, 0x67, 0x76, 0xd7, 0x88, + 0xde, 0x88, 0x35, 0x46, 0xfa, 0x88, 0xbb, 0x34, + 0xae, 0x78, 0x66, 0x79, 0xbe, 0x46, 0xc7, 0x46, + 0xa0, 0x8a, 0xed, 0x8a, 0x8a, 0x8b, 0x55, 0x8c, + 0xa8, 0x7c, 0xab, 0x8c, 0xc1, 0x8c, 0x1b, 0x8d, + 0x77, 0x8d, 0x2f, 0x7f, 0x04, 0x08, 0xcb, 0x8d, + 0xbc, 0x8d, 0xf0, 0x8d, 0xde, 0x08, 0xd4, 0x8e, + 0x38, 0x8f, 0xd2, 0x85, 0xed, 0x85, 0x94, 0x90, + 0xf1, 0x90, 0x11, 0x91, 0x2e, 0x87, 0x1b, 0x91, + 0x38, 0x92, 0xd7, 0x92, 0xd8, 0x92, 0x7c, 0x92, + 0xf9, 0x93, 0x15, 0x94, 0xfa, 0x8b, 0x8b, 0x95, + 0x95, 0x49, 0xb7, 0x95, 0x77, 0x8d, 0xe6, 0x49, + 0xc3, 0x96, 0xb2, 0x5d, 0x23, 0x97, 0x45, 0x91, + 0x1a, 0x92, 0x6e, 0x4a, 0x76, 0x4a, 0xe0, 0x97, + 0x0a, 0x94, 0xb2, 0x4a, 0x96, 0x94, 0x0b, 0x98, + 0x0b, 0x98, 0x29, 0x98, 0xb6, 0x95, 0xe2, 0x98, + 0x33, 0x4b, 0x29, 0x99, 0xa7, 0x99, 0xc2, 0x99, + 0xfe, 0x99, 0xce, 0x4b, 0x30, 0x9b, 0x12, 0x9b, + 0x40, 0x9c, 0xfd, 0x9c, 0xce, 0x4c, 0xed, 0x4c, + 0x67, 0x9d, 0xce, 0xa0, 0xf8, 0x4c, 0x05, 0xa1, + 0x0e, 0xa2, 0x91, 0xa2, 0xbb, 0x9e, 0x56, 0x4d, + 0xf9, 0x9e, 0xfe, 0x9e, 0x05, 0x9f, 0x0f, 0x9f, + 0x16, 0x9f, 0x3b, 0x9f, 0x00, 0xa6, 0x02, 0x88, + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x28, + 0x00, 0x08, 0xa0, 0x80, 0xa0, 0x80, 0x00, 0x80, + 0x80, 0x00, 0x0a, 0x88, 0x80, 0x00, 0x80, 0x00, + 0x20, 0x2a, 0x00, 0x80, +}; + +static const uint16_t unicode_comp_table[965] = { + 0x4a01, 0x49c0, 0x4a02, 0x0280, 0x0281, 0x0282, 0x0283, 0x02c0, + 0x02c2, 0x0a00, 0x0284, 0x2442, 0x0285, 0x07c0, 0x0980, 0x0982, + 0x2440, 0x2280, 0x02c4, 0x2282, 0x2284, 0x2286, 0x02c6, 0x02c8, + 0x02ca, 0x02cc, 0x0287, 0x228a, 0x02ce, 0x228c, 0x2290, 0x2292, + 0x228e, 0x0288, 0x0289, 0x028a, 0x2482, 0x0300, 0x0302, 0x0304, + 0x028b, 0x2480, 0x0308, 0x0984, 0x0986, 0x2458, 0x0a02, 0x0306, + 0x2298, 0x229a, 0x229e, 0x0900, 0x030a, 0x22a0, 0x030c, 0x030e, + 0x0840, 0x0310, 0x0312, 0x22a2, 0x22a6, 0x09c0, 0x22a4, 0x22a8, + 0x22aa, 0x028c, 0x028d, 0x028e, 0x0340, 0x0342, 0x0344, 0x0380, + 0x028f, 0x248e, 0x07c2, 0x0988, 0x098a, 0x2490, 0x0346, 0x22ac, + 0x0400, 0x22b0, 0x0842, 0x22b2, 0x0402, 0x22b4, 0x0440, 0x0444, + 0x22b6, 0x0442, 0x22c2, 0x22c0, 0x22c4, 0x22c6, 0x22c8, 0x0940, + 0x04c0, 0x0291, 0x22ca, 0x04c4, 0x22cc, 0x04c2, 0x22d0, 0x22ce, + 0x0292, 0x0293, 0x0294, 0x0295, 0x0540, 0x0542, 0x0a08, 0x0296, + 0x2494, 0x0544, 0x07c4, 0x098c, 0x098e, 0x06c0, 0x2492, 0x0844, + 0x2308, 0x230a, 0x0580, 0x230c, 0x0584, 0x0990, 0x0992, 0x230e, + 0x0582, 0x2312, 0x0586, 0x0588, 0x2314, 0x058c, 0x2316, 0x0998, + 0x058a, 0x231e, 0x0590, 0x2320, 0x099a, 0x058e, 0x2324, 0x2322, + 0x0299, 0x029a, 0x029b, 0x05c0, 0x05c2, 0x05c4, 0x029c, 0x24ac, + 0x05c6, 0x05c8, 0x07c6, 0x0994, 0x0996, 0x0700, 0x24aa, 0x2326, + 0x05ca, 0x232a, 0x2328, 0x2340, 0x2342, 0x2344, 0x2346, 0x05cc, + 0x234a, 0x2348, 0x234c, 0x234e, 0x2350, 0x24b8, 0x029d, 0x05ce, + 0x24be, 0x0a0c, 0x2352, 0x0600, 0x24bc, 0x24ba, 0x0640, 0x2354, + 0x0642, 0x0644, 0x2356, 0x2358, 0x02a0, 0x02a1, 0x02a2, 0x02a3, + 0x02c1, 0x02c3, 0x0a01, 0x02a4, 0x2443, 0x02a5, 0x07c1, 0x0981, + 0x0983, 0x2441, 0x2281, 0x02c5, 0x2283, 0x2285, 0x2287, 0x02c7, + 0x02c9, 0x02cb, 0x02cd, 0x02a7, 0x228b, 0x02cf, 0x228d, 0x2291, + 0x2293, 0x228f, 0x02a8, 0x02a9, 0x02aa, 0x2483, 0x0301, 0x0303, + 0x0305, 0x02ab, 0x2481, 0x0309, 0x0985, 0x0987, 0x2459, 0x0a03, + 0x0307, 0x2299, 0x229b, 0x229f, 0x0901, 0x030b, 0x22a1, 0x030d, + 0x030f, 0x0841, 0x0311, 0x0313, 0x22a3, 0x22a7, 0x09c1, 0x22a5, + 0x22a9, 0x22ab, 0x2380, 0x02ac, 0x02ad, 0x02ae, 0x0341, 0x0343, + 0x0345, 0x02af, 0x248f, 0x07c3, 0x0989, 0x098b, 0x2491, 0x0347, + 0x22ad, 0x0401, 0x0884, 0x22b1, 0x0843, 0x22b3, 0x0403, 0x22b5, + 0x0441, 0x0445, 0x22b7, 0x0443, 0x22c3, 0x22c1, 0x22c5, 0x22c7, + 0x22c9, 0x0941, 0x04c1, 0x02b1, 0x22cb, 0x04c5, 0x22cd, 0x04c3, + 0x22d1, 0x22cf, 0x02b2, 0x02b3, 0x02b4, 0x02b5, 0x0541, 0x0543, + 0x0a09, 0x02b6, 0x2495, 0x0545, 0x07c5, 0x098d, 0x098f, 0x06c1, + 0x2493, 0x0845, 0x2309, 0x230b, 0x0581, 0x230d, 0x0585, 0x0991, + 0x0993, 0x230f, 0x0583, 0x2313, 0x0587, 0x0589, 0x2315, 0x058d, + 0x2317, 0x0999, 0x058b, 0x231f, 0x2381, 0x0591, 0x2321, 0x099b, + 0x058f, 0x2325, 0x2323, 0x02b9, 0x02ba, 0x02bb, 0x05c1, 0x05c3, + 0x05c5, 0x02bc, 0x24ad, 0x05c7, 0x05c9, 0x07c7, 0x0995, 0x0997, + 0x0701, 0x24ab, 0x2327, 0x05cb, 0x232b, 0x2329, 0x2341, 0x2343, + 0x2345, 0x2347, 0x05cd, 0x234b, 0x2349, 0x2382, 0x234d, 0x234f, + 0x2351, 0x24b9, 0x02bd, 0x05cf, 0x24bf, 0x0a0d, 0x2353, 0x02bf, + 0x24bd, 0x2383, 0x24bb, 0x0641, 0x2355, 0x0643, 0x0645, 0x2357, + 0x2359, 0x3101, 0x0c80, 0x2e00, 0x2446, 0x2444, 0x244a, 0x2448, + 0x0800, 0x0942, 0x0944, 0x0804, 0x2288, 0x2486, 0x2484, 0x248a, + 0x2488, 0x22ae, 0x2498, 0x2496, 0x249c, 0x249a, 0x2300, 0x0a06, + 0x2302, 0x0a04, 0x0946, 0x07ce, 0x07ca, 0x07c8, 0x07cc, 0x2447, + 0x2445, 0x244b, 0x2449, 0x0801, 0x0943, 0x0945, 0x0805, 0x2289, + 0x2487, 0x2485, 0x248b, 0x2489, 0x22af, 0x2499, 0x2497, 0x249d, + 0x249b, 0x2301, 0x0a07, 0x2303, 0x0a05, 0x0947, 0x07cf, 0x07cb, + 0x07c9, 0x07cd, 0x2450, 0x244e, 0x2454, 0x2452, 0x2451, 0x244f, + 0x2455, 0x2453, 0x2294, 0x2296, 0x2295, 0x2297, 0x2304, 0x2306, + 0x2305, 0x2307, 0x2318, 0x2319, 0x231a, 0x231b, 0x232c, 0x232d, + 0x232e, 0x232f, 0x2400, 0x24a2, 0x24a0, 0x24a6, 0x24a4, 0x24a8, + 0x24a3, 0x24a1, 0x24a7, 0x24a5, 0x24a9, 0x24b0, 0x24ae, 0x24b4, + 0x24b2, 0x24b6, 0x24b1, 0x24af, 0x24b5, 0x24b3, 0x24b7, 0x0882, + 0x0880, 0x0881, 0x0802, 0x0803, 0x229c, 0x229d, 0x0a0a, 0x0a0b, + 0x0883, 0x0b40, 0x2c8a, 0x0c81, 0x2c89, 0x2c88, 0x2540, 0x2541, + 0x2d00, 0x2e07, 0x0d00, 0x2640, 0x2641, 0x2e80, 0x0d01, 0x26c8, + 0x26c9, 0x2f00, 0x2f84, 0x0d02, 0x2f83, 0x2f82, 0x0d40, 0x26d8, + 0x26d9, 0x3186, 0x0d04, 0x2740, 0x2741, 0x3100, 0x3086, 0x0d06, + 0x3085, 0x3084, 0x0d41, 0x2840, 0x3200, 0x0d07, 0x284f, 0x2850, + 0x3280, 0x2c84, 0x2e03, 0x2857, 0x0d42, 0x2c81, 0x2c80, 0x24c0, + 0x24c1, 0x2c86, 0x2c83, 0x28c0, 0x0d43, 0x25c0, 0x25c1, 0x2940, + 0x0d44, 0x26c0, 0x26c1, 0x2e05, 0x2e02, 0x29c0, 0x0d45, 0x2f05, + 0x2f04, 0x0d80, 0x26d0, 0x26d1, 0x2f80, 0x2a40, 0x0d82, 0x26e0, + 0x26e1, 0x3080, 0x3081, 0x2ac0, 0x0d83, 0x3004, 0x3003, 0x0d81, + 0x27c0, 0x27c1, 0x3082, 0x2b40, 0x0d84, 0x2847, 0x2848, 0x3184, + 0x3181, 0x2f06, 0x0d08, 0x2f81, 0x3005, 0x0d46, 0x3083, 0x3182, + 0x0e00, 0x0e01, 0x0f40, 0x1180, 0x1182, 0x0f03, 0x0f00, 0x11c0, + 0x0f01, 0x1140, 0x1202, 0x1204, 0x0f81, 0x1240, 0x0fc0, 0x1242, + 0x0f80, 0x1244, 0x1284, 0x0f82, 0x1286, 0x1288, 0x128a, 0x12c0, + 0x1282, 0x1181, 0x1183, 0x1043, 0x1040, 0x11c1, 0x1041, 0x1141, + 0x1203, 0x1205, 0x10c1, 0x1241, 0x1000, 0x1243, 0x10c0, 0x1245, + 0x1285, 0x10c2, 0x1287, 0x1289, 0x128b, 0x12c1, 0x1283, 0x1080, + 0x1100, 0x1101, 0x1200, 0x1201, 0x1280, 0x1281, 0x1340, 0x1341, + 0x1343, 0x1342, 0x1344, 0x13c2, 0x1400, 0x13c0, 0x1440, 0x1480, + 0x14c0, 0x1540, 0x1541, 0x1740, 0x1700, 0x1741, 0x17c0, 0x1800, + 0x1802, 0x1801, 0x1840, 0x1880, 0x1900, 0x18c0, 0x18c1, 0x1901, + 0x1940, 0x1942, 0x1941, 0x1980, 0x19c0, 0x19c2, 0x19c1, 0x1c80, + 0x1cc0, 0x1dc0, 0x1f80, 0x2000, 0x2002, 0x2004, 0x2006, 0x2008, + 0x2040, 0x2080, 0x2082, 0x20c0, 0x20c1, 0x2100, 0x22b8, 0x22b9, + 0x2310, 0x2311, 0x231c, 0x231d, 0x244c, 0x2456, 0x244d, 0x2457, + 0x248c, 0x248d, 0x249e, 0x249f, 0x2500, 0x2502, 0x2504, 0x2bc0, + 0x2501, 0x2503, 0x2505, 0x2bc1, 0x2bc2, 0x2bc3, 0x2bc4, 0x2bc5, + 0x2bc6, 0x2bc7, 0x2580, 0x2582, 0x2584, 0x2bc8, 0x2581, 0x2583, + 0x2585, 0x2bc9, 0x2bca, 0x2bcb, 0x2bcc, 0x2bcd, 0x2bce, 0x2bcf, + 0x2600, 0x2602, 0x2601, 0x2603, 0x2680, 0x2682, 0x2681, 0x2683, + 0x26c2, 0x26c4, 0x26c6, 0x2c00, 0x26c3, 0x26c5, 0x26c7, 0x2c01, + 0x2c02, 0x2c03, 0x2c04, 0x2c05, 0x2c06, 0x2c07, 0x26ca, 0x26cc, + 0x26ce, 0x2c08, 0x26cb, 0x26cd, 0x26cf, 0x2c09, 0x2c0a, 0x2c0b, + 0x2c0c, 0x2c0d, 0x2c0e, 0x2c0f, 0x26d2, 0x26d4, 0x26d6, 0x26d3, + 0x26d5, 0x26d7, 0x26da, 0x26dc, 0x26de, 0x26db, 0x26dd, 0x26df, + 0x2700, 0x2702, 0x2701, 0x2703, 0x2780, 0x2782, 0x2781, 0x2783, + 0x2800, 0x2802, 0x2804, 0x2801, 0x2803, 0x2805, 0x2842, 0x2844, + 0x2846, 0x2849, 0x284b, 0x284d, 0x2c40, 0x284a, 0x284c, 0x284e, + 0x2c41, 0x2c42, 0x2c43, 0x2c44, 0x2c45, 0x2c46, 0x2c47, 0x2851, + 0x2853, 0x2855, 0x2c48, 0x2852, 0x2854, 0x2856, 0x2c49, 0x2c4a, + 0x2c4b, 0x2c4c, 0x2c4d, 0x2c4e, 0x2c4f, 0x2c82, 0x2e01, 0x3180, + 0x2c87, 0x2f01, 0x2f02, 0x2f03, 0x2e06, 0x3185, 0x3000, 0x3001, + 0x3002, 0x4640, 0x4641, 0x4680, 0x46c0, 0x46c2, 0x46c1, 0x4700, + 0x4740, 0x4780, 0x47c0, 0x47c2, 0x4900, 0x4940, 0x4980, 0x4982, + 0x4a00, 0x49c2, 0x4a03, 0x4a04, 0x4a40, 0x4a41, 0x4a80, 0x4a81, + 0x4ac0, 0x4ac1, 0x4bc0, 0x4bc1, 0x4b00, 0x4b01, 0x4b40, 0x4b41, + 0x4bc2, 0x4bc3, 0x4b80, 0x4b81, 0x4b82, 0x4b83, 0x4c00, 0x4c01, + 0x4c02, 0x4c03, 0x5600, 0x5440, 0x5442, 0x5444, 0x5446, 0x5448, + 0x544a, 0x544c, 0x544e, 0x5450, 0x5452, 0x5454, 0x5456, 0x5480, + 0x5482, 0x5484, 0x54c0, 0x54c1, 0x5500, 0x5501, 0x5540, 0x5541, + 0x5580, 0x5581, 0x55c0, 0x55c1, 0x5680, 0x58c0, 0x5700, 0x5702, + 0x5704, 0x5706, 0x5708, 0x570a, 0x570c, 0x570e, 0x5710, 0x5712, + 0x5714, 0x5716, 0x5740, 0x5742, 0x5744, 0x5780, 0x5781, 0x57c0, + 0x57c1, 0x5800, 0x5801, 0x5840, 0x5841, 0x5880, 0x5881, 0x5900, + 0x5901, 0x5902, 0x5903, 0x5940, 0x8ec0, 0x8f00, 0x8fc0, 0x8fc2, + 0x9000, 0x9040, 0x9041, 0x9080, 0x9081, 0x90c0, 0x90c2, 0x9100, + 0x9140, 0x9182, 0x9180, 0x9183, 0x91c1, 0x91c0, 0x91c3, 0x9200, + 0x9201, 0x9240, 0x9280, 0x9282, 0x9284, 0x9281, 0x9285, 0x9287, + 0x9286, 0x9283, 0x92c1, 0x92c0, 0x92c2, +}; + +typedef enum { + UNICODE_GC_Cn, + UNICODE_GC_Lu, + UNICODE_GC_Ll, + UNICODE_GC_Lt, + UNICODE_GC_Lm, + UNICODE_GC_Lo, + UNICODE_GC_Mn, + UNICODE_GC_Mc, + UNICODE_GC_Me, + UNICODE_GC_Nd, + UNICODE_GC_Nl, + UNICODE_GC_No, + UNICODE_GC_Sm, + UNICODE_GC_Sc, + UNICODE_GC_Sk, + UNICODE_GC_So, + UNICODE_GC_Pc, + UNICODE_GC_Pd, + UNICODE_GC_Ps, + UNICODE_GC_Pe, + UNICODE_GC_Pi, + UNICODE_GC_Pf, + UNICODE_GC_Po, + UNICODE_GC_Zs, + UNICODE_GC_Zl, + UNICODE_GC_Zp, + UNICODE_GC_Cc, + UNICODE_GC_Cf, + UNICODE_GC_Cs, + UNICODE_GC_Co, + UNICODE_GC_LC, + UNICODE_GC_L, + UNICODE_GC_M, + UNICODE_GC_N, + UNICODE_GC_S, + UNICODE_GC_P, + UNICODE_GC_Z, + UNICODE_GC_C, + UNICODE_GC_COUNT, +} UnicodeGCEnum; + +static const char unicode_gc_name_table[] = + "Cn,Unassigned" "\0" + "Lu,Uppercase_Letter" "\0" + "Ll,Lowercase_Letter" "\0" + "Lt,Titlecase_Letter" "\0" + "Lm,Modifier_Letter" "\0" + "Lo,Other_Letter" "\0" + "Mn,Nonspacing_Mark" "\0" + "Mc,Spacing_Mark" "\0" + "Me,Enclosing_Mark" "\0" + "Nd,Decimal_Number,digit" "\0" + "Nl,Letter_Number" "\0" + "No,Other_Number" "\0" + "Sm,Math_Symbol" "\0" + "Sc,Currency_Symbol" "\0" + "Sk,Modifier_Symbol" "\0" + "So,Other_Symbol" "\0" + "Pc,Connector_Punctuation" "\0" + "Pd,Dash_Punctuation" "\0" + "Ps,Open_Punctuation" "\0" + "Pe,Close_Punctuation" "\0" + "Pi,Initial_Punctuation" "\0" + "Pf,Final_Punctuation" "\0" + "Po,Other_Punctuation" "\0" + "Zs,Space_Separator" "\0" + "Zl,Line_Separator" "\0" + "Zp,Paragraph_Separator" "\0" + "Cc,Control,cntrl" "\0" + "Cf,Format" "\0" + "Cs,Surrogate" "\0" + "Co,Private_Use" "\0" + "LC,Cased_Letter" "\0" + "L,Letter" "\0" + "M,Mark,Combining_Mark" "\0" + "N,Number" "\0" + "S,Symbol" "\0" + "P,Punctuation,punct" "\0" + "Z,Separator" "\0" + "C,Other" "\0" +; + +static const uint8_t unicode_gc_table[4122] = { + 0xfa, 0x18, 0x17, 0x56, 0x0d, 0x56, 0x12, 0x13, + 0x16, 0x0c, 0x16, 0x11, 0x36, 0xe9, 0x02, 0x36, + 0x4c, 0x36, 0xe1, 0x12, 0x12, 0x16, 0x13, 0x0e, + 0x10, 0x0e, 0xe2, 0x12, 0x12, 0x0c, 0x13, 0x0c, + 0xfa, 0x19, 0x17, 0x16, 0x6d, 0x0f, 0x16, 0x0e, + 0x0f, 0x05, 0x14, 0x0c, 0x1b, 0x0f, 0x0e, 0x0f, + 0x0c, 0x2b, 0x0e, 0x02, 0x36, 0x0e, 0x0b, 0x05, + 0x15, 0x4b, 0x16, 0xe1, 0x0f, 0x0c, 0xc1, 0xe2, + 0x10, 0x0c, 0xe2, 0x00, 0xff, 0x30, 0x02, 0xff, + 0x08, 0x02, 0xff, 0x27, 0xbf, 0x22, 0x21, 0x02, + 0x5f, 0x5f, 0x21, 0x22, 0x61, 0x02, 0x21, 0x02, + 0x41, 0x42, 0x21, 0x02, 0x21, 0x02, 0x9f, 0x7f, + 0x02, 0x5f, 0x5f, 0x21, 0x02, 0x5f, 0x3f, 0x02, + 0x05, 0x3f, 0x22, 0x65, 0x01, 0x03, 0x02, 0x01, + 0x03, 0x02, 0x01, 0x03, 0x02, 0xff, 0x08, 0x02, + 0xff, 0x0a, 0x02, 0x01, 0x03, 0x02, 0x5f, 0x21, + 0x02, 0xff, 0x32, 0xa2, 0x21, 0x02, 0x21, 0x22, + 0x5f, 0x41, 0x02, 0xff, 0x00, 0xe2, 0x3c, 0x25, + 0xe2, 0x12, 0xe4, 0x0a, 0x6e, 0xe4, 0x04, 0xee, + 0x06, 0x84, 0xce, 0x04, 0x0e, 0x04, 0xee, 0x09, + 0xe6, 0x68, 0x7f, 0x04, 0x0e, 0x3f, 0x20, 0x04, + 0x42, 0x16, 0x01, 0x60, 0x2e, 0x01, 0x16, 0x41, + 0x00, 0x01, 0x00, 0x21, 0x02, 0xe1, 0x09, 0x00, + 0xe1, 0x01, 0xe2, 0x1b, 0x3f, 0x02, 0x41, 0x42, + 0xff, 0x10, 0x62, 0x3f, 0x0c, 0x5f, 0x3f, 0x02, + 0xe1, 0x2b, 0xe2, 0x28, 0xff, 0x1a, 0x0f, 0x86, + 0x28, 0xff, 0x2f, 0xff, 0x06, 0x02, 0xff, 0x58, + 0x00, 0xe1, 0x1e, 0x20, 0x04, 0xb6, 0xe2, 0x21, + 0x16, 0x11, 0x20, 0x2f, 0x0d, 0x00, 0xe6, 0x25, + 0x11, 0x06, 0x16, 0x26, 0x16, 0x26, 0x16, 0x06, + 0xe0, 0x00, 0xe5, 0x13, 0x60, 0x65, 0x36, 0xe0, + 0x03, 0xbb, 0x4c, 0x36, 0x0d, 0x36, 0x2f, 0xe6, + 0x03, 0x16, 0x1b, 0x56, 0xe5, 0x18, 0x04, 0xe5, + 0x02, 0xe6, 0x0d, 0xe9, 0x02, 0x76, 0x25, 0x06, + 0xe5, 0x5b, 0x16, 0x05, 0xc6, 0x1b, 0x0f, 0xa6, + 0x24, 0x26, 0x0f, 0x66, 0x25, 0xe9, 0x02, 0x45, + 0x2f, 0x05, 0xf6, 0x06, 0x00, 0x1b, 0x05, 0x06, + 0xe5, 0x16, 0xe6, 0x13, 0x20, 0xe5, 0x51, 0xe6, + 0x03, 0x05, 0xe0, 0x06, 0xe9, 0x02, 0xe5, 0x19, + 0xe6, 0x01, 0x24, 0x0f, 0x56, 0x04, 0x20, 0x06, + 0x2d, 0xe5, 0x0e, 0x66, 0x04, 0xe6, 0x01, 0x04, + 0x46, 0x04, 0x86, 0x20, 0xf6, 0x07, 0x00, 0xe5, + 0x11, 0x46, 0x20, 0x16, 0x00, 0xe5, 0x03, 0x80, + 0xe5, 0x10, 0x0e, 0xc5, 0x3b, 0x80, 0xe6, 0x01, + 0xe5, 0x21, 0x04, 0xe6, 0x10, 0x1b, 0xe6, 0x18, + 0x07, 0xe5, 0x2e, 0x06, 0x07, 0x06, 0x05, 0x47, + 0xe6, 0x00, 0x67, 0x06, 0x27, 0x05, 0xc6, 0xe5, + 0x02, 0x26, 0x36, 0xe9, 0x02, 0x16, 0x04, 0xe5, + 0x07, 0x06, 0x27, 0x00, 0xe5, 0x00, 0x20, 0x25, + 0x20, 0xe5, 0x0e, 0x00, 0xc5, 0x00, 0x05, 0x40, + 0x65, 0x20, 0x06, 0x05, 0x47, 0x66, 0x20, 0x27, + 0x20, 0x27, 0x06, 0x05, 0xe0, 0x00, 0x07, 0x60, + 0x25, 0x00, 0x45, 0x26, 0x20, 0xe9, 0x02, 0x25, + 0x2d, 0xab, 0x0f, 0x0d, 0x05, 0x16, 0x06, 0x20, + 0x26, 0x07, 0x00, 0xa5, 0x60, 0x25, 0x20, 0xe5, + 0x0e, 0x00, 0xc5, 0x00, 0x25, 0x00, 0x25, 0x00, + 0x25, 0x20, 0x06, 0x00, 0x47, 0x26, 0x60, 0x26, + 0x20, 0x46, 0x40, 0x06, 0xc0, 0x65, 0x00, 0x05, + 0xc0, 0xe9, 0x02, 0x26, 0x45, 0x06, 0x16, 0xe0, + 0x02, 0x26, 0x07, 0x00, 0xe5, 0x01, 0x00, 0x45, + 0x00, 0xe5, 0x0e, 0x00, 0xc5, 0x00, 0x25, 0x00, + 0x85, 0x20, 0x06, 0x05, 0x47, 0x86, 0x00, 0x26, + 0x07, 0x00, 0x27, 0x06, 0x20, 0x05, 0xe0, 0x07, + 0x25, 0x26, 0x20, 0xe9, 0x02, 0x16, 0x0d, 0xc0, + 0x05, 0xa6, 0x00, 0x06, 0x27, 0x00, 0xe5, 0x00, + 0x20, 0x25, 0x20, 0xe5, 0x0e, 0x00, 0xc5, 0x00, + 0x25, 0x00, 0x85, 0x20, 0x06, 0x05, 0x07, 0x06, + 0x07, 0x66, 0x20, 0x27, 0x20, 0x27, 0x06, 0xc0, + 0x26, 0x07, 0x60, 0x25, 0x00, 0x45, 0x26, 0x20, + 0xe9, 0x02, 0x0f, 0x05, 0xab, 0xe0, 0x02, 0x06, + 0x05, 0x00, 0xa5, 0x40, 0x45, 0x00, 0x65, 0x40, + 0x25, 0x00, 0x05, 0x00, 0x25, 0x40, 0x25, 0x40, + 0x45, 0x40, 0xe5, 0x04, 0x60, 0x27, 0x06, 0x27, + 0x40, 0x47, 0x00, 0x47, 0x06, 0x20, 0x05, 0xa0, + 0x07, 0xe0, 0x06, 0xe9, 0x02, 0x4b, 0xaf, 0x0d, + 0x0f, 0x80, 0x06, 0x47, 0x06, 0xe5, 0x00, 0x00, + 0x45, 0x00, 0xe5, 0x0f, 0x00, 0xe5, 0x08, 0x20, + 0x06, 0x05, 0x46, 0x67, 0x00, 0x46, 0x00, 0x66, + 0xc0, 0x26, 0x00, 0x45, 0x00, 0x25, 0x20, 0x25, + 0x26, 0x20, 0xe9, 0x02, 0xc0, 0x16, 0xcb, 0x0f, + 0x05, 0x06, 0x27, 0x16, 0xe5, 0x00, 0x00, 0x45, + 0x00, 0xe5, 0x0f, 0x00, 0xe5, 0x02, 0x00, 0x85, + 0x20, 0x06, 0x05, 0x07, 0x06, 0x87, 0x00, 0x06, + 0x27, 0x00, 0x27, 0x26, 0xc0, 0x27, 0x80, 0x45, + 0x00, 0x25, 0x26, 0x20, 0xe9, 0x02, 0x00, 0x25, + 0x07, 0xe0, 0x04, 0x26, 0x27, 0xe5, 0x01, 0x00, + 0x45, 0x00, 0xe5, 0x21, 0x26, 0x05, 0x47, 0x66, + 0x00, 0x47, 0x00, 0x47, 0x06, 0x05, 0x0f, 0x60, + 0x45, 0x07, 0xcb, 0x45, 0x26, 0x20, 0xe9, 0x02, + 0xeb, 0x01, 0x0f, 0xa5, 0x00, 0x06, 0x27, 0x00, + 0xe5, 0x0a, 0x40, 0xe5, 0x10, 0x00, 0xe5, 0x01, + 0x00, 0x05, 0x20, 0xc5, 0x40, 0x06, 0x60, 0x47, + 0x46, 0x00, 0x06, 0x00, 0xe7, 0x00, 0xa0, 0xe9, + 0x02, 0x20, 0x27, 0x16, 0xe0, 0x04, 0xe5, 0x28, + 0x06, 0x25, 0xc6, 0x60, 0x0d, 0xa5, 0x04, 0xe6, + 0x00, 0x16, 0xe9, 0x02, 0x36, 0xe0, 0x1d, 0x25, + 0x00, 0x05, 0x00, 0x85, 0x00, 0xe5, 0x10, 0x00, + 0x05, 0x00, 0xe5, 0x02, 0x06, 0x25, 0xe6, 0x01, + 0x05, 0x20, 0x85, 0x00, 0x04, 0x00, 0xc6, 0x00, + 0xe9, 0x02, 0x20, 0x65, 0xe0, 0x18, 0x05, 0x4f, + 0xf6, 0x07, 0x0f, 0x16, 0x4f, 0x26, 0xaf, 0xe9, + 0x02, 0xeb, 0x02, 0x0f, 0x06, 0x0f, 0x06, 0x0f, + 0x06, 0x12, 0x13, 0x12, 0x13, 0x27, 0xe5, 0x00, + 0x00, 0xe5, 0x1c, 0x60, 0xe6, 0x06, 0x07, 0x86, + 0x16, 0x26, 0x85, 0xe6, 0x03, 0x00, 0xe6, 0x1c, + 0x00, 0xef, 0x00, 0x06, 0xaf, 0x00, 0x2f, 0x96, + 0x6f, 0x36, 0xe0, 0x1d, 0xe5, 0x23, 0x27, 0x66, + 0x07, 0xa6, 0x07, 0x26, 0x27, 0x26, 0x05, 0xe9, + 0x02, 0xb6, 0xa5, 0x27, 0x26, 0x65, 0x46, 0x05, + 0x47, 0x25, 0xc7, 0x45, 0x66, 0xe5, 0x05, 0x06, + 0x27, 0x26, 0xa7, 0x06, 0x05, 0x07, 0xe9, 0x02, + 0x47, 0x06, 0x2f, 0xe1, 0x1e, 0x00, 0x01, 0x80, + 0x01, 0x20, 0xe2, 0x23, 0x16, 0x04, 0x42, 0xe5, + 0x80, 0xc1, 0x00, 0x65, 0x20, 0xc5, 0x00, 0x05, + 0x00, 0x65, 0x20, 0xe5, 0x21, 0x00, 0x65, 0x20, + 0xe5, 0x19, 0x00, 0x65, 0x20, 0xc5, 0x00, 0x05, + 0x00, 0x65, 0x20, 0xe5, 0x07, 0x00, 0xe5, 0x31, + 0x00, 0x65, 0x20, 0xe5, 0x3b, 0x20, 0x46, 0xf6, + 0x01, 0xeb, 0x0c, 0x40, 0xe5, 0x08, 0xef, 0x02, + 0xa0, 0xe1, 0x4e, 0x20, 0xa2, 0x20, 0x11, 0xe5, + 0x81, 0xe4, 0x0f, 0x16, 0xe5, 0x09, 0x17, 0xe5, + 0x12, 0x12, 0x13, 0x40, 0xe5, 0x43, 0x56, 0x4a, + 0xe5, 0x00, 0xc0, 0xe5, 0x0a, 0x46, 0x07, 0xe0, + 0x01, 0xe5, 0x0b, 0x26, 0x07, 0x36, 0xe0, 0x01, + 0xe5, 0x0a, 0x26, 0xe0, 0x04, 0xe5, 0x05, 0x00, + 0x45, 0x00, 0x26, 0xe0, 0x04, 0xe5, 0x2c, 0x26, + 0x07, 0xc6, 0xe7, 0x00, 0x06, 0x27, 0xe6, 0x03, + 0x56, 0x04, 0x56, 0x0d, 0x05, 0x06, 0x20, 0xe9, + 0x02, 0xa0, 0xeb, 0x02, 0xa0, 0xb6, 0x11, 0x76, + 0x46, 0x1b, 0x06, 0xe9, 0x02, 0xa0, 0xe5, 0x1b, + 0x04, 0xe5, 0x2d, 0xc0, 0x85, 0x26, 0xe5, 0x1a, + 0x06, 0x05, 0x80, 0xe5, 0x3e, 0xe0, 0x02, 0xe5, + 0x17, 0x00, 0x46, 0x67, 0x26, 0x47, 0x60, 0x27, + 0x06, 0xa7, 0x46, 0x60, 0x0f, 0x40, 0x36, 0xe9, + 0x02, 0xe5, 0x16, 0x20, 0x85, 0xe0, 0x03, 0xe5, + 0x24, 0x60, 0xe5, 0x12, 0xa0, 0xe9, 0x02, 0x0b, + 0x40, 0xef, 0x1a, 0xe5, 0x0f, 0x26, 0x27, 0x06, + 0x20, 0x36, 0xe5, 0x2d, 0x07, 0x06, 0x07, 0xc6, + 0x00, 0x06, 0x07, 0x06, 0x27, 0xe6, 0x00, 0xa7, + 0xe6, 0x02, 0x20, 0x06, 0xe9, 0x02, 0xa0, 0xe9, + 0x02, 0xa0, 0xd6, 0x04, 0xb6, 0x20, 0xe6, 0x06, + 0x08, 0xe6, 0x17, 0x20, 0xe6, 0x04, 0xe0, 0x0c, + 0x66, 0x07, 0xe5, 0x27, 0x06, 0x07, 0x86, 0x07, + 0x06, 0x87, 0x06, 0x27, 0xe5, 0x00, 0x00, 0x36, + 0xe9, 0x02, 0xd6, 0xef, 0x02, 0xe6, 0x01, 0xef, + 0x01, 0x56, 0x26, 0x07, 0xe5, 0x16, 0x07, 0x66, + 0x27, 0x26, 0x07, 0x46, 0x25, 0xe9, 0x02, 0xe5, + 0x24, 0x06, 0x07, 0x26, 0x47, 0x06, 0x07, 0x46, + 0x27, 0xe0, 0x00, 0x76, 0xe5, 0x1c, 0xe7, 0x00, + 0xe6, 0x00, 0x27, 0x26, 0x40, 0x96, 0xe9, 0x02, + 0x40, 0x45, 0xe9, 0x02, 0xe5, 0x16, 0xa4, 0x36, + 0xe2, 0x01, 0x3f, 0x80, 0xe1, 0x23, 0x20, 0x41, + 0xf6, 0x00, 0xe0, 0x00, 0x46, 0x16, 0xe6, 0x05, + 0x07, 0xc6, 0x65, 0x06, 0xa5, 0x06, 0x25, 0x07, + 0x26, 0x05, 0x80, 0xe2, 0x24, 0xe4, 0x37, 0xe2, + 0x05, 0x04, 0xe2, 0x1a, 0xe4, 0x1d, 0xe6, 0x38, + 0xff, 0x80, 0x0e, 0xe2, 0x00, 0xff, 0x5a, 0xe2, + 0x00, 0xe1, 0x00, 0xa2, 0x20, 0xa1, 0x20, 0xe2, + 0x00, 0xe1, 0x00, 0xe2, 0x00, 0xe1, 0x00, 0xa2, + 0x20, 0xa1, 0x20, 0xe2, 0x00, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x3f, 0xc2, 0xe1, 0x00, + 0xe2, 0x06, 0x20, 0xe2, 0x00, 0xe3, 0x00, 0xe2, + 0x00, 0xe3, 0x00, 0xe2, 0x00, 0xe3, 0x00, 0x82, + 0x00, 0x22, 0x61, 0x03, 0x0e, 0x02, 0x4e, 0x42, + 0x00, 0x22, 0x61, 0x03, 0x4e, 0x62, 0x20, 0x22, + 0x61, 0x00, 0x4e, 0xe2, 0x00, 0x81, 0x4e, 0x20, + 0x42, 0x00, 0x22, 0x61, 0x03, 0x2e, 0x00, 0xf7, + 0x03, 0x9b, 0xb1, 0x36, 0x14, 0x15, 0x12, 0x34, + 0x15, 0x12, 0x14, 0xf6, 0x00, 0x18, 0x19, 0x9b, + 0x17, 0xf6, 0x01, 0x14, 0x15, 0x76, 0x30, 0x56, + 0x0c, 0x12, 0x13, 0xf6, 0x03, 0x0c, 0x16, 0x10, + 0xf6, 0x02, 0x17, 0x9b, 0x00, 0xfb, 0x02, 0x0b, + 0x04, 0x20, 0xab, 0x4c, 0x12, 0x13, 0x04, 0xeb, + 0x02, 0x4c, 0x12, 0x13, 0x00, 0xe4, 0x05, 0x40, + 0xed, 0x1a, 0xe0, 0x06, 0xe6, 0x05, 0x68, 0x06, + 0x48, 0xe6, 0x04, 0xe0, 0x07, 0x2f, 0x01, 0x6f, + 0x01, 0x2f, 0x02, 0x41, 0x22, 0x41, 0x02, 0x0f, + 0x01, 0x2f, 0x0c, 0x81, 0xaf, 0x01, 0x0f, 0x01, + 0x0f, 0x01, 0x0f, 0x61, 0x0f, 0x02, 0x61, 0x02, + 0x65, 0x02, 0x2f, 0x22, 0x21, 0x8c, 0x3f, 0x42, + 0x0f, 0x0c, 0x2f, 0x02, 0x0f, 0xeb, 0x08, 0xea, + 0x1b, 0x3f, 0x6a, 0x0b, 0x2f, 0x60, 0x8c, 0x8f, + 0x2c, 0x6f, 0x0c, 0x2f, 0x0c, 0x2f, 0x0c, 0xcf, + 0x0c, 0xef, 0x17, 0x2c, 0x2f, 0x0c, 0x0f, 0x0c, + 0xef, 0x17, 0xec, 0x80, 0x84, 0xef, 0x00, 0x12, + 0x13, 0x12, 0x13, 0xef, 0x0c, 0x2c, 0xcf, 0x12, + 0x13, 0xef, 0x49, 0x0c, 0xef, 0x16, 0xec, 0x11, + 0xef, 0x20, 0xac, 0xef, 0x40, 0xe0, 0x0e, 0xef, + 0x03, 0xe0, 0x0d, 0xeb, 0x34, 0xef, 0x46, 0xeb, + 0x0e, 0xef, 0x80, 0x2f, 0x0c, 0xef, 0x01, 0x0c, + 0xef, 0x2e, 0xec, 0x00, 0xef, 0x67, 0x0c, 0xef, + 0x80, 0x70, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, + 0xeb, 0x16, 0xef, 0x24, 0x8c, 0x12, 0x13, 0xec, + 0x17, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, + 0x13, 0x12, 0x13, 0xec, 0x08, 0xef, 0x80, 0x78, + 0xec, 0x7b, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, + 0xec, 0x37, 0x12, 0x13, 0x12, 0x13, 0xec, 0x18, + 0x12, 0x13, 0xec, 0x80, 0x7a, 0xef, 0x28, 0xec, + 0x0d, 0x2f, 0xac, 0xef, 0x1f, 0x20, 0xef, 0x80, + 0x02, 0xe1, 0x28, 0xe2, 0x28, 0x5f, 0x21, 0x22, + 0xdf, 0x41, 0x02, 0x3f, 0x02, 0x3f, 0x82, 0x24, + 0x41, 0x02, 0xff, 0x5a, 0x02, 0xaf, 0x7f, 0x46, + 0x3f, 0x80, 0x76, 0x0b, 0x36, 0xe2, 0x1e, 0x00, + 0x02, 0x80, 0x02, 0x20, 0xe5, 0x30, 0xc0, 0x04, + 0x16, 0xe0, 0x06, 0x06, 0xe5, 0x0f, 0xe0, 0x01, + 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, + 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, + 0xe6, 0x18, 0x36, 0x14, 0x15, 0x14, 0x15, 0x56, + 0x14, 0x15, 0x16, 0x14, 0x15, 0xf6, 0x01, 0x11, + 0x36, 0x11, 0x16, 0x14, 0x15, 0x36, 0x14, 0x15, + 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, + 0x96, 0x04, 0xf6, 0x02, 0x31, 0x76, 0x11, 0x16, + 0x12, 0xf6, 0x05, 0x2f, 0x56, 0x12, 0x13, 0x12, + 0x13, 0x12, 0x13, 0x12, 0x13, 0x11, 0xe0, 0x1a, + 0xef, 0x12, 0x00, 0xef, 0x51, 0xe0, 0x04, 0xef, + 0x80, 0x4e, 0xe0, 0x12, 0xef, 0x08, 0x17, 0x56, + 0x0f, 0x04, 0x05, 0x0a, 0x12, 0x13, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x2f, 0x12, + 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x11, + 0x12, 0x33, 0x0f, 0xea, 0x01, 0x66, 0x27, 0x11, + 0x84, 0x2f, 0x4a, 0x04, 0x05, 0x16, 0x2f, 0x00, + 0xe5, 0x4e, 0x20, 0x26, 0x2e, 0x24, 0x05, 0x11, + 0xe5, 0x52, 0x16, 0x44, 0x05, 0x80, 0xe5, 0x23, + 0x00, 0xe5, 0x56, 0x00, 0x2f, 0x6b, 0xef, 0x02, + 0xe5, 0x18, 0xef, 0x1e, 0xe0, 0x01, 0x0f, 0xe5, + 0x08, 0xef, 0x17, 0x00, 0xeb, 0x02, 0xef, 0x16, + 0xeb, 0x00, 0x0f, 0xeb, 0x07, 0xef, 0x18, 0xeb, + 0x02, 0xef, 0x1f, 0xeb, 0x07, 0xef, 0x80, 0xb8, + 0xe5, 0x99, 0x38, 0xef, 0x38, 0xe5, 0xc0, 0x11, + 0x8d, 0x04, 0xe5, 0x83, 0xef, 0x40, 0xef, 0x2f, + 0xe0, 0x01, 0xe5, 0x20, 0xa4, 0x36, 0xe5, 0x80, + 0x84, 0x04, 0x56, 0xe5, 0x08, 0xe9, 0x02, 0x25, + 0xe0, 0x0c, 0xff, 0x26, 0x05, 0x06, 0x48, 0x16, + 0xe6, 0x02, 0x16, 0x04, 0xff, 0x14, 0x24, 0x26, + 0xe5, 0x3e, 0xea, 0x02, 0x26, 0xb6, 0xe0, 0x00, + 0xee, 0x0f, 0xe4, 0x01, 0x2e, 0xff, 0x06, 0x22, + 0xff, 0x36, 0x04, 0xe2, 0x00, 0x9f, 0xff, 0x02, + 0x04, 0x2e, 0x7f, 0x05, 0x7f, 0x22, 0xff, 0x0d, + 0x61, 0x02, 0x81, 0x02, 0xff, 0x07, 0x41, 0x02, + 0x5f, 0xff, 0x09, 0xe0, 0x0c, 0x64, 0x3f, 0x05, + 0x24, 0x02, 0xc5, 0x06, 0x45, 0x06, 0x65, 0x06, + 0xe5, 0x0f, 0x27, 0x26, 0x07, 0x6f, 0x06, 0x40, + 0xab, 0x2f, 0x0d, 0x0f, 0xa0, 0xe5, 0x2c, 0x76, + 0xe0, 0x00, 0x27, 0xe5, 0x2a, 0xe7, 0x08, 0x26, + 0xe0, 0x00, 0x36, 0xe9, 0x02, 0xa0, 0xe6, 0x0a, + 0xa5, 0x56, 0x05, 0x16, 0x25, 0x06, 0xe9, 0x02, + 0xe5, 0x14, 0xe6, 0x00, 0x36, 0xe5, 0x0f, 0xe6, + 0x03, 0x27, 0xe0, 0x03, 0x16, 0xe5, 0x15, 0x40, + 0x46, 0x07, 0xe5, 0x27, 0x06, 0x27, 0x66, 0x27, + 0x26, 0x47, 0xf6, 0x05, 0x00, 0x04, 0xe9, 0x02, + 0x60, 0x36, 0x85, 0x06, 0x04, 0xe5, 0x01, 0xe9, + 0x02, 0x85, 0x00, 0xe5, 0x21, 0xa6, 0x27, 0x26, + 0x27, 0x26, 0xe0, 0x01, 0x45, 0x06, 0xe5, 0x00, + 0x06, 0x07, 0x20, 0xe9, 0x02, 0x20, 0x76, 0xe5, + 0x08, 0x04, 0xa5, 0x4f, 0x05, 0x07, 0x06, 0x07, + 0xe5, 0x2a, 0x06, 0x05, 0x46, 0x25, 0x26, 0x85, + 0x26, 0x05, 0x06, 0x05, 0xe0, 0x10, 0x25, 0x04, + 0x36, 0xe5, 0x03, 0x07, 0x26, 0x27, 0x36, 0x05, + 0x24, 0x07, 0x06, 0xe0, 0x02, 0xa5, 0x20, 0xa5, + 0x20, 0xa5, 0xe0, 0x01, 0xc5, 0x00, 0xc5, 0x00, + 0xe2, 0x23, 0x0e, 0x64, 0xe2, 0x01, 0x04, 0x2e, + 0x60, 0xe2, 0x48, 0xe5, 0x1b, 0x27, 0x06, 0x27, + 0x06, 0x27, 0x16, 0x07, 0x06, 0x20, 0xe9, 0x02, + 0xa0, 0xe5, 0xab, 0x1c, 0xe0, 0x04, 0xe5, 0x0f, + 0x60, 0xe5, 0x29, 0x60, 0xfc, 0x87, 0x78, 0xfd, + 0x98, 0x78, 0xe5, 0x80, 0xe6, 0x20, 0xe5, 0x62, + 0xe0, 0x1e, 0xc2, 0xe0, 0x04, 0x82, 0x80, 0x05, + 0x06, 0xe5, 0x02, 0x0c, 0xe5, 0x05, 0x00, 0x85, + 0x00, 0x05, 0x00, 0x25, 0x00, 0x25, 0x00, 0xe5, + 0x64, 0xee, 0x09, 0xef, 0x08, 0xe5, 0x80, 0xe3, + 0x13, 0x12, 0xef, 0x08, 0xe5, 0x38, 0x2f, 0xe5, + 0x2e, 0xef, 0x00, 0xe0, 0x18, 0xe5, 0x04, 0x0d, + 0x4f, 0xe6, 0x08, 0xd6, 0x12, 0x13, 0x16, 0xa0, + 0xe6, 0x08, 0x16, 0x31, 0x30, 0x12, 0x13, 0x12, + 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, + 0x13, 0x12, 0x13, 0x12, 0x13, 0x36, 0x12, 0x13, + 0x76, 0x50, 0x56, 0x00, 0x76, 0x11, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x13, 0x56, 0x0c, 0x11, 0x4c, + 0x00, 0x16, 0x0d, 0x36, 0x60, 0x85, 0x00, 0xe5, + 0x7f, 0x20, 0x1b, 0x00, 0x56, 0x0d, 0x56, 0x12, + 0x13, 0x16, 0x0c, 0x16, 0x11, 0x36, 0xe9, 0x02, + 0x36, 0x4c, 0x36, 0xe1, 0x12, 0x12, 0x16, 0x13, + 0x0e, 0x10, 0x0e, 0xe2, 0x12, 0x12, 0x0c, 0x13, + 0x0c, 0x12, 0x13, 0x16, 0x12, 0x13, 0x36, 0xe5, + 0x02, 0x04, 0xe5, 0x25, 0x24, 0xe5, 0x17, 0x40, + 0xa5, 0x20, 0xa5, 0x20, 0xa5, 0x20, 0x45, 0x40, + 0x2d, 0x0c, 0x0e, 0x0f, 0x2d, 0x00, 0x0f, 0x6c, + 0x2f, 0xe0, 0x02, 0x5b, 0x2f, 0x20, 0xe5, 0x04, + 0x00, 0xe5, 0x12, 0x00, 0xe5, 0x0b, 0x00, 0x25, + 0x00, 0xe5, 0x07, 0x20, 0xe5, 0x06, 0xe0, 0x1a, + 0xe5, 0x73, 0x80, 0x56, 0x60, 0xeb, 0x25, 0x40, + 0xef, 0x01, 0xea, 0x2d, 0x6b, 0xef, 0x09, 0x2b, + 0x4f, 0x00, 0xef, 0x05, 0x40, 0x0f, 0xe0, 0x27, + 0xef, 0x25, 0x06, 0xe0, 0x7a, 0xe5, 0x15, 0x40, + 0xe5, 0x29, 0xe0, 0x07, 0x06, 0xeb, 0x13, 0x60, + 0xe5, 0x18, 0x6b, 0xe0, 0x01, 0xe5, 0x0c, 0x0a, + 0xe5, 0x00, 0x0a, 0x80, 0xe5, 0x1e, 0x86, 0x80, + 0xe5, 0x16, 0x00, 0x16, 0xe5, 0x1c, 0x60, 0xe5, + 0x00, 0x16, 0x8a, 0xe0, 0x22, 0xe1, 0x20, 0xe2, + 0x20, 0xe5, 0x46, 0x20, 0xe9, 0x02, 0xa0, 0xe1, + 0x1c, 0x60, 0xe2, 0x1c, 0x60, 0xe5, 0x20, 0xe0, + 0x00, 0xe5, 0x2c, 0xe0, 0x03, 0x16, 0xe1, 0x03, + 0x00, 0xe1, 0x07, 0x00, 0xc1, 0x00, 0x21, 0x00, + 0xe2, 0x03, 0x00, 0xe2, 0x07, 0x00, 0xc2, 0x00, + 0x22, 0x40, 0xe5, 0x2c, 0xe0, 0x04, 0xe5, 0x80, + 0xaf, 0xe0, 0x01, 0xe5, 0x0e, 0xe0, 0x02, 0xe5, + 0x00, 0xe0, 0x10, 0xa4, 0x00, 0xe4, 0x22, 0x00, + 0xe4, 0x01, 0xe0, 0x3d, 0xa5, 0x20, 0x05, 0x00, + 0xe5, 0x24, 0x00, 0x25, 0x40, 0x05, 0x20, 0xe5, + 0x0f, 0x00, 0x16, 0xeb, 0x00, 0xe5, 0x0f, 0x2f, + 0xcb, 0xe5, 0x17, 0xe0, 0x00, 0xeb, 0x01, 0xe0, + 0x28, 0xe5, 0x0b, 0x00, 0x25, 0x80, 0x8b, 0xe5, + 0x0e, 0xab, 0x40, 0x16, 0xe5, 0x12, 0x80, 0x16, + 0xe5, 0x12, 0xe0, 0x1e, 0xe5, 0x30, 0x60, 0x2b, + 0x25, 0xeb, 0x08, 0x20, 0xeb, 0x26, 0x05, 0x46, + 0x00, 0x26, 0x80, 0x66, 0x65, 0x00, 0x45, 0x00, + 0xe5, 0x15, 0x20, 0x46, 0x60, 0x06, 0xeb, 0x01, + 0xc0, 0xf6, 0x01, 0xc0, 0xe5, 0x15, 0x2b, 0x16, + 0xe5, 0x15, 0x4b, 0xe0, 0x18, 0xe5, 0x00, 0x0f, + 0xe5, 0x14, 0x26, 0x60, 0x8b, 0xd6, 0xe0, 0x01, + 0xe5, 0x2e, 0x40, 0xd6, 0xe5, 0x0e, 0x20, 0xeb, + 0x00, 0xe5, 0x0b, 0x80, 0xeb, 0x00, 0xe5, 0x0a, + 0xc0, 0x76, 0xe0, 0x04, 0xcb, 0xe0, 0x48, 0xe5, + 0x41, 0xe0, 0x2f, 0xe1, 0x2b, 0xe0, 0x05, 0xe2, + 0x2b, 0xc0, 0xab, 0xe5, 0x1c, 0x66, 0xe0, 0x00, + 0xe9, 0x02, 0xa0, 0xe9, 0x02, 0x65, 0x04, 0x05, + 0xe1, 0x0e, 0x40, 0x86, 0x11, 0x04, 0xe2, 0x0e, + 0xe0, 0x00, 0x2c, 0xe0, 0x80, 0x48, 0xeb, 0x17, + 0x00, 0xe5, 0x22, 0x00, 0x26, 0x11, 0x20, 0x25, + 0xe0, 0x08, 0x45, 0x04, 0x25, 0xe0, 0x00, 0x16, + 0xef, 0x00, 0xe0, 0x19, 0xa6, 0xe5, 0x15, 0xeb, + 0x02, 0x05, 0xe0, 0x00, 0xe5, 0x0e, 0xe6, 0x03, + 0x6b, 0x96, 0xe0, 0x0e, 0xe5, 0x0a, 0x66, 0x76, + 0xe0, 0x1e, 0xe5, 0x0d, 0xcb, 0xe0, 0x0c, 0xe5, + 0x0f, 0xe0, 0x01, 0x07, 0x06, 0x07, 0xe5, 0x2d, + 0xe6, 0x07, 0xd6, 0x60, 0xeb, 0x0c, 0xe9, 0x02, + 0x06, 0x25, 0x26, 0x05, 0xe0, 0x01, 0x46, 0x07, + 0xe5, 0x25, 0x47, 0x66, 0x27, 0x26, 0x36, 0x1b, + 0x76, 0x06, 0xe0, 0x02, 0x1b, 0x20, 0xe5, 0x11, + 0xc0, 0xe9, 0x02, 0xa0, 0x46, 0xe5, 0x1c, 0x86, + 0x07, 0xe6, 0x00, 0x00, 0xe9, 0x02, 0x76, 0x05, + 0x27, 0x05, 0xe0, 0x00, 0xe5, 0x1b, 0x06, 0x36, + 0x05, 0xe0, 0x01, 0x26, 0x07, 0xe5, 0x28, 0x47, + 0xe6, 0x01, 0x27, 0x65, 0x76, 0x66, 0x16, 0x07, + 0x06, 0xe9, 0x02, 0x05, 0x16, 0x05, 0x56, 0x00, + 0xeb, 0x0c, 0xe0, 0x03, 0xe5, 0x0a, 0x00, 0xe5, + 0x11, 0x47, 0x46, 0x27, 0x06, 0x07, 0x26, 0xb6, + 0x06, 0x25, 0x06, 0xe0, 0x36, 0xc5, 0x00, 0x05, + 0x00, 0x65, 0x00, 0xe5, 0x07, 0x00, 0xe5, 0x02, + 0x16, 0xa0, 0xe5, 0x27, 0x06, 0x47, 0xe6, 0x00, + 0x80, 0xe9, 0x02, 0xa0, 0x26, 0x27, 0x00, 0xe5, + 0x00, 0x20, 0x25, 0x20, 0xe5, 0x0e, 0x00, 0xc5, + 0x00, 0x25, 0x00, 0x85, 0x00, 0x26, 0x05, 0x27, + 0x06, 0x67, 0x20, 0x27, 0x20, 0x47, 0x20, 0x05, + 0xa0, 0x07, 0x80, 0x85, 0x27, 0x20, 0xc6, 0x40, + 0x86, 0xe0, 0x03, 0xe5, 0x02, 0x00, 0x05, 0x20, + 0x05, 0x00, 0xe5, 0x1e, 0x00, 0x05, 0x47, 0xa6, + 0x00, 0x07, 0x20, 0x07, 0x00, 0x67, 0x00, 0x27, + 0x06, 0x07, 0x06, 0x05, 0x06, 0x05, 0x36, 0x00, + 0x36, 0xe0, 0x00, 0x26, 0xe0, 0x15, 0xe5, 0x2d, + 0x47, 0xe6, 0x00, 0x27, 0x46, 0x07, 0x06, 0x65, + 0x96, 0xe9, 0x02, 0x36, 0x00, 0x16, 0x06, 0x45, + 0xe0, 0x16, 0xe5, 0x28, 0x47, 0xa6, 0x07, 0x06, + 0x67, 0x26, 0x07, 0x26, 0x25, 0x16, 0x05, 0xe0, + 0x00, 0xe9, 0x02, 0xe0, 0x80, 0x1e, 0xe5, 0x27, + 0x47, 0x66, 0x20, 0x67, 0x26, 0x07, 0x26, 0xf6, + 0x0f, 0x65, 0x26, 0xe0, 0x1a, 0xe5, 0x28, 0x47, + 0xe6, 0x00, 0x27, 0x06, 0x07, 0x26, 0x56, 0x05, + 0xe0, 0x03, 0xe9, 0x02, 0xa0, 0xf6, 0x05, 0xe0, + 0x0b, 0xe5, 0x23, 0x06, 0x07, 0x06, 0x27, 0xa6, + 0x07, 0x06, 0x05, 0x16, 0xa0, 0xe9, 0x02, 0xa0, + 0xe9, 0x0c, 0xe0, 0x14, 0xe5, 0x13, 0x20, 0x06, + 0x07, 0x06, 0x27, 0x66, 0x07, 0x86, 0x60, 0xe9, + 0x02, 0x2b, 0x56, 0x0f, 0xc5, 0xe0, 0x80, 0x31, + 0xe5, 0x24, 0x47, 0xe6, 0x01, 0x07, 0x26, 0x16, + 0xe0, 0x5c, 0xe1, 0x18, 0xe2, 0x18, 0xe9, 0x02, + 0xeb, 0x01, 0xe0, 0x04, 0xe5, 0x00, 0x20, 0x05, + 0x20, 0xe5, 0x00, 0x00, 0x25, 0x00, 0xe5, 0x10, + 0xa7, 0x00, 0x27, 0x20, 0x26, 0x07, 0x06, 0x05, + 0x07, 0x05, 0x07, 0x06, 0x56, 0xe0, 0x01, 0xe9, + 0x02, 0xe0, 0x3e, 0xe5, 0x00, 0x20, 0xe5, 0x1f, + 0x47, 0x66, 0x20, 0x26, 0x67, 0x06, 0x05, 0x16, + 0x05, 0x07, 0xe0, 0x13, 0x05, 0xe6, 0x02, 0xe5, + 0x20, 0xa6, 0x07, 0x05, 0x66, 0xf6, 0x00, 0x06, + 0xe0, 0x00, 0x05, 0xa6, 0x27, 0x46, 0xe5, 0x26, + 0xe6, 0x05, 0x07, 0x26, 0x56, 0x05, 0x96, 0xe0, + 0x05, 0xe5, 0x41, 0xc0, 0xf6, 0x02, 0xe0, 0x4e, + 0x06, 0x07, 0x46, 0x07, 0x06, 0x07, 0xe0, 0x50, + 0xe5, 0x19, 0x16, 0xe0, 0x06, 0xe9, 0x02, 0xa0, + 0xe5, 0x01, 0x00, 0xe5, 0x1d, 0x07, 0xc6, 0x00, + 0xa6, 0x07, 0x06, 0x05, 0x96, 0xe0, 0x02, 0xe9, + 0x02, 0xeb, 0x0b, 0x40, 0x36, 0xe5, 0x16, 0x20, + 0xe6, 0x0e, 0x00, 0x07, 0xc6, 0x07, 0x26, 0x07, + 0x26, 0xe0, 0x41, 0xc5, 0x00, 0x25, 0x00, 0xe5, + 0x1e, 0xa6, 0x40, 0x06, 0x00, 0x26, 0x00, 0xc6, + 0x05, 0x06, 0xe0, 0x00, 0xe9, 0x02, 0xa0, 0xa5, + 0x00, 0x25, 0x00, 0xe5, 0x18, 0x87, 0x00, 0x26, + 0x00, 0x27, 0x06, 0x07, 0x06, 0x05, 0xc0, 0xe9, + 0x02, 0xa0, 0xe5, 0x21, 0x04, 0x25, 0x60, 0xe9, + 0x02, 0xe0, 0x80, 0x6e, 0xe5, 0x0b, 0x26, 0x27, + 0x36, 0xc0, 0x26, 0x05, 0x07, 0xe5, 0x05, 0x00, + 0xe5, 0x1a, 0x27, 0x86, 0x40, 0x27, 0x06, 0x07, + 0x06, 0xf6, 0x05, 0xe9, 0x02, 0x06, 0xe0, 0x4d, + 0x05, 0xe0, 0x07, 0xeb, 0x0d, 0xef, 0x00, 0x6d, + 0xef, 0x09, 0xe0, 0x05, 0x16, 0xe5, 0x83, 0x12, + 0xe0, 0x5e, 0xea, 0x67, 0x00, 0x96, 0xe0, 0x03, + 0xe5, 0x80, 0x3c, 0xe0, 0x89, 0xc4, 0xe5, 0x59, + 0x36, 0xe0, 0x05, 0xe5, 0x83, 0xa8, 0xfb, 0x08, + 0x06, 0xa5, 0xe6, 0x07, 0xe0, 0x02, 0xe5, 0x8f, + 0x13, 0x80, 0xe5, 0x81, 0xbf, 0xe0, 0x9a, 0x31, + 0xe5, 0x16, 0xe6, 0x04, 0x47, 0x46, 0xe9, 0x02, + 0xe0, 0x86, 0x3e, 0xe5, 0x81, 0xb1, 0xc0, 0xe5, + 0x17, 0x00, 0xe9, 0x02, 0x60, 0x36, 0xe5, 0x47, + 0x00, 0xe9, 0x02, 0xa0, 0xe5, 0x16, 0x20, 0x86, + 0x16, 0xe0, 0x02, 0xe5, 0x28, 0xc6, 0x96, 0x6f, + 0x64, 0x16, 0x0f, 0xe0, 0x02, 0xe9, 0x02, 0x00, + 0xcb, 0x00, 0xe5, 0x0d, 0x80, 0xe5, 0x0b, 0xe0, + 0x81, 0x28, 0x44, 0xe5, 0x20, 0x24, 0x56, 0xe9, + 0x02, 0xe0, 0x80, 0x3e, 0xe1, 0x18, 0xe2, 0x18, + 0xeb, 0x0f, 0x76, 0x80, 0xe1, 0x11, 0x20, 0xe2, + 0x11, 0xe0, 0x24, 0xe5, 0x43, 0x60, 0x06, 0x05, + 0xe7, 0x2f, 0xc0, 0x66, 0xe4, 0x05, 0xe0, 0x38, + 0x24, 0x16, 0x04, 0x06, 0xe0, 0x03, 0x27, 0x24, + 0x4a, 0xe0, 0x01, 0xe5, 0x9c, 0x4e, 0xe0, 0x21, + 0xe5, 0x18, 0xe0, 0x59, 0xe5, 0x6b, 0xe0, 0xa1, + 0x75, 0x64, 0x00, 0xc4, 0x00, 0x24, 0x00, 0xe5, + 0x80, 0x9b, 0xe0, 0x07, 0x05, 0xe0, 0x15, 0x45, + 0x20, 0x05, 0xe0, 0x06, 0x65, 0xe0, 0x00, 0xe5, + 0x81, 0x04, 0xe0, 0x88, 0x7c, 0xe5, 0x63, 0x80, + 0xe5, 0x05, 0x40, 0xe5, 0x01, 0xc0, 0xe5, 0x02, + 0x20, 0x0f, 0x26, 0x16, 0x7b, 0xe0, 0x8e, 0xd4, + 0xef, 0x80, 0x68, 0xe9, 0x02, 0x4f, 0x40, 0xef, + 0x81, 0x2c, 0xa0, 0xef, 0x0f, 0xe0, 0x07, 0xef, + 0x08, 0x0c, 0xe0, 0x07, 0xe6, 0x26, 0x20, 0xe6, + 0x0f, 0xe0, 0x01, 0xef, 0x6c, 0xe0, 0x34, 0xef, + 0x80, 0x6e, 0xe0, 0x02, 0xef, 0x1f, 0x20, 0xef, + 0x34, 0x27, 0x46, 0x4f, 0xa7, 0xfb, 0x00, 0xe6, + 0x00, 0x2f, 0xc6, 0xef, 0x16, 0x66, 0xef, 0x35, + 0xe0, 0x0d, 0xef, 0x3a, 0x46, 0x0f, 0xe0, 0x72, + 0xeb, 0x0c, 0xe0, 0x04, 0xeb, 0x0c, 0xe0, 0x04, + 0xef, 0x4f, 0xe0, 0x01, 0xeb, 0x11, 0xe0, 0x7f, + 0xe1, 0x12, 0xe2, 0x12, 0xe1, 0x12, 0xc2, 0x00, + 0xe2, 0x0a, 0xe1, 0x12, 0xe2, 0x12, 0x01, 0x00, + 0x21, 0x20, 0x01, 0x20, 0x21, 0x20, 0x61, 0x00, + 0xe1, 0x00, 0x62, 0x00, 0x02, 0x00, 0xc2, 0x00, + 0xe2, 0x03, 0xe1, 0x12, 0xe2, 0x12, 0x21, 0x00, + 0x61, 0x20, 0xe1, 0x00, 0x00, 0xc1, 0x00, 0xe2, + 0x12, 0x21, 0x00, 0x61, 0x00, 0x81, 0x00, 0x01, + 0x40, 0xc1, 0x00, 0xe2, 0x12, 0xe1, 0x12, 0xe2, + 0x12, 0xe1, 0x12, 0xe2, 0x12, 0xe1, 0x12, 0xe2, + 0x12, 0xe1, 0x12, 0xe2, 0x12, 0xe1, 0x12, 0xe2, + 0x12, 0xe1, 0x12, 0xe2, 0x14, 0x20, 0xe1, 0x11, + 0x0c, 0xe2, 0x11, 0x0c, 0xa2, 0xe1, 0x11, 0x0c, + 0xe2, 0x11, 0x0c, 0xa2, 0xe1, 0x11, 0x0c, 0xe2, + 0x11, 0x0c, 0xa2, 0xe1, 0x11, 0x0c, 0xe2, 0x11, + 0x0c, 0xa2, 0xe1, 0x11, 0x0c, 0xe2, 0x11, 0x0c, + 0xa2, 0x3f, 0x20, 0xe9, 0x2a, 0xef, 0x81, 0x78, + 0xe6, 0x2f, 0x6f, 0xe6, 0x2a, 0xef, 0x00, 0x06, + 0xef, 0x06, 0x06, 0x2f, 0x96, 0xe0, 0x07, 0x86, + 0x00, 0xe6, 0x07, 0xe0, 0x83, 0xc8, 0xe2, 0x02, + 0x05, 0xe2, 0x0c, 0xa0, 0xa2, 0xe0, 0x80, 0x4d, + 0xc6, 0x00, 0xe6, 0x09, 0x20, 0xc6, 0x00, 0x26, + 0x00, 0x86, 0x80, 0xe4, 0x36, 0xe0, 0x19, 0x06, + 0xe0, 0x68, 0xe5, 0x25, 0x40, 0xc6, 0xc4, 0x20, + 0xe9, 0x02, 0x60, 0x05, 0x0f, 0xe0, 0x80, 0xb8, + 0xe5, 0x16, 0x06, 0xe0, 0x09, 0xe5, 0x24, 0x66, + 0xe9, 0x02, 0x80, 0x0d, 0xe0, 0x81, 0x48, 0xe5, + 0x13, 0x04, 0x66, 0xe9, 0x02, 0xe0, 0x80, 0x4e, + 0xe5, 0x16, 0x26, 0x05, 0xe9, 0x02, 0x60, 0x16, + 0xe0, 0x80, 0x38, 0xe5, 0x17, 0x00, 0x45, 0x06, + 0x25, 0x06, 0xc5, 0x26, 0x85, 0x06, 0xe0, 0x00, + 0x05, 0x04, 0xe0, 0x80, 0x58, 0xc5, 0x00, 0x65, + 0x00, 0x25, 0x00, 0xe5, 0x07, 0x00, 0xe5, 0x80, + 0x3d, 0x20, 0xeb, 0x01, 0xc6, 0xe0, 0x21, 0xe1, + 0x1a, 0xe2, 0x1a, 0xc6, 0x04, 0x60, 0xe9, 0x02, + 0x60, 0x36, 0xe0, 0x82, 0x89, 0xeb, 0x33, 0x0f, + 0x4b, 0x0d, 0x6b, 0xe0, 0x44, 0xeb, 0x25, 0x0f, + 0xeb, 0x07, 0xe0, 0x80, 0x3a, 0x65, 0x00, 0xe5, + 0x13, 0x00, 0x25, 0x00, 0x05, 0x20, 0x05, 0x00, + 0xe5, 0x02, 0x00, 0x65, 0x00, 0x05, 0x00, 0x05, + 0xa0, 0x05, 0x60, 0x05, 0x00, 0x05, 0x00, 0x05, + 0x00, 0x45, 0x00, 0x25, 0x00, 0x05, 0x20, 0x05, + 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, + 0x00, 0x25, 0x00, 0x05, 0x20, 0x65, 0x00, 0xc5, + 0x00, 0x65, 0x00, 0x65, 0x00, 0x05, 0x00, 0xe5, + 0x02, 0x00, 0xe5, 0x09, 0x80, 0x45, 0x00, 0x85, + 0x00, 0xe5, 0x09, 0xe0, 0x2c, 0x2c, 0xe0, 0x80, + 0x86, 0xef, 0x24, 0x60, 0xef, 0x5c, 0xe0, 0x04, + 0xef, 0x07, 0x20, 0xef, 0x07, 0x00, 0xef, 0x07, + 0x00, 0xef, 0x1d, 0xe0, 0x02, 0xeb, 0x05, 0xef, + 0x80, 0x19, 0xe0, 0x30, 0xef, 0x15, 0xe0, 0x05, + 0xef, 0x24, 0x60, 0xef, 0x01, 0xc0, 0x2f, 0xe0, + 0x06, 0xaf, 0xe0, 0x80, 0x12, 0xef, 0x80, 0x73, + 0x8e, 0xef, 0x82, 0x51, 0x40, 0xef, 0x09, 0x40, + 0xef, 0x05, 0x40, 0xef, 0x80, 0x52, 0xa0, 0xef, + 0x04, 0x60, 0x0f, 0xe0, 0x07, 0xef, 0x04, 0x60, + 0xef, 0x30, 0xe0, 0x00, 0xef, 0x02, 0xa0, 0xef, + 0x20, 0xe0, 0x00, 0xef, 0x16, 0x20, 0xef, 0x04, + 0x60, 0x2f, 0xe0, 0x06, 0xec, 0x01, 0xe0, 0x1f, + 0xef, 0x80, 0xd0, 0xe0, 0x00, 0xef, 0x06, 0x20, + 0xef, 0x05, 0x40, 0xef, 0x03, 0x40, 0xef, 0x31, + 0x00, 0x0f, 0x60, 0xef, 0x08, 0x20, 0xef, 0x04, + 0x60, 0xef, 0x02, 0xc0, 0xef, 0x80, 0x0b, 0x00, + 0xef, 0x54, 0xe9, 0x02, 0x0f, 0xe0, 0x83, 0x7d, + 0xe5, 0xc0, 0x66, 0x58, 0xe0, 0x18, 0xe5, 0x90, + 0x96, 0x20, 0xe5, 0x96, 0x06, 0x20, 0xe5, 0x9c, + 0xa9, 0xe0, 0x07, 0xe5, 0x81, 0xe6, 0xe0, 0x89, + 0x1a, 0xe5, 0x81, 0x96, 0xe0, 0x85, 0x5a, 0xe5, + 0x92, 0xc3, 0x80, 0xe5, 0xa0, 0xa2, 0xe0, 0xca, + 0x8a, 0xff, 0x1b, 0xe0, 0x16, 0xfb, 0x58, 0xe0, + 0x78, 0xe6, 0x80, 0x68, 0xe0, 0xc0, 0xbd, 0x88, + 0xfd, 0xc0, 0xbf, 0x76, 0x20, 0xfd, 0xc0, 0xbf, + 0x76, 0x20, +}; + +typedef enum { + UNICODE_SCRIPT_Unknown, + UNICODE_SCRIPT_Adlam, + UNICODE_SCRIPT_Ahom, + UNICODE_SCRIPT_Anatolian_Hieroglyphs, + UNICODE_SCRIPT_Arabic, + UNICODE_SCRIPT_Armenian, + UNICODE_SCRIPT_Avestan, + UNICODE_SCRIPT_Balinese, + UNICODE_SCRIPT_Bamum, + UNICODE_SCRIPT_Bassa_Vah, + UNICODE_SCRIPT_Batak, + UNICODE_SCRIPT_Bengali, + UNICODE_SCRIPT_Beria_Erfe, + UNICODE_SCRIPT_Bhaiksuki, + UNICODE_SCRIPT_Bopomofo, + UNICODE_SCRIPT_Brahmi, + UNICODE_SCRIPT_Braille, + UNICODE_SCRIPT_Buginese, + UNICODE_SCRIPT_Buhid, + UNICODE_SCRIPT_Canadian_Aboriginal, + UNICODE_SCRIPT_Carian, + UNICODE_SCRIPT_Caucasian_Albanian, + UNICODE_SCRIPT_Chakma, + UNICODE_SCRIPT_Cham, + UNICODE_SCRIPT_Cherokee, + UNICODE_SCRIPT_Chorasmian, + UNICODE_SCRIPT_Common, + UNICODE_SCRIPT_Coptic, + UNICODE_SCRIPT_Cuneiform, + UNICODE_SCRIPT_Cypriot, + UNICODE_SCRIPT_Cyrillic, + UNICODE_SCRIPT_Cypro_Minoan, + UNICODE_SCRIPT_Deseret, + UNICODE_SCRIPT_Devanagari, + UNICODE_SCRIPT_Dives_Akuru, + UNICODE_SCRIPT_Dogra, + UNICODE_SCRIPT_Duployan, + UNICODE_SCRIPT_Egyptian_Hieroglyphs, + UNICODE_SCRIPT_Elbasan, + UNICODE_SCRIPT_Elymaic, + UNICODE_SCRIPT_Ethiopic, + UNICODE_SCRIPT_Georgian, + UNICODE_SCRIPT_Glagolitic, + UNICODE_SCRIPT_Gothic, + UNICODE_SCRIPT_Garay, + UNICODE_SCRIPT_Grantha, + UNICODE_SCRIPT_Greek, + UNICODE_SCRIPT_Gujarati, + UNICODE_SCRIPT_Gunjala_Gondi, + UNICODE_SCRIPT_Gurmukhi, + UNICODE_SCRIPT_Gurung_Khema, + UNICODE_SCRIPT_Han, + UNICODE_SCRIPT_Hangul, + UNICODE_SCRIPT_Hanifi_Rohingya, + UNICODE_SCRIPT_Hanunoo, + UNICODE_SCRIPT_Hatran, + UNICODE_SCRIPT_Hebrew, + UNICODE_SCRIPT_Hiragana, + UNICODE_SCRIPT_Imperial_Aramaic, + UNICODE_SCRIPT_Inherited, + UNICODE_SCRIPT_Inscriptional_Pahlavi, + UNICODE_SCRIPT_Inscriptional_Parthian, + UNICODE_SCRIPT_Javanese, + UNICODE_SCRIPT_Kaithi, + UNICODE_SCRIPT_Kannada, + UNICODE_SCRIPT_Katakana, + UNICODE_SCRIPT_Katakana_Or_Hiragana, + UNICODE_SCRIPT_Kawi, + UNICODE_SCRIPT_Kayah_Li, + UNICODE_SCRIPT_Kharoshthi, + UNICODE_SCRIPT_Khmer, + UNICODE_SCRIPT_Khojki, + UNICODE_SCRIPT_Khitan_Small_Script, + UNICODE_SCRIPT_Khudawadi, + UNICODE_SCRIPT_Kirat_Rai, + UNICODE_SCRIPT_Lao, + UNICODE_SCRIPT_Latin, + UNICODE_SCRIPT_Lepcha, + UNICODE_SCRIPT_Limbu, + UNICODE_SCRIPT_Linear_A, + UNICODE_SCRIPT_Linear_B, + UNICODE_SCRIPT_Lisu, + UNICODE_SCRIPT_Lycian, + UNICODE_SCRIPT_Lydian, + UNICODE_SCRIPT_Makasar, + UNICODE_SCRIPT_Mahajani, + UNICODE_SCRIPT_Malayalam, + UNICODE_SCRIPT_Mandaic, + UNICODE_SCRIPT_Manichaean, + UNICODE_SCRIPT_Marchen, + UNICODE_SCRIPT_Masaram_Gondi, + UNICODE_SCRIPT_Medefaidrin, + UNICODE_SCRIPT_Meetei_Mayek, + UNICODE_SCRIPT_Mende_Kikakui, + UNICODE_SCRIPT_Meroitic_Cursive, + UNICODE_SCRIPT_Meroitic_Hieroglyphs, + UNICODE_SCRIPT_Miao, + UNICODE_SCRIPT_Modi, + UNICODE_SCRIPT_Mongolian, + UNICODE_SCRIPT_Mro, + UNICODE_SCRIPT_Multani, + UNICODE_SCRIPT_Myanmar, + UNICODE_SCRIPT_Nabataean, + UNICODE_SCRIPT_Nag_Mundari, + UNICODE_SCRIPT_Nandinagari, + UNICODE_SCRIPT_New_Tai_Lue, + UNICODE_SCRIPT_Newa, + UNICODE_SCRIPT_Nko, + UNICODE_SCRIPT_Nushu, + UNICODE_SCRIPT_Nyiakeng_Puachue_Hmong, + UNICODE_SCRIPT_Ogham, + UNICODE_SCRIPT_Ol_Chiki, + UNICODE_SCRIPT_Ol_Onal, + UNICODE_SCRIPT_Old_Hungarian, + UNICODE_SCRIPT_Old_Italic, + UNICODE_SCRIPT_Old_North_Arabian, + UNICODE_SCRIPT_Old_Permic, + UNICODE_SCRIPT_Old_Persian, + UNICODE_SCRIPT_Old_Sogdian, + UNICODE_SCRIPT_Old_South_Arabian, + UNICODE_SCRIPT_Old_Turkic, + UNICODE_SCRIPT_Old_Uyghur, + UNICODE_SCRIPT_Oriya, + UNICODE_SCRIPT_Osage, + UNICODE_SCRIPT_Osmanya, + UNICODE_SCRIPT_Pahawh_Hmong, + UNICODE_SCRIPT_Palmyrene, + UNICODE_SCRIPT_Pau_Cin_Hau, + UNICODE_SCRIPT_Phags_Pa, + UNICODE_SCRIPT_Phoenician, + UNICODE_SCRIPT_Psalter_Pahlavi, + UNICODE_SCRIPT_Rejang, + UNICODE_SCRIPT_Runic, + UNICODE_SCRIPT_Samaritan, + UNICODE_SCRIPT_Saurashtra, + UNICODE_SCRIPT_Sharada, + UNICODE_SCRIPT_Shavian, + UNICODE_SCRIPT_Siddham, + UNICODE_SCRIPT_Sidetic, + UNICODE_SCRIPT_SignWriting, + UNICODE_SCRIPT_Sinhala, + UNICODE_SCRIPT_Sogdian, + UNICODE_SCRIPT_Sora_Sompeng, + UNICODE_SCRIPT_Soyombo, + UNICODE_SCRIPT_Sundanese, + UNICODE_SCRIPT_Sunuwar, + UNICODE_SCRIPT_Syloti_Nagri, + UNICODE_SCRIPT_Syriac, + UNICODE_SCRIPT_Tagalog, + UNICODE_SCRIPT_Tagbanwa, + UNICODE_SCRIPT_Tai_Le, + UNICODE_SCRIPT_Tai_Tham, + UNICODE_SCRIPT_Tai_Viet, + UNICODE_SCRIPT_Tai_Yo, + UNICODE_SCRIPT_Takri, + UNICODE_SCRIPT_Tamil, + UNICODE_SCRIPT_Tangut, + UNICODE_SCRIPT_Telugu, + UNICODE_SCRIPT_Thaana, + UNICODE_SCRIPT_Thai, + UNICODE_SCRIPT_Tibetan, + UNICODE_SCRIPT_Tifinagh, + UNICODE_SCRIPT_Tirhuta, + UNICODE_SCRIPT_Tangsa, + UNICODE_SCRIPT_Todhri, + UNICODE_SCRIPT_Tolong_Siki, + UNICODE_SCRIPT_Toto, + UNICODE_SCRIPT_Tulu_Tigalari, + UNICODE_SCRIPT_Ugaritic, + UNICODE_SCRIPT_Vai, + UNICODE_SCRIPT_Vithkuqi, + UNICODE_SCRIPT_Wancho, + UNICODE_SCRIPT_Warang_Citi, + UNICODE_SCRIPT_Yezidi, + UNICODE_SCRIPT_Yi, + UNICODE_SCRIPT_Zanabazar_Square, + UNICODE_SCRIPT_COUNT, +} UnicodeScriptEnum; + +static const char unicode_script_name_table[] = + "Adlam,Adlm" "\0" + "Ahom,Ahom" "\0" + "Anatolian_Hieroglyphs,Hluw" "\0" + "Arabic,Arab" "\0" + "Armenian,Armn" "\0" + "Avestan,Avst" "\0" + "Balinese,Bali" "\0" + "Bamum,Bamu" "\0" + "Bassa_Vah,Bass" "\0" + "Batak,Batk" "\0" + "Bengali,Beng" "\0" + "Beria_Erfe,Berf" "\0" + "Bhaiksuki,Bhks" "\0" + "Bopomofo,Bopo" "\0" + "Brahmi,Brah" "\0" + "Braille,Brai" "\0" + "Buginese,Bugi" "\0" + "Buhid,Buhd" "\0" + "Canadian_Aboriginal,Cans" "\0" + "Carian,Cari" "\0" + "Caucasian_Albanian,Aghb" "\0" + "Chakma,Cakm" "\0" + "Cham,Cham" "\0" + "Cherokee,Cher" "\0" + "Chorasmian,Chrs" "\0" + "Common,Zyyy" "\0" + "Coptic,Copt,Qaac" "\0" + "Cuneiform,Xsux" "\0" + "Cypriot,Cprt" "\0" + "Cyrillic,Cyrl" "\0" + "Cypro_Minoan,Cpmn" "\0" + "Deseret,Dsrt" "\0" + "Devanagari,Deva" "\0" + "Dives_Akuru,Diak" "\0" + "Dogra,Dogr" "\0" + "Duployan,Dupl" "\0" + "Egyptian_Hieroglyphs,Egyp" "\0" + "Elbasan,Elba" "\0" + "Elymaic,Elym" "\0" + "Ethiopic,Ethi" "\0" + "Georgian,Geor" "\0" + "Glagolitic,Glag" "\0" + "Gothic,Goth" "\0" + "Garay,Gara" "\0" + "Grantha,Gran" "\0" + "Greek,Grek" "\0" + "Gujarati,Gujr" "\0" + "Gunjala_Gondi,Gong" "\0" + "Gurmukhi,Guru" "\0" + "Gurung_Khema,Gukh" "\0" + "Han,Hani" "\0" + "Hangul,Hang" "\0" + "Hanifi_Rohingya,Rohg" "\0" + "Hanunoo,Hano" "\0" + "Hatran,Hatr" "\0" + "Hebrew,Hebr" "\0" + "Hiragana,Hira" "\0" + "Imperial_Aramaic,Armi" "\0" + "Inherited,Zinh,Qaai" "\0" + "Inscriptional_Pahlavi,Phli" "\0" + "Inscriptional_Parthian,Prti" "\0" + "Javanese,Java" "\0" + "Kaithi,Kthi" "\0" + "Kannada,Knda" "\0" + "Katakana,Kana" "\0" + "Katakana_Or_Hiragana,Hrkt" "\0" + "Kawi,Kawi" "\0" + "Kayah_Li,Kali" "\0" + "Kharoshthi,Khar" "\0" + "Khmer,Khmr" "\0" + "Khojki,Khoj" "\0" + "Khitan_Small_Script,Kits" "\0" + "Khudawadi,Sind" "\0" + "Kirat_Rai,Krai" "\0" + "Lao,Laoo" "\0" + "Latin,Latn" "\0" + "Lepcha,Lepc" "\0" + "Limbu,Limb" "\0" + "Linear_A,Lina" "\0" + "Linear_B,Linb" "\0" + "Lisu,Lisu" "\0" + "Lycian,Lyci" "\0" + "Lydian,Lydi" "\0" + "Makasar,Maka" "\0" + "Mahajani,Mahj" "\0" + "Malayalam,Mlym" "\0" + "Mandaic,Mand" "\0" + "Manichaean,Mani" "\0" + "Marchen,Marc" "\0" + "Masaram_Gondi,Gonm" "\0" + "Medefaidrin,Medf" "\0" + "Meetei_Mayek,Mtei" "\0" + "Mende_Kikakui,Mend" "\0" + "Meroitic_Cursive,Merc" "\0" + "Meroitic_Hieroglyphs,Mero" "\0" + "Miao,Plrd" "\0" + "Modi,Modi" "\0" + "Mongolian,Mong" "\0" + "Mro,Mroo" "\0" + "Multani,Mult" "\0" + "Myanmar,Mymr" "\0" + "Nabataean,Nbat" "\0" + "Nag_Mundari,Nagm" "\0" + "Nandinagari,Nand" "\0" + "New_Tai_Lue,Talu" "\0" + "Newa,Newa" "\0" + "Nko,Nkoo" "\0" + "Nushu,Nshu" "\0" + "Nyiakeng_Puachue_Hmong,Hmnp" "\0" + "Ogham,Ogam" "\0" + "Ol_Chiki,Olck" "\0" + "Ol_Onal,Onao" "\0" + "Old_Hungarian,Hung" "\0" + "Old_Italic,Ital" "\0" + "Old_North_Arabian,Narb" "\0" + "Old_Permic,Perm" "\0" + "Old_Persian,Xpeo" "\0" + "Old_Sogdian,Sogo" "\0" + "Old_South_Arabian,Sarb" "\0" + "Old_Turkic,Orkh" "\0" + "Old_Uyghur,Ougr" "\0" + "Oriya,Orya" "\0" + "Osage,Osge" "\0" + "Osmanya,Osma" "\0" + "Pahawh_Hmong,Hmng" "\0" + "Palmyrene,Palm" "\0" + "Pau_Cin_Hau,Pauc" "\0" + "Phags_Pa,Phag" "\0" + "Phoenician,Phnx" "\0" + "Psalter_Pahlavi,Phlp" "\0" + "Rejang,Rjng" "\0" + "Runic,Runr" "\0" + "Samaritan,Samr" "\0" + "Saurashtra,Saur" "\0" + "Sharada,Shrd" "\0" + "Shavian,Shaw" "\0" + "Siddham,Sidd" "\0" + "Sidetic,Sidt" "\0" + "SignWriting,Sgnw" "\0" + "Sinhala,Sinh" "\0" + "Sogdian,Sogd" "\0" + "Sora_Sompeng,Sora" "\0" + "Soyombo,Soyo" "\0" + "Sundanese,Sund" "\0" + "Sunuwar,Sunu" "\0" + "Syloti_Nagri,Sylo" "\0" + "Syriac,Syrc" "\0" + "Tagalog,Tglg" "\0" + "Tagbanwa,Tagb" "\0" + "Tai_Le,Tale" "\0" + "Tai_Tham,Lana" "\0" + "Tai_Viet,Tavt" "\0" + "Tai_Yo,Tayo" "\0" + "Takri,Takr" "\0" + "Tamil,Taml" "\0" + "Tangut,Tang" "\0" + "Telugu,Telu" "\0" + "Thaana,Thaa" "\0" + "Thai,Thai" "\0" + "Tibetan,Tibt" "\0" + "Tifinagh,Tfng" "\0" + "Tirhuta,Tirh" "\0" + "Tangsa,Tnsa" "\0" + "Todhri,Todr" "\0" + "Tolong_Siki,Tols" "\0" + "Toto,Toto" "\0" + "Tulu_Tigalari,Tutg" "\0" + "Ugaritic,Ugar" "\0" + "Vai,Vaii" "\0" + "Vithkuqi,Vith" "\0" + "Wancho,Wcho" "\0" + "Warang_Citi,Wara" "\0" + "Yezidi,Yezi" "\0" + "Yi,Yiii" "\0" + "Zanabazar_Square,Zanb" "\0" +; + +static const uint8_t unicode_script_table[2818] = { + 0xc0, 0x1a, 0x99, 0x4c, 0x85, 0x1a, 0x99, 0x4c, + 0xae, 0x1a, 0x80, 0x4c, 0x8e, 0x1a, 0x80, 0x4c, + 0x84, 0x1a, 0x96, 0x4c, 0x80, 0x1a, 0x9e, 0x4c, + 0x80, 0x1a, 0xe1, 0x60, 0x4c, 0xa6, 0x1a, 0x84, + 0x4c, 0x84, 0x1a, 0x81, 0x0e, 0x93, 0x1a, 0xe0, + 0x0f, 0x3b, 0x83, 0x2e, 0x80, 0x1a, 0x82, 0x2e, + 0x01, 0x83, 0x2e, 0x80, 0x1a, 0x80, 0x2e, 0x03, + 0x80, 0x2e, 0x80, 0x1a, 0x80, 0x2e, 0x80, 0x1a, + 0x82, 0x2e, 0x00, 0x80, 0x2e, 0x00, 0x93, 0x2e, + 0x00, 0xbe, 0x2e, 0x8d, 0x1b, 0x8f, 0x2e, 0xe0, + 0x24, 0x1e, 0x81, 0x3b, 0xe0, 0x48, 0x1e, 0x00, + 0xa5, 0x05, 0x01, 0xb1, 0x05, 0x01, 0x82, 0x05, + 0x00, 0xb6, 0x38, 0x07, 0x9a, 0x38, 0x03, 0x85, + 0x38, 0x0a, 0x84, 0x04, 0x80, 0x1a, 0x85, 0x04, + 0x80, 0x1a, 0x8d, 0x04, 0x80, 0x1a, 0x82, 0x04, + 0x80, 0x1a, 0x9f, 0x04, 0x80, 0x1a, 0x89, 0x04, + 0x8a, 0x3b, 0x99, 0x04, 0x80, 0x3b, 0xe0, 0x0b, + 0x04, 0x80, 0x1a, 0xa1, 0x04, 0x8d, 0x93, 0x00, + 0xbb, 0x93, 0x01, 0x82, 0x93, 0xaf, 0x04, 0xb1, + 0x9e, 0x0d, 0xba, 0x6b, 0x01, 0x82, 0x6b, 0xad, + 0x85, 0x01, 0x8e, 0x85, 0x00, 0x9b, 0x57, 0x01, + 0x80, 0x57, 0x00, 0x8a, 0x93, 0x04, 0xa1, 0x04, + 0x04, 0xca, 0x04, 0x80, 0x1a, 0x9c, 0x04, 0xd0, + 0x21, 0x83, 0x3b, 0x8e, 0x21, 0x81, 0x1a, 0x99, + 0x21, 0x83, 0x0b, 0x00, 0x87, 0x0b, 0x01, 0x81, + 0x0b, 0x01, 0x95, 0x0b, 0x00, 0x86, 0x0b, 0x00, + 0x80, 0x0b, 0x02, 0x83, 0x0b, 0x01, 0x88, 0x0b, + 0x01, 0x81, 0x0b, 0x01, 0x83, 0x0b, 0x07, 0x80, + 0x0b, 0x03, 0x81, 0x0b, 0x00, 0x84, 0x0b, 0x01, + 0x98, 0x0b, 0x01, 0x82, 0x31, 0x00, 0x85, 0x31, + 0x03, 0x81, 0x31, 0x01, 0x95, 0x31, 0x00, 0x86, + 0x31, 0x00, 0x81, 0x31, 0x00, 0x81, 0x31, 0x00, + 0x81, 0x31, 0x01, 0x80, 0x31, 0x00, 0x84, 0x31, + 0x03, 0x81, 0x31, 0x01, 0x82, 0x31, 0x02, 0x80, + 0x31, 0x06, 0x83, 0x31, 0x00, 0x80, 0x31, 0x06, + 0x90, 0x31, 0x09, 0x82, 0x2f, 0x00, 0x88, 0x2f, + 0x00, 0x82, 0x2f, 0x00, 0x95, 0x2f, 0x00, 0x86, + 0x2f, 0x00, 0x81, 0x2f, 0x00, 0x84, 0x2f, 0x01, + 0x89, 0x2f, 0x00, 0x82, 0x2f, 0x00, 0x82, 0x2f, + 0x01, 0x80, 0x2f, 0x0e, 0x83, 0x2f, 0x01, 0x8b, + 0x2f, 0x06, 0x86, 0x2f, 0x00, 0x82, 0x7a, 0x00, + 0x87, 0x7a, 0x01, 0x81, 0x7a, 0x01, 0x95, 0x7a, + 0x00, 0x86, 0x7a, 0x00, 0x81, 0x7a, 0x00, 0x84, + 0x7a, 0x01, 0x88, 0x7a, 0x01, 0x81, 0x7a, 0x01, + 0x82, 0x7a, 0x06, 0x82, 0x7a, 0x03, 0x81, 0x7a, + 0x00, 0x84, 0x7a, 0x01, 0x91, 0x7a, 0x09, 0x81, + 0x9b, 0x00, 0x85, 0x9b, 0x02, 0x82, 0x9b, 0x00, + 0x83, 0x9b, 0x02, 0x81, 0x9b, 0x00, 0x80, 0x9b, + 0x00, 0x81, 0x9b, 0x02, 0x81, 0x9b, 0x02, 0x82, + 0x9b, 0x02, 0x8b, 0x9b, 0x03, 0x84, 0x9b, 0x02, + 0x82, 0x9b, 0x00, 0x83, 0x9b, 0x01, 0x80, 0x9b, + 0x05, 0x80, 0x9b, 0x0d, 0x94, 0x9b, 0x04, 0x8c, + 0x9d, 0x00, 0x82, 0x9d, 0x00, 0x96, 0x9d, 0x00, + 0x8f, 0x9d, 0x01, 0x88, 0x9d, 0x00, 0x82, 0x9d, + 0x00, 0x83, 0x9d, 0x06, 0x81, 0x9d, 0x00, 0x82, + 0x9d, 0x00, 0x81, 0x9d, 0x01, 0x83, 0x9d, 0x01, + 0x89, 0x9d, 0x06, 0x88, 0x9d, 0x8c, 0x40, 0x00, + 0x82, 0x40, 0x00, 0x96, 0x40, 0x00, 0x89, 0x40, + 0x00, 0x84, 0x40, 0x01, 0x88, 0x40, 0x00, 0x82, + 0x40, 0x00, 0x83, 0x40, 0x06, 0x81, 0x40, 0x04, + 0x82, 0x40, 0x00, 0x83, 0x40, 0x01, 0x89, 0x40, + 0x00, 0x82, 0x40, 0x0b, 0x8c, 0x56, 0x00, 0x82, + 0x56, 0x00, 0xb2, 0x56, 0x00, 0x82, 0x56, 0x00, + 0x85, 0x56, 0x03, 0x8f, 0x56, 0x01, 0x99, 0x56, + 0x00, 0x82, 0x8c, 0x00, 0x91, 0x8c, 0x02, 0x97, + 0x8c, 0x00, 0x88, 0x8c, 0x00, 0x80, 0x8c, 0x01, + 0x86, 0x8c, 0x02, 0x80, 0x8c, 0x03, 0x85, 0x8c, + 0x00, 0x80, 0x8c, 0x00, 0x87, 0x8c, 0x05, 0x89, + 0x8c, 0x01, 0x82, 0x8c, 0x0b, 0xb9, 0x9f, 0x03, + 0x80, 0x1a, 0x9b, 0x9f, 0x24, 0x81, 0x4b, 0x00, + 0x80, 0x4b, 0x00, 0x84, 0x4b, 0x00, 0x97, 0x4b, + 0x00, 0x80, 0x4b, 0x00, 0x96, 0x4b, 0x01, 0x84, + 0x4b, 0x00, 0x80, 0x4b, 0x00, 0x86, 0x4b, 0x00, + 0x89, 0x4b, 0x01, 0x83, 0x4b, 0x1f, 0xc7, 0xa0, + 0x00, 0xa3, 0xa0, 0x03, 0xa6, 0xa0, 0x00, 0xa3, + 0xa0, 0x00, 0x8e, 0xa0, 0x00, 0x86, 0xa0, 0x83, + 0x1a, 0x81, 0xa0, 0x24, 0xe0, 0x3f, 0x65, 0xa5, + 0x29, 0x00, 0x80, 0x29, 0x04, 0x80, 0x29, 0x01, + 0xaa, 0x29, 0x80, 0x1a, 0x83, 0x29, 0xe0, 0x9f, + 0x34, 0xc8, 0x28, 0x00, 0x83, 0x28, 0x01, 0x86, + 0x28, 0x00, 0x80, 0x28, 0x00, 0x83, 0x28, 0x01, + 0xa8, 0x28, 0x00, 0x83, 0x28, 0x01, 0xa0, 0x28, + 0x00, 0x83, 0x28, 0x01, 0x86, 0x28, 0x00, 0x80, + 0x28, 0x00, 0x83, 0x28, 0x01, 0x8e, 0x28, 0x00, + 0xb8, 0x28, 0x00, 0x83, 0x28, 0x01, 0xc2, 0x28, + 0x01, 0x9f, 0x28, 0x02, 0x99, 0x28, 0x05, 0xd5, + 0x18, 0x01, 0x85, 0x18, 0x01, 0xe2, 0x1f, 0x13, + 0x9c, 0x6e, 0x02, 0xca, 0x84, 0x82, 0x1a, 0x8a, + 0x84, 0x06, 0x95, 0x94, 0x08, 0x80, 0x94, 0x94, + 0x36, 0x81, 0x1a, 0x08, 0x93, 0x12, 0x0b, 0x8c, + 0x95, 0x00, 0x82, 0x95, 0x00, 0x81, 0x95, 0x0b, + 0xdd, 0x46, 0x01, 0x89, 0x46, 0x05, 0x89, 0x46, + 0x05, 0x81, 0x62, 0x81, 0x1a, 0x80, 0x62, 0x80, + 0x1a, 0x93, 0x62, 0x05, 0xd8, 0x62, 0x06, 0xaa, + 0x62, 0x04, 0xc5, 0x13, 0x09, 0x9e, 0x4e, 0x00, + 0x8b, 0x4e, 0x03, 0x8b, 0x4e, 0x03, 0x80, 0x4e, + 0x02, 0x8b, 0x4e, 0x9d, 0x96, 0x01, 0x84, 0x96, + 0x0a, 0xab, 0x69, 0x03, 0x99, 0x69, 0x05, 0x8a, + 0x69, 0x02, 0x81, 0x69, 0x9f, 0x46, 0x9b, 0x11, + 0x01, 0x81, 0x11, 0xbe, 0x97, 0x00, 0x9c, 0x97, + 0x01, 0x8a, 0x97, 0x05, 0x89, 0x97, 0x05, 0x8d, + 0x97, 0x01, 0xad, 0x3b, 0x01, 0x8b, 0x3b, 0x13, + 0xcc, 0x07, 0x00, 0xb1, 0x07, 0xbf, 0x90, 0xb3, + 0x0a, 0x07, 0x83, 0x0a, 0xb7, 0x4d, 0x02, 0x8e, + 0x4d, 0x02, 0x82, 0x4d, 0xaf, 0x6f, 0x8a, 0x1e, + 0x04, 0xaa, 0x29, 0x01, 0x82, 0x29, 0x87, 0x90, + 0x07, 0x82, 0x3b, 0x80, 0x1a, 0x8c, 0x3b, 0x80, + 0x1a, 0x86, 0x3b, 0x83, 0x1a, 0x80, 0x3b, 0x85, + 0x1a, 0x80, 0x3b, 0x82, 0x1a, 0x81, 0x3b, 0x80, + 0x1a, 0x04, 0xa5, 0x4c, 0x84, 0x2e, 0x80, 0x1e, + 0xb0, 0x4c, 0x84, 0x2e, 0x83, 0x4c, 0x84, 0x2e, + 0x8c, 0x4c, 0x80, 0x1e, 0xc5, 0x4c, 0x80, 0x2e, + 0xbf, 0x3b, 0xe0, 0x9f, 0x4c, 0x95, 0x2e, 0x01, + 0x85, 0x2e, 0x01, 0xa5, 0x2e, 0x01, 0x85, 0x2e, + 0x01, 0x87, 0x2e, 0x00, 0x80, 0x2e, 0x00, 0x80, + 0x2e, 0x00, 0x80, 0x2e, 0x00, 0x9e, 0x2e, 0x01, + 0xb4, 0x2e, 0x00, 0x8e, 0x2e, 0x00, 0x8d, 0x2e, + 0x01, 0x85, 0x2e, 0x00, 0x92, 0x2e, 0x01, 0x82, + 0x2e, 0x00, 0x88, 0x2e, 0x00, 0x8b, 0x1a, 0x81, + 0x3b, 0xd6, 0x1a, 0x00, 0x8a, 0x1a, 0x80, 0x4c, + 0x01, 0x8a, 0x1a, 0x80, 0x4c, 0x8e, 0x1a, 0x00, + 0x8c, 0x4c, 0x02, 0xa1, 0x1a, 0x0d, 0xa0, 0x3b, + 0x0e, 0xa5, 0x1a, 0x80, 0x2e, 0x82, 0x1a, 0x81, + 0x4c, 0x85, 0x1a, 0x80, 0x4c, 0x9a, 0x1a, 0x80, + 0x4c, 0x90, 0x1a, 0xa8, 0x4c, 0x82, 0x1a, 0x03, + 0xe2, 0x39, 0x1a, 0x15, 0x8a, 0x1a, 0x14, 0xe3, + 0x3f, 0x1a, 0xe0, 0x9f, 0x10, 0xe2, 0x13, 0x1a, + 0x01, 0xe0, 0x29, 0x1a, 0xdf, 0x2a, 0x9f, 0x4c, + 0xe0, 0x13, 0x1b, 0x04, 0x86, 0x1b, 0xa5, 0x29, + 0x00, 0x80, 0x29, 0x04, 0x80, 0x29, 0x01, 0xb7, + 0xa1, 0x06, 0x81, 0xa1, 0x0d, 0x80, 0xa1, 0x96, + 0x28, 0x08, 0x86, 0x28, 0x00, 0x86, 0x28, 0x00, + 0x86, 0x28, 0x00, 0x86, 0x28, 0x00, 0x86, 0x28, + 0x00, 0x86, 0x28, 0x00, 0x86, 0x28, 0x00, 0x86, + 0x28, 0x00, 0x9f, 0x1e, 0xdd, 0x1a, 0x21, 0x99, + 0x33, 0x00, 0xd8, 0x33, 0x0b, 0xe0, 0x75, 0x33, + 0x19, 0x94, 0x1a, 0x80, 0x33, 0x80, 0x1a, 0x80, + 0x33, 0x98, 0x1a, 0x88, 0x33, 0x83, 0x3b, 0x81, + 0x34, 0x87, 0x1a, 0x83, 0x33, 0x83, 0x1a, 0x00, + 0xd5, 0x39, 0x01, 0x81, 0x3b, 0x81, 0x1a, 0x82, + 0x39, 0x80, 0x1a, 0xd9, 0x41, 0x81, 0x1a, 0x82, + 0x41, 0x04, 0xaa, 0x0e, 0x00, 0xdd, 0x34, 0x00, + 0x8f, 0x1a, 0x9f, 0x0e, 0xa5, 0x1a, 0x08, 0x80, + 0x1a, 0x8f, 0x41, 0x9e, 0x34, 0x00, 0xbf, 0x1a, + 0x9e, 0x34, 0xd0, 0x1a, 0xae, 0x41, 0x80, 0x1a, + 0xd7, 0x41, 0xe0, 0x47, 0x1a, 0xf0, 0x09, 0x5f, + 0x33, 0xbf, 0x1a, 0xf0, 0x41, 0x9f, 0x33, 0xe4, + 0x2c, 0xae, 0x02, 0xb6, 0xae, 0x08, 0xaf, 0x51, + 0xe0, 0xcb, 0xa9, 0x13, 0xdf, 0x1e, 0xd7, 0x08, + 0x07, 0xa1, 0x1a, 0xe0, 0x05, 0x4c, 0x82, 0x1a, + 0xd1, 0x4c, 0x13, 0x8e, 0x4c, 0xac, 0x92, 0x02, + 0x89, 0x1a, 0x05, 0xb7, 0x80, 0x07, 0xc5, 0x86, + 0x07, 0x8b, 0x86, 0x05, 0x9f, 0x21, 0xad, 0x44, + 0x80, 0x1a, 0x80, 0x44, 0xa3, 0x83, 0x0a, 0x80, + 0x83, 0x9c, 0x34, 0x02, 0xcd, 0x3e, 0x00, 0x80, + 0x1a, 0x89, 0x3e, 0x03, 0x81, 0x3e, 0x9e, 0x65, + 0x00, 0xb6, 0x17, 0x08, 0x8d, 0x17, 0x01, 0x89, + 0x17, 0x01, 0x83, 0x17, 0x9f, 0x65, 0xc2, 0x98, + 0x17, 0x84, 0x98, 0x96, 0x5c, 0x09, 0x85, 0x28, + 0x01, 0x85, 0x28, 0x01, 0x85, 0x28, 0x08, 0x86, + 0x28, 0x00, 0x86, 0x28, 0x00, 0xaa, 0x4c, 0x80, + 0x1a, 0x88, 0x4c, 0x80, 0x2e, 0x83, 0x4c, 0x81, + 0x1a, 0x03, 0xcf, 0x18, 0xad, 0x5c, 0x01, 0x89, + 0x5c, 0x05, 0xf0, 0x1b, 0x43, 0x34, 0x0b, 0x96, + 0x34, 0x03, 0xb0, 0x34, 0x70, 0x10, 0xa3, 0xe1, + 0x0d, 0x33, 0x01, 0xe0, 0x09, 0x33, 0x25, 0x86, + 0x4c, 0x0b, 0x84, 0x05, 0x04, 0x99, 0x38, 0x00, + 0x84, 0x38, 0x00, 0x80, 0x38, 0x00, 0x81, 0x38, + 0x00, 0x81, 0x38, 0x00, 0x89, 0x38, 0xe1, 0x8d, + 0x04, 0x81, 0x1a, 0xe0, 0x2f, 0x04, 0x1f, 0x8f, + 0x04, 0x8f, 0x3b, 0x89, 0x1a, 0x05, 0x8d, 0x3b, + 0x81, 0x1e, 0xa2, 0x1a, 0x00, 0x92, 0x1a, 0x00, + 0x83, 0x1a, 0x03, 0x84, 0x04, 0x00, 0xe0, 0x26, + 0x04, 0x01, 0x80, 0x1a, 0x00, 0x9f, 0x1a, 0x99, + 0x4c, 0x85, 0x1a, 0x99, 0x4c, 0x8a, 0x1a, 0x89, + 0x41, 0x80, 0x1a, 0xac, 0x41, 0x81, 0x1a, 0x9e, + 0x34, 0x02, 0x85, 0x34, 0x01, 0x85, 0x34, 0x01, + 0x85, 0x34, 0x01, 0x82, 0x34, 0x02, 0x86, 0x1a, + 0x00, 0x86, 0x1a, 0x09, 0x84, 0x1a, 0x01, 0x8b, + 0x50, 0x00, 0x99, 0x50, 0x00, 0x92, 0x50, 0x00, + 0x81, 0x50, 0x00, 0x8e, 0x50, 0x01, 0x8d, 0x50, + 0x21, 0xe0, 0x1a, 0x50, 0x04, 0x82, 0x1a, 0x03, + 0xac, 0x1a, 0x02, 0x88, 0x1a, 0xce, 0x2e, 0x00, + 0x8c, 0x1a, 0x02, 0x80, 0x2e, 0x2e, 0xac, 0x1a, + 0x80, 0x3b, 0x60, 0x21, 0x9c, 0x52, 0x02, 0xb0, + 0x14, 0x0e, 0x80, 0x3b, 0x9a, 0x1a, 0x03, 0xa3, + 0x72, 0x08, 0x82, 0x72, 0x9a, 0x2b, 0x04, 0xaa, + 0x74, 0x04, 0x9d, 0xa8, 0x00, 0x80, 0xa8, 0xa3, + 0x75, 0x03, 0x8d, 0x75, 0x29, 0xcf, 0x20, 0xaf, + 0x88, 0x9d, 0x7c, 0x01, 0x89, 0x7c, 0x05, 0xa3, + 0x7b, 0x03, 0xa3, 0x7b, 0x03, 0xa7, 0x26, 0x07, + 0xb3, 0x15, 0x0a, 0x80, 0x15, 0x8a, 0xaa, 0x00, + 0x8e, 0xaa, 0x00, 0x86, 0xaa, 0x00, 0x81, 0xaa, + 0x00, 0x8a, 0xaa, 0x00, 0x8e, 0xaa, 0x00, 0x86, + 0xaa, 0x00, 0x81, 0xaa, 0x02, 0xb3, 0xa4, 0x0b, + 0xe0, 0xd6, 0x4f, 0x08, 0x95, 0x4f, 0x09, 0x87, + 0x4f, 0x17, 0x85, 0x4c, 0x00, 0xa9, 0x4c, 0x00, + 0x88, 0x4c, 0x44, 0x85, 0x1d, 0x01, 0x80, 0x1d, + 0x00, 0xab, 0x1d, 0x00, 0x81, 0x1d, 0x02, 0x80, + 0x1d, 0x01, 0x80, 0x1d, 0x95, 0x3a, 0x00, 0x88, + 0x3a, 0x9f, 0x7e, 0x9e, 0x66, 0x07, 0x88, 0x66, + 0x2f, 0x92, 0x37, 0x00, 0x81, 0x37, 0x04, 0x84, + 0x37, 0x9b, 0x81, 0x02, 0x80, 0x81, 0x99, 0x53, + 0x04, 0x80, 0x53, 0x99, 0x8a, 0x25, 0x9f, 0x5f, + 0x97, 0x5e, 0x03, 0x93, 0x5e, 0x01, 0xad, 0x5e, + 0x83, 0x45, 0x00, 0x81, 0x45, 0x04, 0x87, 0x45, + 0x00, 0x82, 0x45, 0x00, 0x9c, 0x45, 0x01, 0x82, + 0x45, 0x03, 0x89, 0x45, 0x06, 0x88, 0x45, 0x06, + 0x9f, 0x77, 0x9f, 0x73, 0x1f, 0xa6, 0x58, 0x03, + 0x8b, 0x58, 0x08, 0xb5, 0x06, 0x02, 0x86, 0x06, + 0x95, 0x3d, 0x01, 0x87, 0x3d, 0x92, 0x3c, 0x04, + 0x87, 0x3c, 0x91, 0x82, 0x06, 0x83, 0x82, 0x0b, + 0x86, 0x82, 0x4f, 0xc8, 0x78, 0x36, 0xb2, 0x71, + 0x0c, 0xb2, 0x71, 0x06, 0x85, 0x71, 0xa7, 0x35, + 0x07, 0x89, 0x35, 0x05, 0xa5, 0x2c, 0x02, 0x9c, + 0x2c, 0x07, 0x81, 0x2c, 0x60, 0x6f, 0x9e, 0x04, + 0x00, 0xa9, 0xad, 0x00, 0x82, 0xad, 0x01, 0x81, + 0xad, 0x0f, 0x85, 0x04, 0x07, 0x88, 0x04, 0x20, + 0x85, 0x04, 0xa7, 0x76, 0x07, 0xa9, 0x8d, 0x15, + 0x99, 0x79, 0x25, 0x9b, 0x19, 0x13, 0x96, 0x27, + 0x08, 0xcd, 0x0f, 0x03, 0xa3, 0x0f, 0x08, 0x80, + 0x0f, 0xc2, 0x3f, 0x09, 0x80, 0x3f, 0x01, 0x98, + 0x8e, 0x06, 0x89, 0x8e, 0x05, 0xb4, 0x16, 0x00, + 0x91, 0x16, 0x07, 0xa6, 0x55, 0x08, 0xdf, 0x87, + 0x00, 0x93, 0x8c, 0x0a, 0x91, 0x47, 0x00, 0xae, + 0x47, 0x3d, 0x86, 0x64, 0x00, 0x80, 0x64, 0x00, + 0x83, 0x64, 0x00, 0x8e, 0x64, 0x00, 0x8a, 0x64, + 0x05, 0xba, 0x49, 0x04, 0x89, 0x49, 0x05, 0x83, + 0x2d, 0x00, 0x87, 0x2d, 0x01, 0x81, 0x2d, 0x01, + 0x95, 0x2d, 0x00, 0x86, 0x2d, 0x00, 0x81, 0x2d, + 0x00, 0x84, 0x2d, 0x00, 0x80, 0x3b, 0x88, 0x2d, + 0x01, 0x81, 0x2d, 0x01, 0x82, 0x2d, 0x01, 0x80, + 0x2d, 0x05, 0x80, 0x2d, 0x04, 0x86, 0x2d, 0x01, + 0x86, 0x2d, 0x02, 0x84, 0x2d, 0x0a, 0x89, 0xa7, + 0x00, 0x80, 0xa7, 0x01, 0x80, 0xa7, 0x00, 0xa5, + 0xa7, 0x00, 0x89, 0xa7, 0x00, 0x80, 0xa7, 0x01, + 0x80, 0xa7, 0x00, 0x83, 0xa7, 0x00, 0x89, 0xa7, + 0x00, 0x81, 0xa7, 0x07, 0x81, 0xa7, 0x1c, 0xdb, + 0x6a, 0x00, 0x84, 0x6a, 0x1d, 0xc7, 0xa2, 0x07, + 0x89, 0xa2, 0x60, 0x45, 0xb5, 0x89, 0x01, 0xa5, + 0x89, 0x21, 0xc4, 0x61, 0x0a, 0x89, 0x61, 0x05, + 0x8c, 0x62, 0x12, 0xb9, 0x9a, 0x05, 0x89, 0x9a, + 0x05, 0x93, 0x65, 0x1b, 0x9a, 0x02, 0x01, 0x8e, + 0x02, 0x03, 0x96, 0x02, 0x60, 0x58, 0xbb, 0x23, + 0x60, 0x03, 0xd2, 0xac, 0x0b, 0x80, 0xac, 0x86, + 0x22, 0x01, 0x80, 0x22, 0x01, 0x87, 0x22, 0x00, + 0x81, 0x22, 0x00, 0x9d, 0x22, 0x00, 0x81, 0x22, + 0x01, 0x8b, 0x22, 0x08, 0x89, 0x22, 0x45, 0x87, + 0x68, 0x01, 0xad, 0x68, 0x01, 0x8a, 0x68, 0x1a, + 0xc7, 0xaf, 0x07, 0xd2, 0x8f, 0x0c, 0x8f, 0x13, + 0xb8, 0x7f, 0x06, 0x89, 0x21, 0x55, 0x87, 0x87, + 0x57, 0xa1, 0x91, 0x0d, 0x89, 0x91, 0x05, 0x88, + 0x0d, 0x00, 0xac, 0x0d, 0x00, 0x8d, 0x0d, 0x09, + 0x9c, 0x0d, 0x02, 0x9f, 0x59, 0x01, 0x95, 0x59, + 0x00, 0x8d, 0x59, 0x48, 0x86, 0x5a, 0x00, 0x81, + 0x5a, 0x00, 0xab, 0x5a, 0x02, 0x80, 0x5a, 0x00, + 0x81, 0x5a, 0x00, 0x88, 0x5a, 0x07, 0x89, 0x5a, + 0x05, 0x85, 0x30, 0x00, 0x81, 0x30, 0x00, 0xa4, + 0x30, 0x00, 0x81, 0x30, 0x00, 0x85, 0x30, 0x06, + 0x89, 0x30, 0x05, 0xab, 0xa5, 0x03, 0x89, 0xa5, + 0x60, 0x95, 0x98, 0x54, 0x06, 0x90, 0x43, 0x00, + 0xa8, 0x43, 0x02, 0x9c, 0x43, 0x54, 0x80, 0x51, + 0x0e, 0xb1, 0x9b, 0x0c, 0x80, 0x9b, 0xe3, 0x39, + 0x1c, 0x60, 0x05, 0xe0, 0x0e, 0x1c, 0x00, 0x84, + 0x1c, 0x0a, 0xe0, 0x63, 0x1c, 0x69, 0xeb, 0xe0, + 0x02, 0x1f, 0x0c, 0xe3, 0xf5, 0x25, 0x09, 0xef, + 0x3a, 0x25, 0x04, 0xe1, 0xe6, 0x03, 0x70, 0x0a, + 0x58, 0xb9, 0x32, 0x66, 0x65, 0xe1, 0xd8, 0x08, + 0x06, 0x9e, 0x63, 0x00, 0x89, 0x63, 0x03, 0x81, + 0x63, 0xce, 0xa3, 0x00, 0x89, 0xa3, 0x05, 0x9d, + 0x09, 0x01, 0x85, 0x09, 0x09, 0xc5, 0x7d, 0x09, + 0x89, 0x7d, 0x00, 0x86, 0x7d, 0x00, 0x94, 0x7d, + 0x04, 0x92, 0x7d, 0x61, 0x4f, 0xb9, 0x4a, 0x60, + 0x65, 0xda, 0x5b, 0x04, 0x98, 0x0c, 0x01, 0x98, + 0x0c, 0x2b, 0xca, 0x60, 0x03, 0xb8, 0x60, 0x06, + 0x90, 0x60, 0x3f, 0x80, 0x9c, 0x80, 0x6c, 0x81, + 0x33, 0x80, 0x48, 0x0a, 0x86, 0x33, 0x08, 0xf0, + 0x0a, 0x9f, 0x9c, 0xe1, 0x75, 0x48, 0x28, 0x80, + 0x48, 0x9e, 0x9c, 0x60, 0x00, 0xe0, 0x12, 0x9c, + 0x70, 0x11, 0x9c, 0x83, 0x41, 0x00, 0x86, 0x41, + 0x00, 0x81, 0x41, 0x00, 0x80, 0x41, 0xe0, 0xbe, + 0x39, 0x82, 0x41, 0x0e, 0x80, 0x39, 0x1c, 0x82, + 0x39, 0x01, 0x80, 0x41, 0x0d, 0x83, 0x41, 0x07, + 0xe1, 0x2b, 0x6c, 0x68, 0xa3, 0xe0, 0x0a, 0x24, + 0x04, 0x8c, 0x24, 0x02, 0x88, 0x24, 0x06, 0x89, + 0x24, 0x01, 0x83, 0x24, 0x83, 0x1a, 0x6e, 0xfb, + 0xe0, 0x9c, 0x1a, 0x02, 0xe1, 0x53, 0x1a, 0x05, + 0x96, 0x1a, 0x0e, 0x90, 0x1a, 0x0e, 0xad, 0x3b, + 0x01, 0x96, 0x3b, 0x08, 0xe0, 0x13, 0x1a, 0x3b, + 0xe0, 0x95, 0x1a, 0x09, 0xa6, 0x1a, 0x01, 0xbd, + 0x1a, 0x82, 0x3b, 0x90, 0x1a, 0x87, 0x3b, 0x81, + 0x1a, 0x86, 0x3b, 0x9d, 0x1a, 0x83, 0x3b, 0xbc, + 0x1a, 0x14, 0xc5, 0x2e, 0x60, 0x19, 0x93, 0x1a, + 0x0b, 0x93, 0x1a, 0x0b, 0xd6, 0x1a, 0x08, 0x98, + 0x1a, 0x60, 0x26, 0xd4, 0x1a, 0x00, 0xc6, 0x1a, + 0x00, 0x81, 0x1a, 0x01, 0x80, 0x1a, 0x01, 0x81, + 0x1a, 0x01, 0x83, 0x1a, 0x00, 0x8b, 0x1a, 0x00, + 0x80, 0x1a, 0x00, 0x86, 0x1a, 0x00, 0xc0, 0x1a, + 0x00, 0x83, 0x1a, 0x01, 0x87, 0x1a, 0x00, 0x86, + 0x1a, 0x00, 0x9b, 0x1a, 0x00, 0x83, 0x1a, 0x00, + 0x84, 0x1a, 0x00, 0x80, 0x1a, 0x02, 0x86, 0x1a, + 0x00, 0xe0, 0xf3, 0x1a, 0x01, 0xe0, 0xc3, 0x1a, + 0x01, 0xb1, 0x1a, 0xe2, 0x2b, 0x8b, 0x0e, 0x84, + 0x8b, 0x00, 0x8e, 0x8b, 0x63, 0xef, 0x9e, 0x4c, + 0x05, 0x85, 0x4c, 0x60, 0x74, 0x86, 0x2a, 0x00, + 0x90, 0x2a, 0x01, 0x86, 0x2a, 0x00, 0x81, 0x2a, + 0x00, 0x84, 0x2a, 0x04, 0xbd, 0x1e, 0x20, 0x80, + 0x1e, 0x60, 0x0f, 0xac, 0x6d, 0x02, 0x8d, 0x6d, + 0x01, 0x89, 0x6d, 0x03, 0x81, 0x6d, 0x60, 0xdf, + 0x9e, 0xa6, 0x10, 0xb9, 0xab, 0x04, 0x80, 0xab, + 0x61, 0x6f, 0xa9, 0x67, 0x60, 0x75, 0xaa, 0x70, + 0x03, 0x80, 0x70, 0x60, 0x5f, 0x9e, 0x99, 0x00, + 0x95, 0x99, 0x07, 0x81, 0x99, 0x60, 0x7f, 0x86, + 0x28, 0x00, 0x83, 0x28, 0x00, 0x81, 0x28, 0x00, + 0x8e, 0x28, 0x00, 0xe0, 0x64, 0x5d, 0x01, 0x8f, + 0x5d, 0x28, 0xcb, 0x01, 0x03, 0x89, 0x01, 0x03, + 0x81, 0x01, 0x62, 0xb0, 0xc3, 0x1a, 0x4b, 0xbc, + 0x1a, 0x60, 0x61, 0x83, 0x04, 0x00, 0x9a, 0x04, + 0x00, 0x81, 0x04, 0x00, 0x80, 0x04, 0x01, 0x80, + 0x04, 0x00, 0x89, 0x04, 0x00, 0x83, 0x04, 0x00, + 0x80, 0x04, 0x00, 0x80, 0x04, 0x05, 0x80, 0x04, + 0x03, 0x80, 0x04, 0x00, 0x80, 0x04, 0x00, 0x80, + 0x04, 0x00, 0x82, 0x04, 0x00, 0x81, 0x04, 0x00, + 0x80, 0x04, 0x01, 0x80, 0x04, 0x00, 0x80, 0x04, + 0x00, 0x80, 0x04, 0x00, 0x80, 0x04, 0x00, 0x80, + 0x04, 0x00, 0x81, 0x04, 0x00, 0x80, 0x04, 0x01, + 0x83, 0x04, 0x00, 0x86, 0x04, 0x00, 0x83, 0x04, + 0x00, 0x83, 0x04, 0x00, 0x80, 0x04, 0x00, 0x89, + 0x04, 0x00, 0x90, 0x04, 0x04, 0x82, 0x04, 0x00, + 0x84, 0x04, 0x00, 0x90, 0x04, 0x33, 0x81, 0x04, + 0x60, 0xad, 0xab, 0x1a, 0x03, 0xe0, 0x03, 0x1a, + 0x0b, 0x8e, 0x1a, 0x01, 0x8e, 0x1a, 0x00, 0x8e, + 0x1a, 0x00, 0xa4, 0x1a, 0x09, 0xe0, 0x4d, 0x1a, + 0x37, 0x99, 0x1a, 0x80, 0x39, 0x81, 0x1a, 0x0c, + 0xab, 0x1a, 0x03, 0x88, 0x1a, 0x06, 0x81, 0x1a, + 0x0d, 0x85, 0x1a, 0x60, 0x39, 0xe3, 0x78, 0x1a, + 0x02, 0x90, 0x1a, 0x02, 0x8c, 0x1a, 0x02, 0xe0, + 0x79, 0x1a, 0x05, 0x8b, 0x1a, 0x03, 0x80, 0x1a, + 0x0e, 0x8b, 0x1a, 0x03, 0xb7, 0x1a, 0x07, 0x89, + 0x1a, 0x05, 0xa7, 0x1a, 0x07, 0x9d, 0x1a, 0x01, + 0x8b, 0x1a, 0x03, 0x81, 0x1a, 0x0d, 0x88, 0x1a, + 0x26, 0xe0, 0xf7, 0x1a, 0x07, 0x8d, 0x1a, 0x01, + 0x8c, 0x1a, 0x02, 0x8a, 0x1a, 0x02, 0xb8, 0x1a, + 0x00, 0x80, 0x1a, 0x03, 0x8f, 0x1a, 0x01, 0x8b, + 0x1a, 0x03, 0x89, 0x1a, 0x06, 0xe0, 0x32, 0x1a, + 0x00, 0xe0, 0x06, 0x1a, 0x63, 0xa4, 0xf0, 0x96, + 0x7f, 0x33, 0x1f, 0xf0, 0x00, 0xbd, 0x33, 0x01, + 0xf0, 0x06, 0x2d, 0x33, 0x01, 0xf0, 0x0c, 0xd0, + 0x33, 0x0e, 0xe2, 0x0d, 0x33, 0x69, 0x41, 0xe1, + 0xbd, 0x33, 0x65, 0x81, 0xf0, 0x02, 0xea, 0x33, + 0x04, 0xf0, 0x10, 0xc9, 0x33, 0x7a, 0xbb, 0x26, + 0x80, 0x1a, 0x1d, 0xdf, 0x1a, 0x60, 0x1f, 0xe0, + 0x8f, 0x3b, +}; + +static const uint8_t unicode_script_ext_table[1278] = { + 0x80, 0x36, 0x00, 0x00, 0x10, 0x06, 0x14, 0x1b, + 0x24, 0x26, 0x29, 0x2a, 0x30, 0x2b, 0x2e, 0x33, + 0x4c, 0x53, 0x55, 0x74, 0x88, 0x81, 0x83, 0x00, + 0x00, 0x07, 0x0b, 0x1e, 0x21, 0x4c, 0x51, 0x9f, + 0xa6, 0x09, 0x00, 0x00, 0x02, 0x0e, 0x4c, 0x00, + 0x00, 0x02, 0x02, 0x0e, 0x4c, 0x00, 0x00, 0x00, + 0x02, 0x4c, 0x51, 0x08, 0x00, 0x00, 0x02, 0x4c, + 0x9f, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x4c, 0x25, + 0x00, 0x00, 0x08, 0x18, 0x1b, 0x1e, 0x2e, 0x4c, + 0x74, 0x91, 0x96, 0x00, 0x08, 0x18, 0x1e, 0x2e, + 0x4c, 0x7b, 0x91, 0x96, 0xa4, 0x00, 0x04, 0x18, + 0x1e, 0x4c, 0xa1, 0x00, 0x05, 0x2a, 0x4c, 0x91, + 0x93, 0x9f, 0x00, 0x0b, 0x15, 0x18, 0x1b, 0x1e, + 0x2b, 0x2e, 0x4c, 0x7b, 0x93, 0xa1, 0xa4, 0x00, + 0x06, 0x1b, 0x26, 0x2a, 0x2b, 0x41, 0x4c, 0x00, + 0x05, 0x1e, 0x2e, 0x4c, 0x74, 0xa1, 0x00, 0x09, + 0x1b, 0x24, 0x38, 0x4c, 0x74, 0x93, 0x96, 0xa1, + 0xa4, 0x00, 0x0b, 0x05, 0x1e, 0x24, 0x2b, 0x2e, + 0x38, 0x4c, 0x74, 0x93, 0x96, 0xa1, 0x00, 0x02, + 0x4c, 0xa1, 0x00, 0x03, 0x24, 0x4c, 0x93, 0x00, + 0x04, 0x18, 0x1e, 0x4c, 0x7b, 0x00, 0x03, 0x18, + 0x4c, 0x96, 0x00, 0x02, 0x4c, 0x91, 0x00, 0x02, + 0x28, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x4c, 0x91, + 0x00, 0x03, 0x1e, 0x4c, 0xa4, 0x00, 0x00, 0x00, + 0x04, 0x2e, 0x4c, 0x74, 0xa4, 0x0e, 0x00, 0x00, + 0x06, 0x18, 0x24, 0x41, 0x4c, 0x93, 0xa1, 0x00, + 0x04, 0x18, 0x24, 0x4c, 0x93, 0x00, 0x02, 0x4c, + 0x93, 0x06, 0x00, 0x00, 0x03, 0x4c, 0x91, 0x93, + 0x00, 0x02, 0x4c, 0x93, 0x00, 0x00, 0x00, 0x03, + 0x18, 0x4c, 0x93, 0x00, 0x07, 0x15, 0x18, 0x2b, + 0x4c, 0x91, 0x93, 0x9f, 0x0f, 0x00, 0x00, 0x01, + 0x2e, 0x01, 0x00, 0x00, 0x01, 0x2e, 0x11, 0x00, + 0x00, 0x02, 0x4c, 0x7b, 0x04, 0x00, 0x00, 0x03, + 0x15, 0x4c, 0xa4, 0x03, 0x00, 0x0c, 0x01, 0x4c, + 0x03, 0x00, 0x01, 0x02, 0x1b, 0x2e, 0x80, 0x8c, + 0x00, 0x00, 0x02, 0x1e, 0x74, 0x00, 0x02, 0x1e, + 0x2a, 0x01, 0x02, 0x1e, 0x4c, 0x00, 0x02, 0x1e, + 0x2a, 0x80, 0x80, 0x00, 0x00, 0x03, 0x05, 0x29, + 0x2a, 0x80, 0x01, 0x00, 0x00, 0x07, 0x04, 0x2c, + 0x6b, 0x35, 0x93, 0x9e, 0xad, 0x0d, 0x00, 0x00, + 0x07, 0x04, 0x2c, 0x6b, 0x35, 0x93, 0x9e, 0xad, + 0x00, 0x03, 0x04, 0x93, 0x9e, 0x01, 0x00, 0x00, + 0x08, 0x01, 0x04, 0x2c, 0x6b, 0x35, 0x93, 0x9e, + 0xad, 0x1f, 0x00, 0x00, 0x09, 0x01, 0x04, 0x57, + 0x58, 0x79, 0x82, 0x35, 0x8d, 0x93, 0x09, 0x00, + 0x0a, 0x02, 0x04, 0x93, 0x09, 0x00, 0x09, 0x03, + 0x04, 0x9e, 0xad, 0x05, 0x00, 0x00, 0x02, 0x04, + 0x93, 0x62, 0x00, 0x00, 0x02, 0x04, 0x35, 0x81, + 0xfb, 0x00, 0x00, 0x0f, 0x0b, 0x21, 0x2d, 0x2f, + 0x31, 0x40, 0x4c, 0x56, 0x68, 0x6a, 0x7a, 0x87, + 0x9b, 0x9d, 0xa2, 0x00, 0x0d, 0x0b, 0x21, 0x2d, + 0x2f, 0x31, 0x40, 0x4c, 0x56, 0x6a, 0x7a, 0x9b, + 0x9d, 0xa2, 0x10, 0x00, 0x00, 0x15, 0x0b, 0x21, + 0x23, 0x30, 0x5a, 0x2d, 0x2f, 0x31, 0x40, 0x55, + 0x56, 0x68, 0x70, 0x7a, 0x49, 0x8c, 0x92, 0x9a, + 0x9b, 0x9d, 0xa2, 0x00, 0x17, 0x0b, 0x21, 0x23, + 0x30, 0x5a, 0x2d, 0x2f, 0x32, 0x31, 0x40, 0x4e, + 0x55, 0x56, 0x68, 0x70, 0x7a, 0x49, 0x8c, 0x92, + 0x9a, 0x9b, 0x9d, 0xa2, 0x09, 0x04, 0x21, 0x23, + 0x3f, 0x55, 0x75, 0x00, 0x09, 0x03, 0x0b, 0x16, + 0x92, 0x75, 0x00, 0x09, 0x02, 0x31, 0x64, 0x75, + 0x00, 0x09, 0x02, 0x2f, 0x47, 0x80, 0x75, 0x00, + 0x0d, 0x02, 0x2d, 0x9b, 0x80, 0x71, 0x00, 0x09, + 0x03, 0x40, 0x68, 0xa7, 0x82, 0xcf, 0x00, 0x09, + 0x03, 0x16, 0x65, 0x96, 0x80, 0x30, 0x00, 0x00, + 0x03, 0x29, 0x2a, 0x4c, 0x85, 0x6e, 0x00, 0x02, + 0x01, 0x84, 0x46, 0x00, 0x01, 0x04, 0x12, 0x36, + 0x95, 0x94, 0x80, 0x4a, 0x00, 0x01, 0x02, 0x62, + 0x80, 0x00, 0x00, 0x00, 0x02, 0x62, 0x80, 0x84, + 0x49, 0x00, 0x00, 0x04, 0x0b, 0x21, 0x2d, 0x40, + 0x00, 0x01, 0x21, 0x00, 0x04, 0x0b, 0x21, 0x2d, + 0x40, 0x00, 0x03, 0x21, 0x2d, 0x40, 0x00, 0x01, + 0x21, 0x00, 0x05, 0x0b, 0x21, 0x6a, 0x9d, 0xa2, + 0x00, 0x03, 0x0b, 0x21, 0x9d, 0x00, 0x03, 0x21, + 0x6a, 0x87, 0x00, 0x04, 0x0b, 0x21, 0x6a, 0x9d, + 0x00, 0x02, 0x21, 0x87, 0x00, 0x06, 0x21, 0x40, + 0x56, 0x7a, 0x9b, 0x9d, 0x00, 0x01, 0x21, 0x01, + 0x02, 0x21, 0x87, 0x01, 0x01, 0x21, 0x00, 0x02, + 0x21, 0x87, 0x00, 0x02, 0x0b, 0x21, 0x00, 0x03, + 0x21, 0x6a, 0xa2, 0x05, 0x01, 0x21, 0x00, 0x03, + 0x21, 0x68, 0x6a, 0x00, 0x03, 0x0b, 0x21, 0x87, + 0x00, 0x02, 0x21, 0x6a, 0x00, 0x01, 0x21, 0x00, + 0x04, 0x0b, 0x21, 0x6a, 0x87, 0x03, 0x01, 0x21, + 0x00, 0x0b, 0x0b, 0x21, 0x2d, 0x40, 0x56, 0x68, + 0x7a, 0x8c, 0x9d, 0xa2, 0xa7, 0x00, 0x02, 0x21, + 0x2d, 0x00, 0x04, 0x21, 0x2d, 0x40, 0xa7, 0x01, + 0x02, 0x0b, 0x21, 0x00, 0x01, 0x0b, 0x01, 0x02, + 0x21, 0x2d, 0x00, 0x01, 0x68, 0x80, 0x44, 0x00, + 0x01, 0x01, 0x2e, 0x35, 0x00, 0x00, 0x03, 0x1e, + 0x4c, 0x93, 0x00, 0x00, 0x00, 0x01, 0x93, 0x81, + 0xb3, 0x00, 0x00, 0x03, 0x4c, 0x62, 0x80, 0x1e, + 0x00, 0x00, 0x02, 0x01, 0x04, 0x09, 0x00, 0x00, + 0x06, 0x14, 0x29, 0x2a, 0x71, 0x52, 0x78, 0x01, + 0x00, 0x00, 0x04, 0x14, 0x2e, 0x71, 0x5f, 0x80, + 0x11, 0x00, 0x00, 0x03, 0x21, 0x2d, 0x4c, 0x8c, + 0xa5, 0x00, 0x00, 0x02, 0x1b, 0x4c, 0x17, 0x00, + 0x00, 0x02, 0x06, 0x78, 0x00, 0x07, 0x06, 0x14, + 0x29, 0x71, 0x3f, 0x53, 0x85, 0x09, 0x00, 0x00, + 0x01, 0x24, 0x03, 0x00, 0x00, 0x03, 0x01, 0x04, + 0x71, 0x00, 0x00, 0x00, 0x02, 0x1e, 0x2a, 0x81, + 0x2b, 0x00, 0x0f, 0x02, 0x33, 0x9c, 0x00, 0x00, + 0x00, 0x07, 0x0e, 0x34, 0x33, 0x39, 0x41, 0x62, + 0xae, 0x00, 0x08, 0x0e, 0x34, 0x33, 0x39, 0x41, + 0x62, 0x80, 0xae, 0x00, 0x05, 0x0e, 0x34, 0x33, + 0x39, 0x41, 0x01, 0x00, 0x00, 0x01, 0x33, 0x00, + 0x00, 0x01, 0x08, 0x0e, 0x34, 0x33, 0x39, 0x41, + 0x62, 0xa0, 0xae, 0x01, 0x09, 0x0e, 0x34, 0x33, + 0x39, 0x41, 0x51, 0x62, 0xa0, 0xae, 0x05, 0x06, + 0x0e, 0x34, 0x33, 0x39, 0x41, 0xae, 0x00, 0x00, + 0x00, 0x05, 0x0e, 0x34, 0x33, 0x39, 0x41, 0x07, + 0x06, 0x0e, 0x34, 0x33, 0x39, 0x41, 0xae, 0x03, + 0x05, 0x0e, 0x34, 0x33, 0x39, 0x41, 0x09, 0x00, + 0x03, 0x02, 0x0e, 0x33, 0x01, 0x00, 0x00, 0x05, + 0x0e, 0x34, 0x33, 0x39, 0x41, 0x04, 0x02, 0x39, + 0x41, 0x00, 0x00, 0x00, 0x05, 0x0e, 0x34, 0x33, + 0x39, 0x41, 0x03, 0x00, 0x01, 0x03, 0x33, 0x39, + 0x41, 0x01, 0x01, 0x33, 0x58, 0x00, 0x03, 0x02, + 0x39, 0x41, 0x02, 0x00, 0x00, 0x02, 0x39, 0x41, + 0x59, 0x00, 0x00, 0x06, 0x0e, 0x34, 0x33, 0x39, + 0x41, 0xae, 0x00, 0x02, 0x39, 0x41, 0x80, 0x12, + 0x00, 0x0f, 0x01, 0x33, 0x1f, 0x00, 0x25, 0x01, + 0x33, 0x08, 0x00, 0x00, 0x02, 0x33, 0x9c, 0x2f, + 0x00, 0x27, 0x01, 0x33, 0x37, 0x00, 0x30, 0x01, + 0x33, 0x0e, 0x00, 0x0b, 0x01, 0x33, 0x32, 0x00, + 0x00, 0x01, 0x33, 0x57, 0x00, 0x18, 0x01, 0x33, + 0x09, 0x00, 0x04, 0x01, 0x33, 0x5f, 0x00, 0x1e, + 0x01, 0x33, 0xc0, 0x31, 0xef, 0x00, 0x00, 0x02, + 0x1e, 0x2a, 0x80, 0x0f, 0x00, 0x07, 0x02, 0x33, + 0x4c, 0x80, 0xa7, 0x00, 0x02, 0x10, 0x21, 0x23, + 0x2f, 0x31, 0x47, 0x40, 0x3f, 0x55, 0x56, 0x61, + 0x68, 0x87, 0x49, 0x9a, 0xa2, 0xa7, 0x02, 0x0f, + 0x21, 0x23, 0x2f, 0x31, 0x47, 0x40, 0x3f, 0x55, + 0x61, 0x68, 0x87, 0x49, 0x9a, 0xa2, 0xa7, 0x01, + 0x0b, 0x21, 0x23, 0x2f, 0x31, 0x47, 0x3f, 0x55, + 0x61, 0x49, 0x9a, 0xa2, 0x00, 0x0c, 0x21, 0x23, + 0x2f, 0x31, 0x47, 0x3f, 0x55, 0x61, 0x87, 0x49, + 0x9a, 0xa2, 0x00, 0x0b, 0x21, 0x23, 0x2f, 0x31, + 0x47, 0x3f, 0x55, 0x61, 0x49, 0x9a, 0xa2, 0x80, + 0x36, 0x00, 0x00, 0x03, 0x0b, 0x21, 0xa7, 0x00, + 0x00, 0x00, 0x02, 0x21, 0x9b, 0x39, 0x00, 0x00, + 0x03, 0x44, 0x4c, 0x65, 0x80, 0x1f, 0x00, 0x00, + 0x02, 0x11, 0x3e, 0xc0, 0x12, 0xed, 0x00, 0x01, + 0x02, 0x04, 0x6b, 0x80, 0x31, 0x00, 0x00, 0x02, + 0x04, 0x9e, 0x09, 0x00, 0x00, 0x02, 0x04, 0x9e, + 0x46, 0x00, 0x01, 0x05, 0x0e, 0x34, 0x33, 0x39, + 0x41, 0x80, 0x99, 0x00, 0x04, 0x06, 0x0e, 0x34, + 0x33, 0x39, 0x41, 0xae, 0x09, 0x00, 0x00, 0x02, + 0x39, 0x41, 0x2c, 0x00, 0x01, 0x02, 0x39, 0x41, + 0x80, 0xdf, 0x00, 0x01, 0x03, 0x1f, 0x1d, 0x50, + 0x00, 0x02, 0x1d, 0x50, 0x03, 0x00, 0x2c, 0x03, + 0x1d, 0x4f, 0x50, 0x02, 0x00, 0x08, 0x02, 0x1d, + 0x50, 0x81, 0x1f, 0x00, 0x1b, 0x02, 0x04, 0x1b, + 0x87, 0x75, 0x00, 0x00, 0x02, 0x58, 0x79, 0x87, + 0x8d, 0x00, 0x00, 0x02, 0x2d, 0x9b, 0x00, 0x00, + 0x00, 0x02, 0x2d, 0x9b, 0x36, 0x00, 0x01, 0x02, + 0x2d, 0x9b, 0x8c, 0x12, 0x00, 0x01, 0x02, 0x2d, + 0x9b, 0x00, 0x00, 0x00, 0x02, 0x2d, 0x9b, 0xc0, + 0x5c, 0x4b, 0x00, 0x03, 0x01, 0x24, 0x96, 0x3b, + 0x00, 0x11, 0x01, 0x33, 0x9e, 0x5d, 0x00, 0x01, + 0x01, 0x33, 0xce, 0xcd, 0x2d, 0x00, +}; + +static const uint8_t unicode_prop_Hyphen_table[28] = { + 0xac, 0x80, 0xfe, 0x80, 0x44, 0xdb, 0x80, 0x52, + 0x7a, 0x80, 0x48, 0x08, 0x81, 0x4e, 0x04, 0x80, + 0x42, 0xe2, 0x80, 0x60, 0xcd, 0x66, 0x80, 0x40, + 0xa8, 0x80, 0xd6, 0x80, +}; + +static const uint8_t unicode_prop_Other_Math_table[200] = { + 0xdd, 0x80, 0x43, 0x70, 0x11, 0x80, 0x99, 0x09, + 0x81, 0x5c, 0x1f, 0x80, 0x9a, 0x82, 0x8a, 0x80, + 0x9f, 0x83, 0x97, 0x81, 0x8d, 0x81, 0xc0, 0x8c, + 0x18, 0x11, 0x1c, 0x91, 0x03, 0x01, 0x89, 0x00, + 0x14, 0x28, 0x11, 0x09, 0x02, 0x05, 0x13, 0x24, + 0xca, 0x21, 0x18, 0x08, 0x08, 0x00, 0x21, 0x0b, + 0x0b, 0x91, 0x09, 0x00, 0x06, 0x00, 0x29, 0x41, + 0x21, 0x83, 0x40, 0xa7, 0x08, 0x80, 0x97, 0x80, + 0x90, 0x80, 0x41, 0xbc, 0x81, 0x8b, 0x88, 0x24, + 0x21, 0x09, 0x14, 0x8d, 0x00, 0x01, 0x85, 0x97, + 0x81, 0xb8, 0x00, 0x80, 0x9c, 0x83, 0x88, 0x81, + 0x41, 0x55, 0x81, 0x9e, 0x89, 0x41, 0x92, 0x95, + 0xbe, 0x83, 0x9f, 0x81, 0x60, 0xd4, 0x62, 0x00, + 0x03, 0x80, 0x40, 0xd2, 0x00, 0x80, 0x60, 0xd4, + 0xc0, 0xd4, 0x80, 0xc6, 0x01, 0x08, 0x09, 0x0b, + 0x80, 0x8b, 0x00, 0x06, 0x80, 0xc0, 0x03, 0x0f, + 0x06, 0x80, 0x9b, 0x03, 0x04, 0x00, 0x16, 0x80, + 0x41, 0x53, 0x81, 0x98, 0x80, 0x98, 0x80, 0x9e, + 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, 0x9e, + 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x07, 0x81, + 0xb1, 0x55, 0xff, 0x18, 0x9a, 0x01, 0x00, 0x08, + 0x80, 0x89, 0x03, 0x00, 0x00, 0x28, 0x18, 0x00, + 0x00, 0x02, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x0b, 0x06, 0x03, 0x03, 0x00, + 0x80, 0x89, 0x80, 0x90, 0x22, 0x04, 0x80, 0x90, +}; + +static const uint8_t unicode_prop_Other_Alphabetic_table[452] = { + 0x43, 0x44, 0x80, 0x9c, 0x8c, 0x42, 0x3f, 0x8d, + 0x00, 0x01, 0x01, 0x00, 0xc7, 0x8a, 0xaf, 0x8c, + 0x06, 0x8f, 0x80, 0xe4, 0x33, 0x19, 0x0b, 0x80, + 0xa2, 0x80, 0x9d, 0x8f, 0xe5, 0x8a, 0xe4, 0x0a, + 0x88, 0x02, 0x03, 0xe9, 0x80, 0xbb, 0x8b, 0x16, + 0x85, 0x93, 0xb5, 0x09, 0x8e, 0x01, 0x22, 0x89, + 0x81, 0x9c, 0x82, 0xb9, 0x31, 0x09, 0x81, 0x89, + 0x80, 0x89, 0x81, 0x9c, 0x82, 0xb9, 0x23, 0x09, + 0x0b, 0x80, 0x9d, 0x0a, 0x80, 0x8a, 0x82, 0xb9, + 0x38, 0x10, 0x81, 0x94, 0x81, 0x95, 0x13, 0x82, + 0xb9, 0x31, 0x09, 0x81, 0x88, 0x81, 0x89, 0x81, + 0x9d, 0x80, 0xba, 0x22, 0x10, 0x82, 0x89, 0x80, + 0xa7, 0x84, 0xb8, 0x30, 0x10, 0x17, 0x81, 0x8a, + 0x81, 0x9c, 0x82, 0xb9, 0x30, 0x10, 0x17, 0x81, + 0x8a, 0x81, 0x8e, 0x80, 0x8b, 0x83, 0xb9, 0x30, + 0x10, 0x82, 0x89, 0x80, 0x89, 0x81, 0x9c, 0x82, + 0xca, 0x28, 0x00, 0x87, 0x91, 0x81, 0xbc, 0x01, + 0x86, 0x91, 0x80, 0xe2, 0x01, 0x28, 0x81, 0x8f, + 0x80, 0x40, 0xa2, 0x92, 0x88, 0x8a, 0x80, 0xa3, + 0xed, 0x8b, 0x00, 0x0b, 0x96, 0x1b, 0x10, 0x11, + 0x32, 0x83, 0x8c, 0x8b, 0x00, 0x89, 0x83, 0x46, + 0x73, 0x81, 0x9d, 0x81, 0x9d, 0x81, 0x9d, 0x81, + 0xc1, 0x92, 0x40, 0xbb, 0x81, 0xa1, 0x80, 0xf5, + 0x8b, 0x83, 0x88, 0x40, 0xdd, 0x84, 0xb8, 0x89, + 0x81, 0x93, 0xc9, 0x81, 0x8a, 0x82, 0xb0, 0x84, + 0xaf, 0x8e, 0xbb, 0x82, 0x9d, 0x88, 0x09, 0xb8, + 0x8a, 0xb1, 0x92, 0x41, 0x9b, 0xa1, 0x46, 0xc0, + 0xb3, 0x48, 0xf5, 0x9f, 0x60, 0x78, 0x73, 0x87, + 0xa1, 0x81, 0x41, 0x61, 0x07, 0x80, 0x96, 0x84, + 0xd7, 0x81, 0xb1, 0x8f, 0x00, 0xb8, 0x80, 0xa5, + 0x84, 0x9b, 0x8b, 0xac, 0x83, 0xaf, 0x8b, 0xa4, + 0x80, 0xc2, 0x8d, 0x8b, 0x07, 0x81, 0xac, 0x82, + 0xb1, 0x00, 0x11, 0x0c, 0x80, 0xab, 0x24, 0x80, + 0x40, 0xec, 0x87, 0x60, 0x4f, 0x32, 0x80, 0x48, + 0x56, 0x84, 0x46, 0x85, 0x10, 0x0c, 0x83, 0x43, + 0x13, 0x83, 0xc0, 0x80, 0x41, 0x40, 0x81, 0xcc, + 0x82, 0x41, 0x02, 0x82, 0xb4, 0x8d, 0xac, 0x81, + 0x8a, 0x82, 0xac, 0x88, 0x88, 0x80, 0xbc, 0x82, + 0xa3, 0x8b, 0x91, 0x81, 0xb8, 0x82, 0xaf, 0x8c, + 0x8d, 0x81, 0xdb, 0x88, 0x08, 0x28, 0x08, 0x40, + 0x9c, 0x89, 0x96, 0x83, 0xb9, 0x31, 0x09, 0x81, + 0x89, 0x80, 0x89, 0x81, 0xd3, 0x88, 0x00, 0x08, + 0x03, 0x01, 0xe6, 0x8c, 0x02, 0xe9, 0x91, 0x40, + 0xec, 0x31, 0x86, 0x9c, 0x81, 0xd1, 0x8e, 0x00, + 0xe9, 0x8a, 0xe6, 0x8d, 0x41, 0x00, 0x8c, 0x40, + 0xf6, 0x28, 0x09, 0x0a, 0x00, 0x80, 0x40, 0x8d, + 0x31, 0x2b, 0x80, 0x9b, 0x89, 0xa9, 0x20, 0x83, + 0x91, 0x8a, 0xad, 0x8d, 0x40, 0xc7, 0x87, 0x40, + 0xc6, 0x38, 0x86, 0xd2, 0x95, 0x80, 0x8d, 0xf9, + 0x2a, 0x00, 0x08, 0x10, 0x02, 0x80, 0xc1, 0x20, + 0x08, 0x83, 0x41, 0x5b, 0x83, 0x88, 0x08, 0x80, + 0xaf, 0x32, 0x82, 0x60, 0x41, 0xdc, 0x90, 0x4e, + 0x1f, 0x00, 0xb6, 0x33, 0xdc, 0x81, 0x60, 0x4c, + 0xab, 0x80, 0x60, 0x23, 0x60, 0x30, 0x90, 0x0e, + 0x01, 0x04, 0xe3, 0x80, 0x46, 0x52, 0x01, 0x06, + 0x0c, 0x80, 0x42, 0x50, 0x80, 0x47, 0xe7, 0x99, + 0x85, 0x99, 0x85, 0x99, +}; + +static const uint8_t unicode_prop_Other_Lowercase_table[68] = { + 0x40, 0xa9, 0x80, 0x8e, 0x80, 0x41, 0xf4, 0x88, + 0x31, 0x9d, 0x84, 0xdf, 0x80, 0xb3, 0x80, 0x4d, + 0x80, 0x80, 0x4c, 0x2e, 0xbe, 0x8c, 0x80, 0xa1, + 0xa4, 0x42, 0xb0, 0x80, 0x8c, 0x80, 0x8f, 0x8c, + 0x40, 0xd2, 0x8f, 0x43, 0x4f, 0x99, 0x47, 0x91, + 0x81, 0x60, 0x7a, 0x1d, 0x81, 0x40, 0xd1, 0x80, + 0xff, 0x1a, 0x81, 0x43, 0x61, 0x83, 0x88, 0x80, + 0x60, 0x5c, 0x15, 0x01, 0x10, 0xa9, 0x80, 0x88, + 0x60, 0xd8, 0x74, 0xbd, +}; + +static const uint8_t unicode_prop_Other_Uppercase_table[15] = { + 0x60, 0x21, 0x5f, 0x8f, 0x43, 0x45, 0x99, 0x61, + 0xcc, 0x5f, 0x99, 0x85, 0x99, 0x85, 0x99, +}; + +static const uint8_t unicode_prop_Other_Grapheme_Extend_table[112] = { + 0x49, 0xbd, 0x80, 0x97, 0x80, 0x41, 0x65, 0x80, + 0x97, 0x80, 0xe5, 0x80, 0x97, 0x80, 0x40, 0xe7, + 0x00, 0x03, 0x08, 0x81, 0x88, 0x81, 0xe6, 0x80, + 0x97, 0x80, 0xf6, 0x80, 0x8e, 0x80, 0x49, 0x34, + 0x80, 0x9d, 0x80, 0x43, 0xff, 0x04, 0x00, 0x04, + 0x81, 0xe4, 0x80, 0xc6, 0x81, 0x44, 0x17, 0x80, + 0x50, 0x20, 0x81, 0x60, 0x79, 0x22, 0x80, 0xeb, + 0x80, 0x60, 0x55, 0xdc, 0x81, 0x52, 0x1f, 0x80, + 0xf3, 0x80, 0x41, 0x07, 0x80, 0x8d, 0x80, 0x88, + 0x80, 0xdf, 0x80, 0x88, 0x01, 0x00, 0x14, 0x80, + 0x40, 0xdf, 0x80, 0x8b, 0x80, 0x40, 0xf0, 0x80, + 0x41, 0x05, 0x80, 0x42, 0x78, 0x80, 0x8b, 0x80, + 0x46, 0x02, 0x80, 0x60, 0x50, 0xad, 0x81, 0x60, + 0x61, 0x72, 0x0d, 0x85, 0x6c, 0x2e, 0xac, 0xdf, +}; + +static const uint8_t unicode_prop_Other_Default_Ignorable_Code_Point_table[32] = { + 0x43, 0x4e, 0x80, 0x4e, 0x0e, 0x81, 0x46, 0x52, + 0x81, 0x48, 0xae, 0x80, 0x50, 0xfd, 0x80, 0x60, + 0xce, 0x3a, 0x80, 0xce, 0x88, 0x6d, 0x00, 0x06, + 0x00, 0x9d, 0xdf, 0xff, 0x40, 0xef, 0x4e, 0x0f, +}; + +static const uint8_t unicode_prop_Other_ID_Start_table[11] = { + 0x58, 0x84, 0x81, 0x48, 0x90, 0x80, 0x94, 0x80, + 0x4f, 0x6b, 0x81, +}; + +static const uint8_t unicode_prop_Other_ID_Continue_table[22] = { + 0x40, 0xb6, 0x80, 0x42, 0xce, 0x80, 0x4f, 0xe0, + 0x88, 0x46, 0x67, 0x80, 0x46, 0x30, 0x81, 0x50, + 0xec, 0x80, 0x60, 0xce, 0x68, 0x80, +}; + +static const uint8_t unicode_prop_Prepended_Concatenation_Mark_table[19] = { + 0x45, 0xff, 0x85, 0x40, 0xd6, 0x80, 0xb0, 0x80, + 0x41, 0x7f, 0x81, 0xcf, 0x80, 0x61, 0x07, 0xd9, + 0x80, 0x8e, 0x80, +}; + +static const uint8_t unicode_prop_XID_Start1_table[31] = { + 0x43, 0x79, 0x80, 0x4a, 0xb7, 0x80, 0xfe, 0x80, + 0x60, 0x21, 0xe6, 0x81, 0x60, 0xcb, 0xc0, 0x85, + 0x41, 0x95, 0x81, 0xf3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x41, 0x1e, 0x81, +}; + +static const uint8_t unicode_prop_XID_Continue1_table[23] = { + 0x43, 0x79, 0x80, 0x60, 0x2d, 0x1f, 0x81, 0x60, + 0xcb, 0xc0, 0x85, 0x41, 0x95, 0x81, 0xf3, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, +}; + +static const uint8_t unicode_prop_Changes_When_Titlecased1_table[22] = { + 0x41, 0xc3, 0x08, 0x08, 0x81, 0xa4, 0x81, 0x4e, + 0xdc, 0xaa, 0x0a, 0x4e, 0x87, 0x3f, 0x3f, 0x87, + 0x8b, 0x80, 0x8e, 0x80, 0xae, 0x80, +}; + +static const uint8_t unicode_prop_Changes_When_Casefolded1_table[29] = { + 0x41, 0xef, 0x80, 0x41, 0x9e, 0x80, 0x9e, 0x80, + 0x5a, 0xe4, 0x83, 0x40, 0xb5, 0x00, 0x00, 0x00, + 0x80, 0xde, 0x06, 0x06, 0x80, 0x8a, 0x09, 0x81, + 0x89, 0x10, 0x81, 0x8d, 0x80, +}; + +static const uint8_t unicode_prop_Changes_When_NFKC_Casefolded1_table[449] = { + 0x40, 0x9f, 0x06, 0x00, 0x01, 0x00, 0x01, 0x12, + 0x10, 0x82, 0xf3, 0x80, 0x8b, 0x80, 0x40, 0x84, + 0x01, 0x01, 0x80, 0xa2, 0x01, 0x80, 0x40, 0xbb, + 0x88, 0x9e, 0x29, 0x84, 0xda, 0x08, 0x81, 0x89, + 0x80, 0xa3, 0x04, 0x02, 0x04, 0x08, 0x07, 0x80, + 0x9e, 0x80, 0xa0, 0x82, 0x9c, 0x80, 0x42, 0x28, + 0x80, 0xd7, 0x83, 0x42, 0xde, 0x87, 0xfb, 0x08, + 0x80, 0xd2, 0x01, 0x80, 0xa1, 0x11, 0x80, 0x40, + 0xfc, 0x81, 0x42, 0xd4, 0x80, 0xfe, 0x80, 0xa7, + 0x81, 0xad, 0x80, 0xb5, 0x80, 0x88, 0x03, 0x03, + 0x03, 0x80, 0x8b, 0x80, 0x88, 0x00, 0x26, 0x80, + 0x90, 0x80, 0x88, 0x03, 0x03, 0x03, 0x80, 0x8b, + 0x80, 0x41, 0x41, 0x80, 0xe1, 0x81, 0x46, 0x52, + 0x81, 0xd4, 0x84, 0x45, 0x1b, 0x10, 0x8a, 0x80, + 0x91, 0x80, 0x9b, 0x8c, 0x80, 0xa1, 0xa4, 0x40, + 0xd5, 0x83, 0x40, 0xb5, 0x00, 0x00, 0x00, 0x80, + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xb7, 0x05, 0x00, 0x13, 0x05, 0x11, 0x02, 0x0c, + 0x11, 0x00, 0x00, 0x0c, 0x15, 0x05, 0x08, 0x8f, + 0x00, 0x20, 0x8b, 0x12, 0x2a, 0x08, 0x0b, 0x00, + 0x07, 0x82, 0x8c, 0x06, 0x92, 0x81, 0x9a, 0x80, + 0x8c, 0x8a, 0x80, 0xd6, 0x18, 0x10, 0x8a, 0x01, + 0x0c, 0x0a, 0x00, 0x10, 0x11, 0x02, 0x06, 0x05, + 0x1c, 0x85, 0x8f, 0x8f, 0x8f, 0x88, 0x80, 0x40, + 0xa1, 0x08, 0x81, 0x40, 0xf7, 0x81, 0x41, 0x34, + 0xd5, 0x99, 0x9a, 0x45, 0x20, 0x80, 0xe6, 0x82, + 0xe4, 0x80, 0x41, 0x9e, 0x81, 0x40, 0xf0, 0x80, + 0x41, 0x2e, 0x80, 0xd2, 0x80, 0x8b, 0x40, 0xd5, + 0xa9, 0x80, 0xb4, 0x00, 0x82, 0xdf, 0x09, 0x80, + 0xde, 0x80, 0xb0, 0xdd, 0x82, 0x8d, 0xdf, 0x9e, + 0x80, 0xa7, 0x87, 0xae, 0x80, 0x41, 0x7f, 0x60, + 0x72, 0x9b, 0x81, 0x40, 0xd1, 0x80, 0xff, 0x1a, + 0x81, 0x43, 0x61, 0x83, 0x88, 0x80, 0x60, 0x4d, + 0x95, 0x41, 0x0d, 0x08, 0x00, 0x81, 0x89, 0x00, + 0x00, 0x09, 0x82, 0xc3, 0x81, 0xe9, 0xc2, 0x00, + 0x97, 0x04, 0x00, 0x01, 0x01, 0x80, 0xeb, 0xa0, + 0x41, 0x6a, 0x91, 0xbf, 0x81, 0xb5, 0xa7, 0x8c, + 0x82, 0x99, 0x95, 0x94, 0x81, 0x8b, 0x80, 0x92, + 0x03, 0x1a, 0x00, 0x80, 0x40, 0x86, 0x08, 0x80, + 0x9f, 0x99, 0x40, 0x83, 0x15, 0x0d, 0x0d, 0x0a, + 0x16, 0x06, 0x80, 0x88, 0x47, 0x87, 0x20, 0xa9, + 0x80, 0x88, 0x60, 0xb4, 0xe4, 0x83, 0x50, 0x31, + 0xa3, 0x44, 0x63, 0x86, 0x8d, 0x87, 0xbf, 0x85, + 0x42, 0x3e, 0xd4, 0x80, 0xc6, 0x01, 0x08, 0x09, + 0x0b, 0x80, 0x8b, 0x00, 0x06, 0x80, 0xc0, 0x03, + 0x0f, 0x06, 0x80, 0x9b, 0x03, 0x04, 0x00, 0x16, + 0x80, 0x41, 0x53, 0x81, 0x41, 0x23, 0x81, 0xb1, + 0x48, 0x2f, 0xbd, 0x4d, 0x91, 0x18, 0x9a, 0x01, + 0x00, 0x08, 0x80, 0x89, 0x03, 0x00, 0x00, 0x28, + 0x18, 0x00, 0x00, 0x02, 0x01, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x06, 0x03, + 0x03, 0x00, 0x80, 0x89, 0x80, 0x90, 0x22, 0x04, + 0x80, 0x90, 0x42, 0x43, 0x8a, 0x84, 0x9e, 0x80, + 0x9f, 0x99, 0x82, 0xa2, 0x80, 0xee, 0x82, 0x8c, + 0xab, 0x83, 0x88, 0x31, 0x49, 0x9d, 0x89, 0x60, + 0xfc, 0x05, 0x42, 0x1d, 0x6b, 0x05, 0xe1, 0x4f, + 0xff, +}; + +static const uint8_t unicode_prop_Basic_Emoji1_table[144] = { + 0x60, 0x23, 0x19, 0x81, 0x40, 0xcc, 0x1a, 0x01, + 0x80, 0x42, 0x08, 0x81, 0x94, 0x81, 0xb1, 0x8b, + 0xaa, 0x80, 0x92, 0x80, 0x8c, 0x07, 0x81, 0x90, + 0x0c, 0x0f, 0x04, 0x80, 0x94, 0x06, 0x08, 0x03, + 0x01, 0x06, 0x03, 0x81, 0x9b, 0x80, 0xa2, 0x00, + 0x03, 0x10, 0x80, 0xbc, 0x82, 0x97, 0x80, 0x8d, + 0x80, 0x43, 0x5a, 0x81, 0xb2, 0x03, 0x80, 0x61, + 0xc4, 0xad, 0x80, 0x40, 0xc9, 0x80, 0x40, 0xbd, + 0x01, 0x89, 0xe5, 0x80, 0x97, 0x80, 0x93, 0x01, + 0x20, 0x82, 0x94, 0x81, 0x40, 0xad, 0xa0, 0x8b, + 0x88, 0x80, 0xc5, 0x80, 0x95, 0x8b, 0xaa, 0x1c, + 0x8b, 0x90, 0x10, 0x82, 0xc6, 0x00, 0x80, 0x40, + 0xba, 0x81, 0xbe, 0x8c, 0x18, 0x97, 0x91, 0x80, + 0x99, 0x81, 0x8c, 0x80, 0xd5, 0xd4, 0xaf, 0xc5, + 0x28, 0x12, 0x0b, 0x13, 0x8a, 0x0e, 0x88, 0x40, + 0xe2, 0x8b, 0x18, 0x41, 0x1a, 0xae, 0x80, 0x89, + 0x80, 0x40, 0xb8, 0xef, 0x8c, 0x82, 0x8a, 0x82, + 0xb8, 0x00, 0x83, 0x8f, 0x81, 0x8b, 0x83, 0x89, +}; + +static const uint8_t unicode_prop_Basic_Emoji2_table[183] = { + 0x40, 0xa8, 0x03, 0x80, 0x5f, 0x8c, 0x80, 0x8b, + 0x80, 0x40, 0xd7, 0x80, 0x95, 0x80, 0xd9, 0x85, + 0x8e, 0x81, 0x41, 0x7c, 0x80, 0x40, 0xa5, 0x80, + 0x9c, 0x10, 0x0c, 0x82, 0x40, 0xc6, 0x80, 0x40, + 0xe6, 0x81, 0x89, 0x80, 0x88, 0x80, 0xb9, 0x0a, + 0x84, 0x88, 0x01, 0x05, 0x03, 0x01, 0x00, 0x09, + 0x02, 0x02, 0x0f, 0x14, 0x00, 0x80, 0x9b, 0x09, + 0x00, 0x08, 0x80, 0x91, 0x01, 0x80, 0x92, 0x00, + 0x18, 0x00, 0x0a, 0x05, 0x07, 0x81, 0x95, 0x05, + 0x00, 0x00, 0x80, 0x94, 0x05, 0x09, 0x01, 0x17, + 0x04, 0x09, 0x08, 0x01, 0x00, 0x00, 0x05, 0x02, + 0x80, 0x90, 0x81, 0x8e, 0x01, 0x80, 0x9a, 0x81, + 0xbb, 0x80, 0x41, 0x91, 0x81, 0x41, 0xce, 0x82, + 0x45, 0x27, 0x80, 0x8b, 0x80, 0x42, 0x58, 0x00, + 0x80, 0x61, 0xbe, 0xd5, 0x81, 0x8b, 0x81, 0x40, + 0x81, 0x80, 0xb3, 0x80, 0x40, 0xe8, 0x01, 0x88, + 0x88, 0x80, 0xc5, 0x80, 0x97, 0x08, 0x11, 0x81, + 0xaa, 0x1c, 0x8b, 0x92, 0x00, 0x00, 0x80, 0xc6, + 0x00, 0x80, 0x40, 0xba, 0x80, 0xca, 0x81, 0xa3, + 0x09, 0x86, 0x8c, 0x01, 0x19, 0x80, 0x93, 0x01, + 0x07, 0x81, 0x88, 0x04, 0x82, 0x8b, 0x17, 0x11, + 0x00, 0x03, 0x05, 0x02, 0x05, 0x80, 0x40, 0xcf, + 0x00, 0x82, 0x8f, 0x2a, 0x05, 0x01, 0x80, +}; + +static const uint8_t unicode_prop_RGI_Emoji_Flag_Sequence_table[128] = { + 0x0c, 0x00, 0x09, 0x00, 0x04, 0x01, 0x02, 0x06, + 0x03, 0x03, 0x01, 0x02, 0x01, 0x03, 0x07, 0x0d, + 0x18, 0x00, 0x09, 0x00, 0x00, 0x89, 0x08, 0x00, + 0x00, 0x81, 0x88, 0x83, 0x8c, 0x10, 0x00, 0x01, + 0x07, 0x08, 0x29, 0x10, 0x28, 0x00, 0x80, 0x8a, + 0x00, 0x0a, 0x00, 0x0e, 0x15, 0x18, 0x83, 0x89, + 0x06, 0x00, 0x81, 0x8d, 0x00, 0x12, 0x08, 0x00, + 0x03, 0x00, 0x24, 0x00, 0x05, 0x21, 0x00, 0x00, + 0x29, 0x90, 0x00, 0x02, 0x00, 0x08, 0x09, 0x00, + 0x08, 0x18, 0x8b, 0x80, 0x8c, 0x02, 0x19, 0x1a, + 0x11, 0x00, 0x00, 0x80, 0x9c, 0x80, 0x88, 0x02, + 0x00, 0x00, 0x02, 0x20, 0x88, 0x0a, 0x00, 0x03, + 0x01, 0x02, 0x05, 0x08, 0x00, 0x01, 0x09, 0x20, + 0x21, 0x18, 0x22, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x28, 0x89, 0x80, 0x8b, 0x80, 0x90, 0x80, 0x92, + 0x80, 0x8d, 0x05, 0x80, 0x8a, 0x80, 0x88, 0x80, +}; + +static const uint8_t unicode_prop_Emoji_Keycap_Sequence_table[4] = { + 0xa2, 0x05, 0x04, 0x89, +}; + +static const uint8_t unicode_prop_ASCII_Hex_Digit_table[5] = { + 0xaf, 0x89, 0x35, 0x99, 0x85, +}; + +static const uint8_t unicode_prop_Bidi_Control_table[10] = { + 0x46, 0x1b, 0x80, 0x59, 0xf0, 0x81, 0x99, 0x84, + 0xb6, 0x83, +}; + +static const uint8_t unicode_prop_Dash_table[58] = { + 0xac, 0x80, 0x45, 0x5b, 0x80, 0xb2, 0x80, 0x4e, + 0x40, 0x80, 0x44, 0x04, 0x80, 0x48, 0x08, 0x85, + 0xbc, 0x80, 0xa6, 0x80, 0x8e, 0x80, 0x41, 0x85, + 0x80, 0x4c, 0x03, 0x01, 0x80, 0x9e, 0x0b, 0x80, + 0x9b, 0x80, 0x41, 0xbd, 0x80, 0x92, 0x80, 0xee, + 0x80, 0x60, 0xcd, 0x8f, 0x81, 0xa4, 0x80, 0x89, + 0x80, 0x40, 0xa8, 0x80, 0x4e, 0x5f, 0x80, 0x41, + 0x3d, 0x80, +}; + +static const uint8_t unicode_prop_Deprecated_table[23] = { + 0x41, 0x48, 0x80, 0x45, 0x28, 0x80, 0x49, 0x02, + 0x00, 0x80, 0x48, 0x28, 0x81, 0x48, 0xc4, 0x85, + 0x42, 0xb8, 0x81, 0x6d, 0xdc, 0xd5, 0x80, +}; + +static const uint8_t unicode_prop_Diacritic_table[447] = { + 0xdd, 0x00, 0x80, 0xc6, 0x05, 0x03, 0x01, 0x81, + 0x41, 0xf6, 0x40, 0x9e, 0x07, 0x25, 0x90, 0x0b, + 0x80, 0x88, 0x81, 0x40, 0xfc, 0x84, 0x40, 0xd0, + 0x80, 0xb6, 0xac, 0x00, 0x01, 0x01, 0x00, 0x40, + 0x82, 0x3b, 0x81, 0x40, 0x85, 0x0b, 0x0a, 0x82, + 0xc2, 0x9a, 0xda, 0x8a, 0xb9, 0x8a, 0xa1, 0x81, + 0xfd, 0x87, 0xa8, 0x89, 0x8f, 0x9b, 0xbc, 0x80, + 0x8f, 0x02, 0x83, 0x9b, 0x80, 0xc9, 0x80, 0x8f, + 0x80, 0xed, 0x80, 0x8f, 0x80, 0xed, 0x80, 0x8f, + 0x80, 0xae, 0x82, 0xbb, 0x80, 0x8f, 0x06, 0x80, + 0xf6, 0x80, 0xed, 0x80, 0x8f, 0x80, 0xed, 0x80, + 0x8f, 0x80, 0xec, 0x81, 0x8f, 0x80, 0xfb, 0x80, + 0xee, 0x80, 0x8b, 0x28, 0x80, 0xea, 0x80, 0x8c, + 0x84, 0xca, 0x81, 0x9a, 0x00, 0x00, 0x03, 0x81, + 0xc1, 0x10, 0x81, 0xbd, 0x80, 0xef, 0x00, 0x81, + 0xa7, 0x0b, 0x84, 0x98, 0x30, 0x80, 0x89, 0x81, + 0x42, 0xc0, 0x82, 0x43, 0xb3, 0x81, 0x9d, 0x80, + 0x40, 0x93, 0x8a, 0x88, 0x80, 0x41, 0x5a, 0x82, + 0x41, 0x23, 0x80, 0x93, 0x39, 0x80, 0xaf, 0x8e, + 0x81, 0x8a, 0x82, 0x8e, 0x81, 0x8b, 0xc7, 0x80, + 0x8e, 0x80, 0xa5, 0x88, 0xb5, 0x81, 0xb9, 0x80, + 0x8a, 0x81, 0xc1, 0x81, 0xbf, 0x85, 0xd1, 0x98, + 0x18, 0x28, 0x0a, 0xb1, 0xbe, 0xaf, 0xa3, 0x84, + 0x8b, 0xa4, 0x8a, 0x41, 0xbc, 0x00, 0x82, 0x8a, + 0x82, 0x8c, 0x82, 0x8c, 0x82, 0x8c, 0x81, 0x4c, + 0xef, 0x82, 0x41, 0x3c, 0x80, 0x41, 0xf9, 0x85, + 0xe8, 0x83, 0xde, 0x80, 0x60, 0x75, 0x71, 0x80, + 0x8b, 0x08, 0x80, 0x9b, 0x81, 0xd1, 0x81, 0x8d, + 0xa1, 0xe5, 0x82, 0xe5, 0x05, 0x81, 0x8b, 0x80, + 0xa4, 0x80, 0x40, 0x96, 0x80, 0x9a, 0x91, 0xb8, + 0x83, 0xa3, 0x80, 0xde, 0x80, 0x8b, 0x80, 0xa3, + 0x80, 0x40, 0x94, 0x82, 0xc0, 0x83, 0xb2, 0x80, + 0xe3, 0x84, 0x88, 0x82, 0xff, 0x81, 0x60, 0x4f, + 0x2f, 0x80, 0x43, 0x00, 0x8f, 0x41, 0x0d, 0x00, + 0x80, 0xae, 0x80, 0xac, 0x81, 0xc2, 0x80, 0x42, + 0xfb, 0x80, 0x44, 0x9e, 0x28, 0xa9, 0x80, 0x88, + 0x42, 0x7c, 0x13, 0x80, 0x40, 0xa4, 0x81, 0x42, + 0x3a, 0x85, 0xa5, 0x80, 0x99, 0x84, 0x41, 0x8b, + 0x01, 0x82, 0xc5, 0x8a, 0xb0, 0x83, 0x40, 0xbf, + 0x80, 0xa8, 0x80, 0xc7, 0x81, 0xf7, 0x81, 0xbd, + 0x80, 0xcb, 0x80, 0x88, 0x82, 0xe7, 0x81, 0x40, + 0xb1, 0x81, 0xcf, 0x81, 0x8f, 0x80, 0x97, 0x32, + 0x84, 0xd8, 0x10, 0x81, 0x8c, 0x81, 0xde, 0x02, + 0x80, 0xfa, 0x81, 0x40, 0xfa, 0x81, 0xfd, 0x80, + 0xf5, 0x81, 0xf2, 0x80, 0x41, 0x0c, 0x81, 0x41, + 0x01, 0x0b, 0x80, 0x40, 0x9b, 0x80, 0xd2, 0x80, + 0x91, 0x80, 0xd0, 0x80, 0x41, 0xa4, 0x80, 0x41, + 0x01, 0x00, 0x81, 0xd0, 0x80, 0xc0, 0x80, 0x41, + 0x66, 0x81, 0x96, 0x80, 0x54, 0xeb, 0x8e, 0x60, + 0x2c, 0xd8, 0x80, 0x49, 0xbf, 0x84, 0xba, 0x86, + 0x42, 0x33, 0x81, 0x42, 0x21, 0x90, 0xcf, 0x81, + 0x60, 0x3f, 0xfd, 0x18, 0x30, 0x81, 0x5f, 0x00, + 0xad, 0x81, 0x96, 0x42, 0x1f, 0x12, 0x2f, 0x39, + 0x86, 0x9d, 0x83, 0x4e, 0x81, 0xbd, 0x40, 0xc1, + 0x86, 0x41, 0x76, 0x80, 0xbc, 0x83, 0x42, 0xfd, + 0x81, 0x42, 0xdf, 0x86, 0xec, 0x10, 0x82, +}; + +static const uint8_t unicode_prop_Extender_table[116] = { + 0x40, 0xb6, 0x80, 0x42, 0x17, 0x81, 0x43, 0x6d, + 0x80, 0x41, 0xb8, 0x80, 0x42, 0x75, 0x80, 0x40, + 0x88, 0x80, 0xd8, 0x80, 0x42, 0xef, 0x80, 0xfe, + 0x80, 0x49, 0x42, 0x80, 0xb7, 0x80, 0x42, 0x62, + 0x80, 0x41, 0x8d, 0x80, 0xc3, 0x80, 0x53, 0x88, + 0x80, 0xaa, 0x84, 0xe6, 0x81, 0xdc, 0x82, 0x60, + 0x6f, 0x15, 0x80, 0x45, 0xf5, 0x80, 0x43, 0xc1, + 0x80, 0x95, 0x80, 0x40, 0x88, 0x80, 0xeb, 0x80, + 0x94, 0x81, 0x60, 0x54, 0x7a, 0x80, 0x48, 0x0f, + 0x81, 0x45, 0xca, 0x80, 0x9a, 0x03, 0x80, 0x44, + 0xc6, 0x80, 0x41, 0x24, 0x80, 0xf3, 0x81, 0x41, + 0xf1, 0x82, 0x44, 0xce, 0x80, 0x43, 0x3f, 0x80, + 0x60, 0x4d, 0x67, 0x81, 0x44, 0x9b, 0x08, 0x80, + 0x8d, 0x81, 0x60, 0x71, 0x47, 0x81, 0x44, 0xb0, + 0x80, 0x43, 0x53, 0x82, +}; + +static const uint8_t unicode_prop_Hex_Digit_table[12] = { + 0xaf, 0x89, 0x35, 0x99, 0x85, 0x60, 0xfe, 0xa8, + 0x89, 0x35, 0x99, 0x85, +}; + +static const uint8_t unicode_prop_IDS_Unary_Operator_table[4] = { + 0x60, 0x2f, 0xfd, 0x81, +}; + +static const uint8_t unicode_prop_IDS_Binary_Operator_table[8] = { + 0x60, 0x2f, 0xef, 0x09, 0x89, 0x41, 0xf0, 0x80, +}; + +static const uint8_t unicode_prop_IDS_Trinary_Operator_table[4] = { + 0x60, 0x2f, 0xf1, 0x81, +}; + +static const uint8_t unicode_prop_Ideographic_table[71] = { + 0x60, 0x30, 0x05, 0x81, 0x98, 0x88, 0x8d, 0x82, + 0x43, 0xc4, 0x59, 0xbf, 0xbf, 0x60, 0x51, 0xff, + 0x60, 0x58, 0xff, 0x41, 0x6d, 0x81, 0xe9, 0x60, + 0x75, 0x09, 0x80, 0x8c, 0x84, 0x88, 0x5c, 0xd5, + 0xa8, 0x9f, 0xe0, 0xf2, 0x60, 0x23, 0x7c, 0x41, + 0x8b, 0x60, 0x4d, 0x03, 0x60, 0xa6, 0xdf, 0x9f, + 0x51, 0x1d, 0x81, 0x56, 0x8d, 0x81, 0x5d, 0x30, + 0x8e, 0x42, 0x6d, 0x49, 0xa1, 0x42, 0x1d, 0x45, + 0xe1, 0x53, 0x4a, 0x84, 0x60, 0x21, 0x29, +}; + +static const uint8_t unicode_prop_Join_Control_table[4] = { + 0x60, 0x20, 0x0b, 0x81, +}; + +static const uint8_t unicode_prop_Logical_Order_Exception_table[15] = { + 0x4e, 0x3f, 0x84, 0xfa, 0x84, 0x4a, 0xef, 0x11, + 0x80, 0x60, 0x90, 0xf9, 0x09, 0x00, 0x81, +}; + +static const uint8_t unicode_prop_Modifier_Combining_Mark_table[16] = { + 0x46, 0x53, 0x09, 0x80, 0x40, 0x82, 0x05, 0x02, + 0x81, 0x41, 0xe0, 0x08, 0x12, 0x80, 0x9e, 0x80, +}; + +static const uint8_t unicode_prop_Noncharacter_Code_Point_table[71] = { + 0x60, 0xfd, 0xcf, 0x9f, 0x42, 0x0d, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, + 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, +}; + +static const uint8_t unicode_prop_Pattern_Syntax_table[58] = { + 0xa0, 0x8e, 0x89, 0x86, 0x99, 0x18, 0x80, 0x99, + 0x83, 0xa1, 0x30, 0x00, 0x08, 0x00, 0x0b, 0x03, + 0x02, 0x80, 0x96, 0x80, 0x9e, 0x80, 0x5f, 0x17, + 0x97, 0x87, 0x8e, 0x81, 0x92, 0x80, 0x89, 0x41, + 0x30, 0x42, 0xcf, 0x40, 0x9f, 0x42, 0x75, 0x9d, + 0x44, 0x6b, 0x41, 0xff, 0xff, 0x41, 0x80, 0x13, + 0x98, 0x8e, 0x80, 0x60, 0xcd, 0x0c, 0x81, 0x41, + 0x04, 0x81, +}; + +static const uint8_t unicode_prop_Pattern_White_Space_table[11] = { + 0x88, 0x84, 0x91, 0x80, 0xe3, 0x80, 0x5f, 0x87, + 0x81, 0x97, 0x81, +}; + +static const uint8_t unicode_prop_Quotation_Mark_table[31] = { + 0xa1, 0x03, 0x80, 0x40, 0x82, 0x80, 0x8e, 0x80, + 0x5f, 0x5b, 0x87, 0x98, 0x81, 0x4e, 0x06, 0x80, + 0x41, 0xc8, 0x83, 0x8c, 0x82, 0x60, 0xce, 0x20, + 0x83, 0x40, 0xbc, 0x03, 0x80, 0xd9, 0x81, +}; + +static const uint8_t unicode_prop_Radical_table[9] = { + 0x60, 0x2e, 0x7f, 0x99, 0x80, 0xd8, 0x8b, 0x40, + 0xd5, +}; + +static const uint8_t unicode_prop_Regional_Indicator_table[4] = { + 0x61, 0xf1, 0xe5, 0x99, +}; + +static const uint8_t unicode_prop_Sentence_Terminal_table[213] = { + 0xa0, 0x80, 0x8b, 0x80, 0x8f, 0x80, 0x45, 0x48, + 0x80, 0x40, 0x92, 0x82, 0x40, 0xb3, 0x80, 0xaa, + 0x82, 0x40, 0xf5, 0x80, 0xbc, 0x00, 0x02, 0x81, + 0x41, 0x24, 0x81, 0x46, 0xe3, 0x81, 0x43, 0x15, + 0x03, 0x81, 0x43, 0x04, 0x80, 0x40, 0xc5, 0x81, + 0x40, 0x9c, 0x81, 0xac, 0x04, 0x80, 0x41, 0x39, + 0x81, 0x41, 0x61, 0x83, 0x40, 0xa1, 0x81, 0x89, + 0x09, 0x81, 0x9c, 0x82, 0x40, 0xba, 0x81, 0xc0, + 0x81, 0x43, 0xa3, 0x80, 0x96, 0x81, 0x88, 0x82, + 0x4c, 0xae, 0x82, 0x41, 0x31, 0x80, 0x8c, 0x80, + 0x95, 0x81, 0x41, 0xac, 0x80, 0x60, 0x74, 0xfb, + 0x80, 0x41, 0x0d, 0x81, 0x40, 0xe2, 0x02, 0x80, + 0x41, 0x7d, 0x81, 0xd5, 0x81, 0xde, 0x80, 0x40, + 0x97, 0x81, 0x40, 0x92, 0x82, 0x40, 0x8f, 0x81, + 0x40, 0xf8, 0x80, 0x60, 0x52, 0x25, 0x01, 0x81, + 0xba, 0x02, 0x81, 0x40, 0xa8, 0x80, 0x8b, 0x80, + 0x8f, 0x80, 0xc0, 0x80, 0x4a, 0xf3, 0x81, 0x44, + 0xfc, 0x84, 0xab, 0x83, 0x40, 0xbc, 0x81, 0xf4, + 0x83, 0xfe, 0x82, 0x40, 0x80, 0x0d, 0x80, 0x8f, + 0x81, 0xd7, 0x08, 0x81, 0xeb, 0x80, 0x41, 0x29, + 0x81, 0xf4, 0x81, 0x41, 0x74, 0x0c, 0x8e, 0xe8, + 0x81, 0x40, 0xf8, 0x82, 0x42, 0x04, 0x00, 0x80, + 0x40, 0xfa, 0x81, 0xd6, 0x81, 0x41, 0xa3, 0x81, + 0x42, 0xb3, 0x81, 0xc9, 0x81, 0x60, 0x4b, 0x28, + 0x81, 0x40, 0x84, 0x80, 0xc0, 0x81, 0x8a, 0x80, + 0x42, 0x28, 0x81, 0x41, 0x27, 0x80, 0x60, 0x4e, + 0x05, 0x80, 0x5d, 0xe7, 0x80, +}; + +static const uint8_t unicode_prop_Soft_Dotted_table[79] = { + 0xe8, 0x81, 0x40, 0xc3, 0x80, 0x41, 0x18, 0x80, + 0x9d, 0x80, 0xb3, 0x80, 0x93, 0x80, 0x41, 0x3f, + 0x80, 0xe1, 0x00, 0x80, 0x59, 0x08, 0x80, 0xb2, + 0x80, 0x8c, 0x02, 0x80, 0x40, 0x83, 0x80, 0x40, + 0x9c, 0x80, 0x41, 0xa4, 0x80, 0x40, 0xd5, 0x81, + 0x4b, 0x31, 0x80, 0x61, 0xa7, 0xa4, 0x81, 0xb1, + 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, + 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, + 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0x48, + 0x85, 0x80, 0x41, 0x30, 0x81, 0x99, 0x80, +}; + +static const uint8_t unicode_prop_Terminal_Punctuation_table[264] = { + 0xa0, 0x80, 0x89, 0x00, 0x80, 0x8a, 0x0a, 0x80, + 0x43, 0x3d, 0x07, 0x80, 0x42, 0x00, 0x80, 0xb8, + 0x80, 0xc7, 0x80, 0x8d, 0x00, 0x82, 0x40, 0xb3, + 0x80, 0xaa, 0x8a, 0x00, 0x40, 0xea, 0x81, 0xb5, + 0x28, 0x87, 0x9e, 0x80, 0x41, 0x04, 0x81, 0x44, + 0xf3, 0x81, 0x40, 0xab, 0x03, 0x85, 0x41, 0x36, + 0x81, 0x43, 0x14, 0x87, 0x43, 0x04, 0x80, 0xfb, + 0x82, 0xc6, 0x81, 0x40, 0x9c, 0x12, 0x80, 0xa6, + 0x19, 0x81, 0x41, 0x39, 0x81, 0x41, 0x61, 0x83, + 0x40, 0xa1, 0x81, 0x89, 0x08, 0x82, 0x9c, 0x82, + 0x40, 0xba, 0x84, 0xbd, 0x81, 0x43, 0xa3, 0x80, + 0x96, 0x81, 0x88, 0x82, 0x4c, 0xae, 0x82, 0x41, + 0x31, 0x80, 0x8c, 0x03, 0x80, 0x89, 0x00, 0x0a, + 0x81, 0x41, 0xab, 0x81, 0x60, 0x74, 0xfa, 0x81, + 0x41, 0x0c, 0x82, 0x40, 0xe2, 0x84, 0x41, 0x7d, + 0x81, 0xd5, 0x81, 0xde, 0x80, 0x40, 0x96, 0x82, + 0x40, 0x92, 0x82, 0xfe, 0x80, 0x8f, 0x81, 0x40, + 0xf8, 0x80, 0x60, 0x52, 0x25, 0x01, 0x81, 0xb8, + 0x10, 0x83, 0x40, 0xa8, 0x80, 0x89, 0x00, 0x80, + 0x8a, 0x0a, 0x80, 0xc0, 0x01, 0x80, 0x44, 0x39, + 0x80, 0xaf, 0x80, 0x44, 0x85, 0x80, 0x40, 0xc6, + 0x80, 0x41, 0x35, 0x81, 0x40, 0x97, 0x85, 0xc3, + 0x85, 0xd8, 0x83, 0x43, 0xb7, 0x84, 0xab, 0x83, + 0x40, 0xbc, 0x86, 0xef, 0x83, 0xfe, 0x82, 0x40, + 0x80, 0x0d, 0x80, 0x8f, 0x81, 0xd7, 0x84, 0xeb, + 0x80, 0x41, 0x29, 0x81, 0xf4, 0x82, 0x8b, 0x81, + 0x41, 0x65, 0x1a, 0x8e, 0xe8, 0x81, 0x40, 0xf8, + 0x82, 0x42, 0x04, 0x00, 0x80, 0x40, 0xfa, 0x81, + 0xd6, 0x0b, 0x81, 0x41, 0x9d, 0x82, 0xac, 0x80, + 0x42, 0x84, 0x81, 0xc9, 0x81, 0x45, 0x2a, 0x84, + 0x60, 0x45, 0xf8, 0x81, 0x40, 0x84, 0x80, 0xc0, + 0x82, 0x89, 0x80, 0x42, 0x28, 0x81, 0x41, 0x26, + 0x81, 0x60, 0x4e, 0x05, 0x80, 0x5d, 0xe6, 0x83, +}; + +static const uint8_t unicode_prop_Unified_Ideograph_table[46] = { + 0x60, 0x33, 0xff, 0x59, 0xbf, 0xbf, 0x60, 0x51, + 0xff, 0x60, 0x5a, 0x0d, 0x08, 0x00, 0x81, 0x89, + 0x00, 0x00, 0x09, 0x82, 0x61, 0x05, 0xd5, 0x60, + 0xa6, 0xdf, 0x9f, 0x51, 0x1d, 0x81, 0x56, 0x8d, + 0x81, 0x5d, 0x30, 0x8e, 0x42, 0x6d, 0x51, 0xa1, + 0x53, 0x4a, 0x84, 0x60, 0x21, 0x29, +}; + +static const uint8_t unicode_prop_Variation_Selector_table[13] = { + 0x58, 0x0a, 0x10, 0x80, 0x60, 0xe5, 0xef, 0x8f, + 0x6d, 0x02, 0xef, 0x40, 0xef, +}; + +static const uint8_t unicode_prop_Bidi_Mirrored_table[173] = { + 0xa7, 0x81, 0x91, 0x00, 0x80, 0x9b, 0x00, 0x80, + 0x9c, 0x00, 0x80, 0xac, 0x80, 0x8e, 0x80, 0x4e, + 0x7d, 0x83, 0x47, 0x5c, 0x81, 0x49, 0x9b, 0x81, + 0x89, 0x81, 0xb5, 0x81, 0x8d, 0x81, 0x40, 0xb0, + 0x80, 0x40, 0xbf, 0x1a, 0x2a, 0x02, 0x0a, 0x18, + 0x18, 0x00, 0x03, 0x88, 0x20, 0x80, 0x91, 0x23, + 0x88, 0x08, 0x00, 0x38, 0x9f, 0x0b, 0x20, 0x88, + 0x09, 0x92, 0x21, 0x88, 0x21, 0x0b, 0x97, 0x81, + 0x8f, 0x3b, 0x93, 0x0e, 0x81, 0x44, 0x3c, 0x8d, + 0xc9, 0x01, 0x18, 0x08, 0x14, 0x1c, 0x12, 0x8d, + 0x41, 0x92, 0x95, 0x0d, 0x80, 0x8d, 0x38, 0x35, + 0x10, 0x1c, 0x01, 0x0c, 0x18, 0x02, 0x09, 0x89, + 0x29, 0x81, 0x8b, 0x92, 0x03, 0x08, 0x00, 0x08, + 0x03, 0x21, 0x2a, 0x97, 0x81, 0x8a, 0x0b, 0x18, + 0x09, 0x0b, 0xaa, 0x0f, 0x80, 0xa7, 0x20, 0x00, + 0x14, 0x22, 0x18, 0x14, 0x00, 0x40, 0xff, 0x80, + 0x42, 0x02, 0x1a, 0x08, 0x81, 0x8d, 0x09, 0x89, + 0xaa, 0x87, 0x41, 0xaa, 0x89, 0x0f, 0x60, 0xce, + 0x3c, 0x2c, 0x81, 0x40, 0xa1, 0x81, 0x91, 0x00, + 0x80, 0x9b, 0x00, 0x80, 0x9c, 0x00, 0x00, 0x08, + 0x81, 0x60, 0xd7, 0x76, 0x80, 0xb8, 0x80, 0xb8, + 0x80, 0xb8, 0x80, 0xb8, 0x80, +}; + +static const uint8_t unicode_prop_Emoji_table[239] = { + 0xa2, 0x05, 0x04, 0x89, 0xee, 0x03, 0x80, 0x5f, + 0x8c, 0x80, 0x8b, 0x80, 0x40, 0xd7, 0x80, 0x95, + 0x80, 0xd9, 0x85, 0x8e, 0x81, 0x41, 0x6e, 0x81, + 0x8b, 0x80, 0x40, 0xa5, 0x80, 0x98, 0x8a, 0x1a, + 0x40, 0xc6, 0x80, 0x40, 0xe6, 0x81, 0x89, 0x80, + 0x88, 0x80, 0xb9, 0x18, 0x84, 0x88, 0x01, 0x01, + 0x09, 0x03, 0x01, 0x00, 0x09, 0x02, 0x02, 0x0f, + 0x14, 0x00, 0x04, 0x8b, 0x8a, 0x09, 0x00, 0x08, + 0x80, 0x91, 0x01, 0x81, 0x91, 0x28, 0x00, 0x0a, + 0x0c, 0x01, 0x0b, 0x81, 0x8a, 0x0c, 0x09, 0x04, + 0x08, 0x00, 0x81, 0x93, 0x0c, 0x28, 0x19, 0x03, + 0x01, 0x01, 0x28, 0x01, 0x00, 0x00, 0x05, 0x02, + 0x05, 0x80, 0x89, 0x81, 0x8e, 0x01, 0x03, 0x00, + 0x03, 0x10, 0x80, 0x8a, 0x81, 0xaf, 0x82, 0x88, + 0x80, 0x8d, 0x80, 0x8d, 0x80, 0x41, 0x73, 0x81, + 0x41, 0xce, 0x82, 0x92, 0x81, 0xb2, 0x03, 0x80, + 0x44, 0xd9, 0x80, 0x8b, 0x80, 0x42, 0x58, 0x00, + 0x80, 0x61, 0xbd, 0x69, 0x80, 0x40, 0xc9, 0x80, + 0x40, 0x9f, 0x81, 0x8b, 0x81, 0x8d, 0x01, 0x89, + 0xca, 0x99, 0x01, 0x96, 0x80, 0x93, 0x01, 0x88, + 0x94, 0x81, 0x40, 0xad, 0xa1, 0x81, 0xef, 0x09, + 0x02, 0x81, 0xd2, 0x0a, 0x80, 0x41, 0x06, 0x80, + 0xbe, 0x8a, 0x28, 0x97, 0x31, 0x0f, 0x8b, 0x01, + 0x19, 0x03, 0x81, 0x8c, 0x09, 0x07, 0x81, 0x88, + 0x04, 0x82, 0x8b, 0x17, 0x11, 0x00, 0x03, 0x05, + 0x02, 0x05, 0xd5, 0xaf, 0xc5, 0x27, 0x0b, 0x82, + 0x89, 0x10, 0x01, 0x10, 0x81, 0x89, 0x40, 0xe2, + 0x8b, 0x18, 0x41, 0x1a, 0xae, 0x80, 0x89, 0x80, + 0x40, 0xb8, 0xef, 0x8c, 0x82, 0x8a, 0x82, 0xb8, + 0x00, 0x83, 0x8f, 0x81, 0x8b, 0x83, 0x89, +}; + +static const uint8_t unicode_prop_Emoji_Component_table[28] = { + 0xa2, 0x05, 0x04, 0x89, 0x5f, 0xd2, 0x80, 0x40, + 0xd4, 0x80, 0x60, 0xdd, 0x2a, 0x80, 0x60, 0xf3, + 0xd5, 0x99, 0x41, 0xfa, 0x84, 0x45, 0xaf, 0x83, + 0x6c, 0x06, 0x6b, 0xdf, +}; + +static const uint8_t unicode_prop_Emoji_Modifier_table[4] = { + 0x61, 0xf3, 0xfa, 0x84, +}; + +static const uint8_t unicode_prop_Emoji_Modifier_Base_table[71] = { + 0x60, 0x26, 0x1c, 0x80, 0x40, 0xda, 0x80, 0x8f, + 0x83, 0x61, 0xcc, 0x76, 0x80, 0xbb, 0x11, 0x01, + 0x82, 0xf4, 0x09, 0x8a, 0x94, 0x92, 0x10, 0x1a, + 0x02, 0x30, 0x00, 0x97, 0x80, 0x40, 0xc8, 0x0b, + 0x80, 0x94, 0x03, 0x81, 0x40, 0xad, 0x12, 0x84, + 0xd2, 0x80, 0x8f, 0x82, 0x88, 0x80, 0x8a, 0x80, + 0x42, 0x3e, 0x01, 0x07, 0x3d, 0x80, 0x88, 0x89, + 0x0a, 0xb7, 0x80, 0xbc, 0x08, 0x08, 0x80, 0x90, + 0x10, 0x8c, 0x40, 0xe4, 0x82, 0xa9, 0x88, +}; + +static const uint8_t unicode_prop_Emoji_Presentation_table[145] = { + 0x60, 0x23, 0x19, 0x81, 0x40, 0xcc, 0x1a, 0x01, + 0x80, 0x42, 0x08, 0x81, 0x94, 0x81, 0xb1, 0x8b, + 0xaa, 0x80, 0x92, 0x80, 0x8c, 0x07, 0x81, 0x90, + 0x0c, 0x0f, 0x04, 0x80, 0x94, 0x06, 0x08, 0x03, + 0x01, 0x06, 0x03, 0x81, 0x9b, 0x80, 0xa2, 0x00, + 0x03, 0x10, 0x80, 0xbc, 0x82, 0x97, 0x80, 0x8d, + 0x80, 0x43, 0x5a, 0x81, 0xb2, 0x03, 0x80, 0x61, + 0xc4, 0xad, 0x80, 0x40, 0xc9, 0x80, 0x40, 0xbd, + 0x01, 0x89, 0xca, 0x99, 0x00, 0x97, 0x80, 0x93, + 0x01, 0x20, 0x82, 0x94, 0x81, 0x40, 0xad, 0xa0, + 0x8b, 0x88, 0x80, 0xc5, 0x80, 0x95, 0x8b, 0xaa, + 0x1c, 0x8b, 0x90, 0x10, 0x82, 0xc6, 0x00, 0x80, + 0x40, 0xba, 0x81, 0xbe, 0x8c, 0x18, 0x97, 0x91, + 0x80, 0x99, 0x81, 0x8c, 0x80, 0xd5, 0xd4, 0xaf, + 0xc5, 0x28, 0x12, 0x0b, 0x13, 0x8a, 0x0e, 0x88, + 0x40, 0xe2, 0x8b, 0x18, 0x41, 0x1a, 0xae, 0x80, + 0x89, 0x80, 0x40, 0xb8, 0xef, 0x8c, 0x82, 0x8a, + 0x82, 0xb8, 0x00, 0x83, 0x8f, 0x81, 0x8b, 0x83, + 0x89, +}; + +static const uint8_t unicode_prop_Extended_Pictographic_table[254] = { + 0x40, 0xa8, 0x03, 0x80, 0x5f, 0x8c, 0x80, 0x8b, + 0x80, 0x40, 0xd7, 0x80, 0x95, 0x80, 0xd9, 0x85, + 0x8e, 0x81, 0x41, 0x6e, 0x81, 0x8b, 0x80, 0x40, + 0xa5, 0x80, 0x98, 0x8a, 0x1a, 0x40, 0xc6, 0x80, + 0x40, 0xe6, 0x81, 0x89, 0x80, 0x88, 0x80, 0xb9, + 0x18, 0x84, 0x88, 0x01, 0x01, 0x09, 0x03, 0x01, + 0x00, 0x09, 0x02, 0x02, 0x0f, 0x14, 0x00, 0x04, + 0x8b, 0x8a, 0x09, 0x00, 0x08, 0x80, 0x91, 0x01, + 0x81, 0x91, 0x28, 0x00, 0x0a, 0x0c, 0x01, 0x0b, + 0x81, 0x8a, 0x0c, 0x09, 0x04, 0x08, 0x00, 0x81, + 0x93, 0x0c, 0x28, 0x19, 0x03, 0x01, 0x01, 0x28, + 0x01, 0x00, 0x00, 0x05, 0x02, 0x05, 0x80, 0x89, + 0x81, 0x8e, 0x01, 0x03, 0x00, 0x03, 0x10, 0x80, + 0x8a, 0x81, 0xaf, 0x82, 0x88, 0x80, 0x8d, 0x80, + 0x8d, 0x80, 0x41, 0x73, 0x81, 0x41, 0xce, 0x82, + 0x92, 0x81, 0xb2, 0x03, 0x80, 0x44, 0xd9, 0x80, + 0x8b, 0x80, 0x42, 0x58, 0x00, 0x80, 0x61, 0xbd, + 0x69, 0x80, 0xa6, 0x83, 0xe3, 0x8b, 0x8e, 0x81, + 0x8e, 0x80, 0x8d, 0x81, 0xa4, 0x89, 0xef, 0x81, + 0x8b, 0x81, 0x8d, 0x01, 0x89, 0x92, 0xb7, 0x9a, + 0x8e, 0x89, 0x80, 0x93, 0x01, 0x88, 0x03, 0x88, + 0x96, 0x85, 0x40, 0xbb, 0x81, 0xef, 0x09, 0x02, + 0x81, 0xd2, 0x0a, 0x03, 0x84, 0x40, 0xfd, 0x80, + 0xbe, 0x8a, 0x28, 0x97, 0x31, 0x0f, 0x8b, 0x01, + 0x19, 0x03, 0x81, 0x8c, 0x09, 0x07, 0x81, 0x88, + 0x04, 0x82, 0x8b, 0x17, 0x11, 0x00, 0x03, 0x05, + 0x02, 0x05, 0xd5, 0xaf, 0xc5, 0x27, 0x81, 0x90, + 0x10, 0x05, 0x81, 0x8c, 0x40, 0xd9, 0xa5, 0x8b, + 0x83, 0xb7, 0x87, 0x89, 0x85, 0xa7, 0x87, 0x9d, + 0x81, 0x8b, 0x19, 0x8d, 0x88, 0xa6, 0x8b, 0xae, + 0x80, 0x89, 0x80, 0x40, 0xb8, 0xd7, 0x87, 0x8d, + 0x40, 0x91, 0x40, 0xff, 0x43, 0xfd, +}; + +static const uint8_t unicode_prop_Default_Ignorable_Code_Point_table[51] = { + 0x40, 0xac, 0x80, 0x42, 0xa0, 0x80, 0x42, 0xcb, + 0x80, 0x4b, 0x41, 0x81, 0x46, 0x52, 0x81, 0xd4, + 0x84, 0x47, 0xfa, 0x84, 0x99, 0x84, 0xb0, 0x8f, + 0x50, 0xf3, 0x80, 0x60, 0xcc, 0x9a, 0x8f, 0x40, + 0xee, 0x80, 0x40, 0x9f, 0x80, 0xce, 0x88, 0x60, + 0xbc, 0xa6, 0x83, 0x54, 0xce, 0x87, 0x6c, 0x2e, + 0x84, 0x4f, 0xff, +}; + +typedef enum { + UNICODE_PROP_Hyphen, + UNICODE_PROP_Other_Math, + UNICODE_PROP_Other_Alphabetic, + UNICODE_PROP_Other_Lowercase, + UNICODE_PROP_Other_Uppercase, + UNICODE_PROP_Other_Grapheme_Extend, + UNICODE_PROP_Other_Default_Ignorable_Code_Point, + UNICODE_PROP_Other_ID_Start, + UNICODE_PROP_Other_ID_Continue, + UNICODE_PROP_Prepended_Concatenation_Mark, + UNICODE_PROP_ID_Continue1, + UNICODE_PROP_XID_Start1, + UNICODE_PROP_XID_Continue1, + UNICODE_PROP_Changes_When_Titlecased1, + UNICODE_PROP_Changes_When_Casefolded1, + UNICODE_PROP_Changes_When_NFKC_Casefolded1, + UNICODE_PROP_Basic_Emoji1, + UNICODE_PROP_Basic_Emoji2, + UNICODE_PROP_RGI_Emoji_Flag_Sequence, + UNICODE_PROP_Emoji_Keycap_Sequence, + UNICODE_PROP_ASCII_Hex_Digit, + UNICODE_PROP_Bidi_Control, + UNICODE_PROP_Dash, + UNICODE_PROP_Deprecated, + UNICODE_PROP_Diacritic, + UNICODE_PROP_Extender, + UNICODE_PROP_Hex_Digit, + UNICODE_PROP_IDS_Unary_Operator, + UNICODE_PROP_IDS_Binary_Operator, + UNICODE_PROP_IDS_Trinary_Operator, + UNICODE_PROP_Ideographic, + UNICODE_PROP_Join_Control, + UNICODE_PROP_Logical_Order_Exception, + UNICODE_PROP_Modifier_Combining_Mark, + UNICODE_PROP_Noncharacter_Code_Point, + UNICODE_PROP_Pattern_Syntax, + UNICODE_PROP_Pattern_White_Space, + UNICODE_PROP_Quotation_Mark, + UNICODE_PROP_Radical, + UNICODE_PROP_Regional_Indicator, + UNICODE_PROP_Sentence_Terminal, + UNICODE_PROP_Soft_Dotted, + UNICODE_PROP_Terminal_Punctuation, + UNICODE_PROP_Unified_Ideograph, + UNICODE_PROP_Variation_Selector, + UNICODE_PROP_White_Space, + UNICODE_PROP_Bidi_Mirrored, + UNICODE_PROP_Emoji, + UNICODE_PROP_Emoji_Component, + UNICODE_PROP_Emoji_Modifier, + UNICODE_PROP_Emoji_Modifier_Base, + UNICODE_PROP_Emoji_Presentation, + UNICODE_PROP_Extended_Pictographic, + UNICODE_PROP_Default_Ignorable_Code_Point, + UNICODE_PROP_ID_Start, + UNICODE_PROP_Case_Ignorable, + UNICODE_PROP_ASCII, + UNICODE_PROP_Alphabetic, + UNICODE_PROP_Any, + UNICODE_PROP_Assigned, + UNICODE_PROP_Cased, + UNICODE_PROP_Changes_When_Casefolded, + UNICODE_PROP_Changes_When_Casemapped, + UNICODE_PROP_Changes_When_Lowercased, + UNICODE_PROP_Changes_When_NFKC_Casefolded, + UNICODE_PROP_Changes_When_Titlecased, + UNICODE_PROP_Changes_When_Uppercased, + UNICODE_PROP_Grapheme_Base, + UNICODE_PROP_Grapheme_Extend, + UNICODE_PROP_ID_Continue, + UNICODE_PROP_ID_Compat_Math_Start, + UNICODE_PROP_ID_Compat_Math_Continue, + UNICODE_PROP_Lowercase, + UNICODE_PROP_Math, + UNICODE_PROP_Uppercase, + UNICODE_PROP_XID_Continue, + UNICODE_PROP_XID_Start, + UNICODE_PROP_Cased1, + UNICODE_PROP_InCB, + UNICODE_PROP_COUNT, +} UnicodePropertyEnum; + +static const char unicode_prop_name_table[] = + "ASCII_Hex_Digit,AHex" "\0" + "Bidi_Control,Bidi_C" "\0" + "Dash" "\0" + "Deprecated,Dep" "\0" + "Diacritic,Dia" "\0" + "Extender,Ext" "\0" + "Hex_Digit,Hex" "\0" + "IDS_Unary_Operator,IDSU" "\0" + "IDS_Binary_Operator,IDSB" "\0" + "IDS_Trinary_Operator,IDST" "\0" + "Ideographic,Ideo" "\0" + "Join_Control,Join_C" "\0" + "Logical_Order_Exception,LOE" "\0" + "Modifier_Combining_Mark,MCM" "\0" + "Noncharacter_Code_Point,NChar" "\0" + "Pattern_Syntax,Pat_Syn" "\0" + "Pattern_White_Space,Pat_WS" "\0" + "Quotation_Mark,QMark" "\0" + "Radical" "\0" + "Regional_Indicator,RI" "\0" + "Sentence_Terminal,STerm" "\0" + "Soft_Dotted,SD" "\0" + "Terminal_Punctuation,Term" "\0" + "Unified_Ideograph,UIdeo" "\0" + "Variation_Selector,VS" "\0" + "White_Space,space" "\0" + "Bidi_Mirrored,Bidi_M" "\0" + "Emoji" "\0" + "Emoji_Component,EComp" "\0" + "Emoji_Modifier,EMod" "\0" + "Emoji_Modifier_Base,EBase" "\0" + "Emoji_Presentation,EPres" "\0" + "Extended_Pictographic,ExtPict" "\0" + "Default_Ignorable_Code_Point,DI" "\0" + "ID_Start,IDS" "\0" + "Case_Ignorable,CI" "\0" + "ASCII" "\0" + "Alphabetic,Alpha" "\0" + "Any" "\0" + "Assigned" "\0" + "Cased" "\0" + "Changes_When_Casefolded,CWCF" "\0" + "Changes_When_Casemapped,CWCM" "\0" + "Changes_When_Lowercased,CWL" "\0" + "Changes_When_NFKC_Casefolded,CWKCF" "\0" + "Changes_When_Titlecased,CWT" "\0" + "Changes_When_Uppercased,CWU" "\0" + "Grapheme_Base,Gr_Base" "\0" + "Grapheme_Extend,Gr_Ext" "\0" + "ID_Continue,IDC" "\0" + "ID_Compat_Math_Start" "\0" + "ID_Compat_Math_Continue" "\0" + "Lowercase,Lower" "\0" + "Math" "\0" + "Uppercase,Upper" "\0" + "XID_Continue,XIDC" "\0" + "XID_Start,XIDS" "\0" +; + +static const uint8_t * const unicode_prop_table[] = { + unicode_prop_Hyphen_table, + unicode_prop_Other_Math_table, + unicode_prop_Other_Alphabetic_table, + unicode_prop_Other_Lowercase_table, + unicode_prop_Other_Uppercase_table, + unicode_prop_Other_Grapheme_Extend_table, + unicode_prop_Other_Default_Ignorable_Code_Point_table, + unicode_prop_Other_ID_Start_table, + unicode_prop_Other_ID_Continue_table, + unicode_prop_Prepended_Concatenation_Mark_table, + unicode_prop_ID_Continue1_table, + unicode_prop_XID_Start1_table, + unicode_prop_XID_Continue1_table, + unicode_prop_Changes_When_Titlecased1_table, + unicode_prop_Changes_When_Casefolded1_table, + unicode_prop_Changes_When_NFKC_Casefolded1_table, + unicode_prop_Basic_Emoji1_table, + unicode_prop_Basic_Emoji2_table, + unicode_prop_RGI_Emoji_Flag_Sequence_table, + unicode_prop_Emoji_Keycap_Sequence_table, + unicode_prop_ASCII_Hex_Digit_table, + unicode_prop_Bidi_Control_table, + unicode_prop_Dash_table, + unicode_prop_Deprecated_table, + unicode_prop_Diacritic_table, + unicode_prop_Extender_table, + unicode_prop_Hex_Digit_table, + unicode_prop_IDS_Unary_Operator_table, + unicode_prop_IDS_Binary_Operator_table, + unicode_prop_IDS_Trinary_Operator_table, + unicode_prop_Ideographic_table, + unicode_prop_Join_Control_table, + unicode_prop_Logical_Order_Exception_table, + unicode_prop_Modifier_Combining_Mark_table, + unicode_prop_Noncharacter_Code_Point_table, + unicode_prop_Pattern_Syntax_table, + unicode_prop_Pattern_White_Space_table, + unicode_prop_Quotation_Mark_table, + unicode_prop_Radical_table, + unicode_prop_Regional_Indicator_table, + unicode_prop_Sentence_Terminal_table, + unicode_prop_Soft_Dotted_table, + unicode_prop_Terminal_Punctuation_table, + unicode_prop_Unified_Ideograph_table, + unicode_prop_Variation_Selector_table, + unicode_prop_White_Space_table, + unicode_prop_Bidi_Mirrored_table, + unicode_prop_Emoji_table, + unicode_prop_Emoji_Component_table, + unicode_prop_Emoji_Modifier_table, + unicode_prop_Emoji_Modifier_Base_table, + unicode_prop_Emoji_Presentation_table, + unicode_prop_Extended_Pictographic_table, + unicode_prop_Default_Ignorable_Code_Point_table, + unicode_prop_ID_Start_table, + unicode_prop_Case_Ignorable_table, +}; + +static const uint16_t unicode_prop_len_table[] = { + countof(unicode_prop_Hyphen_table), + countof(unicode_prop_Other_Math_table), + countof(unicode_prop_Other_Alphabetic_table), + countof(unicode_prop_Other_Lowercase_table), + countof(unicode_prop_Other_Uppercase_table), + countof(unicode_prop_Other_Grapheme_Extend_table), + countof(unicode_prop_Other_Default_Ignorable_Code_Point_table), + countof(unicode_prop_Other_ID_Start_table), + countof(unicode_prop_Other_ID_Continue_table), + countof(unicode_prop_Prepended_Concatenation_Mark_table), + countof(unicode_prop_ID_Continue1_table), + countof(unicode_prop_XID_Start1_table), + countof(unicode_prop_XID_Continue1_table), + countof(unicode_prop_Changes_When_Titlecased1_table), + countof(unicode_prop_Changes_When_Casefolded1_table), + countof(unicode_prop_Changes_When_NFKC_Casefolded1_table), + countof(unicode_prop_Basic_Emoji1_table), + countof(unicode_prop_Basic_Emoji2_table), + countof(unicode_prop_RGI_Emoji_Flag_Sequence_table), + countof(unicode_prop_Emoji_Keycap_Sequence_table), + countof(unicode_prop_ASCII_Hex_Digit_table), + countof(unicode_prop_Bidi_Control_table), + countof(unicode_prop_Dash_table), + countof(unicode_prop_Deprecated_table), + countof(unicode_prop_Diacritic_table), + countof(unicode_prop_Extender_table), + countof(unicode_prop_Hex_Digit_table), + countof(unicode_prop_IDS_Unary_Operator_table), + countof(unicode_prop_IDS_Binary_Operator_table), + countof(unicode_prop_IDS_Trinary_Operator_table), + countof(unicode_prop_Ideographic_table), + countof(unicode_prop_Join_Control_table), + countof(unicode_prop_Logical_Order_Exception_table), + countof(unicode_prop_Modifier_Combining_Mark_table), + countof(unicode_prop_Noncharacter_Code_Point_table), + countof(unicode_prop_Pattern_Syntax_table), + countof(unicode_prop_Pattern_White_Space_table), + countof(unicode_prop_Quotation_Mark_table), + countof(unicode_prop_Radical_table), + countof(unicode_prop_Regional_Indicator_table), + countof(unicode_prop_Sentence_Terminal_table), + countof(unicode_prop_Soft_Dotted_table), + countof(unicode_prop_Terminal_Punctuation_table), + countof(unicode_prop_Unified_Ideograph_table), + countof(unicode_prop_Variation_Selector_table), + countof(unicode_prop_White_Space_table), + countof(unicode_prop_Bidi_Mirrored_table), + countof(unicode_prop_Emoji_table), + countof(unicode_prop_Emoji_Component_table), + countof(unicode_prop_Emoji_Modifier_table), + countof(unicode_prop_Emoji_Modifier_Base_table), + countof(unicode_prop_Emoji_Presentation_table), + countof(unicode_prop_Extended_Pictographic_table), + countof(unicode_prop_Default_Ignorable_Code_Point_table), + countof(unicode_prop_ID_Start_table), + countof(unicode_prop_Case_Ignorable_table), +}; + +typedef enum { + UNICODE_SEQUENCE_PROP_Basic_Emoji, + UNICODE_SEQUENCE_PROP_Emoji_Keycap_Sequence, + UNICODE_SEQUENCE_PROP_RGI_Emoji_Modifier_Sequence, + UNICODE_SEQUENCE_PROP_RGI_Emoji_Flag_Sequence, + UNICODE_SEQUENCE_PROP_RGI_Emoji_Tag_Sequence, + UNICODE_SEQUENCE_PROP_RGI_Emoji_ZWJ_Sequence, + UNICODE_SEQUENCE_PROP_RGI_Emoji, + UNICODE_SEQUENCE_PROP_COUNT, +} UnicodeSequencePropertyEnum; + +static const char unicode_sequence_prop_name_table[] = + "Basic_Emoji" "\0" + "Emoji_Keycap_Sequence" "\0" + "RGI_Emoji_Modifier_Sequence" "\0" + "RGI_Emoji_Flag_Sequence" "\0" + "RGI_Emoji_Tag_Sequence" "\0" + "RGI_Emoji_ZWJ_Sequence" "\0" + "RGI_Emoji" "\0" +; + +static const uint8_t unicode_rgi_emoji_tag_sequence[18] = { + 0x67, 0x62, 0x65, 0x6e, 0x67, 0x00, 0x67, 0x62, + 0x73, 0x63, 0x74, 0x00, 0x67, 0x62, 0x77, 0x6c, + 0x73, 0x00, +}; + +static const uint8_t unicode_rgi_emoji_zwj_sequence[2392] = { + 0x02, 0xb8, 0x19, 0x40, 0x86, 0x02, 0xd1, 0x39, + 0xb0, 0x19, 0x02, 0x26, 0x39, 0x42, 0x86, 0x02, + 0xb4, 0x36, 0x42, 0x86, 0x03, 0x68, 0x54, 0x64, + 0x87, 0x68, 0x54, 0x02, 0xdc, 0x39, 0x42, 0x86, + 0x02, 0xd1, 0x39, 0x73, 0x13, 0x02, 0x39, 0x39, + 0x40, 0x86, 0x02, 0x69, 0x34, 0xbd, 0x19, 0x03, + 0xb6, 0x36, 0x40, 0x86, 0xa1, 0x87, 0x03, 0x68, + 0x74, 0x1d, 0x19, 0x68, 0x74, 0x03, 0x68, 0x34, + 0xbd, 0x19, 0xa1, 0x87, 0x02, 0xf1, 0x7a, 0xf2, + 0x7a, 0x02, 0xca, 0x33, 0x42, 0x86, 0x02, 0x69, + 0x34, 0xb0, 0x19, 0x04, 0x68, 0x14, 0x68, 0x14, + 0x67, 0x14, 0x66, 0x14, 0x02, 0xf9, 0x26, 0x42, + 0x86, 0x03, 0x69, 0x74, 0x1d, 0x19, 0x69, 0x74, + 0x03, 0xd1, 0x19, 0xbc, 0x19, 0xa1, 0x87, 0x02, + 0x3c, 0x19, 0x40, 0x86, 0x02, 0x68, 0x34, 0xeb, + 0x13, 0x02, 0xc3, 0x33, 0xa1, 0x87, 0x02, 0x70, + 0x34, 0x40, 0x86, 0x02, 0xd4, 0x39, 0x42, 0x86, + 0x02, 0xcf, 0x39, 0x42, 0x86, 0x03, 0xd1, 0x79, + 0xef, 0x1a, 0xd1, 0x79, 0x03, 0x68, 0x74, 0xef, + 0x1a, 0x68, 0x74, 0x03, 0x69, 0x74, 0xef, 0x1a, + 0x69, 0x74, 0x02, 0x47, 0x36, 0x40, 0x86, 0x03, + 0x68, 0x74, 0x30, 0x14, 0x68, 0x74, 0x02, 0x39, + 0x39, 0x42, 0x86, 0x04, 0xd1, 0x79, 0x64, 0x87, + 0x8b, 0x14, 0xd1, 0x79, 0x03, 0x69, 0x74, 0x30, + 0x14, 0x69, 0x74, 0x02, 0xd1, 0x39, 0x95, 0x86, + 0x02, 0x68, 0x34, 0x93, 0x13, 0x02, 0x69, 0x34, + 0xed, 0x13, 0x02, 0xda, 0x39, 0x40, 0x86, 0x03, + 0x69, 0x34, 0xaf, 0x19, 0xa1, 0x87, 0x02, 0xd1, + 0x39, 0x93, 0x13, 0x03, 0xce, 0x39, 0x42, 0x86, + 0xa1, 0x87, 0x03, 0xd1, 0x79, 0x64, 0x87, 0xd1, + 0x79, 0x03, 0xc3, 0x33, 0x42, 0x86, 0xa1, 0x87, + 0x03, 0x69, 0x74, 0x1d, 0x19, 0x68, 0x74, 0x02, + 0x69, 0x34, 0x92, 0x16, 0x02, 0xd1, 0x39, 0x96, + 0x86, 0x04, 0x69, 0x14, 0x64, 0x87, 0x8b, 0x14, + 0x68, 0x14, 0x02, 0x47, 0x36, 0x42, 0x86, 0x02, + 0x68, 0x34, 0x7c, 0x13, 0x02, 0x86, 0x34, 0x42, + 0x86, 0x02, 0xd1, 0x39, 0x7c, 0x13, 0x02, 0x69, + 0x14, 0xa4, 0x13, 0x02, 0xda, 0x39, 0x42, 0x86, + 0x02, 0x37, 0x39, 0x40, 0x86, 0x02, 0xd1, 0x39, + 0x08, 0x87, 0x04, 0x68, 0x54, 0x64, 0x87, 0x8b, + 0x14, 0x68, 0x54, 0x02, 0x4d, 0x36, 0x40, 0x86, + 0x02, 0x68, 0x34, 0x2c, 0x15, 0x02, 0x69, 0x34, + 0xaf, 0x19, 0x02, 0x6e, 0x34, 0x40, 0x86, 0x02, + 0xcd, 0x39, 0x42, 0x86, 0x02, 0xd1, 0x39, 0x2c, + 0x15, 0x02, 0x6f, 0x14, 0x40, 0x86, 0x03, 0xd1, + 0x39, 0xbc, 0x19, 0xa1, 0x87, 0x02, 0x68, 0x34, + 0xa8, 0x13, 0x02, 0x69, 0x34, 0x73, 0x13, 0x04, + 0x69, 0x54, 0x64, 0x87, 0x8b, 0x14, 0x68, 0x54, + 0x02, 0x71, 0x34, 0x42, 0x86, 0x02, 0x45, 0x36, + 0x40, 0x86, 0x02, 0xd1, 0x39, 0xa8, 0x13, 0x03, + 0x69, 0x54, 0x64, 0x87, 0x68, 0x54, 0x03, 0x69, + 0x54, 0x64, 0x87, 0x69, 0x54, 0x03, 0xce, 0x39, + 0x40, 0x86, 0xa1, 0x87, 0x02, 0xd8, 0x39, 0x40, + 0x86, 0x03, 0xc3, 0x33, 0x40, 0x86, 0xa1, 0x87, + 0x02, 0x4d, 0x36, 0x42, 0x86, 0x02, 0xd1, 0x19, + 0x92, 0x16, 0x02, 0xd1, 0x39, 0xeb, 0x13, 0x02, + 0x68, 0x34, 0xbc, 0x14, 0x02, 0xd1, 0x39, 0xbc, + 0x14, 0x02, 0x3d, 0x39, 0x40, 0x86, 0x02, 0xb8, + 0x39, 0x42, 0x86, 0x02, 0xa3, 0x36, 0x40, 0x86, + 0x02, 0x75, 0x35, 0x40, 0x86, 0x02, 0xd8, 0x39, + 0x42, 0x86, 0x02, 0x69, 0x34, 0x93, 0x13, 0x02, + 0x35, 0x39, 0x40, 0x86, 0x02, 0x4b, 0x36, 0x40, + 0x86, 0x02, 0x3d, 0x39, 0x42, 0x86, 0x02, 0x38, + 0x39, 0x42, 0x86, 0x02, 0xa3, 0x36, 0x42, 0x86, + 0x03, 0x69, 0x14, 0x67, 0x14, 0x67, 0x14, 0x02, + 0xb6, 0x36, 0x40, 0x86, 0x02, 0x69, 0x34, 0x7c, + 0x13, 0x02, 0x75, 0x35, 0x42, 0x86, 0x02, 0xcc, + 0x93, 0x40, 0x86, 0x02, 0x6f, 0x34, 0x42, 0x86, + 0x02, 0xcc, 0x33, 0x40, 0x86, 0x03, 0xd1, 0x39, + 0xbd, 0x19, 0xa1, 0x87, 0x02, 0x87, 0x34, 0x40, + 0x86, 0x02, 0x82, 0x34, 0x40, 0x86, 0x02, 0x69, + 0x14, 0x3e, 0x13, 0x02, 0xd6, 0x39, 0x40, 0x86, + 0x02, 0x68, 0x14, 0xbd, 0x19, 0x02, 0x4b, 0x36, + 0x42, 0x86, 0x02, 0x46, 0x36, 0x42, 0x86, 0x02, + 0x69, 0x34, 0x2c, 0x15, 0x03, 0xb6, 0x36, 0x42, + 0x86, 0xa1, 0x87, 0x02, 0xc4, 0x33, 0x40, 0x86, + 0x02, 0x26, 0x19, 0x40, 0x86, 0x02, 0x69, 0x14, + 0xb0, 0x19, 0x02, 0xde, 0x19, 0x42, 0x86, 0x02, + 0x69, 0x34, 0xa8, 0x13, 0x02, 0xcc, 0x33, 0x42, + 0x86, 0x02, 0x82, 0x34, 0x42, 0x86, 0x02, 0xd1, + 0x19, 0x93, 0x13, 0x02, 0x81, 0x14, 0x42, 0x86, + 0x03, 0xd1, 0x79, 0x30, 0x14, 0xd1, 0x79, 0x02, + 0x68, 0x34, 0xbb, 0x14, 0x02, 0x69, 0x34, 0x95, + 0x86, 0x02, 0xd1, 0x39, 0xbb, 0x14, 0x02, 0x69, + 0x34, 0xeb, 0x13, 0x02, 0xd1, 0x39, 0x84, 0x13, + 0x02, 0x69, 0x34, 0xbc, 0x14, 0x04, 0x69, 0x54, + 0x64, 0x87, 0x8b, 0x14, 0x69, 0x54, 0x02, 0x26, + 0x39, 0x40, 0x86, 0x02, 0xb4, 0x36, 0x40, 0x86, + 0x02, 0x47, 0x16, 0x42, 0x86, 0x02, 0xdc, 0x39, + 0x40, 0x86, 0x02, 0xca, 0x33, 0x40, 0x86, 0x02, + 0xf9, 0x26, 0x40, 0x86, 0x02, 0x69, 0x34, 0x08, + 0x87, 0x03, 0x69, 0x14, 0x69, 0x14, 0x66, 0x14, + 0x03, 0xd1, 0x59, 0x1d, 0x19, 0xd1, 0x59, 0x02, + 0xd4, 0x39, 0x40, 0x86, 0x02, 0xcf, 0x39, 0x40, + 0x86, 0x02, 0x68, 0x34, 0xa4, 0x13, 0x02, 0xd1, + 0x39, 0xa4, 0x13, 0x02, 0xd1, 0x19, 0xa8, 0x13, + 0x02, 0xd7, 0x39, 0x42, 0x86, 0x03, 0x69, 0x34, + 0xbc, 0x19, 0xa1, 0x87, 0x02, 0x68, 0x14, 0xb0, + 0x19, 0x02, 0x3c, 0x39, 0x42, 0x86, 0x02, 0x68, + 0x14, 0x73, 0x13, 0x04, 0x69, 0x14, 0x69, 0x14, + 0x66, 0x14, 0x66, 0x14, 0x03, 0x68, 0x34, 0xaf, + 0x19, 0xa1, 0x87, 0x02, 0x68, 0x34, 0x80, 0x16, + 0x02, 0x73, 0x34, 0x42, 0x86, 0x02, 0xd1, 0x39, + 0x80, 0x16, 0x02, 0x68, 0x34, 0xb0, 0x19, 0x02, + 0x86, 0x34, 0x40, 0x86, 0x02, 0x38, 0x19, 0x42, + 0x86, 0x02, 0x69, 0x34, 0xbb, 0x14, 0x02, 0xb5, + 0x36, 0x42, 0x86, 0x02, 0xcd, 0x39, 0x40, 0x86, + 0x02, 0x68, 0x34, 0x27, 0x15, 0x02, 0x68, 0x34, + 0x95, 0x86, 0x03, 0x68, 0x14, 0x68, 0x14, 0x66, + 0x14, 0x02, 0x71, 0x34, 0x40, 0x86, 0x02, 0xd1, + 0x39, 0x27, 0x15, 0x02, 0x2e, 0x16, 0xa8, 0x14, + 0x02, 0xc3, 0x33, 0x42, 0x86, 0x02, 0x69, 0x14, + 0x66, 0x14, 0x02, 0x68, 0x34, 0x96, 0x86, 0x02, + 0xd1, 0x39, 0x70, 0x1a, 0x03, 0x69, 0x14, 0x64, + 0x87, 0x68, 0x14, 0x02, 0x69, 0x34, 0xa4, 0x13, + 0x02, 0xb8, 0x39, 0x40, 0x86, 0x02, 0x68, 0x34, + 0x3e, 0x13, 0x03, 0xd1, 0x19, 0xaf, 0x19, 0xa1, + 0x87, 0x02, 0xd1, 0x39, 0x3e, 0x13, 0x02, 0x68, + 0x34, 0xbd, 0x19, 0x02, 0xd1, 0x19, 0xbb, 0x14, + 0x02, 0xd1, 0x19, 0x95, 0x86, 0x02, 0xdb, 0x39, + 0x42, 0x86, 0x02, 0x38, 0x39, 0x40, 0x86, 0x02, + 0x69, 0x34, 0x80, 0x16, 0x02, 0x69, 0x14, 0xeb, + 0x13, 0x04, 0x68, 0x14, 0x69, 0x14, 0x67, 0x14, + 0x67, 0x14, 0x02, 0x6f, 0x34, 0x40, 0x86, 0x02, + 0x77, 0x34, 0x42, 0x86, 0x02, 0x46, 0x36, 0x40, + 0x86, 0x02, 0x68, 0x34, 0x92, 0x16, 0x02, 0x4e, + 0x36, 0x42, 0x86, 0x03, 0x69, 0x14, 0xbd, 0x19, + 0xa1, 0x87, 0x02, 0xde, 0x19, 0x40, 0x86, 0x02, + 0x69, 0x34, 0x27, 0x15, 0x03, 0xc3, 0x13, 0x40, + 0x86, 0xa1, 0x87, 0x02, 0x81, 0x14, 0x40, 0x86, + 0x03, 0xd1, 0x39, 0xaf, 0x19, 0xa1, 0x87, 0x02, + 0x68, 0x34, 0xbc, 0x19, 0x02, 0xd1, 0x19, 0x80, + 0x16, 0x02, 0xd9, 0x39, 0x42, 0x86, 0x02, 0xd1, + 0x39, 0xbc, 0x19, 0x02, 0xdc, 0x19, 0x42, 0x86, + 0x02, 0x68, 0x34, 0x73, 0x13, 0x02, 0x69, 0x34, + 0x3e, 0x13, 0x02, 0x47, 0x16, 0x40, 0x86, 0x02, + 0xd1, 0x39, 0xbd, 0x19, 0x02, 0x3e, 0x39, 0x42, + 0x86, 0x02, 0x69, 0x14, 0x95, 0x86, 0x02, 0x68, + 0x14, 0x96, 0x86, 0x03, 0x69, 0x34, 0xbd, 0x19, + 0xa1, 0x87, 0x02, 0xd7, 0x39, 0x40, 0x86, 0x02, + 0x45, 0x16, 0x42, 0x86, 0x02, 0x68, 0x34, 0xed, + 0x13, 0x03, 0x68, 0x34, 0xbc, 0x19, 0xa1, 0x87, + 0x02, 0xd1, 0x39, 0xed, 0x13, 0x02, 0x3c, 0x39, + 0x40, 0x86, 0x02, 0xd1, 0x19, 0x70, 0x1a, 0x02, + 0xd1, 0x39, 0x92, 0x16, 0x02, 0x73, 0x34, 0x40, + 0x86, 0x02, 0x38, 0x19, 0x40, 0x86, 0x02, 0xb5, + 0x36, 0x40, 0x86, 0x02, 0x68, 0x34, 0xaf, 0x19, + 0x02, 0xd1, 0x39, 0xaf, 0x19, 0x02, 0x69, 0x34, + 0xbc, 0x19, 0x02, 0xb6, 0x16, 0x42, 0x86, 0x02, + 0x26, 0x14, 0x25, 0x15, 0x02, 0xc3, 0x33, 0x40, + 0x86, 0x02, 0xdd, 0x39, 0x42, 0x86, 0x02, 0xcb, + 0x93, 0x42, 0x86, 0x02, 0xcb, 0x33, 0x42, 0x86, + 0x02, 0x81, 0x34, 0x42, 0x86, 0x02, 0xce, 0x39, + 0xa1, 0x87, 0x02, 0xdb, 0x39, 0x40, 0x86, 0x02, + 0x68, 0x34, 0x08, 0x87, 0x02, 0xd1, 0x19, 0xb0, + 0x19, 0x02, 0x77, 0x34, 0x40, 0x86, 0x02, 0x4e, + 0x36, 0x40, 0x86, 0x02, 0xce, 0x39, 0x42, 0x86, + 0x02, 0x4e, 0x16, 0x42, 0x86, 0x02, 0xd9, 0x39, + 0x40, 0x86, 0x02, 0xdc, 0x19, 0x40, 0x86, 0x02, + 0x3e, 0x39, 0x40, 0x86, 0x02, 0xb9, 0x39, 0x42, + 0x86, 0x02, 0xda, 0x19, 0x42, 0x86, 0x02, 0x42, + 0x16, 0x94, 0x81, 0x02, 0x45, 0x16, 0x40, 0x86, + 0x02, 0x69, 0x14, 0xbd, 0x19, 0x02, 0x70, 0x34, + 0x42, 0x86, 0x02, 0xce, 0x19, 0xa1, 0x87, 0x02, + 0xc3, 0x13, 0x42, 0x86, 0x02, 0x68, 0x14, 0x08, + 0x87, 0x02, 0xd1, 0x19, 0x7c, 0x13, 0x02, 0x68, + 0x14, 0x92, 0x16, 0x02, 0xb6, 0x16, 0x40, 0x86, + 0x02, 0x37, 0x39, 0x42, 0x86, 0x03, 0xce, 0x19, + 0x42, 0x86, 0xa1, 0x87, 0x03, 0x68, 0x14, 0x67, + 0x14, 0x67, 0x14, 0x02, 0xdd, 0x39, 0x40, 0x86, + 0x02, 0xcf, 0x19, 0x42, 0x86, 0x02, 0xd1, 0x19, + 0x2c, 0x15, 0x02, 0x4b, 0x13, 0xe9, 0x17, 0x02, + 0x68, 0x14, 0x67, 0x14, 0x02, 0xcb, 0x93, 0x40, + 0x86, 0x02, 0x6e, 0x34, 0x42, 0x86, 0x02, 0xcb, + 0x33, 0x40, 0x86, 0x02, 0x81, 0x34, 0x40, 0x86, + 0x02, 0xb6, 0x36, 0xa1, 0x87, 0x02, 0x45, 0x36, + 0x42, 0x86, 0x02, 0xb4, 0x16, 0x42, 0x86, 0x02, + 0x69, 0x14, 0x73, 0x13, 0x04, 0x69, 0x14, 0x69, + 0x14, 0x67, 0x14, 0x66, 0x14, 0x02, 0x35, 0x39, + 0x42, 0x86, 0x02, 0x68, 0x14, 0x93, 0x13, 0x02, + 0xb6, 0x36, 0x42, 0x86, 0x03, 0x68, 0x14, 0x69, + 0x14, 0x66, 0x14, 0x02, 0xce, 0x39, 0x40, 0x86, + 0x02, 0x4e, 0x16, 0x40, 0x86, 0x02, 0x87, 0x34, + 0x42, 0x86, 0x02, 0x86, 0x14, 0x42, 0x86, 0x02, + 0xd6, 0x39, 0x42, 0x86, 0x02, 0xc4, 0x33, 0x42, + 0x86, 0x02, 0x69, 0x34, 0x96, 0x86, 0x02, 0xb9, + 0x39, 0x40, 0x86, 0x02, 0x68, 0x14, 0xa8, 0x13, + 0x02, 0xd1, 0x19, 0x84, 0x13, 0x02, 0xda, 0x19, + 0x40, 0x86, 0x02, 0xd8, 0x19, 0x42, 0x86, 0x02, + 0xc3, 0x13, 0x40, 0x86, 0x02, 0xb9, 0x19, 0x42, + 0x86, 0x02, 0x3d, 0x19, 0x42, 0x86, 0x02, 0xcf, + 0x19, 0x40, 0x86, 0x04, 0x68, 0x14, 0x68, 0x14, + 0x67, 0x14, 0x67, 0x14, 0x03, 0xd1, 0x19, 0xd1, + 0x19, 0xd2, 0x19, 0x02, 0x68, 0x14, 0xbb, 0x14, + 0x02, 0x3b, 0x14, 0x44, 0x87, 0x02, 0xd1, 0x19, + 0x27, 0x15, 0x02, 0xb4, 0x16, 0x40, 0x86, 0x02, + 0xcd, 0x19, 0x42, 0x86, 0x02, 0xd3, 0x86, 0xa5, + 0x14, 0x02, 0x70, 0x14, 0x42, 0x86, 0x03, 0xb6, + 0x16, 0x42, 0x86, 0xa1, 0x87, 0x04, 0x69, 0x14, + 0x64, 0x87, 0x8b, 0x14, 0x69, 0x14, 0x02, 0x36, + 0x16, 0x2b, 0x93, 0x02, 0x68, 0x14, 0x80, 0x16, + 0x02, 0x86, 0x14, 0x40, 0x86, 0x02, 0x08, 0x14, + 0x1b, 0x0b, 0x02, 0xd1, 0x19, 0xbc, 0x19, 0x02, + 0xca, 0x13, 0x42, 0x86, 0x02, 0x41, 0x94, 0xe8, + 0x95, 0x02, 0xd8, 0x19, 0x40, 0x86, 0x02, 0xb9, + 0x19, 0x40, 0x86, 0x02, 0xd1, 0x19, 0xed, 0x13, + 0x02, 0xf9, 0x86, 0x42, 0x86, 0x03, 0xd1, 0x19, + 0xbd, 0x19, 0xa1, 0x87, 0x02, 0x3d, 0x19, 0x40, + 0x86, 0x02, 0xd6, 0x19, 0x42, 0x86, 0x03, 0x69, + 0x14, 0x66, 0x14, 0x66, 0x14, 0x02, 0xd1, 0x19, + 0xaf, 0x19, 0x03, 0x69, 0x14, 0x69, 0x14, 0x67, + 0x14, 0x02, 0xcd, 0x19, 0x40, 0x86, 0x02, 0x70, + 0x14, 0x40, 0x86, 0x03, 0x68, 0x14, 0xbc, 0x19, + 0xa1, 0x87, 0x02, 0x6e, 0x14, 0x42, 0x86, 0x02, + 0x69, 0x14, 0x92, 0x16, 0x03, 0x68, 0x14, 0x68, + 0x14, 0x67, 0x14, 0x02, 0x69, 0x14, 0x67, 0x14, + 0x02, 0x75, 0x95, 0x42, 0x86, 0x03, 0x69, 0x14, + 0x64, 0x87, 0x69, 0x14, 0x02, 0xd1, 0x19, 0xbc, + 0x14, 0x02, 0xdf, 0x19, 0x42, 0x86, 0x02, 0xca, + 0x13, 0x40, 0x86, 0x02, 0x82, 0x14, 0x42, 0x86, + 0x02, 0x69, 0x14, 0x93, 0x13, 0x02, 0x68, 0x14, + 0x7c, 0x13, 0x02, 0xf9, 0x86, 0x40, 0x86, 0x02, + 0xd6, 0x19, 0x40, 0x86, 0x02, 0x68, 0x14, 0x2c, + 0x15, 0x02, 0x69, 0x14, 0xa8, 0x13, 0x02, 0xd4, + 0x19, 0x42, 0x86, 0x04, 0x68, 0x14, 0x69, 0x14, + 0x66, 0x14, 0x66, 0x14, 0x02, 0x77, 0x14, 0x42, + 0x86, 0x02, 0x39, 0x19, 0x42, 0x86, 0x02, 0xd1, + 0x19, 0xa4, 0x13, 0x02, 0x6e, 0x14, 0x40, 0x86, + 0x03, 0xd1, 0x19, 0xd2, 0x19, 0xd2, 0x19, 0x02, + 0x69, 0x14, 0xbb, 0x14, 0x02, 0xd1, 0x19, 0x96, + 0x86, 0x02, 0x75, 0x95, 0x40, 0x86, 0x04, 0x68, + 0x14, 0x64, 0x87, 0x8b, 0x14, 0x68, 0x14, 0x02, + 0xd1, 0x19, 0x3e, 0x13, 0x02, 0xdf, 0x19, 0x40, + 0x86, 0x02, 0x82, 0x14, 0x40, 0x86, 0x02, 0x44, + 0x13, 0xeb, 0x17, 0x02, 0xdd, 0x19, 0x42, 0x86, + 0x03, 0x68, 0x14, 0xaf, 0x19, 0xa1, 0x87, 0x02, + 0x69, 0x14, 0x80, 0x16, 0x02, 0xa3, 0x16, 0x42, + 0x86, 0x02, 0x69, 0x14, 0x96, 0x86, 0x02, 0x46, + 0x16, 0x42, 0x86, 0x02, 0xb6, 0x16, 0xa1, 0x87, + 0x02, 0x68, 0x14, 0x27, 0x15, 0x02, 0x26, 0x14, + 0x1b, 0x0b, 0x02, 0xd4, 0x19, 0x40, 0x86, 0x02, + 0x77, 0x14, 0x40, 0x86, 0x02, 0x39, 0x19, 0x40, + 0x86, 0x02, 0x37, 0x19, 0x42, 0x86, 0x03, 0x69, + 0x14, 0x67, 0x14, 0x66, 0x14, 0x03, 0xc3, 0x13, + 0x42, 0x86, 0xa1, 0x87, 0x02, 0x68, 0x14, 0xbc, + 0x19, 0x02, 0xd1, 0x19, 0xeb, 0x13, 0x04, 0x69, + 0x14, 0x69, 0x14, 0x67, 0x14, 0x67, 0x14, 0x02, + 0xd1, 0x19, 0x08, 0x87, 0x02, 0x68, 0x14, 0xed, + 0x13, 0x03, 0x69, 0x14, 0xbc, 0x19, 0xa1, 0x87, + 0x02, 0xdd, 0x19, 0x40, 0x86, 0x02, 0xc3, 0x13, + 0xa1, 0x87, 0x03, 0x68, 0x14, 0x66, 0x14, 0x66, + 0x14, 0x03, 0x68, 0x14, 0x69, 0x14, 0x67, 0x14, + 0x02, 0xa3, 0x16, 0x40, 0x86, 0x02, 0xdb, 0x19, + 0x42, 0x86, 0x02, 0x68, 0x14, 0xaf, 0x19, 0x02, + 0x46, 0x16, 0x40, 0x86, 0x02, 0x35, 0x16, 0xab, + 0x14, 0x02, 0x68, 0x14, 0x95, 0x86, 0x02, 0x42, + 0x16, 0x95, 0x81, 0x02, 0xc4, 0x13, 0x42, 0x86, + 0x02, 0x15, 0x14, 0xba, 0x19, 0x03, 0xd1, 0x19, + 0x1d, 0x19, 0xd1, 0x19, 0x02, 0x69, 0x14, 0x08, + 0x87, 0x02, 0x69, 0x14, 0x7c, 0x13, 0x02, 0x37, + 0x19, 0x40, 0x86, 0x02, 0x73, 0x14, 0x42, 0x86, + 0x02, 0x69, 0x14, 0x2c, 0x15, 0x02, 0xb5, 0x16, + 0x42, 0x86, 0x02, 0x35, 0x19, 0x42, 0x86, 0x04, + 0x68, 0x14, 0x69, 0x14, 0x67, 0x14, 0x66, 0x14, + 0x02, 0x64, 0x87, 0x25, 0x15, 0x02, 0x64, 0x87, + 0x79, 0x1a, 0x02, 0x68, 0x14, 0xbc, 0x14, 0x03, + 0xce, 0x19, 0x40, 0x86, 0xa1, 0x87, 0x02, 0x87, + 0x14, 0x42, 0x86, 0x02, 0x4d, 0x16, 0x42, 0x86, + 0x04, 0x68, 0x14, 0x68, 0x14, 0x66, 0x14, 0x66, + 0x14, 0x02, 0xdb, 0x19, 0x40, 0x86, 0x02, 0xd9, + 0x19, 0x42, 0x86, 0x02, 0xc4, 0x13, 0x40, 0x86, + 0x02, 0xd1, 0x19, 0xbd, 0x19, 0x02, 0x68, 0x14, + 0xa4, 0x13, 0x02, 0x3e, 0x19, 0x42, 0x86, 0x02, + 0xf3, 0x93, 0xa7, 0x86, 0x03, 0x69, 0x14, 0xaf, + 0x19, 0xa1, 0x87, 0x02, 0xf3, 0x93, 0x08, 0x13, + 0x02, 0xd1, 0x19, 0xd2, 0x19, 0x02, 0x73, 0x14, + 0x40, 0x86, 0x02, 0xb5, 0x16, 0x40, 0x86, 0x02, + 0x35, 0x19, 0x40, 0x86, 0x02, 0x69, 0x14, 0x27, + 0x15, 0x02, 0xce, 0x19, 0x42, 0x86, 0x02, 0x71, + 0x14, 0x42, 0x86, 0x02, 0xd1, 0x19, 0x73, 0x13, + 0x02, 0x68, 0x14, 0x3e, 0x13, 0x02, 0xf4, 0x13, + 0x20, 0x86, 0x02, 0x87, 0x14, 0x40, 0x86, 0x03, + 0xb6, 0x16, 0x40, 0x86, 0xa1, 0x87, 0x02, 0x4d, + 0x16, 0x40, 0x86, 0x02, 0x69, 0x14, 0xbc, 0x19, + 0x02, 0x4b, 0x16, 0x42, 0x86, 0x02, 0xd9, 0x19, + 0x40, 0x86, 0x02, 0x3e, 0x19, 0x40, 0x86, 0x02, + 0x69, 0x14, 0xed, 0x13, 0x02, 0xd7, 0x19, 0x42, + 0x86, 0x02, 0xb8, 0x19, 0x42, 0x86, 0x03, 0x68, + 0x14, 0x67, 0x14, 0x66, 0x14, 0x02, 0x3c, 0x19, + 0x42, 0x86, 0x02, 0x68, 0x14, 0x66, 0x14, 0x03, + 0x68, 0x14, 0x64, 0x87, 0x68, 0x14, 0x02, 0x69, + 0x14, 0xaf, 0x19, 0x02, 0xce, 0x19, 0x40, 0x86, + 0x02, 0x71, 0x14, 0x40, 0x86, 0x02, 0x68, 0x14, + 0xeb, 0x13, 0x03, 0x68, 0x14, 0xbd, 0x19, 0xa1, + 0x87, 0x02, 0x6f, 0x14, 0x42, 0x86, 0x04, 0xd1, + 0x19, 0xd1, 0x19, 0xd2, 0x19, 0xd2, 0x19, 0x02, + 0x69, 0x14, 0xbc, 0x14, 0x02, 0xcc, 0x93, 0x42, + 0x86, 0x02, 0x4b, 0x16, 0x40, 0x86, 0x02, 0x26, + 0x19, 0x42, 0x86, 0x02, 0xd7, 0x19, 0x40, 0x86, +}; + diff --git a/userland/qjs/source/libunicode.c b/userland/qjs/source/libunicode.c new file mode 100644 index 0000000..5a681bf --- /dev/null +++ b/userland/qjs/source/libunicode.c @@ -0,0 +1,2074 @@ +/* + * Unicode utilities + * + * Copyright (c) 2017-2018 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include + +#include "cutils.h" +#include "libunicode.h" +#include "libunicode-table.h" + +// note: stored as 4 bit tag, not much room left +enum { + RUN_TYPE_U, + RUN_TYPE_L, + RUN_TYPE_UF, + RUN_TYPE_LF, + RUN_TYPE_UL, + RUN_TYPE_LSU, + RUN_TYPE_U2L_399_EXT2, + RUN_TYPE_UF_D20, + RUN_TYPE_UF_D1_EXT, + RUN_TYPE_U_EXT, + RUN_TYPE_LF_EXT, + RUN_TYPE_UF_EXT2, + RUN_TYPE_LF_EXT2, + RUN_TYPE_UF_EXT3, +}; + +static int lre_case_conv1(uint32_t c, int conv_type) +{ + uint32_t res[LRE_CC_RES_LEN_MAX]; + lre_case_conv(res, c, conv_type); + return res[0]; +} + +/* case conversion using the table entry 'idx' with value 'v' */ +static int lre_case_conv_entry(uint32_t *res, uint32_t c, int conv_type, uint32_t idx, uint32_t v) +{ + uint32_t code, data, type, a, is_lower; + is_lower = (conv_type != 0); + type = (v >> (32 - 17 - 7 - 4)) & 0xf; + data = ((v & 0xf) << 8) | case_conv_table2[idx]; + code = v >> (32 - 17); + switch(type) { + case RUN_TYPE_U: + case RUN_TYPE_L: + case RUN_TYPE_UF: + case RUN_TYPE_LF: + if (conv_type == (type & 1) || + (type >= RUN_TYPE_UF && conv_type == 2)) { + c = c - code + (case_conv_table1[data] >> (32 - 17)); + } + break; + case RUN_TYPE_UL: + a = c - code; + if ((a & 1) != (1 - is_lower)) + break; + c = (a ^ 1) + code; + break; + case RUN_TYPE_LSU: + a = c - code; + if (a == 1) { + c += 2 * is_lower - 1; + } else if (a == (1 - is_lower) * 2) { + c += (2 * is_lower - 1) * 2; + } + break; + case RUN_TYPE_U2L_399_EXT2: + if (!is_lower) { + res[0] = c - code + case_conv_ext[data >> 6]; + res[1] = 0x399; + return 2; + } else { + c = c - code + case_conv_ext[data & 0x3f]; + } + break; + case RUN_TYPE_UF_D20: + if (conv_type == 1) + break; + c = data + (conv_type == 2) * 0x20; + break; + case RUN_TYPE_UF_D1_EXT: + if (conv_type == 1) + break; + c = case_conv_ext[data] + (conv_type == 2); + break; + case RUN_TYPE_U_EXT: + case RUN_TYPE_LF_EXT: + if (is_lower != (type - RUN_TYPE_U_EXT)) + break; + c = case_conv_ext[data]; + break; + case RUN_TYPE_LF_EXT2: + if (!is_lower) + break; + res[0] = c - code + case_conv_ext[data >> 6]; + res[1] = case_conv_ext[data & 0x3f]; + return 2; + case RUN_TYPE_UF_EXT2: + if (conv_type == 1) + break; + res[0] = c - code + case_conv_ext[data >> 6]; + res[1] = case_conv_ext[data & 0x3f]; + if (conv_type == 2) { + /* convert to lower */ + res[0] = lre_case_conv1(res[0], 1); + res[1] = lre_case_conv1(res[1], 1); + } + return 2; + default: + case RUN_TYPE_UF_EXT3: + if (conv_type == 1) + break; + res[0] = case_conv_ext[data >> 8]; + res[1] = case_conv_ext[(data >> 4) & 0xf]; + res[2] = case_conv_ext[data & 0xf]; + if (conv_type == 2) { + /* convert to lower */ + res[0] = lre_case_conv1(res[0], 1); + res[1] = lre_case_conv1(res[1], 1); + res[2] = lre_case_conv1(res[2], 1); + } + return 3; + } + res[0] = c; + return 1; +} + +/* conv_type: + 0 = to upper + 1 = to lower + 2 = case folding (= to lower with modifications) +*/ +int lre_case_conv(uint32_t *res, uint32_t c, int conv_type) +{ + if (c < 128) { + if (conv_type) { + if (c >= 'A' && c <= 'Z') { + c = c - 'A' + 'a'; + } + } else { + if (c >= 'a' && c <= 'z') { + c = c - 'a' + 'A'; + } + } + } else { + uint32_t v, code, len; + int idx, idx_min, idx_max; + + idx_min = 0; + idx_max = countof(case_conv_table1) - 1; + while (idx_min <= idx_max) { + idx = (unsigned)(idx_max + idx_min) / 2; + v = case_conv_table1[idx]; + code = v >> (32 - 17); + len = (v >> (32 - 17 - 7)) & 0x7f; + if (c < code) { + idx_max = idx - 1; + } else if (c >= code + len) { + idx_min = idx + 1; + } else { + return lre_case_conv_entry(res, c, conv_type, idx, v); + } + } + } + res[0] = c; + return 1; +} + +static int lre_case_folding_entry(uint32_t c, uint32_t idx, uint32_t v, bool is_unicode) +{ + uint32_t res[LRE_CC_RES_LEN_MAX]; + int len; + + if (is_unicode) { + len = lre_case_conv_entry(res, c, 2, idx, v); + if (len == 1) { + c = res[0]; + } else { + /* handle the few specific multi-character cases (see + unicode_gen.c:dump_case_folding_special_cases()) */ + if (c == 0xfb06) { + c = 0xfb05; + } else if (c == 0x01fd3) { + c = 0x390; + } else if (c == 0x01fe3) { + c = 0x3b0; + } + } + } else { + if (likely(c < 128)) { + if (c >= 'a' && c <= 'z') + c = c - 'a' + 'A'; + } else { + /* legacy regexp: to upper case if single char >= 128 */ + len = lre_case_conv_entry(res, c, false, idx, v); + if (len == 1 && res[0] >= 128) + c = res[0]; + } + } + return c; +} + +/* JS regexp specific rules for case folding */ +int lre_canonicalize(uint32_t c, bool is_unicode) +{ + if (c < 128) { + /* fast case */ + if (is_unicode) { + if (c >= 'A' && c <= 'Z') { + c = c - 'A' + 'a'; + } + } else { + if (c >= 'a' && c <= 'z') { + c = c - 'a' + 'A'; + } + } + } else { + uint32_t v, code, len; + int idx, idx_min, idx_max; + + idx_min = 0; + idx_max = countof(case_conv_table1) - 1; + while (idx_min <= idx_max) { + idx = (unsigned)(idx_max + idx_min) / 2; + v = case_conv_table1[idx]; + code = v >> (32 - 17); + len = (v >> (32 - 17 - 7)) & 0x7f; + if (c < code) { + idx_max = idx - 1; + } else if (c >= code + len) { + idx_min = idx + 1; + } else { + return lre_case_folding_entry(c, idx, v, is_unicode); + } + } + } + return c; +} + +static uint32_t get_le24(const uint8_t *ptr) +{ + return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16); +} + +#define UNICODE_INDEX_BLOCK_LEN 32 + +/* return -1 if not in table, otherwise the offset in the block */ +static int get_index_pos(uint32_t *pcode, uint32_t c, + const uint8_t *index_table, int index_table_len) +{ + uint32_t code, v; + int idx_min, idx_max, idx; + + idx_min = 0; + v = get_le24(index_table); + code = v & ((1 << 21) - 1); + if (c < code) { + *pcode = 0; + return 0; + } + idx_max = index_table_len - 1; + code = get_le24(index_table + idx_max * 3); + if (c >= code) + return -1; + /* invariant: tab[idx_min] <= c < tab2[idx_max] */ + while ((idx_max - idx_min) > 1) { + idx = (idx_max + idx_min) / 2; + v = get_le24(index_table + idx * 3); + code = v & ((1 << 21) - 1); + if (c < code) { + idx_max = idx; + } else { + idx_min = idx; + } + } + v = get_le24(index_table + idx_min * 3); + *pcode = v & ((1 << 21) - 1); + return (idx_min + 1) * UNICODE_INDEX_BLOCK_LEN + (v >> 21); +} + +static bool lre_is_in_table(uint32_t c, const uint8_t *table, + const uint8_t *index_table, int index_table_len) +{ + uint32_t code, b, bit; + int pos; + const uint8_t *p; + + pos = get_index_pos(&code, c, index_table, index_table_len); + if (pos < 0) + return false; /* outside the table */ + p = table + pos; + bit = 0; + for(;;) { + b = *p++; + if (b < 64) { + code += (b >> 3) + 1; + if (c < code) + return bit; + bit ^= 1; + code += (b & 7) + 1; + } else if (b >= 0x80) { + code += b - 0x80 + 1; + } else if (b < 0x60) { + code += (((b - 0x40) << 8) | p[0]) + 1; + p++; + } else { + code += (((b - 0x60) << 16) | (p[0] << 8) | p[1]) + 1; + p += 2; + } + if (c < code) + return bit; + bit ^= 1; + } +} + +bool lre_is_cased(uint32_t c) +{ + uint32_t v, code, len; + int idx, idx_min, idx_max; + + idx_min = 0; + idx_max = countof(case_conv_table1) - 1; + while (idx_min <= idx_max) { + idx = (unsigned)(idx_max + idx_min) / 2; + v = case_conv_table1[idx]; + code = v >> (32 - 17); + len = (v >> (32 - 17 - 7)) & 0x7f; + if (c < code) { + idx_max = idx - 1; + } else if (c >= code + len) { + idx_min = idx + 1; + } else { + return true; + } + } + return lre_is_in_table(c, unicode_prop_Cased1_table, + unicode_prop_Cased1_index, + sizeof(unicode_prop_Cased1_index) / 3); +} + +bool lre_is_case_ignorable(uint32_t c) +{ + return lre_is_in_table(c, unicode_prop_Case_Ignorable_table, + unicode_prop_Case_Ignorable_index, + sizeof(unicode_prop_Case_Ignorable_index) / 3); +} + +/* character range */ + +static __maybe_unused void cr_dump(CharRange *cr) +{ + int i; + for(i = 0; i < cr->len; i++) + printf("%d: 0x%04x\n", i, cr->points[i]); +} + +static void *cr_default_realloc(void *opaque, void *ptr, size_t size) +{ + return realloc(ptr, size); +} + +void cr_init(CharRange *cr, void *mem_opaque, DynBufReallocFunc *realloc_func) +{ + cr->len = cr->size = 0; + cr->points = NULL; + cr->mem_opaque = mem_opaque; + cr->realloc_func = realloc_func ? realloc_func : cr_default_realloc; +} + +void cr_free(CharRange *cr) +{ + cr->realloc_func(cr->mem_opaque, cr->points, 0); +} + +int cr_realloc(CharRange *cr, int size) +{ + int new_size; + uint32_t *new_buf; + + if (size > cr->size) { + new_size = max_int(size, cr->size * 3 / 2); + new_buf = cr->realloc_func(cr->mem_opaque, cr->points, + new_size * sizeof(cr->points[0])); + if (!new_buf) + return -1; + cr->points = new_buf; + cr->size = new_size; + } + return 0; +} + +int cr_copy(CharRange *cr, const CharRange *cr1) +{ + if (cr_realloc(cr, cr1->len)) + return -1; + memcpy(cr->points, cr1->points, sizeof(cr->points[0]) * cr1->len); + cr->len = cr1->len; + return 0; +} + +/* merge consecutive intervals and remove empty intervals */ +static void cr_compress(CharRange *cr) +{ + int i, j, k, len; + uint32_t *pt; + + pt = cr->points; + len = cr->len; + i = 0; + j = 0; + k = 0; + while ((i + 1) < len) { + if (pt[i] == pt[i + 1]) { + /* empty interval */ + i += 2; + } else { + j = i; + while ((j + 3) < len && pt[j + 1] == pt[j + 2]) + j += 2; + /* just copy */ + pt[k] = pt[i]; + pt[k + 1] = pt[j + 1]; + k += 2; + i = j + 2; + } + } + cr->len = k; +} + +/* union or intersection */ +int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len, + const uint32_t *b_pt, int b_len, int op) +{ + int a_idx, b_idx, is_in; + uint32_t v; + + a_idx = 0; + b_idx = 0; + for(;;) { + /* get one more point from a or b in increasing order */ + if (a_idx < a_len && b_idx < b_len) { + if (a_pt[a_idx] < b_pt[b_idx]) { + goto a_add; + } else if (a_pt[a_idx] == b_pt[b_idx]) { + v = a_pt[a_idx]; + a_idx++; + b_idx++; + } else { + goto b_add; + } + } else if (a_idx < a_len) { + a_add: + v = a_pt[a_idx++]; + } else if (b_idx < b_len) { + b_add: + v = b_pt[b_idx++]; + } else { + break; + } + /* add the point if the in/out status changes */ + switch(op) { + case CR_OP_UNION: + is_in = (a_idx & 1) | (b_idx & 1); + break; + case CR_OP_INTER: + is_in = (a_idx & 1) & (b_idx & 1); + break; + case CR_OP_XOR: + is_in = (a_idx & 1) ^ (b_idx & 1); + break; + case CR_OP_SUB: + is_in = (a_idx & 1) & ((b_idx & 1) ^ 1); + break; + default: + abort(); + } + if (is_in != (cr->len & 1)) { + if (cr_add_point(cr, v)) + return -1; + } + } + cr_compress(cr); + return 0; +} + +int cr_op1(CharRange *cr, const uint32_t *b_pt, int b_len, int op) +{ + CharRange a = *cr; + int ret; + cr->len = 0; + cr->size = 0; + cr->points = NULL; + ret = cr_op(cr, a.points, a.len, b_pt, b_len, op); + cr_free(&a); + return ret; +} + +int cr_invert(CharRange *cr) +{ + int len; + len = cr->len; + if (cr_realloc(cr, len + 2)) + return -1; + memmove(cr->points + 1, cr->points, len * sizeof(cr->points[0])); + cr->points[0] = 0; + cr->points[len + 1] = UINT32_MAX; + cr->len = len + 2; + cr_compress(cr); + return 0; +} + +bool lre_is_id_start(uint32_t c) +{ + return lre_is_in_table(c, unicode_prop_ID_Start_table, + unicode_prop_ID_Start_index, + sizeof(unicode_prop_ID_Start_index) / 3); +} + +bool lre_is_id_continue(uint32_t c) +{ + return lre_is_id_start(c) || + lre_is_in_table(c, unicode_prop_ID_Continue1_table, + unicode_prop_ID_Continue1_index, + sizeof(unicode_prop_ID_Continue1_index) / 3); +} + +bool lre_is_white_space(uint32_t c) +{ + return lre_is_in_table(c, unicode_prop_White_Space_table, + unicode_prop_White_Space_index, + sizeof(unicode_prop_White_Space_index) / 3); +} + +/*---- lre codepoint categorizing functions ----*/ + +#define S UNICODE_C_SPACE +#define D UNICODE_C_DIGIT +#define X UNICODE_C_XDIGIT +#define U UNICODE_C_UPPER +#define L UNICODE_C_LOWER +#define _ UNICODE_C_UNDER +#define d UNICODE_C_DOLLAR + +uint8_t const lre_ctype_bits[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, S, S, S, S, S, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + S, 0, 0, 0, d, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + X|D, X|D, X|D, X|D, X|D, X|D, X|D, X|D, + X|D, X|D, 0, 0, 0, 0, 0, 0, + + 0, X|U, X|U, X|U, X|U, X|U, X|U, U, + U, U, U, U, U, U, U, U, + U, U, U, U, U, U, U, U, + U, U, U, 0, 0, 0, 0, _, + + 0, X|L, X|L, X|L, X|L, X|L, X|L, L, + L, L, L, L, L, L, L, L, + L, L, L, L, L, L, L, L, + L, L, L, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + S, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +#undef S +#undef D +#undef X +#undef U +#undef L +#undef _ +#undef d + +/* code point ranges for Zs,Zl or Zp property */ +static const uint16_t char_range_space[] = { + 10, + 0x0009, 0x000D + 1, + 0x0020, 0x0020 + 1, + 0x00A0, 0x00A0 + 1, + 0x1680, 0x1680 + 1, + 0x2000, 0x200A + 1, + /* 2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;; */ + /* 2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;; */ + 0x2028, 0x2029 + 1, + 0x202F, 0x202F + 1, + 0x205F, 0x205F + 1, + 0x3000, 0x3000 + 1, + /* FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; */ + 0xFEFF, 0xFEFF + 1, +}; + +int lre_is_space_non_ascii(uint32_t c) +{ + size_t i, n; + + n = countof(char_range_space); + for(i = 5; i < n; i += 2) { + uint32_t low = char_range_space[i]; + uint32_t high = char_range_space[i + 1]; + if (c < low) + return false; + if (c < high) + return true; + } + return false; +} + + +#define UNICODE_DECOMP_LEN_MAX 18 + +typedef enum { + DECOMP_TYPE_C1, /* 16 bit char */ + DECOMP_TYPE_L1, /* 16 bit char table */ + DECOMP_TYPE_L2, + DECOMP_TYPE_L3, + DECOMP_TYPE_L4, + DECOMP_TYPE_L5, /* XXX: not used */ + DECOMP_TYPE_L6, /* XXX: could remove */ + DECOMP_TYPE_L7, /* XXX: could remove */ + DECOMP_TYPE_LL1, /* 18 bit char table */ + DECOMP_TYPE_LL2, + DECOMP_TYPE_S1, /* 8 bit char table */ + DECOMP_TYPE_S2, + DECOMP_TYPE_S3, + DECOMP_TYPE_S4, + DECOMP_TYPE_S5, + DECOMP_TYPE_I1, /* increment 16 bit char value */ + DECOMP_TYPE_I2_0, + DECOMP_TYPE_I2_1, + DECOMP_TYPE_I3_1, + DECOMP_TYPE_I3_2, + DECOMP_TYPE_I4_1, + DECOMP_TYPE_I4_2, + DECOMP_TYPE_B1, /* 16 bit base + 8 bit offset */ + DECOMP_TYPE_B2, + DECOMP_TYPE_B3, + DECOMP_TYPE_B4, + DECOMP_TYPE_B5, + DECOMP_TYPE_B6, + DECOMP_TYPE_B7, + DECOMP_TYPE_B8, + DECOMP_TYPE_B18, + DECOMP_TYPE_LS2, + DECOMP_TYPE_PAT3, + DECOMP_TYPE_S2_UL, + DECOMP_TYPE_LS2_UL, +} DecompTypeEnum; + +static uint32_t unicode_get_short_code(uint32_t c) +{ + static const uint16_t unicode_short_table[2] = { 0x2044, 0x2215 }; + + if (c < 0x80) + return c; + else if (c < 0x80 + 0x50) + return c - 0x80 + 0x300; + else + return unicode_short_table[c - 0x80 - 0x50]; +} + +static uint32_t unicode_get_lower_simple(uint32_t c) +{ + if (c < 0x100 || (c >= 0x410 && c <= 0x42f)) + c += 0x20; + else + c++; + return c; +} + +static uint16_t unicode_get16(const uint8_t *p) +{ + return p[0] | (p[1] << 8); +} + +static int unicode_decomp_entry(uint32_t *res, uint32_t c, + int idx, uint32_t code, uint32_t len, + uint32_t type) +{ + uint32_t c1; + int l, i, p; + const uint8_t *d; + + if (type == DECOMP_TYPE_C1) { + res[0] = unicode_decomp_table2[idx]; + return 1; + } else { + d = unicode_decomp_data + unicode_decomp_table2[idx]; + switch(type) { + case DECOMP_TYPE_L1: + case DECOMP_TYPE_L2: + case DECOMP_TYPE_L3: + case DECOMP_TYPE_L4: + case DECOMP_TYPE_L5: + case DECOMP_TYPE_L6: + case DECOMP_TYPE_L7: + l = type - DECOMP_TYPE_L1 + 1; + d += (c - code) * l * 2; + for(i = 0; i < l; i++) { + if ((res[i] = unicode_get16(d + 2 * i)) == 0) + return 0; + } + return l; + case DECOMP_TYPE_LL1: + case DECOMP_TYPE_LL2: + { + uint32_t k, p; + l = type - DECOMP_TYPE_LL1 + 1; + k = (c - code) * l; + p = len * l * 2; + for(i = 0; i < l; i++) { + c1 = unicode_get16(d + 2 * k) | + (((d[p + (k / 4)] >> ((k % 4) * 2)) & 3) << 16); + if (!c1) + return 0; + res[i] = c1; + k++; + } + } + return l; + case DECOMP_TYPE_S1: + case DECOMP_TYPE_S2: + case DECOMP_TYPE_S3: + case DECOMP_TYPE_S4: + case DECOMP_TYPE_S5: + l = type - DECOMP_TYPE_S1 + 1; + d += (c - code) * l; + for(i = 0; i < l; i++) { + if ((res[i] = unicode_get_short_code(d[i])) == 0) + return 0; + } + return l; + case DECOMP_TYPE_I1: + l = 1; + p = 0; + goto decomp_type_i; + case DECOMP_TYPE_I2_0: + case DECOMP_TYPE_I2_1: + case DECOMP_TYPE_I3_1: + case DECOMP_TYPE_I3_2: + case DECOMP_TYPE_I4_1: + case DECOMP_TYPE_I4_2: + l = 2 + ((type - DECOMP_TYPE_I2_0) >> 1); + p = ((type - DECOMP_TYPE_I2_0) & 1) + (l > 2); + decomp_type_i: + for(i = 0; i < l; i++) { + c1 = unicode_get16(d + 2 * i); + if (i == p) + c1 += c - code; + res[i] = c1; + } + return l; + case DECOMP_TYPE_B18: + l = 18; + goto decomp_type_b; + case DECOMP_TYPE_B1: + case DECOMP_TYPE_B2: + case DECOMP_TYPE_B3: + case DECOMP_TYPE_B4: + case DECOMP_TYPE_B5: + case DECOMP_TYPE_B6: + case DECOMP_TYPE_B7: + case DECOMP_TYPE_B8: + l = type - DECOMP_TYPE_B1 + 1; + decomp_type_b: + { + uint32_t c_min; + c_min = unicode_get16(d); + d += 2 + (c - code) * l; + for(i = 0; i < l; i++) { + c1 = d[i]; + if (c1 == 0xff) + c1 = 0x20; + else + c1 += c_min; + res[i] = c1; + } + } + return l; + case DECOMP_TYPE_LS2: + d += (c - code) * 3; + if (!(res[0] = unicode_get16(d))) + return 0; + res[1] = unicode_get_short_code(d[2]); + return 2; + case DECOMP_TYPE_PAT3: + res[0] = unicode_get16(d); + res[2] = unicode_get16(d + 2); + d += 4 + (c - code) * 2; + res[1] = unicode_get16(d); + return 3; + case DECOMP_TYPE_S2_UL: + case DECOMP_TYPE_LS2_UL: + c1 = c - code; + if (type == DECOMP_TYPE_S2_UL) { + d += c1 & ~1; + c = unicode_get_short_code(*d); + d++; + } else { + d += (c1 >> 1) * 3; + c = unicode_get16(d); + d += 2; + } + if (c1 & 1) + c = unicode_get_lower_simple(c); + res[0] = c; + res[1] = unicode_get_short_code(*d); + return 2; + } + } + return 0; +} + + +/* return the length of the decomposition (length <= + UNICODE_DECOMP_LEN_MAX) or 0 if no decomposition */ +static int unicode_decomp_char(uint32_t *res, uint32_t c, bool is_compat1) +{ + uint32_t v, type, is_compat, code, len; + int idx_min, idx_max, idx; + + idx_min = 0; + idx_max = countof(unicode_decomp_table1) - 1; + while (idx_min <= idx_max) { + idx = (idx_max + idx_min) / 2; + v = unicode_decomp_table1[idx]; + code = v >> (32 - 18); + len = (v >> (32 - 18 - 7)) & 0x7f; + // printf("idx=%d code=%05x len=%d\n", idx, code, len); + if (c < code) { + idx_max = idx - 1; + } else if (c >= code + len) { + idx_min = idx + 1; + } else { + is_compat = v & 1; + if (is_compat1 < is_compat) + break; + type = (v >> (32 - 18 - 7 - 6)) & 0x3f; + return unicode_decomp_entry(res, c, idx, code, len, type); + } + } + return 0; +} + +/* return 0 if no pair found */ +static int unicode_compose_pair(uint32_t c0, uint32_t c1) +{ + uint32_t code, len, type, v, idx1, d_idx, d_offset, ch; + int idx_min, idx_max, idx, d; + uint32_t pair[2]; + + idx_min = 0; + idx_max = countof(unicode_comp_table) - 1; + while (idx_min <= idx_max) { + idx = (idx_max + idx_min) / 2; + idx1 = unicode_comp_table[idx]; + + /* idx1 represent an entry of the decomposition table */ + d_idx = idx1 >> 6; + d_offset = idx1 & 0x3f; + v = unicode_decomp_table1[d_idx]; + code = v >> (32 - 18); + len = (v >> (32 - 18 - 7)) & 0x7f; + type = (v >> (32 - 18 - 7 - 6)) & 0x3f; + ch = code + d_offset; + unicode_decomp_entry(pair, ch, d_idx, code, len, type); + d = c0 - pair[0]; + if (d == 0) + d = c1 - pair[1]; + if (d < 0) { + idx_max = idx - 1; + } else if (d > 0) { + idx_min = idx + 1; + } else { + return ch; + } + } + return 0; +} + +/* return the combining class of character c (between 0 and 255) */ +static int unicode_get_cc(uint32_t c) +{ + uint32_t code, n, type, cc, c1, b; + int pos; + const uint8_t *p; + + pos = get_index_pos(&code, c, + unicode_cc_index, sizeof(unicode_cc_index) / 3); + if (pos < 0) + return 0; + p = unicode_cc_table + pos; + for(;;) { + b = *p++; + type = b >> 6; + n = b & 0x3f; + if (n < 48) { + } else if (n < 56) { + n = (n - 48) << 8; + n |= *p++; + n += 48; + } else { + n = (n - 56) << 8; + n |= *p++ << 8; + n |= *p++; + n += 48 + (1 << 11); + } + if (type <= 1) + p++; + c1 = code + n + 1; + if (c < c1) { + switch(type) { + case 0: + cc = p[-1]; + break; + case 1: + cc = p[-1] + c - code; + break; + case 2: + cc = 0; + break; + default: + case 3: + cc = 230; + break; + } + return cc; + } + code = c1; + } +} + +static void sort_cc(int *buf, int len) +{ + int i, j, k, cc, cc1, start, ch1; + + for(i = 0; i < len; i++) { + cc = unicode_get_cc(buf[i]); + if (cc != 0) { + start = i; + j = i + 1; + while (j < len) { + ch1 = buf[j]; + cc1 = unicode_get_cc(ch1); + if (cc1 == 0) + break; + k = j - 1; + while (k >= start) { + if (unicode_get_cc(buf[k]) <= cc1) + break; + buf[k + 1] = buf[k]; + k--; + } + buf[k + 1] = ch1; + j++; + } + i = j; + } + } +} + +static void to_nfd_rec(DynBuf *dbuf, + const int *src, int src_len, int is_compat) +{ + uint32_t c, v; + int i, l; + uint32_t res[UNICODE_DECOMP_LEN_MAX]; + + for(i = 0; i < src_len; i++) { + c = src[i]; + if (c >= 0xac00 && c < 0xd7a4) { + /* Hangul decomposition */ + c -= 0xac00; + dbuf_put_u32(dbuf, 0x1100 + c / 588); + dbuf_put_u32(dbuf, 0x1161 + (c % 588) / 28); + v = c % 28; + if (v != 0) + dbuf_put_u32(dbuf, 0x11a7 + v); + } else { + l = unicode_decomp_char(res, c, is_compat); + if (l) { + to_nfd_rec(dbuf, (int *)res, l, is_compat); + } else { + dbuf_put_u32(dbuf, c); + } + } + } +} + +/* return 0 if not found */ +static int compose_pair(uint32_t c0, uint32_t c1) +{ + /* Hangul composition */ + if (c0 >= 0x1100 && c0 < 0x1100 + 19 && + c1 >= 0x1161 && c1 < 0x1161 + 21) { + return 0xac00 + (c0 - 0x1100) * 588 + (c1 - 0x1161) * 28; + } else if (c0 >= 0xac00 && c0 < 0xac00 + 11172 && + (c0 - 0xac00) % 28 == 0 && + c1 >= 0x11a7 && c1 < 0x11a7 + 28) { + return c0 + c1 - 0x11a7; + } else { + return unicode_compose_pair(c0, c1); + } +} + +int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len, + UnicodeNormalizationEnum n_type, + void *opaque, DynBufReallocFunc *realloc_func) +{ + int *buf, buf_len, i, p, starter_pos, cc, last_cc, out_len; + bool is_compat; + DynBuf dbuf_s, *dbuf = &dbuf_s; + + if (src_len == 0) { + *pdst = NULL; + return 0; + } + + is_compat = n_type >> 1; + + dbuf_init2(dbuf, opaque, realloc_func); + if (dbuf_claim(dbuf, sizeof(int) * src_len)) + goto fail; + + /* common case: latin1 is unaffected by NFC */ + if (n_type == UNICODE_NFC) { + for(i = 0; i < src_len; i++) { + if (src[i] >= 0x100) + goto not_latin1; + } + buf = (int *)dbuf->buf; + memcpy(buf, src, src_len * sizeof(int)); + *pdst = (uint32_t *)buf; + return src_len; + not_latin1: ; + } + + to_nfd_rec(dbuf, (const int *)src, src_len, is_compat); + if (dbuf_error(dbuf)) { + fail: + *pdst = NULL; + return -1; + } + buf = (int *)dbuf->buf; + buf_len = dbuf->size / sizeof(int); + + sort_cc(buf, buf_len); + + if (buf_len <= 1 || (n_type & 1) != 0) { + /* NFD / NFKD */ + *pdst = (uint32_t *)buf; + return buf_len; + } + + i = 1; + out_len = 1; + while (i < buf_len) { + /* find the starter character and test if it is blocked from + the character at 'i' */ + last_cc = unicode_get_cc(buf[i]); + starter_pos = out_len - 1; + while (starter_pos >= 0) { + cc = unicode_get_cc(buf[starter_pos]); + if (cc == 0) + break; + if (cc >= last_cc) + goto next; + last_cc = 256; + starter_pos--; + } + if (starter_pos >= 0 && + (p = compose_pair(buf[starter_pos], buf[i])) != 0) { + buf[starter_pos] = p; + i++; + } else { + next: + buf[out_len++] = buf[i++]; + } + } + *pdst = (uint32_t *)buf; + return out_len; +} + +/* char ranges for various unicode properties */ + +static int unicode_find_name(const char *name_table, const char *name) +{ + const char *p, *r; + int pos; + size_t name_len, len; + + p = name_table; + pos = 0; + name_len = strlen(name); + while (*p) { + for(;;) { + r = strchr(p, ','); + if (!r) + len = strlen(p); + else + len = r - p; + if (len == name_len && !memcmp(p, name, name_len)) + return pos; + p += len + 1; + if (!r) + break; + } + pos++; + } + return -1; +} + +/* 'cr' must be initialized and empty. Return 0 if OK, -1 if error, -2 + if not found */ +int unicode_script(CharRange *cr, + const char *script_name, bool is_ext) +{ + int script_idx; + const uint8_t *p, *p_end; + uint32_t c, c1, b, n, v, v_len, i, type; + CharRange cr1_s = { 0 }, *cr1 = NULL; + CharRange cr2_s = { 0 }, *cr2 = &cr2_s; + bool is_common; + + if (!strcmp(script_name, "Unknown") || !strcmp(script_name, "Zzzz")) { + /* "Unknown" (ISO 15924 code "Zzzz") is excluded from the name table; + it matches every character outside any script. */ + script_idx = UNICODE_SCRIPT_Unknown; + } else { + script_idx = unicode_find_name(unicode_script_name_table, script_name); + if (script_idx < 0) + return -2; + /* Note: the name table excludes the "Unknown" Script */ + script_idx += UNICODE_SCRIPT_Unknown + 1; + } + + is_common = (script_idx == UNICODE_SCRIPT_Common || + script_idx == UNICODE_SCRIPT_Inherited); + if (is_ext) { + cr1 = &cr1_s; + cr_init(cr1, cr->mem_opaque, cr->realloc_func); + cr_init(cr2, cr->mem_opaque, cr->realloc_func); + } else { + cr1 = cr; + } + + p = unicode_script_table; + p_end = unicode_script_table + countof(unicode_script_table); + c = 0; + while (p < p_end) { + b = *p++; + type = b >> 7; + n = b & 0x7f; + if (n < 96) { + } else if (n < 112) { + n = (n - 96) << 8; + n |= *p++; + n += 96; + } else { + n = (n - 112) << 16; + n |= *p++ << 8; + n |= *p++; + n += 96 + (1 << 12); + } + if (type == 0) + v = 0; + else + v = *p++; + c1 = c + n + 1; + /* only script-bearing ranges (type != 0); for Unknown, match every + such range and invert afterwards */ + if (type != 0 && + (v == script_idx || script_idx == UNICODE_SCRIPT_Unknown)) { + if (cr_add_interval(cr1, c, c1)) + goto fail; + } + c = c1; + } + + if (script_idx == UNICODE_SCRIPT_Unknown) { + /* Unknown is all the characters outside scripts */ + if (cr_invert(cr1)) + goto fail; + } + + if (is_ext) { + /* add the script extensions */ + p = unicode_script_ext_table; + p_end = unicode_script_ext_table + countof(unicode_script_ext_table); + c = 0; + while (p < p_end) { + b = *p++; + if (b < 128) { + n = b; + } else if (b < 128 + 64) { + n = (b - 128) << 8; + n |= *p++; + n += 128; + } else { + n = (b - 128 - 64) << 16; + n |= *p++ << 8; + n |= *p++; + n += 128 + (1 << 14); + } + c1 = c + n + 1; + v_len = *p++; + if (is_common) { + if (v_len != 0) { + if (cr_add_interval(cr2, c, c1)) + goto fail; + } + } else { + for(i = 0; i < v_len; i++) { + if (p[i] == script_idx) { + if (cr_add_interval(cr2, c, c1)) + goto fail; + break; + } + } + } + p += v_len; + c = c1; + } + if (is_common) { + /* remove all the characters with script extensions */ + if (cr_invert(cr2)) + goto fail; + if (cr_op(cr, cr1->points, cr1->len, cr2->points, cr2->len, + CR_OP_INTER)) + goto fail; + } else { + if (cr_op(cr, cr1->points, cr1->len, cr2->points, cr2->len, + CR_OP_UNION)) + goto fail; + } + cr_free(cr1); + cr_free(cr2); + } + return 0; + fail: + if (is_ext) { + cr_free(cr1); + cr_free(cr2); + } + return -1; +} + +#define M(id) (1U << UNICODE_GC_ ## id) + +static int unicode_general_category1(CharRange *cr, uint32_t gc_mask) +{ + const uint8_t *p, *p_end; + uint32_t c, c0, b, n, v; + + p = unicode_gc_table; + p_end = unicode_gc_table + countof(unicode_gc_table); + c = 0; + while (p < p_end) { + b = *p++; + n = b >> 5; + v = b & 0x1f; + if (n == 7) { + n = *p++; + if (n < 128) { + n += 7; + } else if (n < 128 + 64) { + n = (n - 128) << 8; + n |= *p++; + n += 7 + 128; + } else { + n = (n - 128 - 64) << 16; + n |= *p++ << 8; + n |= *p++; + n += 7 + 128 + (1 << 14); + } + } + c0 = c; + c += n + 1; + if (v == 31) { + /* run of Lu / Ll */ + b = gc_mask & (M(Lu) | M(Ll)); + if (b != 0) { + if (b == (M(Lu) | M(Ll))) { + goto add_range; + } else { + c0 += ((gc_mask & M(Ll)) != 0); + for(; c0 < c; c0 += 2) { + if (cr_add_interval(cr, c0, c0 + 1)) + return -1; + } + } + } + } else if ((gc_mask >> v) & 1) { + add_range: + if (cr_add_interval(cr, c0, c)) + return -1; + } + } + return 0; +} + +static int unicode_prop1(CharRange *cr, int prop_idx) +{ + const uint8_t *p, *p_end; + uint32_t c, c0, b, bit; + + p = unicode_prop_table[prop_idx]; + p_end = p + unicode_prop_len_table[prop_idx]; + c = 0; + bit = 0; + while (p < p_end) { + c0 = c; + b = *p++; + if (b < 64) { + c += (b >> 3) + 1; + if (bit) { + if (cr_add_interval(cr, c0, c)) + return -1; + } + bit ^= 1; + c0 = c; + c += (b & 7) + 1; + } else if (b >= 0x80) { + c += b - 0x80 + 1; + } else if (b < 0x60) { + c += (((b - 0x40) << 8) | p[0]) + 1; + p++; + } else { + c += (((b - 0x60) << 16) | (p[0] << 8) | p[1]) + 1; + p += 2; + } + if (bit) { + if (cr_add_interval(cr, c0, c)) + return -1; + } + bit ^= 1; + } + return 0; +} + +#define CASE_U (1 << 0) +#define CASE_L (1 << 1) +#define CASE_F (1 << 2) + +/* use the case conversion table to generate range of characters. + CASE_U: set char if modified by uppercasing, + CASE_L: set char if modified by lowercasing, + CASE_F: set char if modified by case folding, + */ +static int unicode_case1(CharRange *cr, int case_mask) +{ +#define MR(x) (1 << RUN_TYPE_ ## x) + const uint32_t tab_run_mask[3] = { + MR(U) | MR(UF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(UF_D20) | + MR(UF_D1_EXT) | MR(U_EXT) | MR(UF_EXT2) | MR(UF_EXT3), + + MR(L) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(LF_EXT2), + + MR(UF) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(LF_EXT2) | MR(UF_D20) | MR(UF_D1_EXT) | MR(LF_EXT) | MR(UF_EXT2) | MR(UF_EXT3), + }; +#undef MR + uint32_t mask, v, code, type, len, i, idx; + + if (case_mask == 0) + return 0; + mask = 0; + for(i = 0; i < 3; i++) { + if ((case_mask >> i) & 1) + mask |= tab_run_mask[i]; + } + for(idx = 0; idx < countof(case_conv_table1); idx++) { + v = case_conv_table1[idx]; + type = (v >> (32 - 17 - 7 - 4)) & 0xf; + code = v >> (32 - 17); + len = (v >> (32 - 17 - 7)) & 0x7f; + if ((mask >> type) & 1) { + // printf("%d: type=%d %04x %04x\n", idx, type, code, code + len - 1); + switch(type) { + case RUN_TYPE_UL: + if ((case_mask & CASE_U) && (case_mask & (CASE_L | CASE_F))) + goto def_case; + code += ((case_mask & CASE_U) != 0); + for(i = 0; i < len; i += 2) { + if (cr_add_interval(cr, code + i, code + i + 1)) + return -1; + } + break; + case RUN_TYPE_LSU: + if ((case_mask & CASE_U) && (case_mask & (CASE_L | CASE_F))) + goto def_case; + if (!(case_mask & CASE_U)) { + if (cr_add_interval(cr, code, code + 1)) + return -1; + } + if (cr_add_interval(cr, code + 1, code + 2)) + return -1; + if (case_mask & CASE_U) { + if (cr_add_interval(cr, code + 2, code + 3)) + return -1; + } + break; + default: + def_case: + if (cr_add_interval(cr, code, code + len)) + return -1; + break; + } + } + } + return 0; +} + +static int point_cmp(const void *p1, const void *p2, void *arg) +{ + uint32_t v1 = *(uint32_t *)p1; + uint32_t v2 = *(uint32_t *)p2; + return (v1 > v2) - (v1 < v2); +} + +static void cr_sort_and_remove_overlap(CharRange *cr) +{ + uint32_t start, end, start1, end1, i, j; + + /* the resulting ranges are not necessarily sorted and may overlap */ + rqsort(cr->points, cr->len / 2, sizeof(cr->points[0]) * 2, point_cmp, NULL); + j = 0; + for(i = 0; i < cr->len; ) { + start = cr->points[i]; + end = cr->points[i + 1]; + i += 2; + while (i < cr->len) { + start1 = cr->points[i]; + end1 = cr->points[i + 1]; + if (start1 > end) { + /* |------| + * |-------| */ + break; + } else if (end1 <= end) { + /* |------| + * |--| */ + i += 2; + } else { + /* |------| + * |-------| */ + end = end1; + i += 2; + } + } + cr->points[j] = start; + cr->points[j + 1] = end; + j += 2; + } + cr->len = j; +} + +/* canonicalize a character set using the JS regex case folding rules + (see lre_canonicalize()) */ +int cr_regexp_canonicalize(CharRange *cr, bool is_unicode) +{ + CharRange cr_inter, cr_mask, cr_result, cr_sub; + uint32_t v, code, len, i, idx, start, end, c, d_start, d_end, d; + + cr_init(&cr_mask, cr->mem_opaque, cr->realloc_func); + cr_init(&cr_inter, cr->mem_opaque, cr->realloc_func); + cr_init(&cr_result, cr->mem_opaque, cr->realloc_func); + cr_init(&cr_sub, cr->mem_opaque, cr->realloc_func); + + if (unicode_case1(&cr_mask, is_unicode ? CASE_F : CASE_U)) + goto fail; + if (cr_op(&cr_inter, cr_mask.points, cr_mask.len, cr->points, cr->len, CR_OP_INTER)) + goto fail; + + if (cr_invert(&cr_mask)) + goto fail; + if (cr_op(&cr_sub, cr_mask.points, cr_mask.len, cr->points, cr->len, CR_OP_INTER)) + goto fail; + + /* cr_inter = cr & cr_mask */ + /* cr_sub = cr & ~cr_mask */ + + /* use the case conversion table to compute the result */ + d_start = -1; + d_end = -1; + idx = 0; + v = case_conv_table1[idx]; + code = v >> (32 - 17); + len = (v >> (32 - 17 - 7)) & 0x7f; + for(i = 0; i < cr_inter.len; i += 2) { + start = cr_inter.points[i]; + end = cr_inter.points[i + 1]; + + for(c = start; c < end; c++) { + for(;;) { + if (c >= code && c < code + len) + break; + idx++; + assert(idx < countof(case_conv_table1)); + v = case_conv_table1[idx]; + code = v >> (32 - 17); + len = (v >> (32 - 17 - 7)) & 0x7f; + } + d = lre_case_folding_entry(c, idx, v, is_unicode); + /* try to merge with the current interval */ + if (d_start == -1) { + d_start = d; + d_end = d + 1; + } else if (d_end == d) { + d_end++; + } else { + cr_add_interval(&cr_result, d_start, d_end); + d_start = d; + d_end = d + 1; + } + } + } + if (d_start != -1) { + if (cr_add_interval(&cr_result, d_start, d_end)) + goto fail; + } + + /* the resulting ranges are not necessarily sorted and may overlap */ + cr_sort_and_remove_overlap(&cr_result); + + /* or with the character not affected by the case folding */ + cr->len = 0; + if (cr_op(cr, cr_result.points, cr_result.len, cr_sub.points, cr_sub.len, CR_OP_UNION)) + goto fail; + + cr_free(&cr_inter); + cr_free(&cr_mask); + cr_free(&cr_result); + cr_free(&cr_sub); + return 0; + fail: + cr_free(&cr_inter); + cr_free(&cr_mask); + cr_free(&cr_result); + cr_free(&cr_sub); + return -1; +} + +typedef enum { + POP_GC, + POP_PROP, + POP_CASE, + POP_UNION, + POP_INTER, + POP_XOR, + POP_INVERT, + POP_END, +} PropOPEnum; + +#define POP_STACK_LEN_MAX 4 + +static int unicode_prop_ops(CharRange *cr, ...) +{ + va_list ap; + CharRange stack[POP_STACK_LEN_MAX]; + int stack_len, op, ret, i; + uint32_t a; + + va_start(ap, cr); + stack_len = 0; + for(;;) { + op = va_arg(ap, int); + switch(op) { + case POP_GC: + assert(stack_len < POP_STACK_LEN_MAX); + a = va_arg(ap, int); + cr_init(&stack[stack_len++], cr->mem_opaque, cr->realloc_func); + if (unicode_general_category1(&stack[stack_len - 1], a)) + goto fail; + break; + case POP_PROP: + assert(stack_len < POP_STACK_LEN_MAX); + a = va_arg(ap, int); + cr_init(&stack[stack_len++], cr->mem_opaque, cr->realloc_func); + if (unicode_prop1(&stack[stack_len - 1], a)) + goto fail; + break; + case POP_CASE: + assert(stack_len < POP_STACK_LEN_MAX); + a = va_arg(ap, int); + cr_init(&stack[stack_len++], cr->mem_opaque, cr->realloc_func); + if (unicode_case1(&stack[stack_len - 1], a)) + goto fail; + break; + case POP_UNION: + case POP_INTER: + case POP_XOR: + { + CharRange *cr1, *cr2, *cr3; + assert(stack_len >= 2); + assert(stack_len < POP_STACK_LEN_MAX); + cr1 = &stack[stack_len - 2]; + cr2 = &stack[stack_len - 1]; + cr3 = &stack[stack_len++]; + cr_init(cr3, cr->mem_opaque, cr->realloc_func); + if (cr_op(cr3, cr1->points, cr1->len, + cr2->points, cr2->len, op - POP_UNION + CR_OP_UNION)) + goto fail; + cr_free(cr1); + cr_free(cr2); + *cr1 = *cr3; + stack_len -= 2; + } + break; + case POP_INVERT: + assert(stack_len >= 1); + if (cr_invert(&stack[stack_len - 1])) + goto fail; + break; + case POP_END: + goto done; + default: + abort(); + } + } + done: + va_end(ap); + assert(stack_len == 1); + ret = cr_copy(cr, &stack[0]); + cr_free(&stack[0]); + return ret; + fail: + va_end(ap); + for(i = 0; i < stack_len; i++) + cr_free(&stack[i]); + return -1; +} + +static const uint32_t unicode_gc_mask_table[] = { + M(Lu) | M(Ll) | M(Lt), /* LC */ + M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo), /* L */ + M(Mn) | M(Mc) | M(Me), /* M */ + M(Nd) | M(Nl) | M(No), /* N */ + M(Sm) | M(Sc) | M(Sk) | M(So), /* S */ + M(Pc) | M(Pd) | M(Ps) | M(Pe) | M(Pi) | M(Pf) | M(Po), /* P */ + M(Zs) | M(Zl) | M(Zp), /* Z */ + M(Cc) | M(Cf) | M(Cs) | M(Co) | M(Cn), /* C */ +}; + +/* 'cr' must be initialized and empty. Return 0 if OK, -1 if error, -2 + if not found */ +int unicode_general_category(CharRange *cr, const char *gc_name) +{ + int gc_idx; + uint32_t gc_mask; + + gc_idx = unicode_find_name(unicode_gc_name_table, gc_name); + if (gc_idx < 0) + return -2; + if (gc_idx <= UNICODE_GC_Co) { + gc_mask = (uint64_t)1 << gc_idx; + } else { + gc_mask = unicode_gc_mask_table[gc_idx - UNICODE_GC_LC]; + } + return unicode_general_category1(cr, gc_mask); +} + + +/* 'cr' must be initialized and empty. Return 0 if OK, -1 if error, -2 + if not found */ +/* Unicode "properties of strings" (e.g. \p{RGI_Emoji}) used by the v flag; + expands a string property into a list of code-point sequences via the + callback. Returns -2 if the property name is unknown. */ +#define SEQ_MAX_LEN 16 + +static int unicode_sequence_prop1(int seq_prop_idx, UnicodeSequencePropCB *cb, void *opaque, + CharRange *cr) +{ + int i, c, j; + uint32_t seq[SEQ_MAX_LEN]; + + switch(seq_prop_idx) { + case UNICODE_SEQUENCE_PROP_Basic_Emoji: + if (unicode_prop1(cr, UNICODE_PROP_Basic_Emoji1) < 0) + return -1; + for(i = 0; i < cr->len; i += 2) { + for(c = cr->points[i]; c < cr->points[i + 1]; c++) { + seq[0] = c; + cb(opaque, seq, 1); + } + } + + cr->len = 0; + + if (unicode_prop1(cr, UNICODE_PROP_Basic_Emoji2) < 0) + return -1; + for(i = 0; i < cr->len; i += 2) { + for(c = cr->points[i]; c < cr->points[i + 1]; c++) { + seq[0] = c; + seq[1] = 0xfe0f; + cb(opaque, seq, 2); + } + } + + break; + case UNICODE_SEQUENCE_PROP_RGI_Emoji_Modifier_Sequence: + if (unicode_prop1(cr, UNICODE_PROP_Emoji_Modifier_Base) < 0) + return -1; + for(i = 0; i < cr->len; i += 2) { + for(c = cr->points[i]; c < cr->points[i + 1]; c++) { + for(j = 0; j < 5; j++) { + seq[0] = c; + seq[1] = 0x1f3fb + j; + cb(opaque, seq, 2); + } + } + } + break; + case UNICODE_SEQUENCE_PROP_RGI_Emoji_Flag_Sequence: + if (unicode_prop1(cr, UNICODE_PROP_RGI_Emoji_Flag_Sequence) < 0) + return -1; + for(i = 0; i < cr->len; i += 2) { + for(c = cr->points[i]; c < cr->points[i + 1]; c++) { + int c0, c1; + c0 = c / 26; + c1 = c % 26; + seq[0] = 0x1F1E6 + c0; + seq[1] = 0x1F1E6 + c1; + cb(opaque, seq, 2); + } + } + break; + case UNICODE_SEQUENCE_PROP_RGI_Emoji_ZWJ_Sequence: + { + int len, code, pres, k, mod, mod_count, mod_pos[2], hc_pos, n_mod, n_hc, mod1; + int mod_idx, hc_idx, i0, i1; + const uint8_t *tab = unicode_rgi_emoji_zwj_sequence; + + for(i = 0; i < countof(unicode_rgi_emoji_zwj_sequence);) { + len = tab[i++]; + k = 0; + mod = 0; + mod_count = 0; + hc_pos = -1; + for(j = 0; j < len; j++) { + code = tab[i++]; + code |= tab[i++] << 8; + pres = code >> 15; + mod1 = (code >> 13) & 3; + code &= 0x1fff; + if (code < 0x1000) { + c = code + 0x2000; + } else { + c = 0x1f000 + (code - 0x1000); + } + if (c == 0x1f9b0) + hc_pos = k; + seq[k++] = c; + if (mod1 != 0) { + assert(mod_count < 2); + mod = mod1; + mod_pos[mod_count++] = k; + seq[k++] = 0; /* will be filled later */ + } + if (pres) { + seq[k++] = 0xfe0f; + } + if (j < len - 1) { + seq[k++] = 0x200d; + } + } + + /* genrate all the variants */ + switch(mod) { + case 1: + n_mod = 5; + break; + case 2: + n_mod = 25; + break; + case 3: + n_mod = 20; + break; + default: + n_mod = 1; + break; + } + if (hc_pos >= 0) + n_hc = 4; + else + n_hc = 1; + for(hc_idx = 0; hc_idx < n_hc; hc_idx++) { + for(mod_idx = 0; mod_idx < n_mod; mod_idx++) { + if (hc_pos >= 0) + seq[hc_pos] = 0x1f9b0 + hc_idx; + + switch(mod) { + case 1: + seq[mod_pos[0]] = 0x1f3fb + mod_idx; + break; + case 2: + case 3: + i0 = mod_idx / 5; + i1 = mod_idx % 5; + /* avoid identical values */ + if (mod == 3 && i0 >= i1) + i0++; + seq[mod_pos[0]] = 0x1f3fb + i0; + seq[mod_pos[1]] = 0x1f3fb + i1; + break; + default: + break; + } +#if 0 + for(j = 0; j < k; j++) + printf(" %04x", seq[j]); + printf("\n"); +#endif + cb(opaque, seq, k); + } + } + } + } + break; + case UNICODE_SEQUENCE_PROP_RGI_Emoji_Tag_Sequence: + { + for(i = 0; i < countof(unicode_rgi_emoji_tag_sequence);) { + j = 0; + seq[j++] = 0x1F3F4; + for(;;) { + c = unicode_rgi_emoji_tag_sequence[i++]; + if (c == 0x00) + break; + seq[j++] = 0xe0000 + c; + } + seq[j++] = 0xe007f; + cb(opaque, seq, j); + } + } + break; + case UNICODE_SEQUENCE_PROP_Emoji_Keycap_Sequence: + if (unicode_prop1(cr, UNICODE_PROP_Emoji_Keycap_Sequence) < 0) + return -1; + for(i = 0; i < cr->len; i += 2) { + for(c = cr->points[i]; c < cr->points[i + 1]; c++) { + seq[0] = c; + seq[1] = 0xfe0f; + seq[2] = 0x20e3; + cb(opaque, seq, 3); + } + } + break; + case UNICODE_SEQUENCE_PROP_RGI_Emoji: + /* all prevous sequences */ + for(i = UNICODE_SEQUENCE_PROP_Basic_Emoji; i <= UNICODE_SEQUENCE_PROP_RGI_Emoji_ZWJ_Sequence; i++) { + int ret; + ret = unicode_sequence_prop1(i, cb, opaque, cr); + if (ret < 0) + return ret; + cr->len = 0; + } + break; + default: + return -2; + } + return 0; +} + +/* build a unicode sequence property */ +/* return -2 if not found, -1 if other error. 'cr' is used as temporary memory. */ +int unicode_sequence_prop(const char *prop_name, UnicodeSequencePropCB *cb, void *opaque, + CharRange *cr) +{ + int seq_prop_idx; + seq_prop_idx = unicode_find_name(unicode_sequence_prop_name_table, prop_name); + if (seq_prop_idx < 0) + return -2; + return unicode_sequence_prop1(seq_prop_idx, cb, opaque, cr); +} + +int unicode_prop(CharRange *cr, const char *prop_name) +{ + int prop_idx, ret; + + prop_idx = unicode_find_name(unicode_prop_name_table, prop_name); + if (prop_idx < 0) + return -2; + prop_idx += UNICODE_PROP_ASCII_Hex_Digit; + + ret = 0; + switch(prop_idx) { + case UNICODE_PROP_ASCII: + if (cr_add_interval(cr, 0x00, 0x7f + 1)) + return -1; + break; + case UNICODE_PROP_Any: + if (cr_add_interval(cr, 0x00000, 0x10ffff + 1)) + return -1; + break; + case UNICODE_PROP_Assigned: + ret = unicode_prop_ops(cr, + POP_GC, M(Cn), + POP_INVERT, + POP_END); + break; + case UNICODE_PROP_Math: + ret = unicode_prop_ops(cr, + POP_GC, M(Sm), + POP_PROP, UNICODE_PROP_Other_Math, + POP_UNION, + POP_END); + break; + case UNICODE_PROP_Lowercase: + ret = unicode_prop_ops(cr, + POP_GC, M(Ll), + POP_PROP, UNICODE_PROP_Other_Lowercase, + POP_UNION, + POP_END); + break; + case UNICODE_PROP_Uppercase: + ret = unicode_prop_ops(cr, + POP_GC, M(Lu), + POP_PROP, UNICODE_PROP_Other_Uppercase, + POP_UNION, + POP_END); + break; + case UNICODE_PROP_Cased: + ret = unicode_prop_ops(cr, + POP_GC, M(Lu) | M(Ll) | M(Lt), + POP_PROP, UNICODE_PROP_Other_Uppercase, + POP_UNION, + POP_PROP, UNICODE_PROP_Other_Lowercase, + POP_UNION, + POP_END); + break; + case UNICODE_PROP_Alphabetic: + ret = unicode_prop_ops(cr, + POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl), + POP_PROP, UNICODE_PROP_Other_Uppercase, + POP_UNION, + POP_PROP, UNICODE_PROP_Other_Lowercase, + POP_UNION, + POP_PROP, UNICODE_PROP_Other_Alphabetic, + POP_UNION, + POP_END); + break; + case UNICODE_PROP_Grapheme_Base: + ret = unicode_prop_ops(cr, + POP_GC, M(Cc) | M(Cf) | M(Cs) | M(Co) | M(Cn) | M(Zl) | M(Zp) | M(Me) | M(Mn), + POP_PROP, UNICODE_PROP_Other_Grapheme_Extend, + POP_UNION, + POP_INVERT, + POP_END); + break; + case UNICODE_PROP_Grapheme_Extend: + ret = unicode_prop_ops(cr, + POP_GC, M(Me) | M(Mn), + POP_PROP, UNICODE_PROP_Other_Grapheme_Extend, + POP_UNION, + POP_END); + break; + case UNICODE_PROP_XID_Start: + ret = unicode_prop_ops(cr, + POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl), + POP_PROP, UNICODE_PROP_Other_ID_Start, + POP_UNION, + POP_PROP, UNICODE_PROP_Pattern_Syntax, + POP_PROP, UNICODE_PROP_Pattern_White_Space, + POP_UNION, + POP_PROP, UNICODE_PROP_XID_Start1, + POP_UNION, + POP_INVERT, + POP_INTER, + POP_END); + break; + case UNICODE_PROP_XID_Continue: + ret = unicode_prop_ops(cr, + POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl) | + M(Mn) | M(Mc) | M(Nd) | M(Pc), + POP_PROP, UNICODE_PROP_Other_ID_Start, + POP_UNION, + POP_PROP, UNICODE_PROP_Other_ID_Continue, + POP_UNION, + POP_PROP, UNICODE_PROP_Pattern_Syntax, + POP_PROP, UNICODE_PROP_Pattern_White_Space, + POP_UNION, + POP_PROP, UNICODE_PROP_XID_Continue1, + POP_UNION, + POP_INVERT, + POP_INTER, + POP_END); + break; + case UNICODE_PROP_Changes_When_Uppercased: + ret = unicode_case1(cr, CASE_U); + break; + case UNICODE_PROP_Changes_When_Lowercased: + ret = unicode_case1(cr, CASE_L); + break; + case UNICODE_PROP_Changes_When_Casemapped: + ret = unicode_case1(cr, CASE_U | CASE_L | CASE_F); + break; + case UNICODE_PROP_Changes_When_Titlecased: + ret = unicode_prop_ops(cr, + POP_CASE, CASE_U, + POP_PROP, UNICODE_PROP_Changes_When_Titlecased1, + POP_XOR, + POP_END); + break; + case UNICODE_PROP_Changes_When_Casefolded: + ret = unicode_prop_ops(cr, + POP_CASE, CASE_F, + POP_PROP, UNICODE_PROP_Changes_When_Casefolded1, + POP_XOR, + POP_END); + break; + case UNICODE_PROP_Changes_When_NFKC_Casefolded: + ret = unicode_prop_ops(cr, + POP_CASE, CASE_F, + POP_PROP, UNICODE_PROP_Changes_When_NFKC_Casefolded1, + POP_XOR, + POP_END); + break; + /* we use the existing tables */ + case UNICODE_PROP_ID_Continue: + ret = unicode_prop_ops(cr, + POP_PROP, UNICODE_PROP_ID_Start, + POP_PROP, UNICODE_PROP_ID_Continue1, + POP_XOR, + POP_END); + break; + default: + if (prop_idx >= countof(unicode_prop_table)) + return -2; + ret = unicode_prop1(cr, prop_idx); + break; + } + return ret; +} diff --git a/userland/qjs/source/libunicode.h b/userland/qjs/source/libunicode.h new file mode 100644 index 0000000..66c0b38 --- /dev/null +++ b/userland/qjs/source/libunicode.h @@ -0,0 +1,172 @@ +/* + * Unicode utilities + * + * Copyright (c) 2017-2018 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef LIBUNICODE_H +#define LIBUNICODE_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define LRE_CC_RES_LEN_MAX 3 + +typedef enum { + UNICODE_NFC, + UNICODE_NFD, + UNICODE_NFKC, + UNICODE_NFKD, +} UnicodeNormalizationEnum; + +int lre_case_conv(uint32_t *res, uint32_t c, int conv_type); +int lre_canonicalize(uint32_t c, bool is_unicode); +bool lre_is_cased(uint32_t c); +bool lre_is_case_ignorable(uint32_t c); + +/* char ranges */ + +typedef struct { + int len; /* in points, always even */ + int size; + uint32_t *points; /* points sorted by increasing value */ + void *mem_opaque; + void *(*realloc_func)(void *opaque, void *ptr, size_t size); +} CharRange; + +typedef enum { + CR_OP_UNION, + CR_OP_INTER, + CR_OP_XOR, + CR_OP_SUB, +} CharRangeOpEnum; + +void cr_init(CharRange *cr, void *mem_opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); +void cr_free(CharRange *cr); +int cr_realloc(CharRange *cr, int size); +int cr_copy(CharRange *cr, const CharRange *cr1); + +static inline int cr_add_point(CharRange *cr, uint32_t v) +{ + if (cr->len >= cr->size) { + if (cr_realloc(cr, cr->len + 1)) + return -1; + } + cr->points[cr->len++] = v; + return 0; +} + +static inline int cr_add_interval(CharRange *cr, uint32_t c1, uint32_t c2) +{ + if ((cr->len + 2) > cr->size) { + if (cr_realloc(cr, cr->len + 2)) + return -1; + } + cr->points[cr->len++] = c1; + cr->points[cr->len++] = c2; + return 0; +} + +int cr_op1(CharRange *cr, const uint32_t *b_pt, int b_len, int op); + +static inline int cr_union_interval(CharRange *cr, uint32_t c1, uint32_t c2) +{ + uint32_t b_pt[2]; + b_pt[0] = c1; + b_pt[1] = c2 + 1; + return cr_op1(cr, b_pt, 2, CR_OP_UNION); +} + +int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len, + const uint32_t *b_pt, int b_len, int op); + +int cr_invert(CharRange *cr); +int cr_regexp_canonicalize(CharRange *cr, bool is_unicode); + +bool lre_is_id_start(uint32_t c); +bool lre_is_id_continue(uint32_t c); +bool lre_is_white_space(uint32_t c); + +int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len, + UnicodeNormalizationEnum n_type, + void *opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); + +/* Unicode character range functions */ + +int unicode_script(CharRange *cr, + const char *script_name, bool is_ext); +int unicode_general_category(CharRange *cr, const char *gc_name); +int unicode_prop(CharRange *cr, const char *prop_name); + +typedef void UnicodeSequencePropCB(void *opaque, const uint32_t *buf, int len); +int unicode_sequence_prop(const char *prop_name, UnicodeSequencePropCB *cb, void *opaque, + CharRange *cr); + +/* Code point type categories (ASCII fast path table) */ +enum { + UNICODE_C_SPACE = (1 << 0), + UNICODE_C_DIGIT = (1 << 1), + UNICODE_C_UPPER = (1 << 2), + UNICODE_C_LOWER = (1 << 3), + UNICODE_C_UNDER = (1 << 4), + UNICODE_C_DOLLAR = (1 << 5), + UNICODE_C_XDIGIT = (1 << 6), +}; +extern uint8_t const lre_ctype_bits[256]; + +static inline int lre_is_space_byte(uint8_t c) { + return lre_ctype_bits[c] & UNICODE_C_SPACE; +} + +static inline int lre_is_id_start_byte(uint8_t c) { + return lre_ctype_bits[c] & (UNICODE_C_UPPER | UNICODE_C_LOWER | + UNICODE_C_UNDER | UNICODE_C_DOLLAR); +} + +static inline int lre_is_id_continue_byte(uint8_t c) { + return lre_ctype_bits[c] & (UNICODE_C_UPPER | UNICODE_C_LOWER | + UNICODE_C_UNDER | UNICODE_C_DOLLAR | + UNICODE_C_DIGIT); +} + +static inline int lre_is_word_byte(uint8_t c) { + return lre_ctype_bits[c] & (UNICODE_C_UPPER | UNICODE_C_LOWER | + UNICODE_C_UNDER | UNICODE_C_DIGIT); +} + +int lre_is_space_non_ascii(uint32_t c); + +static inline int lre_is_space(uint32_t c) { + if (c < 256) + return lre_is_space_byte(c); + else + return lre_is_space_non_ascii(c); +} + +#ifdef __cplusplus +} /* extern "C" { */ +#endif + +#endif /* LIBUNICODE_H */ diff --git a/userland/qjs/source/list.h b/userland/qjs/source/list.h new file mode 100644 index 0000000..b8dd716 --- /dev/null +++ b/userland/qjs/source/list.h @@ -0,0 +1,107 @@ +/* + * Linux klist like system + * + * Copyright (c) 2016-2017 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef LIST_H +#define LIST_H + +#ifndef NULL +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +struct list_head { + struct list_head *prev; + struct list_head *next; +}; + +#define LIST_HEAD_INIT(el) { &(el), &(el) } + +/* return the pointer of type 'type *' containing 'el' as field 'member' */ +#define list_entry(el, type, member) container_of(el, type, member) + +static inline void init_list_head(struct list_head *head) +{ + head->prev = head; + head->next = head; +} + +/* insert 'el' between 'prev' and 'next' */ +static inline void __list_add(struct list_head *el, + struct list_head *prev, struct list_head *next) +{ + prev->next = el; + el->prev = prev; + el->next = next; + next->prev = el; +} + +/* add 'el' at the head of the list 'head' (= after element head) */ +static inline void list_add(struct list_head *el, struct list_head *head) +{ + __list_add(el, head, head->next); +} + +/* add 'el' at the end of the list 'head' (= before element head) */ +static inline void list_add_tail(struct list_head *el, struct list_head *head) +{ + __list_add(el, head->prev, head); +} + +static inline void list_del(struct list_head *el) +{ + struct list_head *prev, *next; + prev = el->prev; + next = el->next; + prev->next = next; + next->prev = prev; + el->prev = NULL; /* fail safe */ + el->next = NULL; /* fail safe */ +} + +static inline int list_empty(struct list_head *el) +{ + return el->next == el; +} + +#define list_for_each(el, head) \ + for(el = (head)->next; el != (head); el = el->next) + +#define list_for_each_safe(el, el1, head) \ + for(el = (head)->next, el1 = el->next; el != (head); \ + el = el1, el1 = el->next) + +#define list_for_each_prev(el, head) \ + for(el = (head)->prev; el != (head); el = el->prev) + +#define list_for_each_prev_safe(el, el1, head) \ + for(el = (head)->prev, el1 = el->prev; el != (head); \ + el = el1, el1 = el->prev) + +#ifdef __cplusplus +} /* extern "C" { */ +#endif + +#endif /* LIST_H */ diff --git a/userland/qjs/source/lre-test.c b/userland/qjs/source/lre-test.c new file mode 100644 index 0000000..6f57188 --- /dev/null +++ b/userland/qjs/source/lre-test.c @@ -0,0 +1,112 @@ +#ifdef NDEBUG +#undef NDEBUG +#endif +#include +#include +#include +#include "libregexp.h" + +// If >= 0, the next 'alloc_countdown' allocations succeed and the one after +// that fails. Used to inject out-of-memory conditions in the compiler. +// When alloc_fail_persist is true, every subsequent allocation fails too. +static int alloc_countdown = -1; +static bool alloc_fail_persist; + +bool lre_check_stack_overflow(void *opaque, size_t alloca_size) +{ + return false; +} + +int lre_check_timeout(void *opaque) +{ + return 0; +} + +void *lre_realloc(void *opaque, void *ptr, size_t size) +{ + if (size == 0) { + free(ptr); + return NULL; + } + if (alloc_countdown >= 0) { + if (alloc_countdown == 0) { + if (!alloc_fail_persist) + alloc_countdown = -1; + return NULL; + } + alloc_countdown--; + } + return realloc(ptr, size); +} + +// https://github.com/quickjs-ng/quickjs/issues/1375 +static void oob_save_index(void) +{ + // Bytecode with REOP_save_start index=100, but capture_count=1. + // Without validation this causes a heap-buffer-overflow in lre_exec_backtrack. + uint8_t bc[] = { + 0x00, 0x00, // RE_HEADER_FLAGS = 0 + 0x01, // RE_HEADER_CAPTURE_COUNT = 1 + 0x00, // RE_HEADER_REGISTER_COUNT = 0 + 0x04, 0x00, 0x00, 0x00, // RE_HEADER_BYTECODE_LEN = 4 (little-endian) + 0x06, // REOP_any + 0x13, 0x64, // REOP_save_start, index=100 + 0x10, // REOP_match + }; + + uint8_t *capture[2] = {NULL, NULL}; + int ret = lre_exec(capture, bc, (const uint8_t *)"a", 0, 1, 0, NULL); + assert(ret < 0); +} + +static void oom_no_oob_write(void) +{ + static const struct { + const char *prefix; + const char *suffix; + int flags; + } templates[] = { + { "", "|b", 0 }, + { "", "*b", 0 }, + { "", "{2,4}b", 0 }, + { "(", "|b)", 0 }, + { "(?:", "|b){2,7}c", 0 }, + { "(?=", "|b)c", 0 }, + { "(?<=", "|b)c", 0 }, + { "[\\q{", "|bc}]", LRE_FLAG_UNICODE_SETS }, + }; + char pattern[128], error_msg[128]; + size_t i, prefix_len; + int k, n, len, persist; + uint8_t *bc; + + for (i = 0; i < sizeof(templates) / sizeof(templates[0]); i++) { + prefix_len = strlen(templates[i].prefix); + for (k = 0; k < 64; k++) { + memcpy(pattern, templates[i].prefix, prefix_len); + memset(pattern + prefix_len, 'a', k); + strcpy(pattern + prefix_len + k, templates[i].suffix); + for (n = 0; n < 128; n++) { + for (persist = 0; persist < 2; persist++) { + alloc_fail_persist = persist; + alloc_countdown = n; + error_msg[0] = '\0'; + bc = lre_compile(&len, error_msg, sizeof(error_msg), + pattern, strlen(pattern), + templates[i].flags, NULL); + alloc_countdown = -1; + // Failure must always come with an error message. + assert(bc || error_msg[0] != '\0'); + lre_realloc(NULL, bc, 0); + } + } + } + } +} + +int main(void) +{ + oob_save_index(); + oom_no_oob_write(); + return 0; +} diff --git a/userland/qjs/source/meson.build b/userland/qjs/source/meson.build new file mode 100644 index 0000000..ca835d2 --- /dev/null +++ b/userland/qjs/source/meson.build @@ -0,0 +1,686 @@ +project( + 'quickjs-ng', + 'c', + version: '0.18.0', + default_options: [ + 'c_std=gnu11,c11', + 'warning_level=3', + 'buildtype=release', + 'b_ndebug=if-release', + ], + license: 'MIT', + license_files: 'LICENSE', + meson_version: '>=1.3.0', +) + +host_system = host_machine.system() +cc = meson.get_compiler('c') + +add_project_arguments('-DQUICKJS_NG_BUILD', language: 'c') + +qjs_gcc_warning_args = [ + '-Wno-unsafe-buffer-usage', + '-Wno-sign-conversion', + '-Wno-nonportable-system-include-path', + '-Wno-implicit-int-conversion', + '-Wno-shorten-64-to-32', + '-Wno-reserved-macro-identifier', + '-Wno-reserved-identifier', + '-Wdeprecated-declarations', + + '-Wno-implicit-fallthrough', + '-Wno-sign-compare', + '-Wno-missing-field-initializers', + '-Wno-unused-parameter', + '-Wno-unused-but-set-variable', + '-Wno-array-bounds', + '-Wno-format-truncation', +] +qjs_gcc_args = [] + +if host_system != 'sunos' + qjs_gcc_args += '-funsigned-char' +endif + +if host_system == 'darwin' + # https://github.com/quickjs-ng/quickjs/issues/453 + qjs_gcc_warning_args += '-Wno-maybe-uninitialized' +endif + +# https://github.com/microsoft/cpp-docs/tree/main/docs/error-messages/compiler-warnings +qjs_msvc_warning_args = [ + '/wd4018', # -Wno-sign-conversion + '/wd4061', # -Wno-implicit-fallthrough + '/wd4100', # -Wno-unused-parameter + '/wd4200', # -Wno-zero-length-array + '/wd4242', # -Wno-shorten-64-to-32 + '/wd4244', # -Wno-shorten-64-to-32 + '/wd4245', # -Wno-sign-compare + '/wd4267', # -Wno-shorten-64-to-32 + '/wd4388', # -Wno-sign-compare + '/wd4389', # -Wno-sign-compare + '/wd4710', # Function not inlined + '/wd4711', # Function was inlined + '/wd4820', # Padding added after construct + '/wd4996', # -Wdeprecated-declarations + '/wd5045', # Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified +] +qjs_msvc_args = [ + '/experimental:c11atomics', + '/J', # -funsigned-char +] + +if cc.get_argument_syntax() == 'msvc' + add_project_arguments( + cc.get_supported_arguments(qjs_msvc_warning_args), + cc.get_id().contains('clang') ? cc.get_supported_arguments(qjs_gcc_warning_args) : [], + qjs_msvc_args, + language: 'c', + ) +else + add_project_arguments( + cc.get_supported_arguments(qjs_gcc_warning_args), + qjs_gcc_args, + language: 'c', + ) +endif + +if host_system == 'windows' + # Set a 8MB default stack size on Windows. + # It defaults to 1MB on MSVC, which is the same as our current JS stack size, + # so it will overflow and crash otherwise. + # On MinGW it defaults to 2MB. + stack_size = 8 * 1024 * 1024 + if cc.get_argument_syntax() == 'msvc' + add_project_link_arguments(f'/STACK:@stack_size@', language: 'c') + else + add_project_link_arguments(f'-Wl,--stack,@stack_size@', language: 'c') + endif +endif + +if meson.is_cross_build() + native_cc = meson.get_compiler('c', native: true) + + if native_cc.get_argument_syntax() == 'msvc' + # https://github.com/microsoft/cpp-docs/tree/main/docs/error-messages/compiler-warnings + add_project_arguments( + native_cc.get_supported_arguments(qjs_msvc_warning_args), + native_cc.get_id().contains('clang') ? native_cc.get_supported_arguments(qjs_gcc_warning_args) : [], + qjs_msvc_args, + + language: 'c', + native: true, + ) + else + add_project_arguments( + native_cc.get_supported_arguments(qjs_gcc_warning_args), + qjs_gcc_args, + + language: 'c', + native: true, + ) + endif +endif +if get_option('debug') + add_project_arguments( + cc.get_supported_arguments('-fno-omit-frame-pointer'), + language: 'c', + ) +endif + +qjs_sys_deps = [] + +m_dep = cc.find_library('m', required: false) +qjs_sys_deps += m_dep +qjs_sys_deps += dependency('threads', required: false) +qjs_sys_deps += dependency('dl', required: false) + +qjs_srcs = files( + 'dtoa.c', + 'libregexp.c', + 'libunicode.c', + 'quickjs.c', +) +qjs_hdrs = files( + 'quickjs.h', +) + +qjs_libc = get_option('libc') +qjs_libc_srcs = files('quickjs-libc.c') +qjs_libc_hdrs = files('quickjs-libc.h') + +if qjs_libc + qjs_hdrs += qjs_libc_hdrs + add_project_arguments( + '-DQJS_BUILD_LIBC', + language: 'c' + ) +endif + +qjs_parser = get_option('parser') + +qjs_c_args = ['-D_GNU_SOURCE'] + +if host_system == 'windows' + qjs_c_args += ['-DWIN32_LEAN_AND_MEAN', '-D_WIN32_WINNT=0x0601'] +endif + +if not qjs_parser + qjs_c_args += ['-DQJS_DISABLE_PARSER'] +endif + +qjs_lib = library( + 'qjs', + qjs_srcs, + qjs_libc ? qjs_libc_srcs : [], + + dependencies: qjs_sys_deps, + c_args: qjs_c_args, + c_shared_args: ['-DBUILDING_QJS_SHARED'], + gnu_symbol_visibility: 'hidden', + + install: true, + version: meson.project_version(), +) + +qjs_export_variables = [ + f'have_parser=@qjs_parser@' +] + +# This note is only of interest on Windows. +# Be conservative here: only pass -DUSING_QJS_SHARED iff default_library == +# 'shared', thus qjs is guaranteed to be a DLL. Not passing -DUSING_QJS_SHARED if +# qjs is a DLL is not harmful, but passing the definition for DLL qjs is desired. +# Conversely, if -DUSING_QJS_SHARED is passed for static qjs, the consumers +# will not compile. +qjs_dep_args = get_option('default_library') == 'shared' ? ['-DUSING_QJS_SHARED'] : [] + +qjs_dep = declare_dependency( + compile_args: qjs_dep_args, + link_with: qjs_lib, + dependencies: qjs_sys_deps, + include_directories: include_directories('.'), + variables: qjs_export_variables, +) + +if host_system != 'windows' + qjs_module_dep = declare_dependency( + compile_args: [qjs_dep_args, '-DQUICKJS_NG_MODULE_BUILD'], + include_directories: include_directories('.'), + ) +else + qjs_module_dep = declare_dependency( + compile_args: [qjs_dep_args, '-DQUICKJS_NG_MODULE_BUILD'], + include_directories: include_directories('.'), + # Windows can't resolve symbols at runtime thus we explicitly link to qjs. + dependencies: qjs_dep, + ) +endif + +if qjs_libc + qjs_libc_dep = declare_dependency( + include_directories: include_directories('.'), + dependencies: qjs_dep, + ) +else + qjs_libc_lib = static_library( + 'quickjs-libc', + qjs_libc_srcs, + + c_args: qjs_c_args, + dependencies: [qjs_sys_deps, qjs_dep], + gnu_symbol_visibility: 'hidden', + ) + qjs_libc_dep = declare_dependency( + link_with: qjs_libc_lib, + # Pick up quickjs-libc.h. + include_directories: include_directories('.'), + ) +endif + +if host_system == 'emscripten' + qjs_wasm_export_name = 'getQuickJs' + executable( + 'qjs_wasm', + qjs_srcs, + link_args: cc.get_supported_link_arguments( + # in emscripten 3.x, this will be set to 16k which is too small for quickjs. + '-sSTACK_SIZE=@0@'.format(2 * 1024 * 1024), # let it be 2m = 2 * 1024 * 1024, otherwise, stack overflow may be occured at bootstrap + '-sNO_INVOKE_RUN', + '-sNO_EXIT_RUNTIME', + '-sMODULARIZE', # do not mess the global + '-sEXPORT_ES6', # export js file to morden es module + '-sEXPORT_NAME=@0@'.format(qjs_wasm_export_name), # give a name + '-sTEXTDECODER=1', # it will be 2 if we use -Oz, and that will cause js -> c string convertion fail + '-sNO_DEFAULT_TO_CXX', # this project is pure c project, no need for c plus plus handle + '-sEXPORTED_RUNTIME_METHODS=ccall,cwrap', + ), + dependencies: m_dep, + c_args: qjs_c_args, + ) +endif + +install_headers(qjs_hdrs, subdir: 'quickjs-ng') + +if not meson.is_subproject() + docdir = get_option('docdir') + datadir = get_option('datadir') + + if docdir == '' + docdir = datadir / 'doc' / meson.project_name() + endif + install_data( + 'LICENSE', + install_dir: docdir, + + install_tag: 'doc', + ) + install_subdir( + 'examples', + install_dir: docdir, + + strip_directory: false, + install_tag: 'doc', + ) +endif + +meson.override_dependency('quickjs-ng', qjs_dep) + +import('pkgconfig').generate( + qjs_lib, + subdirs: 'quickjs-ng', + name: 'quickjs-ng', + description: 'QuickJS, the Next Generation: a mighty JavaScript engine', + url: 'https://github.com/quickjs-ng/quickjs', + version: meson.project_version(), + variables: qjs_export_variables, + # Export -DUSING_QJS_SHARED, if needed, in the pkgconfig file. + extra_cflags: qjs_dep_args, +) + +if not qjs_parser + subdir_done() +endif + +# QuickJS bytecode compiler +qjsc_srcs = files( + 'qjsc.c', +) +qjsc_exe = executable( + 'qjsc', + qjsc_srcs, + + c_args: qjs_c_args, + dependencies: [qjs_dep, qjs_libc_dep], + install: true, +) + +mimalloc_dep = [] +mimalloc_sys_dep = dependency('mimalloc', required: get_option('cli_mimalloc')) +if mimalloc_sys_dep.found() + mimalloc_dep = declare_dependency( + dependencies: mimalloc_sys_dep, + compile_args: '-DQJS_USE_MIMALLOC', + ) +endif + +# QuickJS CLI +qjs_exe_srcs = files( + 'gen/repl.c', + 'gen/standalone.c', + 'qjs.c', +) +qjs_exe = executable( + 'qjs', + qjs_exe_srcs, + + c_args: qjs_c_args, + dependencies: [qjs_dep, qjs_libc_dep, mimalloc_dep], + export_dynamic: true, + + install: true, +) + +if meson.is_cross_build() + mimalloc_native_dep = [] + mimalloc_sys_native_dep = dependency('mimalloc', required: get_option('cli_mimalloc'), native: true) + if mimalloc_sys_dep.found() + mimalloc_native_dep = declare_dependency( + dependencies: mimalloc_sys_native_dep, + compile_args: '-DQJS_USE_MIMALLOC', + ) + endif + + qjs_sys_native_deps = [ + native_cc.find_library('m', required: false), + dependency('threads', required: false, native: true), + dependency('dl', required: false, native: true), + ] + qjs_native_lib = static_library( + 'qjs_native', + qjs_srcs, + qjs_libc_srcs, + + dependencies: qjs_sys_native_deps, + c_args: qjs_c_args, + gnu_symbol_visibility: 'hidden', + + build_by_default: false, + native: true, + install: false, + ) + + meson.override_find_program( + 'qjsc', + executable( + 'qjsc_native', + qjsc_srcs, + + c_args: qjs_c_args, + link_with: qjs_native_lib, + dependencies: qjs_sys_native_deps, + + build_by_default: false, + native: true, + install: false, + ), + ) + meson.override_find_program( + 'qjs', + executable( + 'qjs_native', + qjs_exe_srcs, + + c_args: qjs_c_args, + link_with: qjs_native_lib, + dependencies: [qjs_sys_native_deps, mimalloc_native_dep], + export_dynamic: true, + + build_by_default: false, + native: true, + install: false, + ), + ) +else + meson.override_find_program('qjsc', qjsc_exe) + meson.override_find_program('qjs', qjs_exe) +endif + +tests = get_option('tests').disable_auto_if(meson.is_subproject()) +examples = get_option('examples').disable_auto_if(meson.is_subproject()) + +if tests.allowed() + if host_system != 'emscripten' + # Test262 runner + run262_exe = executable( + 'run-test262', + 'run-test262.c', + + c_args: qjs_c_args, + dependencies: [qjs_dep, qjs_libc_dep] + ) + + test( + 'test', + run262_exe, + args: ['-c', files('tests.conf')], + workdir: meson.current_source_dir(), + ) + + foreach bench : [ + 'empty_loop', + + 'date_now', + + 'prop_read', + 'prop_write', + 'prop_create', + 'prop_delete', + + 'array_read', + 'array_write', + 'array_prop_create', + 'array_length_decr', + 'array_hole_length_decr', + 'array_push', + 'array_pop', + + 'typed_array_read', + 'typed_array_write', + + 'global_read', + 'global_write', + 'global_write_strict', + + 'local_destruct', + 'global_destruct', + 'global_destruct_strict', + + 'func_call', + 'closure_var', + + 'int_arith', + 'float_arith', + + 'map_set', + 'map_delete', + 'weak_map_set', + 'weak_map_delete', + + 'array_for', + 'array_for_in', + 'array_for_of', + + 'math_min', + + 'object_null', + + 'regexp_ascii', + 'regexp_utf16', + + 'string_build1', + 'string_build2', + + 'string_slice1', + 'string_slice2', + 'string_slice3', + + 'sort_bench', + + 'int_to_string', + 'int_toString', + + 'float_to_string', + 'float_toString', + 'float_toFixed', + 'float_toPrecision', + 'float_toExponential', + + 'string_to_int', + 'string_to_float', + + 'bigint64_arith', + 'bigint256_arith', + ] + benchmark( + bench, + qjs_exe, + args: [files('tests/microbench.js'), bench], + ) + endforeach + endif + + # API test + test( + 'api', + executable( + 'api-test', + 'api-test.c', + + c_args: qjs_c_args, + dependencies: [qjs_dep, qjs_libc_dep], + build_by_default: false, + ), + ) + + # LRE test + test( + 'lre', + executable( + 'lre-test', + 'lre-test.c', + 'libregexp.c', + 'libunicode.c', + + c_args: qjs_c_args, + build_by_default: false, + ), + ) + + # Function.toString() test + test( + 'function_source', + executable( + 'function_source', + 'gen/function_source.c', + + c_args: qjs_c_args, + dependencies: [qjs_dep, qjs_libc_dep], + build_by_default: false, + ), + ) +endif + +# Unicode generator +unicode_gen = executable( + 'unicode_gen', + 'unicode_gen.c', + + c_args: qjs_c_args, + build_by_default: false, +) + +run_target( + 'libunicode-table.h', + command: [ + unicode_gen, + meson.current_source_dir() / 'unicode', + files('libunicode-table.h'), + ], +) + +# bytecode to c source code for builtin and examples +alias_target('codegen', + run_target( + 'codegen_repl.c', + command: [ + qjsc_exe, + '-ss', + '-o', files('gen/repl.c'), + '-m', + '-n', 'repl.js', + files('repl.js'), + ], + ), + run_target( + 'codegen_standalone.c', + command: [ + qjsc_exe, + '-ss', + '-o', files('gen/standalone.c'), + '-m', + '-n', 'standalone.js', + files('standalone.js'), + ], + ), + run_target( + 'codegen_function_source.c', + command: [ + qjsc_exe, + '-e', + '-o', files('gen/function_source.c'), + '-n', 'tests/function_source.js', + files('tests/function_source.js'), + ], + ), + run_target( + 'codegen_hello.c', + command: [ + qjsc_exe, + '-e', + '-o', files('gen/hello.c'), + '-n', 'examples/hello.js', + files('examples/hello.js'), + ], + ), + run_target( + 'codegen_hello_module.c', + command: [ + qjsc_exe, + '-e', + '-o', files('gen/hello_module.c'), + '-m', + '-n', 'examples/hello_module.js', + files('examples/hello_module.js'), + ], + ), + run_target( + 'codegen_test_fib.c', + command: [ + qjsc_exe, + '-e', + '-o', files('gen/test_fib.c'), + '-m', + '-n', 'examples/test_fib.js', + files('examples/test_fib.js'), + ], + ), + run_target( + 'codegen_builtin-array-fromasync.h', + command: [ + qjsc_exe, + '-C', + '-ss', + '-o', files('builtin-array-fromasync.h'), + '-n', 'builtin-array-fromasync.js', + files('builtin-array-fromasync.js'), + ], + ), +) + +if examples.allowed() + if host_system == 'windows' and get_option('default_library') != 'shared' + warning('Binary modules used with static qjs on Windows.') + warning( + 'There might be runtime errors when the modules are used due to', + 'two copies of qjs in memory.' + ) + warning('Please use "-Ddefault_library=shared" if possible.') + endif + executable( + 'hello', + 'gen/hello.c', + + c_args: qjs_c_args, + dependencies: [qjs_dep, qjs_libc_dep] + ) + + executable( + 'hello_module', + 'gen/hello_module.c', + + c_args: qjs_c_args, + dependencies: [qjs_dep, qjs_libc_dep] + ) + + subdir('examples') + + executable( + 'test_fib', + 'gen/test_fib.c', + + c_args: qjs_c_args, + dependencies: [qjs_dep, qjs_libc_dep], + export_dynamic: true, + ) +endif diff --git a/userland/qjs/source/meson_options.txt b/userland/qjs/source/meson_options.txt new file mode 100644 index 0000000..20e661e --- /dev/null +++ b/userland/qjs/source/meson_options.txt @@ -0,0 +1,6 @@ +option('tests', type: 'feature', description: 'build tests') +option('examples', type: 'feature', description: 'build examples') +option('libc', type: 'boolean', value: false, description: 'build qjs standard library modules as part of the library') +option('cli_mimalloc', type: 'feature', value: 'disabled', description: 'build qjs cli with mimalloc') +option('docdir', type: 'string', description: 'documentation directory') +option('parser', type: 'boolean', value: true, description: 'Enable JS source code parser') diff --git a/userland/qjs/source/qjs-wasi-reactor.c b/userland/qjs/source/qjs-wasi-reactor.c new file mode 100644 index 0000000..91d74eb --- /dev/null +++ b/userland/qjs/source/qjs-wasi-reactor.c @@ -0,0 +1,208 @@ +/* + * QuickJS WASI Reactor Mode + * + * In reactor mode, QuickJS exports functions that can be called repeatedly + * by the host instead of running main() once and blocking in the event loop. + * + * Copyright (c) 2017-2021 Fabrice Bellard + * Copyright (c) 2017-2021 Charlie Gordon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* Include qjs.c to get access to static functions like eval_buf, eval_file, + * parse_limit, and JS_NewCustomContext */ +#include "qjs.c" + +static JSRuntime *reactor_rt = NULL; +static JSContext *reactor_ctx = NULL; + +int qjs_init_argv(int argc, char **argv); + +__attribute__((export_name("qjs_init"))) +int qjs_init(void) +{ + static char *empty_argv[] = { "qjs", NULL }; + return qjs_init_argv(1, empty_argv); +} + +__attribute__((export_name("qjs_init_argv"))) +int qjs_init_argv(int argc, char **argv) +{ + int optind = 1; + char *expr = NULL; + int module = -1; + int load_std = 0; + char *include_list[32]; + int i, include_count = 0; + int64_t memory_limit = -1; + int64_t stack_size = -1; + + if (reactor_rt) + return -1; /* already initialized */ + + /* Parse options (subset of main()) */ + while (optind < argc && *argv[optind] == '-') { + char *arg = argv[optind] + 1; + const char *longopt = ""; + char *optarg = NULL; + if (!*arg) + break; + optind++; + if (*arg == '-') { + longopt = arg + 1; + optarg = strchr(longopt, '='); + if (optarg) + *optarg++ = '\0'; + arg += strlen(arg); + if (!*longopt) + break; + } + for (; *arg || *longopt; longopt = "") { + char opt = *arg; + if (opt) { + arg++; + if (!optarg && *arg) + optarg = arg; + } + if (opt == 'e' || !strcmp(longopt, "eval")) { + if (!optarg) { + if (optind >= argc) + return -1; + optarg = argv[optind++]; + } + expr = optarg; + break; + } + if (opt == 'I' || !strcmp(longopt, "include")) { + if (optind >= argc || include_count >= countof(include_list)) + return -1; + include_list[include_count++] = argv[optind++]; + continue; + } + if (opt == 'm' || !strcmp(longopt, "module")) { + module = 1; + continue; + } + if (!strcmp(longopt, "std")) { + load_std = 1; + continue; + } + if (!strcmp(longopt, "memory-limit")) { + if (!optarg) { + if (optind >= argc) + return -1; + optarg = argv[optind++]; + } + memory_limit = parse_limit(optarg); + break; + } + if (!strcmp(longopt, "stack-size")) { + if (!optarg) { + if (optind >= argc) + return -1; + optarg = argv[optind++]; + } + stack_size = parse_limit(optarg); + break; + } + break; /* ignore unknown options */ + } + } + + reactor_rt = JS_NewRuntime(); + if (!reactor_rt) + return -1; + if (memory_limit >= 0) + JS_SetMemoryLimit(reactor_rt, (size_t)memory_limit); + if (stack_size >= 0) + JS_SetMaxStackSize(reactor_rt, (size_t)stack_size); + + js_std_set_worker_new_context_func(JS_NewCustomContext); + js_std_init_handlers(reactor_rt); + + reactor_ctx = JS_NewCustomContext(reactor_rt); + if (!reactor_ctx) { + js_std_free_handlers(reactor_rt); + JS_FreeRuntime(reactor_rt); + reactor_rt = NULL; + return -1; + } + + JS_SetModuleLoaderFunc2(reactor_rt, NULL, js_module_loader, + js_module_check_attributes, NULL); + JS_SetHostPromiseRejectionTracker(reactor_rt, js_std_promise_rejection_tracker, NULL); + js_std_add_helpers(reactor_ctx, argc - optind, argv + optind); + + if (load_std) { + const char *str = + "import * as bjson from 'qjs:bjson';\n" + "import * as std from 'qjs:std';\n" + "import * as os from 'qjs:os';\n" + "globalThis.bjson = bjson;\n" + "globalThis.std = std;\n" + "globalThis.os = os;\n"; + if (eval_buf(reactor_ctx, str, strlen(str), "", JS_EVAL_TYPE_MODULE)) + goto fail; + } + + for (i = 0; i < include_count; i++) { + if (eval_file(reactor_ctx, include_list[i], 0)) + goto fail; + } + + if (expr) { + if (eval_buf(reactor_ctx, expr, strlen(expr), "", + module == 1 ? JS_EVAL_TYPE_MODULE : 0)) + goto fail; + } else if (optind < argc) { + if (eval_file(reactor_ctx, argv[optind], module)) + goto fail; + } + + return 0; + +fail: + js_std_free_handlers(reactor_rt); + JS_FreeContext(reactor_ctx); + JS_FreeRuntime(reactor_rt); + reactor_rt = NULL; + reactor_ctx = NULL; + return -1; +} + +__attribute__((export_name("qjs_get_context"))) +JSContext *qjs_get_context(void) +{ + return reactor_ctx; +} + +__attribute__((export_name("qjs_destroy"))) +void qjs_destroy(void) +{ + if (reactor_ctx) { + js_std_free_handlers(reactor_rt); + JS_FreeContext(reactor_ctx); + reactor_ctx = NULL; + } + if (reactor_rt) { + JS_FreeRuntime(reactor_rt); + reactor_rt = NULL; + } +} diff --git a/userland/qjs/source/qjs.c b/userland/qjs/source/qjs.c new file mode 100644 index 0000000..d9f0ecb --- /dev/null +++ b/userland/qjs/source/qjs.c @@ -0,0 +1,777 @@ +/* + * QuickJS stand alone interpreter + * + * Copyright (c) 2017-2021 Fabrice Bellard + * Copyright (c) 2017-2021 Charlie Gordon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cutils.h" +#include "quickjs.h" +#include "quickjs-libc.h" + +#ifdef QJS_USE_MIMALLOC +#include +#endif + +extern const uint8_t qjsc_repl[]; +extern const uint32_t qjsc_repl_size; +extern const uint8_t qjsc_standalone[]; +extern const uint32_t qjsc_standalone_size; + +#if defined(EMSCRIPTEN) || defined(__wasi__) +// Standalone executables (the --compile option and detecting/running an +// executable with appended bytecode) can't work in these environments. +#define emscripten_or_wasi 1 +#else +#define emscripten_or_wasi 0 +#endif + +static int qjs__argc; +static char **qjs__argv; + +// Must match standalone.js +#define TRAILER_SIZE 12 +static const char trailer_magic[] = "quickjs2"; +static const int trailer_magic_size = sizeof(trailer_magic) - 1; +static const int trailer_size = TRAILER_SIZE; + +static bool is_standalone(const char *exe) +{ + FILE *exe_f = fopen(exe, "rb"); + if (!exe_f) + return false; + if (fseek(exe_f, -trailer_size, SEEK_END) < 0) + goto fail; + uint8_t buf[TRAILER_SIZE]; + if (fread(buf, 1, trailer_size, exe_f) != trailer_size) + goto fail; + fclose(exe_f); + return !memcmp(buf, trailer_magic, trailer_magic_size); +fail: + fclose(exe_f); + return false; +} + +static JSValue load_standalone_module(JSContext *ctx) +{ + JSModuleDef *m; + JSValue obj, val; + obj = JS_ReadObject(ctx, qjsc_standalone, qjsc_standalone_size, JS_READ_OBJ_BYTECODE); + if (JS_IsException(obj)) + goto exception; + assert(JS_VALUE_GET_TAG(obj) == JS_TAG_MODULE); + if (JS_ResolveModule(ctx, obj) < 0) { + JS_FreeValue(ctx, obj); + goto exception; + } + if (js_module_set_import_meta(ctx, obj, false, true) < 0) { + JS_FreeValue(ctx, obj); + goto exception; + } + val = JS_EvalFunction(ctx, JS_DupValue(ctx, obj)); + val = js_std_await(ctx, val); + + if (JS_IsException(val)) { + JS_FreeValue(ctx, obj); + exception: + js_std_dump_error(ctx); + exit(1); + } + JS_FreeValue(ctx, val); + + m = JS_VALUE_GET_PTR(obj); + JS_FreeValue(ctx, obj); + return JS_GetModuleNamespace(ctx, m); +} + +static int eval_buf(JSContext *ctx, const void *buf, int buf_len, + const char *filename, int eval_flags) +{ + bool use_realpath; + JSValue val; + int ret; + + if ((eval_flags & JS_EVAL_TYPE_MASK) == JS_EVAL_TYPE_MODULE) { + /* for the modules, we compile then run to be able to set + import.meta */ + val = JS_Eval(ctx, buf, buf_len, filename, + eval_flags | JS_EVAL_FLAG_COMPILE_ONLY); + if (!JS_IsException(val)) { + // ex. "" pr "/dev/stdin" + use_realpath = + !(*filename == '<' || !strncmp(filename, "/dev/", 5)); + if (js_module_set_import_meta(ctx, val, use_realpath, true) < 0) { + js_std_dump_error(ctx); + ret = -1; + goto end; + } + val = JS_EvalFunction(ctx, val); + } + val = js_std_await(ctx, val); + } else { + val = JS_Eval(ctx, buf, buf_len, filename, eval_flags); + } + if (JS_IsException(val)) { + js_std_dump_error(ctx); + ret = -1; + } else { + ret = 0; + } +end: + JS_FreeValue(ctx, val); + return ret; +} + +static void js_dynamic_import(JSContext *ctx, const char *basename, + const char *filename, JSValue token, + JSValueConst attributes, void *opaque) +{ + JSValue exception, promise; + + exception = JS_UNDEFINED; + promise = JS_LoadModule(ctx, basename, filename, attributes); + if (JS_IsException(promise)) + exception = JS_GetException(ctx); + if (JS_FinishDynamicImport(ctx, token, promise, exception)) + js_std_dump_error(ctx); +} + +static int eval_file(JSContext *ctx, const char *filename, int module) +{ + uint8_t *buf; + int ret, eval_flags; + size_t buf_len; + + buf = js_load_file(ctx, &buf_len, filename); + if (!buf) { + perror(filename); + exit(1); + } + + if (module < 0) { + module = (js__has_suffix(filename, ".mjs") || + JS_DetectModule((const char *)buf, buf_len)); + } + if (module) + eval_flags = JS_EVAL_TYPE_MODULE; + else + eval_flags = JS_EVAL_TYPE_GLOBAL; + ret = eval_buf(ctx, buf, buf_len, filename, eval_flags); + js_free(ctx, buf); + return ret; +} + +static int64_t parse_limit(const char *arg) { + char *p; + unsigned long unit = 1024; /* default to traditional KB */ + double d = strtod(arg, &p); + + if (p == arg) { + fprintf(stderr, "Invalid limit: %s\n", arg); + return -1; + } + + if (*p) { + switch (*p++) { + case 'b': case 'B': unit = 1UL << 0; break; + case 'k': case 'K': unit = 1UL << 10; break; /* IEC kibibytes */ + case 'm': case 'M': unit = 1UL << 20; break; /* IEC mebibytes */ + case 'g': case 'G': unit = 1UL << 30; break; /* IEC gigibytes */ + default: + fprintf(stderr, "Invalid limit: %s, unrecognized suffix, only k,m,g are allowed\n", arg); + return -1; + } + if (*p) { + fprintf(stderr, "Invalid limit: %s, only one suffix allowed\n", arg); + return -1; + } + } + + return (int64_t)(d * unit); +} + +static JSValue js_gc(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JS_RunGC(JS_GetRuntime(ctx)); + return JS_UNDEFINED; +} + +static JSValue js_navigator_get_userAgent(JSContext *ctx, JSValueConst this_val) +{ + char version[32]; + snprintf(version, sizeof(version), "quickjs-ng/%s", JS_GetVersion()); + return JS_NewString(ctx, version); +} + +static const JSCFunctionListEntry navigator_proto_funcs[] = { + JS_CGETSET_DEF2("userAgent", js_navigator_get_userAgent, NULL, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE), + JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Navigator", JS_PROP_CONFIGURABLE), +}; + +static const JSCFunctionListEntry global_obj[] = { + JS_CFUNC_DEF("gc", 0, js_gc), +}; + +/* also used to initialize the worker context */ +static JSContext *JS_NewCustomContext(JSRuntime *rt) +{ + JSContext *ctx; + ctx = JS_NewContext(rt); + if (!ctx) + return NULL; + /* system modules */ + js_init_module_std(ctx, "qjs:std"); + js_init_module_os(ctx, "qjs:os"); + js_init_module_bjson(ctx, "qjs:bjson"); + + JSValue global = JS_GetGlobalObject(ctx); + JS_SetPropertyFunctionList(ctx, global, global_obj, countof(global_obj)); + JSValue args = JS_NewArray(ctx); + int i; + for(i = 0; i < qjs__argc; i++) { + JS_SetPropertyUint32(ctx, args, i, JS_NewString(ctx, qjs__argv[i])); + } + JS_SetPropertyStr(ctx, global, "execArgv", args); + JS_SetPropertyStr(ctx, global, "argv0", JS_NewString(ctx, qjs__argv[0])); + JSValue navigator_proto = JS_NewObject(ctx); + JS_SetPropertyFunctionList(ctx, navigator_proto, navigator_proto_funcs, countof(navigator_proto_funcs)); + JSValue navigator = JS_NewObjectProto(ctx, navigator_proto); + JS_DefinePropertyValueStr(ctx, global, "navigator", navigator, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE); + JS_FreeValue(ctx, global); + JS_FreeValue(ctx, navigator_proto); + + return ctx; +} + +struct trace_malloc_data { + uint8_t *base; +}; + +static inline unsigned long long js_trace_malloc_ptr_offset(uint8_t *ptr, + struct trace_malloc_data *dp) +{ + return ptr - dp->base; +} + +static void JS_PRINTF_FORMAT_ATTR(2, 3) js_trace_malloc_printf(void *opaque, JS_PRINTF_FORMAT const char *fmt, ...) +{ + va_list ap; + int c; + + va_start(ap, fmt); + while ((c = *fmt++) != '\0') { + if (c == '%') { + /* only handle %p and %zd */ + if (*fmt == 'p') { + uint8_t *ptr = va_arg(ap, void *); + if (ptr == NULL) { + printf("NULL"); + } else { + printf("H%+06lld.%zd", + js_trace_malloc_ptr_offset(ptr, opaque), + js__malloc_usable_size(ptr)); + } + fmt++; + continue; + } + if (fmt[0] == 'z' && fmt[1] == 'd') { + size_t sz = va_arg(ap, size_t); + printf("%zd", sz); + fmt += 2; + continue; + } + } + putc(c, stdout); + } + va_end(ap); +} + +static void js_trace_malloc_init(struct trace_malloc_data *s) +{ + free(s->base = malloc(8)); +} + +static void *js_trace_calloc(void *opaque, size_t count, size_t size) +{ + void *ptr; + ptr = calloc(count, size); + js_trace_malloc_printf(opaque, "C %zd %zd -> %p\n", count, size, ptr); + return ptr; +} + +static void *js_trace_malloc(void *opaque, size_t size) +{ + void *ptr; + ptr = malloc(size); + js_trace_malloc_printf(opaque, "A %zd -> %p\n", size, ptr); + return ptr; +} + +static void js_trace_free(void *opaque, void *ptr) +{ + if (!ptr) + return; + js_trace_malloc_printf(opaque, "F %p\n", ptr); + free(ptr); +} + +static void *js_trace_realloc(void *opaque, void *ptr, size_t size) +{ + js_trace_malloc_printf(opaque, "R %zd %p", size, ptr); + ptr = realloc(ptr, size); + js_trace_malloc_printf(opaque, " -> %p\n", ptr); + return ptr; +} + +static const JSMallocFunctions trace_mf = { + js_trace_calloc, + js_trace_malloc, + js_trace_free, + js_trace_realloc, + js__malloc_usable_size +}; + +#ifdef QJS_USE_MIMALLOC +static void *js_mi_calloc(void *opaque, size_t count, size_t size) +{ + return mi_calloc(count, size); +} + +static void *js_mi_malloc(void *opaque, size_t size) +{ + return mi_malloc(size); +} + +static void js_mi_free(void *opaque, void *ptr) +{ + if (!ptr) + return; + mi_free(ptr); +} + +static void *js_mi_realloc(void *opaque, void *ptr, size_t size) +{ + return mi_realloc(ptr, size); +} + +static const JSMallocFunctions mi_mf = { + js_mi_calloc, + js_mi_malloc, + js_mi_free, + js_mi_realloc, + mi_usable_size +}; +#endif + +#define PROG_NAME "qjs" + +void help(int exit_status) +{ + printf("QuickJS-ng version %s\n" + "usage: " PROG_NAME " [options] [file [args]]\n" + "-h --help list options\n" + "-v --version print version string and then exit\n" + "-e --eval EXPR evaluate EXPR\n" + "-i --interactive go to interactive mode\n" + "-C --script load as JS classic script (default=autodetect)\n" + "-m --module load as ES module (default=autodetect)\n" + "-I --include file include an additional file\n" + " --std make 'std', 'os' and 'bjson' available to script\n" + "-T --trace trace memory allocation\n" + "-d --dump dump the memory usage stats\n" + "-D --dump-flags flags for dumping debug data (see DUMP_* defines)\n", + JS_GetVersion()); + if (!emscripten_or_wasi) + printf("-c --compile FILE compile the given JS file as a standalone executable\n" + "-o --out FILE output file for standalone executables\n" + " --exe select the executable to use as the base, defaults to the current one\n"); + printf(" --memory-limit n limit the memory usage to 'n' Kbytes\n" + " --stack-size n limit the stack size to 'n' Kbytes\n" + "-q --quit just instantiate the interpreter and quit\n"); + exit(exit_status); +} + +int main(int argc, char **argv) +{ + JSRuntime *rt; + JSContext *ctx; + struct trace_malloc_data trace_data = { NULL }; + int r = 0; + int optind = 1; + JSValue ret = JS_UNDEFINED; + char exebuf[JS__PATH_MAX]; + size_t exebuf_size = sizeof(exebuf); + char *compile_file = NULL; + char *exe = NULL; + char *out = NULL; + int standalone = 0; + char *expr = NULL; + char *dump_flags_str = NULL; + int interactive = 0; + int dump_memory = 0; + int dump_flags = 0; + int trace_memory = 0; + int empty_run = 0; + int module = -1; + int load_std = 0; + char *include_list[32]; + int i, include_count = 0; + int64_t memory_limit = -1; + int64_t stack_size = -1; + + /* save for later */ + qjs__argc = argc; + qjs__argv = argv; + + /* check if this is a standalone executable */ + if (!emscripten_or_wasi && + !js_exepath(exebuf, &exebuf_size) && is_standalone(exebuf)) { + standalone = 1; + goto start; + } + + dump_flags_str = getenv("QJS_DUMP_FLAGS"); + dump_flags = dump_flags_str ? strtol(dump_flags_str, NULL, 16) : 0; + + /* cannot use getopt because we want to pass the command line to + the script */ + while (optind < argc && *argv[optind] == '-') { + char *arg = argv[optind] + 1; + char *longopt = ""; + char *optarg = NULL; + /* a single - is not an option, it also stops argument scanning */ + if (!*arg) + break; + optind++; + if (*arg == '-') { + longopt = arg + 1; + optarg = strchr(longopt, '='); + if (optarg) + *optarg++ = '\0'; + arg += strlen(arg); + /* -- stops argument scanning */ + if (!*longopt) + break; + } + for (; *arg || *longopt; longopt = "") { + char opt = *arg; + if (opt) { + arg++; + if (!optarg && *arg) + optarg = arg; + } + if (opt == 'h' || opt == '?' || !strcmp(longopt, "help")) { + help(0); + } + if (opt == 'v' || !strcmp(longopt, "version")) { + printf("%s\n",JS_GetVersion()); + return 0; + } + if (opt == 'e' || !strcmp(longopt, "eval")) { + if (!optarg) { + if (optind >= argc) { + fprintf(stderr, "qjs: missing expression for -e\n"); + exit(1); + } + optarg = argv[optind++]; + } + expr = optarg; + break; + } + if (opt == 'I' || !strcmp(longopt, "include")) { + if (optind >= argc) { + fprintf(stderr, "expecting filename"); + exit(1); + } + if (include_count >= countof(include_list)) { + fprintf(stderr, "too many included files"); + exit(1); + } + include_list[include_count++] = argv[optind++]; + continue; + } + if (opt == 'i' || !strcmp(longopt, "interactive")) { + interactive++; + continue; + } + if (opt == 'm' || !strcmp(longopt, "module")) { + module = 1; + continue; + } + if (opt == 'C' || !strcmp(longopt, "script")) { + module = 0; + continue; + } + if (opt == 'd' || !strcmp(longopt, "dump")) { + dump_memory++; + continue; + } + if (opt == 'D' || !strcmp(longopt, "dump-flags")) { + dump_flags = optarg ? strtol(optarg, NULL, 16) : 0; + break; + } + if (opt == 'T' || !strcmp(longopt, "trace")) { + trace_memory++; + continue; + } + if (!strcmp(longopt, "std")) { + load_std = 1; + continue; + } + if (opt == 'q' || !strcmp(longopt, "quit")) { + empty_run++; + continue; + } + if (!strcmp(longopt, "memory-limit")) { + if (!optarg) { + if (optind >= argc) { + fprintf(stderr, "expecting memory limit"); + exit(1); + } + optarg = argv[optind++]; + } + memory_limit = parse_limit(optarg); + break; + } + if (!strcmp(longopt, "stack-size")) { + if (!optarg) { + if (optind >= argc) { + fprintf(stderr, "expecting stack size"); + exit(1); + } + optarg = argv[optind++]; + } + stack_size = parse_limit(optarg); + break; + } + if (!emscripten_or_wasi && + (opt == 'c' || !strcmp(longopt, "compile"))) { + if (!optarg) { + if (optind >= argc) { + fprintf(stderr, "qjs: missing file for -c\n"); + exit(1); + } + optarg = argv[optind++]; + } + compile_file = optarg; + break; + } + if (!emscripten_or_wasi && (opt == 'o' || !strcmp(longopt, "out"))) { + if (!optarg) { + if (optind >= argc) { + fprintf(stderr, "qjs: missing file for -o\n"); + exit(1); + } + optarg = argv[optind++]; + } + out = optarg; + break; + } + if (!emscripten_or_wasi && !strcmp(longopt, "exe")) { + if (!optarg) { + if (optind >= argc) { + fprintf(stderr, "qjs: missing file for --exe\n"); + exit(1); + } + optarg = argv[optind++]; + } + exe = optarg; + break; + } + if (opt) { + fprintf(stderr, "qjs: unknown option '-%c'\n", opt); + } else { + fprintf(stderr, "qjs: unknown option '--%s'\n", longopt); + } + help(1); + } + } + + if (!emscripten_or_wasi && compile_file && !out) + help(1); + +start: + + if (trace_memory) { + js_trace_malloc_init(&trace_data); + rt = JS_NewRuntime2(&trace_mf, &trace_data); + } else { +#ifdef QJS_USE_MIMALLOC + rt = JS_NewRuntime2(&mi_mf, NULL); +#else + rt = JS_NewRuntime(); +#endif + } + if (!rt) { + fprintf(stderr, "qjs: cannot allocate JS runtime\n"); + exit(2); + } + if (memory_limit >= 0) + JS_SetMemoryLimit(rt, (size_t)memory_limit); + if (stack_size >= 0) + JS_SetMaxStackSize(rt, (size_t)stack_size); + if (dump_flags != 0) + JS_SetDumpFlags(rt, dump_flags); + js_std_set_worker_new_context_func(JS_NewCustomContext); + js_std_init_handlers(rt); + ctx = JS_NewCustomContext(rt); + if (!ctx) { + fprintf(stderr, "qjs: cannot allocate JS context\n"); + exit(2); + } + + /* loader for ES6 modules */ + JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader, js_module_check_attributes, NULL); + JS_SetDynamicImportFunc(rt, js_dynamic_import, NULL); + + /* exit on unhandled promise rejections */ + JS_SetHostPromiseRejectionTracker(rt, js_std_promise_rejection_tracker, NULL); + + if (!empty_run) { + js_std_add_helpers(ctx, argc - optind, argv + optind); + + /* make 'std' and 'os' visible to non module code */ + if (load_std) { + const char *str = + "import * as bjson from 'qjs:bjson';\n" + "import * as std from 'qjs:std';\n" + "import * as os from 'qjs:os';\n" + "globalThis.bjson = bjson;\n" + "globalThis.std = std;\n" + "globalThis.os = os;\n"; + eval_buf(ctx, str, strlen(str), "", JS_EVAL_TYPE_MODULE); + } + + for(i = 0; i < include_count; i++) { + if (eval_file(ctx, include_list[i], 0)) + goto fail; + } + + if (standalone) { + JSValue ns = load_standalone_module(ctx); + if (JS_IsException(ns)) + goto fail; + JSValue func = JS_GetPropertyStr(ctx, ns, "runStandalone"); + JS_FreeValue(ctx, ns); + if (JS_IsException(func)) + goto fail; + ret = JS_Call(ctx, func, JS_UNDEFINED, 0, NULL); + JS_FreeValue(ctx, func); + } else if (compile_file) { + JSValue ns = load_standalone_module(ctx); + if (JS_IsException(ns)) + goto fail; + JSValue func = JS_GetPropertyStr(ctx, ns, "compileStandalone"); + JS_FreeValue(ctx, ns); + if (JS_IsException(func)) + goto fail; + JSValue args[3]; + args[0] = JS_NewString(ctx, compile_file); + args[1] = JS_NewString(ctx, out); + args[2] = exe != NULL ? JS_NewString(ctx, exe) : JS_UNDEFINED; + ret = JS_Call(ctx, func, JS_UNDEFINED, 3, (JSValueConst *)args); + JS_FreeValue(ctx, func); + JS_FreeValue(ctx, args[0]); + JS_FreeValue(ctx, args[1]); + JS_FreeValue(ctx, args[2]); + } else if (expr) { + int flags = module ? JS_EVAL_TYPE_MODULE : 0; + if (eval_buf(ctx, expr, strlen(expr), "", flags)) + goto fail; + } else if (optind >= argc) { + /* interactive mode */ + interactive = 1; + } else { + const char *filename; + filename = argv[optind]; + if (eval_file(ctx, filename, module)) + goto fail; + } + if (interactive) { + JS_SetHostPromiseRejectionTracker(rt, NULL, NULL); + js_std_eval_binary(ctx, qjsc_repl, qjsc_repl_size, 0); + } + if (standalone || compile_file) { + if (JS_IsException(ret)) { + r = 1; + } else { + JS_FreeValue(ctx, ret); + r = js_std_loop(ctx); + } + } else { + r = js_std_loop(ctx); + } + if (r) { + js_std_dump_error(ctx); + goto fail; + } + } + + if (dump_memory) { + JSMemoryUsage stats; + JS_ComputeMemoryUsage(rt, &stats); + JS_DumpMemoryUsage(stdout, &stats, rt); + } + js_std_free_handlers(rt); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + + if (empty_run && dump_memory) { + clock_t t[5]; + double best[5] = {0}; + int i, j; + for (i = 0; i < 100; i++) { + t[0] = clock(); + rt = JS_NewRuntime(); + t[1] = clock(); + ctx = JS_NewContext(rt); + t[2] = clock(); + JS_FreeContext(ctx); + t[3] = clock(); + JS_FreeRuntime(rt); + t[4] = clock(); + for (j = 4; j > 0; j--) { + double ms = 1000.0 * (t[j] - t[j - 1]) / CLOCKS_PER_SEC; + if (i == 0 || best[j] > ms) + best[j] = ms; + } + } + printf("\nInstantiation times (ms): %.3f = %.3f+%.3f+%.3f+%.3f\n", + best[1] + best[2] + best[3] + best[4], + best[1], best[2], best[3], best[4]); + } + return 0; + fail: + js_std_free_handlers(rt); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + return 1; +} diff --git a/userland/qjs/source/qjs.man b/userland/qjs/source/qjs.man new file mode 100644 index 0000000..5672a52 --- /dev/null +++ b/userland/qjs/source/qjs.man @@ -0,0 +1,90 @@ +.TH QJS 1 "2026-07-22" +.SH NAME +qjs - QuickJS-NG JavaScript interpreter + +.SH SYNOPSIS +.SY qjs +.RI [ OPTION ].\|.\|.\& +.RI [ FILE " [" ARGUMENT ].\|.\|.] +.YS + +.SH DESCRIPTION +QuickJS-NG is a small and embeddable JavaScript engine. +It aims to support the latest ECMAScript specification. +.PP +The \fBqjs\fR executable runs the JavaScript interpreter. +It includes a simple standard library and REPL. + +.SH OPTIONS +.TP +.B \-c\fR,\fP \-\-compile +Compile \fIFILE\fR into a standalone executable, bundling the interpreter and the script. + +.TP +.B \-C\fR,\fP \-\-script +Load \fIFILE\fR as a classic JavaScript script. +By default, \fBqjs\fR will try to detect if \fIFILE\fR is a JS script or an ES module. + +.TP +.B \-d\fR,\fP \-\-dump +Dump memory usage statistics. + +.TP +\fB\-D \fIFLAGS\fR, \fB\-\-dump-flags\fR=\fIFLAGS\fR +Specify debug dump flags. +These can also be set through the \fBQJS_DUMP_FLAGS\fR environment variable. + +.TP +\fB\-e\fR \fIEXPR\fR, \fB\-\-eval\fR \fIEXPR\fR +Evaluate \fIEXPR\fR and exit. + +.TP +.B \-h\fR,\fP \-\-help +Print a help message and exit. + +.TP +.B \-i\fR,\fP \-\-interactive +Enter interactive mode. This is the default if no \fIFILE\fR is provided. + +.TP +\fB\-I\fR \fIIFILE\fR, \fB\-\-include\fR \fIIFILE\fR +Include an additional file. + +.TP +.BI \-\-memory\-limit " N" +Limit memory usage to \fIN\fR Kbytes. + +.TP +.B \-m\fR,\fP \-\-module +Load \fIFILE\fR as an ECMAScript module. +By default, \fBqjs\fR will try to detect if \fIFILE\fR is a JS script or an ES module. + +.TP +\fB\-\-o\fR \fIOUTPUT\fR, \fB\-\-out\fR \fIOUTPUT\fR +Output file name when creating a standalone executable with \fB\-c\fR. + +.TP +.BI \-\-stack\-size " N" +Limit the stack size to \fIN\fR Kbytes. + +.TP +.B \-\-std +Make \fI'std'\fR, \fI'os'\fR and \fI'bjson'\fR available to the script. + +.TP +.B \-T\fR,\fP \-\-trace +Trace memory allocation. + +.TP +.B \-v\fR,\fP \-\-version +Print version string and exit. + +.TP +.B \-q\fR,\fP \-\-quit +Instantiate the interpreter and immediately exit. + +.SH SEE ALSO +.SS "Man pages" +.BR qjsc (1) +.SS "Online documentation" +Detailed documentation about the project can be found at: https://quickjs-ng.github.io/quickjs/ diff --git a/userland/qjs/source/qjsc.c b/userland/qjs/source/qjsc.c new file mode 100644 index 0000000..635ed27 --- /dev/null +++ b/userland/qjs/source/qjsc.c @@ -0,0 +1,673 @@ +/* + * QuickJS command line compiler + * + * Copyright (c) 2018-2026 Fabrice Bellard + * Copyright (c) 2023-2026 Ben Noordhuis + * Copyright (c) 2023-2026 Saúl Ibarra Corretgé + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "cutils.h" +#include "quickjs-libc.h" + +typedef enum { + OUTPUT_C, + OUTPUT_C_MAIN, + OUTPUT_RAW, +} OutputTypeEnum; + +typedef struct { + char *name; + char *short_name; + int flags; +} namelist_entry_t; + +typedef struct namelist_t { + namelist_entry_t *array; + int count; + int size; +} namelist_t; + +static namelist_t cname_list; +static namelist_t cmodule_list; +static namelist_t init_module_list; +static OutputTypeEnum output_type; +static FILE *outfile; +static const char *c_ident_prefix = "qjsc_"; +static int strip; + +void namelist_add(namelist_t *lp, const char *name, const char *short_name, + int flags) +{ + namelist_entry_t *e; + if (lp->count == lp->size) { + size_t newsize = lp->size + (lp->size >> 1) + 4; + namelist_entry_t *a = + realloc(lp->array, sizeof(lp->array[0]) * newsize); + /* XXX: check for realloc failure */ + lp->array = a; + lp->size = newsize; + } + e = &lp->array[lp->count++]; + e->name = strdup(name); + if (short_name) + e->short_name = strdup(short_name); + else + e->short_name = NULL; + e->flags = flags; +} + +void namelist_free(namelist_t *lp) +{ + while (lp->count > 0) { + namelist_entry_t *e = &lp->array[--lp->count]; + free(e->name); + free(e->short_name); + } + free(lp->array); + lp->array = NULL; + lp->size = 0; +} + +namelist_entry_t *namelist_find(namelist_t *lp, const char *name) +{ + int i; + for(i = 0; i < lp->count; i++) { + namelist_entry_t *e = &lp->array[i]; + if (!strcmp(e->name, name)) + return e; + } + return NULL; +} + +static void get_c_name(char *buf, size_t buf_size, const char *file) +{ + const char *p, *r; + size_t len, i; + int c; + char *q; + + p = strrchr(file, '/'); + if (!p) + p = file; + else + p++; + r = strrchr(p, '.'); + if (!r) + len = strlen(p); + else + len = r - p; + js__pstrcpy(buf, buf_size, c_ident_prefix); + q = buf + strlen(buf); + for(i = 0; i < len; i++) { + c = p[i]; + if (!((c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z'))) { + c = '_'; + } + if ((q - buf) < buf_size - 1) + *q++ = c; + } + *q = '\0'; +} + +static void dump_hex(FILE *f, const uint8_t *buf, size_t len) +{ + size_t i, col; + col = 0; + for(i = 0; i < len; i++) { + fprintf(f, " 0x%02x,", buf[i]); + if (++col == 8) { + fprintf(f, "\n"); + col = 0; + } + } + if (col != 0) + fprintf(f, "\n"); +} + +static void output_object_code(JSContext *ctx, + FILE *fo, JSValue obj, const char *c_name, + bool load_only) +{ + uint8_t *out_buf; + size_t out_buf_len; + int flags = JS_WRITE_OBJ_BYTECODE; + + if (strip) { + flags |= JS_WRITE_OBJ_STRIP_SOURCE; + if (strip > 1) + flags |= JS_WRITE_OBJ_STRIP_DEBUG; + } + + out_buf = JS_WriteObject(ctx, &out_buf_len, obj, flags); + if (!out_buf) { + js_std_dump_error(ctx); + exit(1); + } + + namelist_add(&cname_list, c_name, NULL, load_only); + + if (output_type == OUTPUT_RAW) { + fwrite(out_buf, 1, out_buf_len, fo); + } else { + fprintf(fo, "const uint32_t %s_size = %u;\n\n", + c_name, (unsigned int)out_buf_len); + fprintf(fo, "const uint8_t %s[%u] = {\n", + c_name, (unsigned int)out_buf_len); + dump_hex(fo, out_buf, out_buf_len); + fprintf(fo, "};\n\n"); + } + + js_free(ctx, out_buf); +} + +static int js_module_dummy_init(JSContext *ctx, JSModuleDef *m) +{ + /* should never be called when compiling JS code */ + abort(); + return -1; // pacify compiler +} + +static void find_unique_cname(char *cname, size_t cname_size) +{ + char cname1[1024]; + int suffix_num; + size_t len, max_len; + assert(cname_size >= 32); + /* find a C name not matching an existing module C name by + adding a numeric suffix */ + len = strlen(cname); + max_len = cname_size - 16; + if (len > max_len) + cname[max_len] = '\0'; + suffix_num = 1; + for(;;) { + snprintf(cname1, sizeof(cname1), "%s_%d", cname, suffix_num); + if (!namelist_find(&cname_list, cname1)) + break; + suffix_num++; + } + js__pstrcpy(cname, cname_size, cname1); +} + +JSModuleDef *jsc_module_loader(JSContext *ctx, + const char *module_name, void *opaque) +{ + JSModuleDef *m; + namelist_entry_t *e; + + /* check if it is a declared C or system module */ + e = namelist_find(&cmodule_list, module_name); + if (e) { + /* add in the static init module list */ + namelist_add(&init_module_list, e->name, e->short_name, 0); + /* create a dummy module */ + m = JS_NewCModule(ctx, module_name, js_module_dummy_init); + } else if (js__has_suffix(module_name, ".so")) { + JS_ThrowReferenceError(ctx, "%s: dynamically linking to shared libraries not supported", + module_name); + return NULL; + } else { + size_t buf_len; + uint8_t *buf; + JSValue func_val; + char cname[1000]; + + buf = js_load_file(ctx, &buf_len, module_name); + if (!buf) { + JS_ThrowReferenceError(ctx, "could not load module filename '%s'", + module_name); + return NULL; + } + + /* compile the module */ + func_val = JS_Eval(ctx, (char *)buf, buf_len, module_name, + JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY); + js_free(ctx, buf); + if (JS_IsException(func_val)) + return NULL; + get_c_name(cname, sizeof(cname), module_name); + if (namelist_find(&cname_list, cname)) { + find_unique_cname(cname, sizeof(cname)); + } + output_object_code(ctx, outfile, func_val, cname, true); + + /* the module is already referenced, so we must free it */ + m = JS_VALUE_GET_PTR(func_val); + JS_FreeValue(ctx, func_val); + } + return m; +} + +static void compile_file(JSContext *ctx, FILE *fo, + const char *filename, + const char *script_name, + const char *c_name1, + int module) +{ + uint8_t *buf; + char c_name[1024]; + int eval_flags; + JSValue obj; + size_t buf_len; + + buf = js_load_file(ctx, &buf_len, filename); + if (!buf) { + fprintf(stderr, "Could not load '%s'\n", filename); + exit(1); + } + eval_flags = JS_EVAL_FLAG_COMPILE_ONLY; + if (module < 0) { + module = (js__has_suffix(filename, ".mjs") || + JS_DetectModule((const char *)buf, buf_len)); + } + if (module) + eval_flags |= JS_EVAL_TYPE_MODULE; + else + eval_flags |= JS_EVAL_TYPE_GLOBAL; + obj = JS_Eval(ctx, (const char *)buf, buf_len, script_name ? script_name : filename, eval_flags); + if (JS_IsException(obj)) { + js_std_dump_error(ctx); + exit(1); + } + js_free(ctx, buf); + if (c_name1) { + js__pstrcpy(c_name, sizeof(c_name), c_name1); + } else { + get_c_name(c_name, sizeof(c_name), filename); + } + output_object_code(ctx, fo, obj, c_name, false); + JS_FreeValue(ctx, obj); +} + +static const char main_c_template1[] = + "int main(int argc, char **argv)\n" + "{\n" + " int r;\n" + " JSRuntime *rt;\n" + " JSContext *ctx;\n" + " r = 0;\n" + " rt = JS_NewRuntime();\n" + " js_std_set_worker_new_context_func(JS_NewCustomContext);\n" + " js_std_init_handlers(rt);\n" + ; + +static const char main_c_template2[] = + " r = js_std_loop(ctx);\n" + " if (r) {\n" + " js_std_dump_error(ctx);\n" + " }\n" + " js_std_free_handlers(rt);\n" + " JS_FreeContext(ctx);\n" + " JS_FreeRuntime(rt);\n" + " return r;\n" + "}\n"; + +#define PROG_NAME "qjsc" + +void help(void) +{ + printf("QuickJS-ng Compiler version %s\n" + "usage: " PROG_NAME " [options] [files]\n" + "\n" + "options are:\n" + "-b output raw bytecode instead of C code\n" + "-e output main() and bytecode in a C file\n" + "-o output set the output filename\n" + "-n script_name set the script name (as used in stack traces)\n" + "-N cname set the C name of the generated data\n" + "-C compile as JS classic script (default=autodetect)\n" + "-m compile as ES module (default=autodetect)\n" + "-D module_name compile a dynamically loaded module or worker\n" + "-M module_name[,cname] add initialization code for an external C module\n" + "-p prefix set the prefix of the generated C names\n" + "-P do not add default system modules\n" + "-s strip the source code, specify twice to also strip debug info\n" + "-S n set the maximum stack size to 'n' bytes (default=%d)\n", + JS_GetVersion(), + JS_DEFAULT_STACK_SIZE); + exit(1); +} + +// TODO(bnoordhuis) share with qjs.c maybe +static int64_t parse_limit(const char *arg) { + char *p; + unsigned long unit = 1; // bytes for backcompat; qjs defaults to kilobytes + double d = strtod(arg, &p); + + if (p == arg) { + fprintf(stderr, "qjsc: invalid limit: %s\n", arg); + return -1; + } + + if (*p) { + switch (*p++) { + case 'b': case 'B': unit = 1UL << 0; break; + case 'k': case 'K': unit = 1UL << 10; break; /* IEC kibibytes */ + case 'm': case 'M': unit = 1UL << 20; break; /* IEC mebibytes */ + case 'g': case 'G': unit = 1UL << 30; break; /* IEC gigibytes */ + default: + fprintf(stderr, "qjsc: invalid limit: %s, unrecognized suffix, only k,m,g are allowed\n", arg); + return -1; + } + if (*p) { + fprintf(stderr, "qjsc: invalid limit: %s, only one suffix allowed\n", arg); + return -1; + } + } + + return (int64_t)(d * unit); +} + +static void check_hasarg(int optind, int argc, int opt) +{ + if (optind >= argc) { + fprintf(stderr, "qjsc: missing file for -%c\n", opt); + exit(1); + } +} + +int main(int argc, char **argv) +{ + int optind = 1; + int i; + const char *out_filename, *cname, *script_name; + char cfilename[1024]; + FILE *fo; + JSRuntime *rt; + JSContext *ctx; + int module; + size_t stack_size; + namelist_t dynamic_module_list; + bool load_system_modules = true; + + out_filename = NULL; + script_name = NULL; + output_type = OUTPUT_C; + cname = NULL; + module = -1; + strip = 0; + stack_size = 0; + memset(&dynamic_module_list, 0, sizeof(dynamic_module_list)); + + + while (optind < argc && *argv[optind] == '-') { + char *arg = argv[optind] + 1; + char *longopt = ""; + char *optarg = NULL; + /* a single - is not an option, it also stops argument scanning */ + if (!*arg) + break; + optind++; + if (*arg == '-') { + longopt = arg + 1; + optarg = strchr(longopt, '='); + if (optarg) + *optarg++ = '\0'; + arg += strlen(arg); + /* -- stops argument scanning */ + if (!*longopt) + break; + } + for (; *arg || *longopt; longopt = "") { + char opt = *arg; + if (opt) { + arg++; + if (!optarg && *arg) + optarg = arg; + } + if (opt == 'h' || opt == '?' || !strcmp(longopt, "help")) { + help(); + continue; + } + if (opt == 'b') { + output_type = OUTPUT_RAW; + continue; + } + if (opt == 'o') { + if (!optarg) { + check_hasarg(optind, argc, opt); + optarg = argv[optind++]; + } + out_filename = optarg; + continue; + } + if (opt == 'e') { + output_type = OUTPUT_C_MAIN; + continue; + } + if (opt == 'n') { + if (!optarg) { + check_hasarg(optind, argc, opt); + optarg = argv[optind++]; + } + script_name = optarg; + continue; + } + if (opt == 'N') { + if (!optarg) { + check_hasarg(optind, argc, opt); + optarg = argv[optind++]; + } + cname = optarg; + continue; + } + if (opt == 'C') { + module = 0; + continue; + } + if (opt == 'm') { + module = 1; + continue; + } + if (opt == 'M') { + char *p; + char path[1024]; + char cname[1024]; + if (!optarg) { + check_hasarg(optind, argc, opt); + optarg = argv[optind++]; + } + js__pstrcpy(path, sizeof(path), optarg); + p = strchr(path, ','); + if (p) { + *p = '\0'; + js__pstrcpy(cname, sizeof(cname), p + 1); + } else { + get_c_name(cname, sizeof(cname), path); + } + namelist_add(&cmodule_list, path, cname, 0); + continue; + } + if (opt == 'D') { + if (!optarg) { + check_hasarg(optind, argc, opt); + optarg = argv[optind++]; + } + namelist_add(&dynamic_module_list, optarg, NULL, 0); + continue; + } + if (opt == 'P') { + load_system_modules = false; + continue; + } + if (opt == 's') { + strip++; + continue; + } + if (opt == 'p') { + if (!optarg) { + check_hasarg(optind, argc, opt); + optarg = argv[optind++]; + } + c_ident_prefix = optarg; + continue; + } + if (opt == 'S') { + if (!optarg) { + check_hasarg(optind, argc, opt); + optarg = argv[optind++]; + } + stack_size = parse_limit(optarg); + continue; + } + help(); + } + } + + if (load_system_modules) { + /* add system modules */ + namelist_add(&cmodule_list, "qjs:std", "std", 0); + namelist_add(&cmodule_list, "qjs:os", "os", 0); + namelist_add(&cmodule_list, "qjs:bjson", "bjson", 0); + namelist_add(&cmodule_list, "std", "std", 0); + namelist_add(&cmodule_list, "os", "os", 0); + namelist_add(&cmodule_list, "bjson", "bjson", 0); + } + + if (optind >= argc) + help(); + + if (!out_filename) + out_filename = "out.c"; + + js__pstrcpy(cfilename, sizeof(cfilename), out_filename); + + if (output_type == OUTPUT_RAW) + fo = fopen(cfilename, "wb"); + else + fo = fopen(cfilename, "w"); + + if (!fo) { + perror(cfilename); + exit(1); + } + outfile = fo; + + rt = JS_NewRuntime(); + ctx = JS_NewContext(rt); + + /* loader for ES6 modules */ + JS_SetModuleLoaderFunc(rt, NULL, jsc_module_loader, NULL); + + if (output_type != OUTPUT_RAW) { + fprintf(fo, "/* File generated automatically by the QuickJS-ng compiler. */\n" + "\n" + ); + } + + if (output_type == OUTPUT_C_MAIN) { + fprintf(fo, "#include \"quickjs-libc.h\"\n" + "\n" + ); + } else if (output_type == OUTPUT_C) { + fprintf(fo, "#include \n" + "\n" + ); + } + + for(i = optind; i < argc; i++) { + const char *filename = argv[i]; + compile_file(ctx, fo, filename, script_name, cname, module); + cname = NULL; + } + + for(i = 0; i < dynamic_module_list.count; i++) { + if (!jsc_module_loader(ctx, dynamic_module_list.array[i].name, NULL)) { + fprintf(stderr, "Could not load dynamic module '%s'\n", + dynamic_module_list.array[i].name); + exit(1); + } + } + + if (output_type == OUTPUT_C_MAIN) { + fprintf(fo, + "static JSContext *JS_NewCustomContext(JSRuntime *rt)\n" + "{\n" + " JSContext *ctx = JS_NewContext(rt);\n" + " if (!ctx)\n" + " return NULL;\n"); + /* add the precompiled modules (XXX: could modify the module + loader instead) */ + for(i = 0; i < init_module_list.count; i++) { + namelist_entry_t *e = &init_module_list.array[i]; + /* initialize the static C modules */ + + fprintf(fo, + " {\n" + " extern JSModuleDef *js_init_module_%s(JSContext *ctx, const char *name);\n" + " js_init_module_%s(ctx, \"%s\");\n" + " }\n", + e->short_name, e->short_name, e->name); + } + for(i = 0; i < cname_list.count; i++) { + namelist_entry_t *e = &cname_list.array[i]; + if (e->flags) { + fprintf(fo, " js_std_eval_binary(ctx, %s, %s_size, 1);\n", + e->name, e->name); + } + } + fprintf(fo, + " return ctx;\n" + "}\n\n"); + + fputs(main_c_template1, fo); + + if (stack_size != 0) { + fprintf(fo, " JS_SetMaxStackSize(rt, %u);\n", + (unsigned int)stack_size); + } + + /* add the module loader */ + fprintf(fo, " JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader, js_module_check_attributes, NULL);\n"); + + fprintf(fo, + " ctx = JS_NewCustomContext(rt);\n" + " js_std_add_helpers(ctx, argc, argv);\n"); + + for(i = 0; i < cname_list.count; i++) { + namelist_entry_t *e = &cname_list.array[i]; + if (!e->flags) { + fprintf(fo, " js_std_eval_binary(ctx, %s, %s_size, 0);\n", + e->name, e->name); + } + } + fputs(main_c_template2, fo); + } + + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + + fclose(fo); + + namelist_free(&cname_list); + namelist_free(&cmodule_list); + namelist_free(&init_module_list); + return 0; +} diff --git a/userland/qjs/source/qjsc.man b/userland/qjs/source/qjsc.man new file mode 100644 index 0000000..1b61a1e --- /dev/null +++ b/userland/qjs/source/qjsc.man @@ -0,0 +1,78 @@ +.TH QJSC 1 "2026-07-22" +.SH NAME +qjsc - QuickJS-NG bytecode compiler + +.SH SYNOPSIS +.SY qjsc +.RI [ OPTION ].\|.\|.\& +.RI [ FILE ].\|.\|. +.YS + +.SH DESCRIPTION +QuickJS-NG is a small and embeddable JavaScript engine. +It aims to support the latest ECMAScript specification. +.PP +The \fBqjsc\fR executable runs the JavaScript compiler. +It can generate bytecode from source files which can then be embedded in an executable, +or it can generate the necessary scaffolding to build a C application which embeds QuickJS. + +.SH OPTIONS +.TP +.B \-b +Output raw bytecode instead of C code. + +.TP +.B \-C +Compile as classic JavaScript script. +By default, \fBqjsc\fR will try to detect if each \fIFILE\fR is a JS script or an ES module. + +.TP +.BI \-D " MODULE_NAME" +Compile a dynamically loaded module or worker. + +.TP +.B \-e +Output \fBmain()\fR and bytecode in a C file. + +.TP +.B \-m +Compile as ECMAScript module. +By default, \fBqjsc\fR will try to detect if each \fIFILE\fR is a JS script or an ES module. + +.TP +\fB\-M\fR \fIMODULE_NAME\fR[,\fICNAME\fR] +Add initialization code for an external C module. + +.TP +.BI \-n " SCRIPT_NAME" +Set the script name (as used in stack traces). + +.TP +.BI \-N " CNAME" +Set the C name of the generated data. + +.TP +.BI \-o " OUTPUT" +Set the output filename. + +.TP +.BI \-p " PREFIX" +Add a prefix to generated C names. + +.TP +.B \-P +Do not add default system modules. + +.TP +.B \-s +Strip the source code. Specify this option twice to also strip debug info. + +.TP +.BI \-S " N" +Set the maximum stack size to \fIN\fR bytes (default is 1 048 576). + +.SH SEE ALSO +.SS "Man pages" +.BR qjs (1) +.SS "Online documentation" +Detailed documentation about the project can be found at: https://quickjs-ng.github.io/quickjs/ diff --git a/userland/qjs/source/quickjs-atom.h b/userland/qjs/source/quickjs-atom.h new file mode 100644 index 0000000..5b8d563 --- /dev/null +++ b/userland/qjs/source/quickjs-atom.h @@ -0,0 +1,279 @@ +/* + * QuickJS atom definitions + * + * Copyright (c) 2017-2018 Fabrice Bellard + * Copyright (c) 2017-2018 Charlie Gordon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifdef DEF + +/* Note: first atoms are considered as keywords in the parser */ +DEF(null, "null") /* must be first */ +DEF(false, "false") +DEF(true, "true") +DEF(if, "if") +DEF(else, "else") +DEF(return, "return") +DEF(var, "var") +DEF(this, "this") +DEF(delete, "delete") +DEF(void, "void") +DEF(typeof, "typeof") +DEF(new, "new") +DEF(in, "in") +DEF(instanceof, "instanceof") +DEF(do, "do") +DEF(while, "while") +DEF(for, "for") +DEF(break, "break") +DEF(continue, "continue") +DEF(switch, "switch") +DEF(case, "case") +DEF(default, "default") +DEF(throw, "throw") +DEF(try, "try") +DEF(catch, "catch") +DEF(finally, "finally") +DEF(function, "function") +DEF(debugger, "debugger") +DEF(with, "with") +/* FutureReservedWord */ +DEF(class, "class") +DEF(const, "const") +DEF(enum, "enum") +DEF(export, "export") +DEF(extends, "extends") +DEF(import, "import") +DEF(super, "super") +DEF(using, "using") +/* FutureReservedWords when parsing strict mode code */ +DEF(implements, "implements") +DEF(interface, "interface") +DEF(let, "let") +DEF(package, "package") +DEF(private, "private") +DEF(protected, "protected") +DEF(public, "public") +DEF(static, "static") +DEF(yield, "yield") +DEF(await, "await") + +/* empty string */ +DEF(empty_string, "") +/* identifiers */ +DEF(keys, "keys") +DEF(size, "size") +DEF(length, "length") +DEF(message, "message") +DEF(cause, "cause") +DEF(errors, "errors") +DEF(error, "error") +DEF(suppressed, "suppressed") +DEF(stack, "stack") +DEF(name, "name") +DEF(toString, "toString") +DEF(toLocaleString, "toLocaleString") +DEF(valueOf, "valueOf") +DEF(eval, "eval") +DEF(prototype, "prototype") +DEF(constructor, "constructor") +DEF(configurable, "configurable") +DEF(writable, "writable") +DEF(enumerable, "enumerable") +DEF(value, "value") +DEF(get, "get") +DEF(set, "set") +DEF(of, "of") +DEF(__proto__, "__proto__") +DEF(undefined, "undefined") +DEF(number, "number") +DEF(boolean, "boolean") +DEF(string, "string") +DEF(object, "object") +DEF(symbol, "symbol") +DEF(integer, "integer") +DEF(unknown, "unknown") +DEF(arguments, "arguments") +DEF(callee, "callee") +DEF(caller, "caller") +DEF(_eval_, "") +DEF(_ret_, "") +DEF(_var_, "") +DEF(_arg_var_, "") +DEF(_with_, "") +DEF(_using_dispose_, "") +DEF(use, "use") +DEF(dispose, "dispose") +DEF(disposeAsync, "disposeAsync") +DEF(lastIndex, "lastIndex") +DEF(target, "target") +DEF(index, "index") +DEF(input, "input") +DEF(defineProperties, "defineProperties") +DEF(apply, "apply") +DEF(join, "join") +DEF(split, "split") +DEF(construct, "construct") +DEF(getPrototypeOf, "getPrototypeOf") +DEF(setPrototypeOf, "setPrototypeOf") +DEF(isExtensible, "isExtensible") +DEF(preventExtensions, "preventExtensions") +DEF(has, "has") +DEF(deleteProperty, "deleteProperty") +DEF(defineProperty, "defineProperty") +DEF(getOwnPropertyDescriptor, "getOwnPropertyDescriptor") +DEF(ownKeys, "ownKeys") +DEF(add, "add") +DEF(done, "done") +DEF(next, "next") +DEF(values, "values") +DEF(source, "source") +DEF(flags, "flags") +DEF(global, "global") +DEF(unicode, "unicode") +DEF(raw, "raw") +DEF(rawJSON, "rawJSON") +DEF(new_target, "new.target") +DEF(this_active_func, "this.active_func") +DEF(home_object, "") +DEF(computed_field, "") +DEF(static_computed_field, "") /* must come after computed_fields */ +DEF(class_fields_init, "") +DEF(brand, "") +DEF(hash_constructor, "#constructor") +DEF(as, "as") +DEF(from, "from") +DEF(fromAsync, "fromAsync") +DEF(meta, "meta") +DEF(_default_, "*default*") +DEF(_star_, "*") +DEF(Module, "Module") +DEF(then, "then") +DEF(resolve, "resolve") +DEF(reject, "reject") +DEF(promise, "promise") +DEF(proxy, "proxy") +DEF(revoke, "revoke") +DEF(async, "async") +DEF(exec, "exec") +DEF(groups, "groups") +DEF(indices, "indices") +DEF(status, "status") +DEF(reason, "reason") +DEF(globalThis, "globalThis") +DEF(bigint, "bigint") +DEF(not_equal, "not-equal") +DEF(timed_out, "timed-out") +DEF(ok, "ok") +DEF(toJSON, "toJSON") +DEF(maxByteLength, "maxByteLength") +DEF(zip, "zip") +DEF(zipKeyed, "zipKeyed") +/* class names */ +DEF(Object, "Object") +DEF(Array, "Array") +DEF(Error, "Error") +DEF(Number, "Number") +DEF(String, "String") +DEF(Boolean, "Boolean") +DEF(Symbol, "Symbol") +DEF(Arguments, "Arguments") +DEF(Math, "Math") +DEF(JSON, "JSON") +DEF(Date, "Date") +DEF(Function, "Function") +DEF(GeneratorFunction, "GeneratorFunction") +DEF(ForInIterator, "ForInIterator") +DEF(RegExp, "RegExp") +DEF(ArrayBuffer, "ArrayBuffer") +DEF(SharedArrayBuffer, "SharedArrayBuffer") +/* must keep same order as class IDs for typed arrays */ +DEF(Uint8ClampedArray, "Uint8ClampedArray") +DEF(Int8Array, "Int8Array") +DEF(Uint8Array, "Uint8Array") +DEF(Int16Array, "Int16Array") +DEF(Uint16Array, "Uint16Array") +DEF(Int32Array, "Int32Array") +DEF(Uint32Array, "Uint32Array") +DEF(BigInt64Array, "BigInt64Array") +DEF(BigUint64Array, "BigUint64Array") +DEF(Float16Array, "Float16Array") +DEF(Float32Array, "Float32Array") +DEF(Float64Array, "Float64Array") +DEF(DataView, "DataView") +DEF(BigInt, "BigInt") +DEF(WeakRef, "WeakRef") +DEF(FinalizationRegistry, "FinalizationRegistry") +DEF(Map, "Map") +DEF(Set, "Set") /* Map + 1 */ +DEF(WeakMap, "WeakMap") /* Map + 2 */ +DEF(WeakSet, "WeakSet") /* Map + 3 */ +DEF(Iterator, "Iterator") +DEF(IteratorConcat, "Iterator Concat") +DEF(IteratorHelper, "Iterator Helper") +DEF(IteratorWrap, "Iterator Wrap") +DEF(Map_Iterator, "Map Iterator") +DEF(Set_Iterator, "Set Iterator") +DEF(Array_Iterator, "Array Iterator") +DEF(String_Iterator, "String Iterator") +DEF(RegExp_String_Iterator, "RegExp String Iterator") +DEF(Generator, "Generator") +DEF(Proxy, "Proxy") +DEF(Promise, "Promise") +DEF(PromiseResolveFunction, "PromiseResolveFunction") +DEF(PromiseRejectFunction, "PromiseRejectFunction") +DEF(AsyncFunction, "AsyncFunction") +DEF(AsyncFunctionResolve, "AsyncFunctionResolve") +DEF(AsyncFunctionReject, "AsyncFunctionReject") +DEF(AsyncGeneratorFunction, "AsyncGeneratorFunction") +DEF(AsyncGenerator, "AsyncGenerator") +DEF(EvalError, "EvalError") +DEF(RangeError, "RangeError") +DEF(ReferenceError, "ReferenceError") +DEF(SyntaxError, "SyntaxError") +DEF(TypeError, "TypeError") +DEF(URIError, "URIError") +DEF(InternalError, "InternalError") +DEF(DOMException, "DOMException") +DEF(CallSite, "CallSite") +DEF(DisposableStack, "DisposableStack") +DEF(AsyncDisposableStack, "AsyncDisposableStack") +DEF(SuppressedError, "SuppressedError") +/* private symbols */ +DEF(Private_brand, "") +/* symbols */ +DEF(Symbol_toPrimitive, "Symbol.toPrimitive") +DEF(Symbol_iterator, "Symbol.iterator") +DEF(Symbol_match, "Symbol.match") +DEF(Symbol_matchAll, "Symbol.matchAll") +DEF(Symbol_replace, "Symbol.replace") +DEF(Symbol_search, "Symbol.search") +DEF(Symbol_split, "Symbol.split") +DEF(Symbol_toStringTag, "Symbol.toStringTag") +DEF(Symbol_isConcatSpreadable, "Symbol.isConcatSpreadable") +DEF(Symbol_hasInstance, "Symbol.hasInstance") +DEF(Symbol_species, "Symbol.species") +DEF(Symbol_unscopables, "Symbol.unscopables") +DEF(Symbol_asyncIterator, "Symbol.asyncIterator") +DEF(Symbol_dispose, "Symbol.dispose") +DEF(Symbol_asyncDispose, "Symbol.asyncDispose") + +#endif /* DEF */ diff --git a/userland/qjs/source/quickjs-c-atomics.h b/userland/qjs/source/quickjs-c-atomics.h new file mode 100644 index 0000000..8fc6b72 --- /dev/null +++ b/userland/qjs/source/quickjs-c-atomics.h @@ -0,0 +1,54 @@ +/* + * QuickJS C atomics definitions + * + * Copyright (c) 2023 Marcin Kolny + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#if (defined(__GNUC__) || defined(__GNUG__)) && !defined(__clang__) + // Use GCC builtins for version < 4.9 +# if((__GNUC__ << 16) + __GNUC_MINOR__ < ((4) << 16) + 9) +# define GCC_BUILTIN_ATOMICS +# endif +#endif + +#ifdef GCC_BUILTIN_ATOMICS +#define atomic_fetch_add(obj, arg) \ + __atomic_fetch_add(obj, arg, __ATOMIC_SEQ_CST) +#define atomic_compare_exchange_strong(obj, expected, desired) \ + __atomic_compare_exchange_n(obj, expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) +#define atomic_exchange(obj, desired) \ + __atomic_exchange_n (obj, desired, __ATOMIC_SEQ_CST) +#define atomic_load(obj) \ + __atomic_load_n(obj, __ATOMIC_SEQ_CST) +#define atomic_store(obj, desired) \ + __atomic_store_n(obj, desired, __ATOMIC_SEQ_CST) +#define atomic_fetch_or(obj, arg) \ + __atomic_fetch_or(obj, arg, __ATOMIC_SEQ_CST) +#define atomic_fetch_xor(obj, arg) \ + __atomic_fetch_xor(obj, arg, __ATOMIC_SEQ_CST) +#define atomic_fetch_and(obj, arg) \ + __atomic_fetch_and(obj, arg, __ATOMIC_SEQ_CST) +#define atomic_fetch_sub(obj, arg) \ + __atomic_fetch_sub(obj, arg, __ATOMIC_SEQ_CST) +#define _Atomic +#else +#include +#endif diff --git a/userland/qjs/source/quickjs-libc.c b/userland/qjs/source/quickjs-libc.c new file mode 100644 index 0000000..42d7f03 --- /dev/null +++ b/userland/qjs/source/quickjs-libc.c @@ -0,0 +1,5085 @@ +/* + * QuickJS C library + * + * Copyright (c) 2017-2021 Fabrice Bellard + * Copyright (c) 2017-2021 Charlie Gordon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "quickjs.h" +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(_MSC_VER) +#include +#include +#endif +#include +#include +#include +#include +#if !defined(_MSC_VER) +#include +#endif +#if defined(_WIN32) +#include +#include +#include +#include +#include +#include +#include +#define popen _popen +#define pclose _pclose +#define rmdir _rmdir +#define getcwd _getcwd +#define chdir _chdir +#else +#include +#include +#if !defined(__wasi__) +#include +#include +#include +#include +#include +#endif + +#if defined(__COSMOPOLITAN__) +#include +#endif + +#if defined(__APPLE__) +typedef sig_t sighandler_t; +#include +#include +#define environ (*_NSGetEnviron()) +#endif + +#ifdef __sun +typedef void (*sighandler_t)(int); +extern char **environ; +#endif + +#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) +typedef sig_t sighandler_t; +extern char **environ; +#endif + +#endif /* _WIN32 */ + +#include "cutils.h" +#include "list.h" +#include "quickjs-libc.h" + +#if JS_HAVE_THREADS +#include "quickjs-c-atomics.h" +#define USE_WORKER // enable os.Worker +#endif + +#ifndef S_IFBLK +#define S_IFBLK 0 +#endif + +#ifndef S_IFIFO +#define S_IFIFO 0 +#endif + +#ifndef MAX_SAFE_INTEGER // already defined in amalgamation builds +#define MAX_SAFE_INTEGER (((int64_t) 1 << 53) - 1) +#endif + +#ifndef QJS_NATIVE_MODULE_SUFFIX +#ifdef _WIN32 +#define QJS_NATIVE_MODULE_SUFFIX ".dll" +#else +#define QJS_NATIVE_MODULE_SUFFIX ".so" +#endif +#endif + +/* TODO: + - add socket calls +*/ + +typedef struct { + struct list_head link; + int fd; + JSValue rw_func[2]; +} JSOSRWHandler; + +typedef struct { + struct list_head link; + int sig_num; + JSValue func; +} JSOSSignalHandler; + +typedef struct { + struct list_head link; + int64_t timer_id; + uint8_t repeats:1; + int64_t timeout; + int64_t delay; + JSValue func; +} JSOSTimer; + +typedef struct { + struct list_head link; + JSValue promise; + JSValue reason; +} JSRejectedPromiseEntry; + +#ifdef USE_WORKER + +typedef struct { + struct list_head link; + uint8_t *data; + size_t data_len; + /* list of SharedArrayBuffers, necessary to free the message */ + uint8_t **sab_tab; + size_t sab_tab_len; +} JSWorkerMessage; + +typedef struct JSWaker { +#ifdef _WIN32 + HANDLE handle; +#else + int read_fd; + int write_fd; +#endif +} JSWaker; + +typedef struct { + int ref_count; + js_mutex_t mutex; + struct list_head msg_queue; /* list of JSWorkerMessage.link */ + JSWaker waker; +} JSWorkerMessagePipe; + +typedef struct { + struct list_head link; + JSWorkerMessagePipe *recv_pipe; + JSValue on_message_func; +} JSWorkerMessageHandler; + +#endif // USE_WORKER + +typedef struct JSThreadState { + struct list_head os_rw_handlers; /* list of JSOSRWHandler.link */ + struct list_head os_signal_handlers; /* list JSOSSignalHandler.link */ + struct list_head os_timers; /* list of JSOSTimer.link */ + struct list_head port_list; /* list of JSWorkerMessageHandler.link */ + struct list_head rejected_promise_list; /* list of JSRejectedPromiseEntry.link */ + int eval_script_recurse; /* only used in the main thread */ + int64_t next_timer_id; /* for setTimeout / setInterval */ + bool can_js_os_poll; + /* not used in the main thread */ +#ifdef USE_WORKER + JSWorkerMessagePipe *recv_pipe, *send_pipe; +#else + void *recv_pipe; +#endif // USE_WORKER + JSClassID std_file_class_id; + JSClassID worker_class_id; + JSInterruptHandler *prev_interrupt_handler; + void *prev_interrupt_opaque; +} JSThreadState; + +static uint64_t os_pending_signals; + +static void *js_std_dbuf_realloc(void *opaque, void *ptr, size_t size) +{ + JSRuntime *rt = opaque; + return js_realloc_rt(rt, ptr, size); +} + +static void js_std_dbuf_init(JSContext *ctx, DynBuf *s) +{ + dbuf_init2(s, JS_GetRuntime(ctx), js_std_dbuf_realloc); +} + +static bool my_isdigit(int c) +{ + return (c >= '0' && c <= '9'); +} + +static JSThreadState *js_get_thread_state(JSRuntime *rt) +{ + return (JSThreadState *)js_std_cmd(/*GetOpaque*/0, rt); +} + +static void js_set_thread_state(JSRuntime *rt, JSThreadState *ts) +{ + js_std_cmd(/*SetOpaque*/1, rt, ts); +} + +// Non-CL Clang on Windows does not define __GNUC__ +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +#endif // __GNUC__ || __clang__ +static JSValue js_printf_internal(JSContext *ctx, + int argc, JSValueConst *argv, FILE *fp) +{ + char fmtbuf[32]; + uint8_t cbuf[UTF8_CHAR_LEN_MAX+1]; + JSValue res; + DynBuf dbuf; + const char *fmt_str = NULL; + const uint8_t *fmt, *fmt_end; + const uint8_t *p; + char *q; + int i, c, len, mod; + size_t fmt_len; + int32_t int32_arg; + int64_t int64_arg; + double double_arg; + const char *string_arg; + + js_std_dbuf_init(ctx, &dbuf); + + if (argc > 0) { + fmt_str = JS_ToCStringLen(ctx, &fmt_len, argv[0]); + if (!fmt_str) + goto fail; + + i = 1; + fmt = (const uint8_t *)fmt_str; + fmt_end = fmt + fmt_len; + while (fmt < fmt_end) { + for (p = fmt; fmt < fmt_end && *fmt != '%'; fmt++) + continue; + dbuf_put(&dbuf, p, fmt - p); + if (fmt >= fmt_end) + break; + q = fmtbuf; + *q++ = *fmt++; /* copy '%' */ + + /* flags */ + for(;;) { + c = *fmt; + if (c == '0' || c == '#' || c == '+' || c == '-' || c == ' ' || + c == '\'') { + if (q >= fmtbuf + sizeof(fmtbuf) - 1) + goto invalid; + *q++ = c; + fmt++; + } else { + break; + } + } + /* width */ + if (*fmt == '*') { + if (i >= argc) + goto missing; + if (JS_ToInt32(ctx, &int32_arg, argv[i++])) + goto fail; + q += snprintf(q, fmtbuf + sizeof(fmtbuf) - q, "%d", int32_arg); + fmt++; + } else { + while (my_isdigit(*fmt)) { + if (q >= fmtbuf + sizeof(fmtbuf) - 1) + goto invalid; + *q++ = *fmt++; + } + } + if (*fmt == '.') { + if (q >= fmtbuf + sizeof(fmtbuf) - 1) + goto invalid; + *q++ = *fmt++; + if (*fmt == '*') { + if (i >= argc) + goto missing; + if (JS_ToInt32(ctx, &int32_arg, argv[i++])) + goto fail; + q += snprintf(q, fmtbuf + sizeof(fmtbuf) - q, "%d", int32_arg); + fmt++; + } else { + while (my_isdigit(*fmt)) { + if (q >= fmtbuf + sizeof(fmtbuf) - 1) + goto invalid; + *q++ = *fmt++; + } + } + } + + /* we only support the "l" modifier for 64 bit numbers */ + mod = ' '; + if (*fmt == 'l') { + mod = *fmt++; + } + + /* type */ + c = *fmt++; + if (q >= fmtbuf + sizeof(fmtbuf) - 1) + goto invalid; + *q++ = c; + *q = '\0'; + + switch (c) { + case 'c': + if (i >= argc) + goto missing; + if (JS_IsString(argv[i])) { + // TODO(chqrlie) need an API to wrap charCodeAt and codePointAt */ + string_arg = JS_ToCString(ctx, argv[i++]); + if (!string_arg) + goto fail; + int32_arg = utf8_decode((const uint8_t *)string_arg, &p); + JS_FreeCString(ctx, string_arg); + } else { + if (JS_ToInt32(ctx, &int32_arg, argv[i++])) + goto fail; + } + // XXX: throw an exception? + if ((unsigned)int32_arg > 0x10FFFF) + int32_arg = 0xFFFD; + /* ignore conversion flags, width and precision */ + len = utf8_encode(cbuf, int32_arg); + dbuf_put(&dbuf, cbuf, len); + break; + + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + if (i >= argc) + goto missing; + if (JS_ToInt64Ext(ctx, &int64_arg, argv[i++])) + goto fail; + if (mod == 'l') { + /* 64 bit number */ +#if defined(_WIN32) + if (q >= fmtbuf + sizeof(fmtbuf) - 3) + goto invalid; + q[2] = q[-1]; + q[-1] = 'I'; + q[0] = '6'; + q[1] = '4'; + q[3] = '\0'; + dbuf_printf(&dbuf, fmtbuf, (int64_t)int64_arg); +#else + if (q >= fmtbuf + sizeof(fmtbuf) - 2) + goto invalid; + q[1] = q[-1]; + q[-1] = q[0] = 'l'; + q[2] = '\0'; + dbuf_printf(&dbuf, fmtbuf, (long long)int64_arg); +#endif + } else { + dbuf_printf(&dbuf, fmtbuf, (int)int64_arg); + } + break; + + case 's': + if (i >= argc) + goto missing; + /* XXX: handle strings containing null characters */ + string_arg = JS_ToCString(ctx, argv[i++]); + if (!string_arg) + goto fail; + dbuf_printf(&dbuf, fmtbuf, string_arg); + JS_FreeCString(ctx, string_arg); + break; + + case 'e': + case 'f': + case 'g': + case 'a': + case 'E': + case 'F': + case 'G': + case 'A': + if (i >= argc) + goto missing; + if (JS_ToFloat64(ctx, &double_arg, argv[i++])) + goto fail; + dbuf_printf(&dbuf, fmtbuf, double_arg); + break; + + case '%': + dbuf_putc(&dbuf, '%'); + break; + + default: + /* XXX: should support an extension mechanism */ + invalid: + JS_ThrowTypeError(ctx, "invalid conversion specifier in format string"); + goto fail; + missing: + JS_ThrowReferenceError(ctx, "missing argument for conversion specifier"); + goto fail; + } + } + JS_FreeCString(ctx, fmt_str); + } + if (dbuf.error) { + res = JS_ThrowOutOfMemory(ctx); + } else { + if (fp) { + len = fwrite(dbuf.buf, 1, dbuf.size, fp); + res = JS_NewInt32(ctx, len); + } else { + res = JS_NewStringLen(ctx, (char *)dbuf.buf, dbuf.size); + } + } + dbuf_free(&dbuf); + return res; + +fail: + JS_FreeCString(ctx, fmt_str); + dbuf_free(&dbuf); + return JS_EXCEPTION; +} +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop // ignored "-Wformat-nonliteral" +#endif // __GNUC__ || __clang__ + +uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename) +{ + FILE *f; + size_t n, len; + uint8_t *p, *buf, tmp[8192]; + + f = fopen(filename, "rb"); + if (!f) + return NULL; + buf = NULL; + len = 0; + do { + n = fread(tmp, 1, sizeof(tmp), f); + if (ctx) { + p = js_realloc(ctx, buf, len + n + 1); + } else { + p = realloc(buf, len + n + 1); + } + if (!p) { + if (ctx) { + js_free(ctx, buf); + } else { + free(buf); + } + fclose(f); + return NULL; + } + memcpy(&p[len], tmp, n); + buf = p; + len += n; + buf[len] = '\0'; + } while (n == sizeof(tmp)); + fclose(f); + *pbuf_len = len; + return buf; +} + +/* load and evaluate a file */ +static JSValue js_loadScript(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + uint8_t *buf; + const char *filename; + JSValue ret; + size_t buf_len; + + filename = JS_ToCString(ctx, argv[0]); + if (!filename) + return JS_EXCEPTION; + buf = js_load_file(ctx, &buf_len, filename); + if (!buf) { + JS_ThrowReferenceError(ctx, "could not load '%s'", filename); + JS_FreeCString(ctx, filename); + return JS_EXCEPTION; + } + ret = JS_Eval(ctx, (char *)buf, buf_len, filename, + JS_EVAL_TYPE_GLOBAL); + js_free(ctx, buf); + JS_FreeCString(ctx, filename); + return ret; +} + +static int get_bool_option(JSContext *ctx, bool *pbool, + JSValueConst obj, + const char *option) +{ + JSValue val; + val = JS_GetPropertyStr(ctx, obj, option); + if (JS_IsException(val)) + return -1; + if (!JS_IsUndefined(val)) { + *pbool = JS_ToBool(ctx, val); + } + JS_FreeValue(ctx, val); + return 0; +} + +// js_realloc_array_buffer to avoid a name conflict with +// js_array_buffer_realloc from quickjs.c in the amalgamation build +static void *js_realloc_array_buffer(JSRuntime *rt, void *opaque, void *ptr, + size_t size) +{ + return js_realloc_rt(rt, ptr, size); +} + +/* load a file as a UTF-8 encoded string or Uint8Array */ +static JSValue js_std_loadFile(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + uint8_t *buf; + const char *filename; + JSValueConst options_obj; + JSValue ret; + size_t buf_len; + bool binary = false; + + if (argc >= 2) { + options_obj = argv[1]; + if (get_bool_option(ctx, &binary, options_obj, + "binary")) + return JS_EXCEPTION; + } + + filename = JS_ToCString(ctx, argv[0]); + if (!filename) + return JS_EXCEPTION; + buf = js_load_file(ctx, &buf_len, filename); + JS_FreeCString(ctx, filename); + if (!buf) + return JS_NULL; + if (binary) { + ret = JS_NewUint8Array(ctx, buf, buf_len, js_realloc_array_buffer, + NULL, false); + } else { + ret = JS_NewStringLen(ctx, (char *)buf, buf_len); + js_free(ctx, buf); + } + + return ret; +} + +static JSValue js_std_writeFile(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *filename; + const char *mode; + const void *buf; + size_t len, n; + JSValueConst data; + JSValue val, ret, unref; + bool release; + FILE *fp; + + ret = JS_EXCEPTION; + len = 0; + buf = ""; + mode = "w"; + data = argv[1]; + unref = JS_UNDEFINED; + release = false; + filename = JS_ToCString(ctx, argv[0]); + if (!filename) + return JS_EXCEPTION; + if (JS_IsObject(data)) { + val = JS_GetPropertyStr(ctx, data, "buffer"); + if (JS_IsException(val)) + goto exception; + if (JS_IsArrayBuffer(val)) { + data = unref = val; + } else { + JS_FreeValue(ctx, val); + } + } + if (JS_IsArrayBuffer(data)) { + buf = JS_GetArrayBuffer(ctx, &len, data); + mode = "wb"; + } else if (!JS_IsUndefined(data)) { + buf = JS_ToCStringLen(ctx, &len, data); + release = true; + } + if (!buf) + goto exception; + fp = fopen(filename, mode); + if (!fp) { + JS_ThrowPlainError(ctx, "error opening %s for writing", filename); + goto exception; + } + n = fwrite(buf, len, 1, fp); + fclose(fp); + if (n != 1) { + JS_ThrowPlainError(ctx, "error writing to %s", filename); + goto exception; + } + ret = JS_UNDEFINED; +exception: + JS_FreeCString(ctx, filename); + if (release) + JS_FreeCString(ctx, buf); + JS_FreeValue(ctx, unref); + return ret; +} + +typedef JSModuleDef *(JSInitModuleFunc)(JSContext *ctx, + const char *module_name); + + +#if defined(_WIN32) +static JSModuleDef *js_module_loader_so(JSContext *ctx, + const char *module_name) +{ + JSModuleDef *m; + HINSTANCE hd; + JSInitModuleFunc *init; + char *filename = NULL; + size_t len = strlen(module_name); + bool is_absolute = len > 2 && ((module_name[0] >= 'A' && module_name[0] <= 'Z') || + (module_name[0] >= 'a' && module_name[0] <= 'z')) && module_name[1] == ':'; + bool is_relative = len > 2 && module_name[0] == '.' && (module_name[1] == '/' || module_name[1] == '\\'); + if (is_absolute || is_relative) { + filename = (char *)module_name; + } else { + filename = js_malloc(ctx, len + 2 + 1); + if (!filename) + return NULL; + strcpy(filename, "./"); + strcpy(filename + 2, module_name); + } + hd = LoadLibraryA(filename); + if (filename != module_name) + js_free(ctx, filename); + if (hd == NULL) { + JS_ThrowReferenceError(ctx, "js_load_module '%s' error: %lu", + module_name, GetLastError()); + goto fail; + } + init = (JSInitModuleFunc *)(uintptr_t)GetProcAddress(hd, "js_init_module"); + if (!init) { + JS_ThrowReferenceError(ctx, "js_init_module '%s' not found: %lu", + module_name, GetLastError()); + goto fail; + } + m = init(ctx, module_name); + if (!m) { + JS_ThrowReferenceError(ctx, "js_call_module '%s' initialization error", + module_name); + fail: + if (hd != NULL) + FreeLibrary(hd); + return NULL; + } + return m; +} +#elif defined(__wasi__) +static JSModuleDef *js_module_loader_so(JSContext *ctx, + const char *module_name) +{ + JS_ThrowReferenceError(ctx, "shared library modules are not supported yet"); + return NULL; +} +#else +static JSModuleDef *js_module_loader_so(JSContext *ctx, + const char *module_name) +{ + JSModuleDef *m; + void *hd; + JSInitModuleFunc *init; + char *filename; + + if (!strchr(module_name, '/')) { + /* must add a '/' so that the DLL is not searched in the + system library paths */ + filename = js_malloc(ctx, strlen(module_name) + 2 + 1); + if (!filename) + return NULL; + strcpy(filename, "./"); + strcpy(filename + 2, module_name); + } else { + filename = (char *)module_name; + } + + /* C module */ + hd = dlopen(filename, RTLD_NOW | RTLD_LOCAL); + if (filename != module_name) + js_free(ctx, filename); + if (!hd) { + JS_ThrowReferenceError(ctx, "could not load module filename '%s' as shared library: %s", + module_name, dlerror()); + goto fail; + } + + *(void **) (&init) = dlsym(hd, "js_init_module"); + if (!init) { + JS_ThrowReferenceError(ctx, "could not load module filename '%s': js_init_module not found", + module_name); + goto fail; + } + + m = init(ctx, module_name); + if (!m) { + JS_ThrowReferenceError(ctx, "could not load module filename '%s': initialization error", + module_name); + fail: + if (hd) + dlclose(hd); + return NULL; + } + return m; +} +#endif /* !_WIN32 */ + +int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val, + bool use_realpath, bool is_main) +{ + JSModuleDef *m; + char buf[JS__PATH_MAX + 16]; + JSValue meta_obj; + JSAtom module_name_atom; + const char *module_name; + + assert(JS_VALUE_GET_TAG(func_val) == JS_TAG_MODULE); + m = JS_VALUE_GET_PTR(func_val); + + module_name_atom = JS_GetModuleName(ctx, m); + module_name = JS_AtomToCString(ctx, module_name_atom); + JS_FreeAtom(ctx, module_name_atom); + if (!module_name) + return -1; + if (!strchr(module_name, ':')) { + strcpy(buf, "file://"); +#if !defined(_WIN32) && !defined(__wasi__) + /* realpath() cannot be used with modules compiled with qjsc + because the corresponding module source code is not + necessarily present */ + if (use_realpath) { + char *res = realpath(module_name, buf + strlen(buf)); + if (!res) { + JS_ThrowTypeError(ctx, "realpath failure"); + JS_FreeCString(ctx, module_name); + return -1; + } + } else +#endif + { + js__pstrcat(buf, sizeof(buf), module_name); + } + } else { + js__pstrcpy(buf, sizeof(buf), module_name); + } + JS_FreeCString(ctx, module_name); + + meta_obj = JS_GetImportMeta(ctx, m); + if (JS_IsException(meta_obj)) + return -1; + JS_DefinePropertyValueStr(ctx, meta_obj, "url", + JS_NewString(ctx, buf), + JS_PROP_C_W_E); + JS_DefinePropertyValueStr(ctx, meta_obj, "main", + JS_NewBool(ctx, is_main), + JS_PROP_C_W_E); + JS_FreeValue(ctx, meta_obj); + return 0; +} + +static int default_module_init(JSContext *ctx, JSModuleDef *m) +{ + JSValue val; + val = JS_GetModulePrivateValue(ctx, m); + JS_SetModuleExport(ctx, m, "default", val); + return 0; +} + +/* in order to conform with the specification, only the keys should be + tested and not the associated values. */ +int js_module_check_attributes(JSContext *ctx, void *opaque, + JSValueConst attributes) +{ + JSPropertyEnum *tab; + uint32_t i, len; + int ret; + const char *cstr; + size_t cstr_len; + + if (JS_GetOwnPropertyNames(ctx, &tab, &len, attributes, JS_GPN_ENUM_ONLY | JS_GPN_STRING_MASK)) + return -1; + ret = 0; + for(i = 0; i < len; i++) { + cstr = JS_AtomToCStringLen(ctx, &cstr_len, tab[i].atom); + if (!cstr) { + ret = -1; + break; + } + if (!(cstr_len == 4 && !memcmp(cstr, "type", cstr_len))) { + JS_ThrowTypeError(ctx, "import attribute '%s' is not supported", cstr); + ret = -1; + } + JS_FreeCString(ctx, cstr); + if (ret) + break; + } + JS_FreePropertyEnum(ctx, tab, len); + return ret; +} + +enum { + JS_IMPORT_TYPE_JS, + JS_IMPORT_TYPE_JSON, + JS_IMPORT_TYPE_TEXT, + JS_IMPORT_TYPE_BYTES, +}; + +/* return > 0 if the attributes indicate a JSON module, 0 otherwise, -1 on error */ +static int js_module_import_type(JSContext *ctx, JSValueConst attributes) +{ + JSValue str; + const char *cstr; + size_t len; + int res; + + if (JS_IsUndefined(attributes)) + return JS_IMPORT_TYPE_JS; + str = JS_GetPropertyStr(ctx, attributes, "type"); + if (JS_IsException(str)) + return -1; + if (!JS_IsString(str)) { + JS_FreeValue(ctx, str); + return JS_IMPORT_TYPE_JS; + } + cstr = JS_ToCStringLen(ctx, &len, str); + JS_FreeValue(ctx, str); + if (!cstr) + return -1; + if (len == 4 && !memcmp(cstr, "json", len)) { + res = JS_IMPORT_TYPE_JSON; + } else if (len == 4 && !memcmp(cstr, "text", len)) { + res = JS_IMPORT_TYPE_TEXT; + } else if (len == 5 && !memcmp(cstr, "bytes", len)) { + res = JS_IMPORT_TYPE_BYTES; + } else { + /* unknown type - throw error */ + JS_ThrowTypeError(ctx, "unsupported module type: '%s'", cstr); + res = -1; + } + JS_FreeCString(ctx, cstr); + return res; +} + +JSModuleDef *js_module_load(JSContext *ctx, const char *module_name, + void *opaque, JSValueConst attributes, + JSLoadFileFunc *load_file) +{ + JSModuleDef *m; + JSValue val; + size_t buf_len; + char *buf; + int type; + + type = js_module_import_type(ctx, attributes); + if (type < 0) + return NULL; + /* the .json suffix only selects the JSON type when no type attribute + was given, so that e.g. 'with { type: "text" }' is honored */ + if (type == JS_IMPORT_TYPE_JS) + if (js__has_suffix(module_name, ".json")) + type = JS_IMPORT_TYPE_JSON; + buf = (char *)load_file(ctx, &buf_len, module_name); + if (!buf) { + JS_ThrowReferenceError(ctx, "could not load module filename '%s'", + module_name); + return NULL; + } + switch (type) { + case JS_IMPORT_TYPE_JS: + val = JS_Eval(ctx, buf, buf_len, module_name, + JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY); + break; + case JS_IMPORT_TYPE_JSON: + val = JS_ParseJSON(ctx, buf, buf_len, module_name); + break; + case JS_IMPORT_TYPE_TEXT: + val = JS_NewStringLen(ctx, buf, buf_len); + break; + case JS_IMPORT_TYPE_BYTES: + val = JS_NewUint8Array(ctx, (uint8_t *)buf, buf_len, + js_realloc_array_buffer, NULL, + /*is_shared*/false); + if (!JS_IsException(val)) { + JSValue abuf = JS_GetTypedArrayBuffer(ctx, val, NULL, NULL, NULL); + JS_SetImmutableArrayBuffer(abuf, /*immutable*/true); + JS_FreeValue(ctx, abuf); + buf = NULL; + } + break; + default: + val = JS_ThrowInternalError(ctx, "unhandled import type"); + break; + } + js_free(ctx, buf); + if (JS_IsException(val)) + return NULL; + if (type == JS_IMPORT_TYPE_JS) { + if (js_module_set_import_meta(ctx, val, true, false) < 0) { + JS_FreeValue(ctx, val); + return NULL; + } + // the module is already referenced, so we must free it + m = JS_VALUE_GET_PTR(val); + JS_FreeValue(ctx, val); + } else { + m = JS_NewCModule(ctx, module_name, default_module_init); + if (!m) { + JS_FreeValue(ctx, val); + return NULL; + } + // only export the "default" symbol which will contain the string + // or JSON object + JS_AddModuleExport(ctx, m, "default"); + JS_SetModulePrivateValue(ctx, m, val); + } + return m; +} + +JSModuleDef *js_module_loader(JSContext *ctx, const char *module_name, + void *opaque, JSValueConst attributes) +{ + if (js__has_suffix(module_name, QJS_NATIVE_MODULE_SUFFIX)) + return js_module_loader_so(ctx, module_name); + return js_module_load(ctx, module_name, opaque, attributes, js_load_file); +} + +static JSValue js_std_exit(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int status; + if (JS_ToInt32(ctx, &status, argv[0])) + status = -1; + exit(status); + return JS_UNDEFINED; +} + +static JSValue js_std_getenv(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *name, *str; + name = JS_ToCString(ctx, argv[0]); + if (!name) + return JS_EXCEPTION; + str = getenv(name); + JS_FreeCString(ctx, name); + if (!str) + return JS_UNDEFINED; + else + return JS_NewString(ctx, str); +} + +#if defined(_WIN32) +static void setenv(const char *name, const char *value, int overwrite) +{ + char *str; + size_t name_len, value_len; + name_len = strlen(name); + value_len = strlen(value); + str = malloc(name_len + 1 + value_len + 1); + memcpy(str, name, name_len); + str[name_len] = '='; + memcpy(str + name_len + 1, value, value_len); + str[name_len + 1 + value_len] = '\0'; + _putenv(str); + free(str); +} + +static void unsetenv(const char *name) +{ + setenv(name, "", true); +} +#endif /* _WIN32 */ + +static JSValue js_std_setenv(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *name, *value; + name = JS_ToCString(ctx, argv[0]); + if (!name) + return JS_EXCEPTION; + value = JS_ToCString(ctx, argv[1]); + if (!value) { + JS_FreeCString(ctx, name); + return JS_EXCEPTION; + } + setenv(name, value, true); + JS_FreeCString(ctx, name); + JS_FreeCString(ctx, value); + return JS_UNDEFINED; +} + +static JSValue js_std_unsetenv(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *name; + name = JS_ToCString(ctx, argv[0]); + if (!name) + return JS_EXCEPTION; + unsetenv(name); + JS_FreeCString(ctx, name); + return JS_UNDEFINED; +} + +/* return an object containing the list of the available environment + variables. */ +static JSValue js_std_getenviron(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + char **envp; + const char *name, *p, *value; + JSValue obj; + uint32_t idx; + size_t name_len; + JSAtom atom; + int ret; + + obj = JS_NewObject(ctx); + if (JS_IsException(obj)) + return JS_EXCEPTION; + envp = environ; + for(idx = 0; envp[idx] != NULL; idx++) { + name = envp[idx]; + p = strchr(name, '='); + name_len = p - name; + if (!p) + continue; + value = p + 1; + atom = JS_NewAtomLen(ctx, name, name_len); + if (atom == JS_ATOM_NULL) + goto fail; + ret = JS_DefinePropertyValue(ctx, obj, atom, JS_NewString(ctx, value), + JS_PROP_C_W_E); + JS_FreeAtom(ctx, atom); + if (ret < 0) + goto fail; + } + return obj; + fail: + JS_FreeValue(ctx, obj); + return JS_EXCEPTION; +} + +static JSValue js_std_gc(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JS_RunGC(JS_GetRuntime(ctx)); + return JS_UNDEFINED; +} + +static int interrupt_handler(JSContext *ctx, void *opaque) +{ + JSThreadState *ts = opaque; + + if (1 & (os_pending_signals >> SIGINT)) + return 1; + if (ts->prev_interrupt_handler) + return ts->prev_interrupt_handler(ctx, ts->prev_interrupt_opaque); + return 0; +} + +static JSValue js_evalScript(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + const char *str = NULL; + size_t len; + JSValue ret, obj; + JSValueConst options_obj, arg; + bool backtrace_barrier = false; + bool eval_function = false; + bool eval_module = false; + bool compile_only = false; + bool compile_module = false; + bool is_async = false; + int flags; + + if (argc >= 2) { + options_obj = argv[1]; + if (get_bool_option(ctx, &backtrace_barrier, options_obj, + "backtrace_barrier")) + return JS_EXCEPTION; + if (get_bool_option(ctx, &eval_function, options_obj, + "eval_function")) + return JS_EXCEPTION; + if (get_bool_option(ctx, &eval_module, options_obj, + "eval_module")) + return JS_EXCEPTION; + if (get_bool_option(ctx, &compile_only, options_obj, + "compile_only")) + return JS_EXCEPTION; + if (get_bool_option(ctx, &compile_module, options_obj, + "compile_module")) + return JS_EXCEPTION; + if (get_bool_option(ctx, &is_async, options_obj, + "async")) + return JS_EXCEPTION; + } + + if (eval_module) { + arg = argv[0]; + if (JS_VALUE_GET_TAG(arg) != JS_TAG_MODULE) + return JS_ThrowTypeError(ctx, "not a module"); + + if (JS_ResolveModule(ctx, arg) < 0) + return JS_EXCEPTION; + + if (js_module_set_import_meta(ctx, arg, false, false) < 0) + return JS_EXCEPTION; + + return JS_EvalFunction(ctx, JS_DupValue(ctx, arg)); + } + + if (!eval_function) { + str = JS_ToCStringLen(ctx, &len, argv[0]); + if (!str) + return JS_EXCEPTION; + } + if (!ts->recv_pipe && ++ts->eval_script_recurse == 1) { + /* install the interrupt handler */ + ts->prev_interrupt_handler = + (JSInterruptHandler *)js_std_cmd(/*GetInterruptHandler*/5, rt); + ts->prev_interrupt_opaque = + (void *)js_std_cmd(/*GetInterruptOpaque*/6, rt); + // FIXME(bnoordhuis) Questionable hack to make the REPL interruptible. + // Ideally qjs installs a signal handler + interrupt handler but then + // scripts can intercept it with os.signal(SIGINT). + JS_SetInterruptHandler(JS_GetRuntime(ctx), interrupt_handler, ts); + } + flags = compile_module ? JS_EVAL_TYPE_MODULE : JS_EVAL_TYPE_GLOBAL; + if (backtrace_barrier) + flags |= JS_EVAL_FLAG_BACKTRACE_BARRIER; + if (compile_only) + flags |= JS_EVAL_FLAG_COMPILE_ONLY; + if (is_async) + flags |= JS_EVAL_FLAG_ASYNC; + if (eval_function) { + obj = JS_DupValue(ctx, argv[0]); + ret = JS_EvalFunction(ctx, obj); // takes ownership of |obj| + } else { + ret = JS_Eval(ctx, str, len, "", flags); + } + JS_FreeCString(ctx, str); + if (!ts->recv_pipe && --ts->eval_script_recurse == 0) { + /* remove the interrupt handler */ + JS_SetInterruptHandler(JS_GetRuntime(ctx), + ts->prev_interrupt_handler, + ts->prev_interrupt_opaque); + ts->prev_interrupt_handler = NULL; + ts->prev_interrupt_opaque = NULL; + os_pending_signals &= ~((uint64_t)1 << SIGINT); + /* convert the uncatchable "interrupted" error into a normal error + so that it can be caught by the REPL */ + if (JS_IsException(ret)) + JS_ResetUncatchableError(ctx); + } + return ret; +} + +typedef struct { + FILE *f; + bool is_popen; +} JSSTDFile; + +static bool is_stdio(FILE *f) +{ + return f == stdin || f == stdout || f == stderr; +} + +static void safe_close(FILE *f, bool is_popen) +{ + if (!f) + return; + if (is_stdio(f)) + return; + if (is_popen) { +#if !defined(__wasi__) + pclose(f); +#endif + } else { + fclose(f); + } +} + +static void js_std_file_finalizer(JSRuntime *rt, JSValueConst val) +{ + JSThreadState *ts = js_get_thread_state(rt); + JSSTDFile *s = JS_GetOpaque(val, ts->std_file_class_id); + if (s) { + safe_close(s->f, s->is_popen); + js_free_rt(rt, s); + } +} + +static ssize_t js_get_errno(ssize_t ret) +{ + if (ret == -1) + ret = -errno; + return ret; +} + +static JSValue js_std_strerror(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int err; + if (JS_ToInt32(ctx, &err, argv[0])) + return JS_EXCEPTION; + return JS_NewString(ctx, strerror(err)); +} + +static JSValue js_new_std_file(JSContext *ctx, FILE *f, bool is_popen) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + JSSTDFile *s; + JSValue obj; + obj = JS_NewObjectClass(ctx, ts->std_file_class_id); + if (JS_IsException(obj)) + goto exception; + s = js_mallocz(ctx, sizeof(*s)); + if (!s) + goto exception; + s->is_popen = is_popen; + s->f = f; + JS_SetOpaque(obj, s); + return obj; +exception: + safe_close(f, is_popen); + JS_FreeValue(ctx, obj); + return JS_EXCEPTION; +} + +static void js_set_error_object(JSContext *ctx, JSValueConst obj, int err) +{ + if (!JS_IsUndefined(obj)) { + JS_SetPropertyStr(ctx, obj, "errno", JS_NewInt32(ctx, err)); + } +} + +static JSValue js_std_open(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *filename, *mode = NULL; + FILE *f; + int err; + + filename = JS_ToCString(ctx, argv[0]); + if (!filename) + goto fail; + mode = JS_ToCString(ctx, argv[1]); + if (!mode) + goto fail; + if (mode[strspn(mode, "rwa+bx")] != '\0') { + JS_ThrowTypeError(ctx, "invalid file mode"); + goto fail; + } + + f = fopen(filename, mode); + if (!f) + err = errno; + else + err = 0; + if (argc >= 3) + js_set_error_object(ctx, argv[2], err); + JS_FreeCString(ctx, filename); + JS_FreeCString(ctx, mode); + if (!f) + return JS_NULL; + return js_new_std_file(ctx, f, false); + fail: + JS_FreeCString(ctx, filename); + JS_FreeCString(ctx, mode); + return JS_EXCEPTION; +} + +#if !defined(__wasi__) +static JSValue js_std_popen(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *filename, *mode = NULL; + FILE *f; + int err; + + filename = JS_ToCString(ctx, argv[0]); + if (!filename) + goto fail; + mode = JS_ToCString(ctx, argv[1]); + if (!mode) + goto fail; + if (strcmp(mode, "r") && strcmp(mode, "w")) { + JS_ThrowTypeError(ctx, "invalid file mode"); + goto fail; + } + + f = popen(filename, mode); + if (!f) + err = errno; + else + err = 0; + if (argc >= 3) + js_set_error_object(ctx, argv[2], err); + JS_FreeCString(ctx, filename); + JS_FreeCString(ctx, mode); + if (!f) + return JS_NULL; + return js_new_std_file(ctx, f, true); + fail: + JS_FreeCString(ctx, filename); + JS_FreeCString(ctx, mode); + return JS_EXCEPTION; +} +#endif // !defined(__wasi__) + +static JSValue js_std_fdopen(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *mode; + FILE *f; + int fd, err; + + if (JS_ToInt32(ctx, &fd, argv[0])) + return JS_EXCEPTION; + mode = JS_ToCString(ctx, argv[1]); + if (!mode) + goto fail; + if (mode[strspn(mode, "rwa+")] != '\0') { + JS_ThrowTypeError(ctx, "invalid file mode"); + goto fail; + } + + f = fdopen(fd, mode); + if (!f) + err = errno; + else + err = 0; + if (argc >= 3) + js_set_error_object(ctx, argv[2], err); + JS_FreeCString(ctx, mode); + if (!f) + return JS_NULL; + return js_new_std_file(ctx, f, false); + fail: + JS_FreeCString(ctx, mode); + return JS_EXCEPTION; +} + +#if !defined(__wasi__) +static JSValue js_std_tmpfile(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + FILE *f; + f = tmpfile(); + if (argc >= 1) + js_set_error_object(ctx, argv[0], f ? 0 : errno); + if (!f) + return JS_NULL; + return js_new_std_file(ctx, f, false); +} +#endif + +static JSValue js_std_sprintf(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + return js_printf_internal(ctx, argc, argv, NULL); +} + +static JSValue js_std_printf(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + return js_printf_internal(ctx, argc, argv, stdout); +} + +static FILE *js_std_file_get(JSContext *ctx, JSValueConst obj) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + JSSTDFile *s = JS_GetOpaque2(ctx, obj, ts->std_file_class_id); + if (!s) + return NULL; + if (!s->f) { + JS_ThrowTypeError(ctx, "invalid file handle"); + return NULL; + } + return s->f; +} + +static JSValue js_std_file_puts(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int magic) +{ + FILE *f; + int i; + const char *str; + size_t len; + + if (magic == 0) { + f = stdout; + } else { + f = js_std_file_get(ctx, this_val); + if (!f) + return JS_EXCEPTION; + } + + for(i = 0; i < argc; i++) { + str = JS_ToCStringLen(ctx, &len, argv[i]); + if (!str) + return JS_EXCEPTION; + fwrite(str, 1, len, f); + JS_FreeCString(ctx, str); + } + return JS_UNDEFINED; +} + +static JSValue js_std_file_close(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + JSSTDFile *s = JS_GetOpaque2(ctx, this_val, ts->std_file_class_id); + int err; + if (!s) + return JS_EXCEPTION; + if (!s->f) + return JS_ThrowTypeError(ctx, "invalid file handle"); + if (is_stdio(s->f)) + return JS_ThrowTypeError(ctx, "cannot close stdio"); +#if !defined(__wasi__) + if (s->is_popen) + err = js_get_errno(pclose(s->f)); + else +#endif + err = js_get_errno(fclose(s->f)); + s->f = NULL; + return JS_NewInt32(ctx, err); +} + +static JSValue js_std_file_printf(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + FILE *f = js_std_file_get(ctx, this_val); + if (!f) + return JS_EXCEPTION; + return js_printf_internal(ctx, argc, argv, f); +} + +static JSValue js_std_file_flush(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + FILE *f = js_std_file_get(ctx, this_val); + if (!f) + return JS_EXCEPTION; + fflush(f); + return JS_UNDEFINED; +} + +static JSValue js_std_file_tell(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int is_bigint) +{ + FILE *f = js_std_file_get(ctx, this_val); + int64_t pos; + if (!f) + return JS_EXCEPTION; +#if defined(__linux__) || defined(__GLIBC__) + pos = ftello(f); +#else + pos = ftell(f); +#endif + if (is_bigint) + return JS_NewBigInt64(ctx, pos); + else + return JS_NewInt64(ctx, pos); +} + +static JSValue js_std_file_seek(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + FILE *f = js_std_file_get(ctx, this_val); + int64_t pos; + int whence, ret; + if (!f) + return JS_EXCEPTION; + if (JS_ToInt64Ext(ctx, &pos, argv[0])) + return JS_EXCEPTION; + if (JS_ToInt32(ctx, &whence, argv[1])) + return JS_EXCEPTION; +#if defined(__linux__) || defined(__GLIBC__) + ret = fseeko(f, pos, whence); +#else + ret = fseek(f, pos, whence); +#endif + if (ret < 0) + ret = -errno; + return JS_NewInt32(ctx, ret); +} + +static JSValue js_std_file_eof(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + FILE *f = js_std_file_get(ctx, this_val); + if (!f) + return JS_EXCEPTION; + return JS_NewBool(ctx, feof(f)); +} + +static JSValue js_std_file_error(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + FILE *f = js_std_file_get(ctx, this_val); + if (!f) + return JS_EXCEPTION; + return JS_NewBool(ctx, ferror(f)); +} + +static JSValue js_std_file_clearerr(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + FILE *f = js_std_file_get(ctx, this_val); + if (!f) + return JS_EXCEPTION; + clearerr(f); + return JS_UNDEFINED; +} + +static JSValue js_std_file_fileno(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + FILE *f = js_std_file_get(ctx, this_val); + if (!f) + return JS_EXCEPTION; + return JS_NewInt32(ctx, fileno(f)); +} + +static JSValue js_std_file_read_write(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int magic) +{ + FILE *f = js_std_file_get(ctx, this_val); + bool is_write = (magic != 0); + uint64_t pos, len; + size_t size, ret; + const char *str; + uint8_t *buf; + + if (!f) + return JS_EXCEPTION; + pos = 0; + if (argc > 1 && JS_ToIndex(ctx, &pos, argv[1])) + return JS_EXCEPTION; + len = 0; + if (argc > 2 && JS_ToIndex(ctx, &len, argv[2])) + return JS_EXCEPTION; + if (is_write && JS_IsString(argv[0])) { + str = JS_ToCStringLen(ctx, &size, argv[0]); + buf = (void *)str; + } else { + str = NULL; + buf = JS_GetArrayBuffer(ctx, &size, argv[0]); + } + if (!buf) + return JS_EXCEPTION; + if (pos > size) + pos = size; + if (argc < 3) + len = size - pos; + if (pos + len > size) + len = size - pos; + if (is_write) { + ret = fwrite(buf + pos, 1, len, f); + } else { + ret = fread(buf + pos, 1, len, f); + } + JS_FreeCString(ctx, str); + return JS_NewInt64(ctx, ret); +} + +/* XXX: could use less memory and go faster */ +static JSValue js_std_file_getline(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + FILE *f = js_std_file_get(ctx, this_val); + int c; + DynBuf dbuf; + JSValue obj; + + if (!f) + return JS_EXCEPTION; + + js_std_dbuf_init(ctx, &dbuf); + for(;;) { + c = fgetc(f); + if (c == EOF) { + if (dbuf.size == 0) { + /* EOF */ + dbuf_free(&dbuf); + return JS_NULL; + } else { + break; + } + } + if (c == '\n') + break; + if (dbuf_putc(&dbuf, c)) { + dbuf_free(&dbuf); + return JS_ThrowOutOfMemory(ctx); + } + } + obj = JS_NewStringLen(ctx, (const char *)dbuf.buf, dbuf.size); + dbuf_free(&dbuf); + return obj; +} + +/* XXX: could use less memory and go faster */ +static JSValue js_std_file_readAs(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int magic) +{ + FILE *f = js_std_file_get(ctx, this_val); + int c; + DynBuf dbuf; + JSValue obj; + uint64_t max_size64; + size_t max_size; + JSValueConst max_size_val; + + if (!f) + return JS_EXCEPTION; + + if (argc >= 1) + max_size_val = argv[0]; + else + max_size_val = JS_UNDEFINED; + max_size = (size_t)-1; + if (!JS_IsUndefined(max_size_val)) { + if (JS_ToIndex(ctx, &max_size64, max_size_val)) + return JS_EXCEPTION; + if (max_size64 < max_size) + max_size = max_size64; + } + + js_std_dbuf_init(ctx, &dbuf); + while (max_size != 0) { + c = fgetc(f); + if (c == EOF) + break; + if (dbuf_putc(&dbuf, c)) { + dbuf_free(&dbuf); + return JS_EXCEPTION; + } + max_size--; + } + if (magic) { + obj = JS_NewStringLen(ctx, (const char *)dbuf.buf, dbuf.size); + } else { + obj = JS_NewArrayBufferCopy(ctx, dbuf.buf, dbuf.size); + } + dbuf_free(&dbuf); + return obj; +} + +static JSValue js_std_file_getByte(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + FILE *f = js_std_file_get(ctx, this_val); + if (!f) + return JS_EXCEPTION; + return JS_NewInt32(ctx, fgetc(f)); +} + +static JSValue js_std_file_putByte(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + FILE *f = js_std_file_get(ctx, this_val); + int c; + if (!f) + return JS_EXCEPTION; + if (JS_ToInt32(ctx, &c, argv[0])) + return JS_EXCEPTION; + c = fputc(c, f); + return JS_NewInt32(ctx, c); +} + +/* urlGet */ +#if !defined(__wasi__) + +#define URL_GET_PROGRAM "curl -s -i --" +#define URL_GET_BUF_SIZE 4096 + +static int http_get_header_line(FILE *f, char *buf, size_t buf_size, + DynBuf *dbuf) +{ + int c; + char *p; + + p = buf; + for(;;) { + c = fgetc(f); + if (c < 0) + return -1; + if ((p - buf) < buf_size - 1) + *p++ = c; + if (dbuf) + dbuf_putc(dbuf, c); + if (c == '\n') + break; + } + *p = '\0'; + return 0; +} + +static int http_get_status(const char *buf) +{ + const char *p = buf; + while (*p != ' ' && *p != '\0') + p++; + if (*p != ' ') + return 0; + while (*p == ' ') + p++; + return atoi(p); +} + +static JSValue js_std_urlGet(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *url; + DynBuf cmd_buf; + DynBuf data_buf_s, *data_buf = &data_buf_s; + DynBuf header_buf_s, *header_buf = &header_buf_s; + char *buf; + size_t i, len; + int status; + JSValue response = JS_UNDEFINED, ret_obj; + JSValueConst options_obj; + FILE *f; + bool binary_flag, full_flag; + + url = JS_ToCString(ctx, argv[0]); + if (!url) + return JS_EXCEPTION; + + binary_flag = false; + full_flag = false; + + if (argc >= 2) { + options_obj = argv[1]; + + if (get_bool_option(ctx, &binary_flag, options_obj, "binary")) + goto fail_obj; + + if (get_bool_option(ctx, &full_flag, options_obj, "full")) { + fail_obj: + JS_FreeCString(ctx, url); + return JS_EXCEPTION; + } + } + + js_std_dbuf_init(ctx, &cmd_buf); + dbuf_printf(&cmd_buf, "%s '", URL_GET_PROGRAM); + for(i = 0; url[i] != '\0'; i++) { + unsigned char c = url[i]; + switch (c) { + case '\'': + /* shell single quoted string does not support \' */ + dbuf_putstr(&cmd_buf, "'\\''"); + break; + case '[': case ']': case '{': case '}': case '\\': + /* prevent interpretation by curl as range or set specification */ + dbuf_putc(&cmd_buf, '\\'); + /* FALLTHROUGH */ + default: + dbuf_putc(&cmd_buf, c); + break; + } + } + JS_FreeCString(ctx, url); + dbuf_putstr(&cmd_buf, "'"); + dbuf_putc(&cmd_buf, '\0'); + if (dbuf_error(&cmd_buf)) { + dbuf_free(&cmd_buf); + return JS_EXCEPTION; + } + // printf("%s\n", (char *)cmd_buf.buf); + f = popen((char *)cmd_buf.buf, "r"); + dbuf_free(&cmd_buf); + if (!f) { + return JS_ThrowTypeError(ctx, "could not start curl"); + } + + js_std_dbuf_init(ctx, data_buf); + js_std_dbuf_init(ctx, header_buf); + + buf = js_malloc(ctx, URL_GET_BUF_SIZE); + if (!buf) + goto fail; + + /* get the HTTP status */ + if (http_get_header_line(f, buf, URL_GET_BUF_SIZE, NULL) < 0) { + status = 0; + goto bad_header; + } + status = http_get_status(buf); + if (!full_flag && !(status >= 200 && status <= 299)) { + goto bad_header; + } + + /* wait until there is an empty line */ + for(;;) { + if (http_get_header_line(f, buf, URL_GET_BUF_SIZE, header_buf) < 0) { + bad_header: + response = JS_NULL; + goto done; + } + if (!strcmp(buf, "\r\n")) + break; + } + if (dbuf_error(header_buf)) + goto fail; + header_buf->size -= 2; /* remove the trailing CRLF */ + + /* download the data */ + for(;;) { + len = fread(buf, 1, URL_GET_BUF_SIZE, f); + if (len == 0) + break; + dbuf_put(data_buf, (uint8_t *)buf, len); + } + if (dbuf_error(data_buf)) + goto fail; + if (binary_flag) { + response = JS_NewArrayBufferCopy(ctx, + data_buf->buf, data_buf->size); + } else { + response = JS_NewStringLen(ctx, (char *)data_buf->buf, data_buf->size); + } + if (JS_IsException(response)) + goto fail; + done: + js_free(ctx, buf); + buf = NULL; + pclose(f); + f = NULL; + dbuf_free(data_buf); + data_buf = NULL; + + if (full_flag) { + ret_obj = JS_NewObject(ctx); + if (JS_IsException(ret_obj)) + goto fail; + JS_DefinePropertyValueStr(ctx, ret_obj, "response", + response, + JS_PROP_C_W_E); + if (!JS_IsNull(response)) { + JS_DefinePropertyValueStr(ctx, ret_obj, "responseHeaders", + JS_NewStringLen(ctx, (char *)header_buf->buf, + header_buf->size), + JS_PROP_C_W_E); + JS_DefinePropertyValueStr(ctx, ret_obj, "status", + JS_NewInt32(ctx, status), + JS_PROP_C_W_E); + } + } else { + ret_obj = response; + } + dbuf_free(header_buf); + return ret_obj; + fail: + if (f) + pclose(f); + js_free(ctx, buf); + if (data_buf) + dbuf_free(data_buf); + if (header_buf) + dbuf_free(header_buf); + JS_FreeValue(ctx, response); + return JS_EXCEPTION; +} +#endif // !defined(__wasi__) + +static JSClassDef js_std_file_class = { + "FILE", + .finalizer = js_std_file_finalizer, +}; + +static const JSCFunctionListEntry js_std_error_props[] = { + /* various errno values */ +#define DEF(x) JS_PROP_INT32_DEF(#x, x, JS_PROP_CONFIGURABLE ) + DEF(EINVAL), + DEF(EIO), + DEF(EACCES), + DEF(EEXIST), + DEF(ENOSPC), + DEF(ENOSYS), + DEF(EBUSY), + DEF(ENOENT), + DEF(EPERM), + DEF(EPIPE), + DEF(EBADF), +#undef DEF +}; + +static const JSCFunctionListEntry js_std_funcs[] = { + JS_CFUNC_DEF("exit", 1, js_std_exit ), + JS_CFUNC_DEF("gc", 0, js_std_gc ), + JS_CFUNC_DEF("evalScript", 1, js_evalScript ), + JS_CFUNC_DEF("loadScript", 1, js_loadScript ), + JS_CFUNC_DEF("getenv", 1, js_std_getenv ), + JS_CFUNC_DEF("setenv", 2, js_std_setenv ), + JS_CFUNC_DEF("unsetenv", 1, js_std_unsetenv ), + JS_CFUNC_DEF("getenviron", 1, js_std_getenviron ), +#if !defined(__wasi__) + JS_CFUNC_DEF("urlGet", 1, js_std_urlGet ), +#endif + JS_CFUNC_DEF("loadFile", 1, js_std_loadFile ), + JS_CFUNC_DEF("writeFile", 2, js_std_writeFile ), + JS_CFUNC_DEF("strerror", 1, js_std_strerror ), + + /* FILE I/O */ + JS_CFUNC_DEF("open", 2, js_std_open ), +#if !defined(__wasi__) + JS_CFUNC_DEF("popen", 2, js_std_popen ), + JS_CFUNC_DEF("tmpfile", 0, js_std_tmpfile ), +#endif + JS_CFUNC_DEF("fdopen", 2, js_std_fdopen ), + JS_CFUNC_MAGIC_DEF("puts", 1, js_std_file_puts, 0 ), + JS_CFUNC_DEF("printf", 1, js_std_printf ), + JS_CFUNC_DEF("sprintf", 1, js_std_sprintf ), + JS_PROP_INT32_DEF("SEEK_SET", SEEK_SET, JS_PROP_CONFIGURABLE ), + JS_PROP_INT32_DEF("SEEK_CUR", SEEK_CUR, JS_PROP_CONFIGURABLE ), + JS_PROP_INT32_DEF("SEEK_END", SEEK_END, JS_PROP_CONFIGURABLE ), + JS_OBJECT_DEF("Error", js_std_error_props, countof(js_std_error_props), JS_PROP_CONFIGURABLE), +}; + +static const JSCFunctionListEntry js_std_file_proto_funcs[] = { + JS_CFUNC_DEF("close", 0, js_std_file_close ), + JS_CFUNC_MAGIC_DEF("puts", 1, js_std_file_puts, 1 ), + JS_CFUNC_DEF("printf", 1, js_std_file_printf ), + JS_CFUNC_DEF("flush", 0, js_std_file_flush ), + JS_CFUNC_MAGIC_DEF("tell", 0, js_std_file_tell, 0 ), + JS_CFUNC_MAGIC_DEF("tello", 0, js_std_file_tell, 1 ), + JS_CFUNC_DEF("seek", 2, js_std_file_seek ), + JS_CFUNC_DEF("eof", 0, js_std_file_eof ), + JS_CFUNC_DEF("fileno", 0, js_std_file_fileno ), + JS_CFUNC_DEF("error", 0, js_std_file_error ), + JS_CFUNC_DEF("clearerr", 0, js_std_file_clearerr ), + JS_CFUNC_MAGIC_DEF("read", 1, js_std_file_read_write, 0 ), + JS_CFUNC_MAGIC_DEF("write", 1, js_std_file_read_write, 1 ), + JS_CFUNC_DEF("getline", 0, js_std_file_getline ), + JS_CFUNC_MAGIC_DEF("readAsArrayBuffer", 0, js_std_file_readAs, 0 ), + JS_CFUNC_MAGIC_DEF("readAsString", 0, js_std_file_readAs, 1 ), + JS_CFUNC_DEF("getByte", 0, js_std_file_getByte ), + JS_CFUNC_DEF("putByte", 1, js_std_file_putByte ), + /* setvbuf, ... */ +}; + +static int js_std_init(JSContext *ctx, JSModuleDef *m) +{ + JSValue proto; + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + + /* FILE class */ + /* the class ID is created once */ + JS_NewClassID(rt, &ts->std_file_class_id); + /* the class is created once per runtime */ + JS_NewClass(rt, ts->std_file_class_id, &js_std_file_class); + proto = JS_NewObject(ctx); + JS_SetPropertyFunctionList(ctx, proto, js_std_file_proto_funcs, + countof(js_std_file_proto_funcs)); + JS_SetClassProto(ctx, ts->std_file_class_id, proto); + + JS_SetModuleExportList(ctx, m, js_std_funcs, + countof(js_std_funcs)); + JS_SetModuleExport(ctx, m, "in", js_new_std_file(ctx, stdin, false)); + JS_SetModuleExport(ctx, m, "out", js_new_std_file(ctx, stdout, false)); + JS_SetModuleExport(ctx, m, "err", js_new_std_file(ctx, stderr, false)); + return 0; +} + +JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name) +{ + JSModuleDef *m; + m = JS_NewCModule(ctx, module_name, js_std_init); + if (!m) + return NULL; + JS_AddModuleExportList(ctx, m, js_std_funcs, countof(js_std_funcs)); + JS_AddModuleExport(ctx, m, "in"); + JS_AddModuleExport(ctx, m, "out"); + JS_AddModuleExport(ctx, m, "err"); + return m; +} + +/**********************************************************/ +/* 'os' object */ + +static JSValue js_os_open(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *filename; + int flags, mode, ret; + + filename = JS_ToCString(ctx, argv[0]); + if (!filename) + return JS_EXCEPTION; + if (JS_ToInt32(ctx, &flags, argv[1])) + goto fail; + if (argc >= 3 && !JS_IsUndefined(argv[2])) { + if (JS_ToInt32(ctx, &mode, argv[2])) { + fail: + JS_FreeCString(ctx, filename); + return JS_EXCEPTION; + } + } else { + mode = 0666; + } +#if defined(_WIN32) + /* force binary mode by default */ + if (!(flags & O_TEXT)) + flags |= O_BINARY; +#endif + ret = js_get_errno(open(filename, flags, mode)); + JS_FreeCString(ctx, filename); + return JS_NewInt32(ctx, ret); +} + +static JSValue js_os_close(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int fd, ret; + if (JS_ToInt32(ctx, &fd, argv[0])) + return JS_EXCEPTION; + ret = js_get_errno(close(fd)); + return JS_NewInt32(ctx, ret); +} + +static JSValue js_os_seek(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int fd, whence; + int64_t pos, ret; + bool is_bigint; + + if (JS_ToInt32(ctx, &fd, argv[0])) + return JS_EXCEPTION; + is_bigint = JS_IsBigInt(argv[1]); + if (JS_ToInt64Ext(ctx, &pos, argv[1])) + return JS_EXCEPTION; + if (JS_ToInt32(ctx, &whence, argv[2])) + return JS_EXCEPTION; + ret = lseek(fd, pos, whence); + if (ret == -1) + ret = -errno; + if (is_bigint) + return JS_NewBigInt64(ctx, ret); + else + return JS_NewInt64(ctx, ret); +} + +static JSValue js_os_read_write(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int magic) +{ + int fd; + uint64_t pos, len; + size_t size; + ssize_t ret; + uint8_t *buf; + + if (JS_ToInt32(ctx, &fd, argv[0])) + return JS_EXCEPTION; + if (JS_ToIndex(ctx, &pos, argv[2])) + return JS_EXCEPTION; + if (JS_ToIndex(ctx, &len, argv[3])) + return JS_EXCEPTION; + buf = JS_GetArrayBuffer(ctx, &size, argv[1]); + if (!buf) + return JS_EXCEPTION; + if (pos + len > size) + return JS_ThrowRangeError(ctx, "read/write array buffer overflow"); + if (magic) + ret = js_get_errno(write(fd, buf + pos, len)); + else + ret = js_get_errno(read(fd, buf + pos, len)); + return JS_NewInt64(ctx, ret); +} + +static JSValue js_os_isatty(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int fd; + if (JS_ToInt32(ctx, &fd, argv[0])) + return JS_EXCEPTION; + return JS_NewBool(ctx, (isatty(fd) != 0)); +} + +#if defined(_WIN32) +static JSValue js_os_ttyGetWinSize(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int fd; + HANDLE handle; + CONSOLE_SCREEN_BUFFER_INFO info; + JSValue obj; + + if (JS_ToInt32(ctx, &fd, argv[0])) + return JS_EXCEPTION; + handle = (HANDLE)_get_osfhandle(fd); + + if (!GetConsoleScreenBufferInfo(handle, &info)) + return JS_NULL; + obj = JS_NewArray(ctx); + if (JS_IsException(obj)) + return obj; + JS_DefinePropertyValueUint32(ctx, obj, 0, JS_NewInt32(ctx, info.dwSize.X), JS_PROP_C_W_E); + JS_DefinePropertyValueUint32(ctx, obj, 1, JS_NewInt32(ctx, info.dwSize.Y), JS_PROP_C_W_E); + return obj; +} + +/* Windows 10 built-in VT100 emulation */ +#define __ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 +#define __ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200 + +static JSValue js_os_ttySetRaw(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int fd; + HANDLE handle; + + if (JS_ToInt32(ctx, &fd, argv[0])) + return JS_EXCEPTION; + handle = (HANDLE)_get_osfhandle(fd); + SetConsoleMode(handle, ENABLE_WINDOW_INPUT | __ENABLE_VIRTUAL_TERMINAL_INPUT); + _setmode(fd, _O_BINARY); + if (fd == 0) { + handle = (HANDLE)_get_osfhandle(1); /* corresponding output */ + SetConsoleMode(handle, ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT | __ENABLE_VIRTUAL_TERMINAL_PROCESSING); + } + return JS_UNDEFINED; +} +#elif !defined(__wasi__) +static JSValue js_os_ttyGetWinSize(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int fd; + struct winsize ws; + JSValue obj; + + if (JS_ToInt32(ctx, &fd, argv[0])) + return JS_EXCEPTION; + if (ioctl(fd, TIOCGWINSZ, &ws) == 0 && + ws.ws_col >= 4 && ws.ws_row >= 4) { + obj = JS_NewArray(ctx); + if (JS_IsException(obj)) + return obj; + JS_DefinePropertyValueUint32(ctx, obj, 0, JS_NewInt32(ctx, ws.ws_col), JS_PROP_C_W_E); + JS_DefinePropertyValueUint32(ctx, obj, 1, JS_NewInt32(ctx, ws.ws_row), JS_PROP_C_W_E); + return obj; + } else { + return JS_NULL; + } +} + +static struct termios oldtty; + +static void term_exit(void) +{ + tcsetattr(0, TCSANOW, &oldtty); +} + +/* XXX: should add a way to go back to normal mode */ +static JSValue js_os_ttySetRaw(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + struct termios tty; + int fd; + + if (JS_ToInt32(ctx, &fd, argv[0])) + return JS_EXCEPTION; + + memset(&tty, 0, sizeof(tty)); + tcgetattr(fd, &tty); + oldtty = tty; + + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP + |INLCR|IGNCR|ICRNL|IXON); + tty.c_oflag |= OPOST; + tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); + tty.c_cflag &= ~(CSIZE|PARENB); + tty.c_cflag |= CS8; + tty.c_cc[VMIN] = 1; + tty.c_cc[VTIME] = 0; + + tcsetattr(fd, TCSANOW, &tty); + + atexit(term_exit); + return JS_UNDEFINED; +} + +#endif /* !_WIN32 && !__wasi__ */ + +static JSValue js_os_remove(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *filename; + int ret; + + filename = JS_ToCString(ctx, argv[0]); + if (!filename) + return JS_EXCEPTION; +#if defined(_WIN32) + { + struct stat st; + if (stat(filename, &st) == 0 && (st.st_mode & _S_IFDIR)) { + ret = rmdir(filename); + } else { + ret = unlink(filename); + } + } +#else + ret = remove(filename); +#endif + ret = js_get_errno(ret); + JS_FreeCString(ctx, filename); + return JS_NewInt32(ctx, ret); +} + +static JSValue js_os_rename(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *oldpath, *newpath; + int ret; + + oldpath = JS_ToCString(ctx, argv[0]); + if (!oldpath) + return JS_EXCEPTION; + newpath = JS_ToCString(ctx, argv[1]); + if (!newpath) { + JS_FreeCString(ctx, oldpath); + return JS_EXCEPTION; + } + ret = js_get_errno(rename(oldpath, newpath)); + JS_FreeCString(ctx, oldpath); + JS_FreeCString(ctx, newpath); + return JS_NewInt32(ctx, ret); +} + +static bool is_main_thread(JSRuntime *rt) +{ + JSThreadState *ts = js_get_thread_state(rt); + return !ts->recv_pipe; +} + +static JSOSRWHandler *find_rh(JSThreadState *ts, int fd) +{ + JSOSRWHandler *rh; + struct list_head *el; + + list_for_each(el, &ts->os_rw_handlers) { + rh = list_entry(el, JSOSRWHandler, link); + if (rh->fd == fd) + return rh; + } + return NULL; +} + +static void free_rw_handler(JSRuntime *rt, JSOSRWHandler *rh) +{ + int i; + list_del(&rh->link); + for(i = 0; i < 2; i++) { + JS_FreeValueRT(rt, rh->rw_func[i]); + } + js_free_rt(rt, rh); +} + +static JSValue js_os_setReadHandler(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int magic) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + JSOSRWHandler *rh; + int fd; + JSValueConst func; + + if (JS_ToInt32(ctx, &fd, argv[0])) + return JS_EXCEPTION; + func = argv[1]; + if (JS_IsNull(func)) { + rh = find_rh(ts, fd); + if (rh) { + JS_FreeValue(ctx, rh->rw_func[magic]); + rh->rw_func[magic] = JS_NULL; + if (JS_IsNull(rh->rw_func[0]) && + JS_IsNull(rh->rw_func[1])) { + /* remove the entry */ + free_rw_handler(JS_GetRuntime(ctx), rh); + } + } + } else { + if (!JS_IsFunction(ctx, func)) + return JS_ThrowTypeError(ctx, "not a function"); + rh = find_rh(ts, fd); + if (!rh) { + rh = js_mallocz(ctx, sizeof(*rh)); + if (!rh) + return JS_EXCEPTION; + rh->fd = fd; + rh->rw_func[0] = JS_NULL; + rh->rw_func[1] = JS_NULL; + list_add_tail(&rh->link, &ts->os_rw_handlers); + } + JS_FreeValue(ctx, rh->rw_func[magic]); + rh->rw_func[magic] = JS_DupValue(ctx, func); + } + return JS_UNDEFINED; +} + +static JSOSSignalHandler *find_sh(JSThreadState *ts, int sig_num) +{ + JSOSSignalHandler *sh; + struct list_head *el; + list_for_each(el, &ts->os_signal_handlers) { + sh = list_entry(el, JSOSSignalHandler, link); + if (sh->sig_num == sig_num) + return sh; + } + return NULL; +} + +static void free_sh(JSRuntime *rt, JSOSSignalHandler *sh) +{ + list_del(&sh->link); + JS_FreeValueRT(rt, sh->func); + js_free_rt(rt, sh); +} + +static void os_signal_handler(int sig_num) +{ + os_pending_signals |= ((uint64_t)1 << sig_num); +} + +#if defined(_WIN32) +typedef void (*sighandler_t)(int sig_num); +#endif + +static JSValue js_os_signal(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + JSOSSignalHandler *sh; + uint32_t sig_num; + JSValueConst func; + sighandler_t handler; + + if (!is_main_thread(rt)) + return JS_ThrowTypeError(ctx, "signal handler can only be set in the main thread"); + + if (JS_ToUint32(ctx, &sig_num, argv[0])) + return JS_EXCEPTION; + if (sig_num >= 64) + return JS_ThrowRangeError(ctx, "invalid signal number"); + func = argv[1]; + /* func = null: SIG_DFL, func = undefined, SIG_IGN */ + if (JS_IsNull(func) || JS_IsUndefined(func)) { + sh = find_sh(ts, sig_num); + if (sh) { + free_sh(JS_GetRuntime(ctx), sh); + } + if (JS_IsNull(func)) + handler = SIG_DFL; + else + handler = SIG_IGN; + signal(sig_num, handler); + } else { + if (!JS_IsFunction(ctx, func)) + return JS_ThrowTypeError(ctx, "not a function"); + sh = find_sh(ts, sig_num); + if (!sh) { + sh = js_mallocz(ctx, sizeof(*sh)); + if (!sh) + return JS_EXCEPTION; + sh->sig_num = sig_num; + list_add_tail(&sh->link, &ts->os_signal_handlers); + } + JS_FreeValue(ctx, sh->func); + sh->func = JS_DupValue(ctx, func); + signal(sig_num, os_signal_handler); + } + return JS_UNDEFINED; +} + +#if !defined(_WIN32) && !defined(__wasi__) +static JSValue js_os_cputime(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + struct rusage ru; + int64_t cputime; + + cputime = 0; + if (!getrusage(RUSAGE_SELF, &ru)) + cputime = (int64_t)ru.ru_utime.tv_sec * 1000000 + ru.ru_utime.tv_usec; + + return JS_NewInt64(ctx, cputime); +} +#endif + +static JSValue js_os_exepath(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + char buf[JS__PATH_MAX]; + size_t len = sizeof(buf); + if (js_exepath(buf, &len)) + return JS_UNDEFINED; + return JS_NewStringLen(ctx, buf, len); +} + +static JSValue js_os_now(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + return JS_NewInt64(ctx, js__hrtime_ns() / 1000); +} + +static uint64_t js__hrtime_ms(void) +{ + return js__hrtime_ns() / (1000 * 1000); +} + +static void free_timer(JSRuntime *rt, JSOSTimer *th) +{ + list_del(&th->link); + JS_FreeValueRT(rt, th->func); + js_free_rt(rt, th); +} + +// TODO(bnoordhuis) accept string as first arg and eval at timer expiry +// TODO(bnoordhuis) retain argv[2..] as args for callback if argc > 2 +static JSValue js_os_setTimeout(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int magic) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + int64_t delay; + JSValueConst func; + JSOSTimer *th; + + func = argv[0]; + if (!JS_IsFunction(ctx, func)) + return JS_ThrowTypeError(ctx, "not a function"); + if (JS_ToInt64(ctx, &delay, argv[1])) + return JS_EXCEPTION; + if (delay < 1) + delay = 1; + th = js_mallocz(ctx, sizeof(*th)); + if (!th) + return JS_EXCEPTION; + th->timer_id = ts->next_timer_id++; + if (ts->next_timer_id > MAX_SAFE_INTEGER) + ts->next_timer_id = 1; + th->repeats = (magic > 0); + th->timeout = js__hrtime_ms() + delay; + th->delay = delay; + th->func = JS_DupValue(ctx, func); + list_add_tail(&th->link, &ts->os_timers); + return JS_NewInt64(ctx, th->timer_id); +} + +static JSOSTimer *find_timer_by_id(JSThreadState *ts, int timer_id) +{ + struct list_head *el; + if (timer_id <= 0) + return NULL; + list_for_each(el, &ts->os_timers) { + JSOSTimer *th = list_entry(el, JSOSTimer, link); + if (th->timer_id == timer_id) + return th; + } + return NULL; +} + +static JSValue js_os_clearTimeout(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + JSOSTimer *th; + int64_t timer_id; + + if (JS_ToInt64(ctx, &timer_id, argv[0])) + return JS_EXCEPTION; + th = find_timer_by_id(ts, timer_id); + if (!th) + return JS_UNDEFINED; + free_timer(rt, th); + return JS_UNDEFINED; +} + +/* return a promise */ +static JSValue js_os_sleepAsync(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + int64_t delay; + JSOSTimer *th; + JSValue promise, resolving_funcs[2]; + + if (JS_ToInt64(ctx, &delay, argv[0])) + return JS_EXCEPTION; + promise = JS_NewPromiseCapability(ctx, resolving_funcs); + if (JS_IsException(promise)) + return JS_EXCEPTION; + + th = js_mallocz(ctx, sizeof(*th)); + if (!th) { + JS_FreeValue(ctx, promise); + JS_FreeValue(ctx, resolving_funcs[0]); + JS_FreeValue(ctx, resolving_funcs[1]); + return JS_EXCEPTION; + } + th->timer_id = -1; + th->timeout = js__hrtime_ms() + delay; + th->func = JS_DupValue(ctx, resolving_funcs[0]); + list_add_tail(&th->link, &ts->os_timers); + JS_FreeValue(ctx, resolving_funcs[0]); + JS_FreeValue(ctx, resolving_funcs[1]); + return promise; +} + +static int call_handler(JSContext *ctx, JSValue func) +{ + int r; + JSValue ret, func1; + /* 'func' might be destroyed when calling itself (if it frees the + handler), so must take extra care */ + func1 = JS_DupValue(ctx, func); + ret = JS_Call(ctx, func1, JS_UNDEFINED, 0, NULL); + JS_FreeValue(ctx, func1); + r = 0; + if (JS_IsException(ret)) + r = -1; + JS_FreeValue(ctx, ret); + return r; +} + +static int js_os_run_timers(JSRuntime *rt, JSContext *ctx, JSThreadState *ts, int *min_delay) +{ + JSValue func; + JSOSTimer *th; + int64_t cur_time, delay; + struct list_head *el; + int r; + + if (list_empty(&ts->os_timers)) { + *min_delay = -1; + return 0; + } + + cur_time = js__hrtime_ms(); + *min_delay = INT32_MAX; + + list_for_each(el, &ts->os_timers) { + th = list_entry(el, JSOSTimer, link); + delay = th->timeout - cur_time; + if (delay > 0) { + *min_delay = min_int(*min_delay, delay); + } else { + *min_delay = 0; + func = JS_DupValueRT(rt, th->func); + if (th->repeats) + th->timeout = cur_time + th->delay; + else + free_timer(rt, th); + r = call_handler(ctx, func); + JS_FreeValueRT(rt, func); + return r; + } + } + + return 0; +} + +#ifdef USE_WORKER + +#ifdef _WIN32 + +static int js_waker_init(JSWaker *w) +{ + w->handle = CreateEvent(NULL, TRUE, FALSE, NULL); + return w->handle ? 0 : -1; +} + +static void js_waker_signal(JSWaker *w) +{ + SetEvent(w->handle); +} + +static void js_waker_clear(JSWaker *w) +{ + ResetEvent(w->handle); +} + +static void js_waker_close(JSWaker *w) +{ + CloseHandle(w->handle); + w->handle = INVALID_HANDLE_VALUE; +} + +#else // !_WIN32 + +static int js_waker_init(JSWaker *w) +{ + int fds[2]; + + if (pipe(fds) < 0) + return -1; + w->read_fd = fds[0]; + w->write_fd = fds[1]; + return 0; +} + +static void js_waker_signal(JSWaker *w) +{ + int ret; + + for(;;) { + ret = write(w->write_fd, "", 1); + if (ret == 1) + break; + if (ret < 0 && errno != EAGAIN && errno != EINTR) + break; + } +} + +static void js_waker_clear(JSWaker *w) +{ + uint8_t buf[16]; + int ret; + + for(;;) { + ret = read(w->read_fd, buf, sizeof(buf)); + if (ret >= 0) + break; + if (errno != EAGAIN && errno != EINTR) + break; + } +} + +static void js_waker_close(JSWaker *w) +{ + close(w->read_fd); + close(w->write_fd); + w->read_fd = -1; + w->write_fd = -1; +} + +#endif // _WIN32 + +static void js_free_message(JSWorkerMessage *msg); + +/* return 1 if a message was handled, 0 if no message */ +static int handle_posted_message(JSRuntime *rt, JSContext *ctx, + JSWorkerMessageHandler *port) +{ + JSWorkerMessagePipe *ps = port->recv_pipe; + int ret; + struct list_head *el; + JSWorkerMessage *msg; + JSValue obj, data_obj, func, retval; + + js_mutex_lock(&ps->mutex); + if (!list_empty(&ps->msg_queue)) { + el = ps->msg_queue.next; + msg = list_entry(el, JSWorkerMessage, link); + + /* remove the message from the queue */ + list_del(&msg->link); + + // drain read end of pipe + if (list_empty(&ps->msg_queue)) + js_waker_clear(&ps->waker); + + js_mutex_unlock(&ps->mutex); + + data_obj = JS_ReadObject(ctx, msg->data, msg->data_len, + JS_READ_OBJ_SAB | JS_READ_OBJ_REFERENCE); + + js_free_message(msg); + + if (JS_IsException(data_obj)) + goto fail; + obj = JS_NewObject(ctx); + if (JS_IsException(obj)) { + JS_FreeValue(ctx, data_obj); + goto fail; + } + JS_DefinePropertyValueStr(ctx, obj, "data", data_obj, JS_PROP_C_W_E); + + /* 'func' might be destroyed when calling itself (if it frees the + handler), so must take extra care */ + func = JS_DupValue(ctx, port->on_message_func); + retval = JS_Call(ctx, func, JS_UNDEFINED, 1, (JSValueConst *)&obj); + JS_FreeValue(ctx, obj); + JS_FreeValue(ctx, func); + if (JS_IsException(retval)) { + fail: + js_std_dump_error(ctx); + } else { + JS_FreeValue(ctx, retval); + } + ret = 1; + } else { + js_mutex_unlock(&ps->mutex); + ret = 0; + } + return ret; +} + +#endif // USE_WORKER + +/* flags for js_os_poll_internal */ +#define JS_OS_POLL_RUN_TIMERS (1 << 0) +#define JS_OS_POLL_WORKERS (1 << 1) +#define JS_OS_POLL_SIGNALS (1 << 2) + +#if defined(_WIN32) +static int js_os_poll_internal(JSContext *ctx, int timeout_ms, int flags) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + int min_delay, count; + JSOSRWHandler *rh; + struct list_head *el; + HANDLE handles[MAXIMUM_WAIT_OBJECTS]; // 64 + + /* XXX: handle signals if useful */ + + min_delay = timeout_ms; + + if (flags & JS_OS_POLL_RUN_TIMERS) { + if (js_os_run_timers(rt, ctx, ts, &min_delay)) + return -1; + if (min_delay == 0) + return 0; // expired timer + if (min_delay < 0) + if (list_empty(&ts->os_rw_handlers) && list_empty(&ts->port_list)) + return -1; /* no more events */ + } + + count = 0; + list_for_each(el, &ts->os_rw_handlers) { + rh = list_entry(el, JSOSRWHandler, link); + if (rh->fd == 0 && !JS_IsNull(rh->rw_func[0])) + handles[count++] = (HANDLE)_get_osfhandle(rh->fd); // stdin + if (count == (int)countof(handles)) + break; + } + + if (flags & JS_OS_POLL_WORKERS) { + list_for_each(el, &ts->port_list) { + JSWorkerMessageHandler *port = list_entry(el, JSWorkerMessageHandler, link); + if (JS_IsNull(port->on_message_func)) + continue; + handles[count++] = port->recv_pipe->waker.handle; + if (count == (int)countof(handles)) + break; + } + } + + if (count > 0) { + DWORD ret, timeout = INFINITE; + if (min_delay != -1) + timeout = min_delay; + ret = WaitForMultipleObjects(count, handles, FALSE, timeout); + if (ret < (DWORD)count) { + list_for_each(el, &ts->os_rw_handlers) { + rh = list_entry(el, JSOSRWHandler, link); + if (rh->fd == 0 && !JS_IsNull(rh->rw_func[0])) { + return call_handler(ctx, rh->rw_func[0]); + /* must stop because the list may have been modified */ + } + } + + if (flags & JS_OS_POLL_WORKERS) { + list_for_each(el, &ts->port_list) { + JSWorkerMessageHandler *port = list_entry(el, JSWorkerMessageHandler, link); + if (!JS_IsNull(port->on_message_func)) { + JSWorkerMessagePipe *ps = port->recv_pipe; + if (ps->waker.handle == handles[ret]) { + if (handle_posted_message(rt, ctx, port)) + goto done; + } + } + } + } + } + } else if (min_delay > 0) { + Sleep(min_delay); + } +done: + return 0; +} + +static int js_os_poll(JSContext *ctx) +{ + return js_os_poll_internal(ctx, -1, + JS_OS_POLL_RUN_TIMERS | JS_OS_POLL_WORKERS | JS_OS_POLL_SIGNALS); +} + +int js_std_poll_io(JSContext *ctx, int timeout_ms) +{ + int ret = js_os_poll_internal(ctx, timeout_ms, 0); + /* map return codes: -1 on error stays -1, negative from handler becomes -2 */ + if (ret < -1) + return -2; + return ret; +} +#else // !defined(_WIN32) +static int js_os_poll_internal(JSContext *ctx, int timeout_ms, int flags) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + int r, w, ret, nfds, min_delay, poll_nfds; + JSOSRWHandler *rh; + struct list_head *el; + struct pollfd *pfd, *pfds, pfds_local[64]; + + min_delay = timeout_ms; + + /* only check signals in the main thread */ + if ((flags & JS_OS_POLL_SIGNALS) && + !ts->recv_pipe && + unlikely(os_pending_signals != 0)) { + JSOSSignalHandler *sh; + uint64_t mask; + + list_for_each(el, &ts->os_signal_handlers) { + sh = list_entry(el, JSOSSignalHandler, link); + mask = (uint64_t)1 << sh->sig_num; + if (os_pending_signals & mask) { + os_pending_signals &= ~mask; + return call_handler(ctx, sh->func); + } + } + } + + if (flags & JS_OS_POLL_RUN_TIMERS) { + if (js_os_run_timers(rt, ctx, ts, &min_delay)) + return -1; + if (min_delay == 0) + return 0; // expired timer + if (min_delay < 0) + if (list_empty(&ts->os_rw_handlers) && list_empty(&ts->port_list)) + return -1; /* no more events */ + } + + nfds = 0; + list_for_each(el, &ts->os_rw_handlers) { + rh = list_entry(el, JSOSRWHandler, link); + nfds += (!JS_IsNull(rh->rw_func[0]) || !JS_IsNull(rh->rw_func[1])); + } + +#ifdef USE_WORKER + if (flags & JS_OS_POLL_WORKERS) { + list_for_each(el, &ts->port_list) { + JSWorkerMessageHandler *port = list_entry(el, JSWorkerMessageHandler, link); + nfds += !JS_IsNull(port->on_message_func); + } + } +#endif // USE_WORKER + + if (nfds == 0) { + if (min_delay > 0) { + struct timespec ts_sleep = { + .tv_sec = min_delay / 1000, + .tv_nsec = (min_delay % 1000) * 1000000L + }; + uint64_t mask = os_pending_signals; + while (nanosleep(&ts_sleep, &ts_sleep) + && errno == EINTR + && mask == os_pending_signals); + } + return 0; + } + + pfd = pfds = pfds_local; + if (nfds > (int)countof(pfds_local)) { + pfd = pfds = js_malloc(ctx, nfds * sizeof(*pfd)); + if (!pfd) + return -1; + } + + list_for_each(el, &ts->os_rw_handlers) { + rh = list_entry(el, JSOSRWHandler, link); + r = POLLIN * !JS_IsNull(rh->rw_func[0]); + w = POLLOUT * !JS_IsNull(rh->rw_func[1]); + if (r || w) + *pfd++ = (struct pollfd){rh->fd, r|w, 0}; + } + +#ifdef USE_WORKER + if (flags & JS_OS_POLL_WORKERS) { + list_for_each(el, &ts->port_list) { + JSWorkerMessageHandler *port = list_entry(el, JSWorkerMessageHandler, link); + if (!JS_IsNull(port->on_message_func)) { + JSWorkerMessagePipe *ps = port->recv_pipe; + *pfd++ = (struct pollfd){ps->waker.read_fd, POLLIN, 0}; + } + } + } +#endif // USE_WORKER + + // FIXME(bnoordhuis) the loop below is quadratic in theory but + // linear-ish in practice because we bail out on the first hit, + // i.e., it's probably good enough for now + ret = 0; + /* poll() returns the number of ready descriptors, not the array length. */ + poll_nfds = nfds; + nfds = poll(pfds, nfds, min_delay); + if (nfds < 0) { + ret = -1; + goto done; + } + for (pfd = pfds; poll_nfds-- > 0; pfd++) { + rh = find_rh(ts, pfd->fd); + if (rh) { + r = (POLLERR|POLLHUP|POLLNVAL|POLLIN) * !JS_IsNull(rh->rw_func[0]); + w = (POLLERR|POLLHUP|POLLNVAL|POLLOUT) * !JS_IsNull(rh->rw_func[1]); + if (r & pfd->revents) { + ret = call_handler(ctx, rh->rw_func[0]); + goto done; + /* must stop because the list may have been modified */ + } + if (w & pfd->revents) { + ret = call_handler(ctx, rh->rw_func[1]); + goto done; + /* must stop because the list may have been modified */ + } + } +#ifdef USE_WORKER + else if (flags & JS_OS_POLL_WORKERS) { + list_for_each(el, &ts->port_list) { + JSWorkerMessageHandler *port = list_entry(el, JSWorkerMessageHandler, link); + if (!JS_IsNull(port->on_message_func)) { + JSWorkerMessagePipe *ps = port->recv_pipe; + if (pfd->fd == ps->waker.read_fd) { + if (handle_posted_message(rt, ctx, port)) + goto done; + } + } + } + } +#endif // USE_WORKER + } +done: + if (pfds != pfds_local) + js_free(ctx, pfds); + return ret; +} + +static int js_os_poll(JSContext *ctx) +{ + return js_os_poll_internal(ctx, -1, + JS_OS_POLL_RUN_TIMERS | JS_OS_POLL_WORKERS | JS_OS_POLL_SIGNALS); +} + +int js_std_poll_io(JSContext *ctx, int timeout_ms) +{ + int ret = js_os_poll_internal(ctx, timeout_ms, 0); + /* map return codes: -1 on error stays -1, negative from handler becomes -2 */ + if (ret < -1) + return -2; + return ret; +} +#endif // defined(_WIN32) + +static JSValue make_obj_error(JSContext *ctx, + JSValue obj, + int err) +{ + JSValue vals[2]; + + if (JS_IsException(obj)) + return obj; + vals[0] = obj; + vals[1] = JS_NewInt32(ctx, err); + return JS_NewArrayFrom(ctx, countof(vals), vals); +} + +static JSValue make_string_error(JSContext *ctx, + const char *buf, + int err) +{ + return make_obj_error(ctx, JS_NewString(ctx, buf), err); +} + +/* return [cwd, errorcode] */ +static JSValue js_os_getcwd(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + char buf[JS__PATH_MAX]; + int err; + + if (!getcwd(buf, sizeof(buf))) { + buf[0] = '\0'; + err = errno; + } else { + err = 0; + } + return make_string_error(ctx, buf, err); +} + +static JSValue js_os_chdir(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *target; + int err; + + target = JS_ToCString(ctx, argv[0]); + if (!target) + return JS_EXCEPTION; + err = js_get_errno(chdir(target)); + JS_FreeCString(ctx, target); + return JS_NewInt32(ctx, err); +} + +static JSValue js_os_mkdir(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int mode, ret; + const char *path; + + if (argc >= 2) { + if (JS_ToInt32(ctx, &mode, argv[1])) + return JS_EXCEPTION; + } else { + mode = 0777; + } + path = JS_ToCString(ctx, argv[0]); + if (!path) + return JS_EXCEPTION; +#if defined(_WIN32) + (void)mode; + ret = js_get_errno(mkdir(path)); +#else + ret = js_get_errno(mkdir(path, mode)); +#endif + JS_FreeCString(ctx, path); + return JS_NewInt32(ctx, ret); +} + +/* return [array, errorcode] */ +static JSValue js_os_readdir(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ +#ifdef _WIN32 + const char *path; + JSValue obj; + int err; + uint32_t len; + HANDLE h; + WIN32_FIND_DATAA d; + char s[1024]; + + path = JS_ToCString(ctx, argv[0]); + if (!path) + return JS_EXCEPTION; + obj = JS_NewArray(ctx); + if (JS_IsException(obj)) { + JS_FreeCString(ctx, path); + return JS_EXCEPTION; + } + snprintf(s, sizeof(s), "%s/*", path); + JS_FreeCString(ctx, path); + err = 0; + h = FindFirstFileA(s, &d); + if (h == INVALID_HANDLE_VALUE) + err = GetLastError(); + if (err) + goto done; + JS_DefinePropertyValueUint32(ctx, obj, 0, JS_NewString(ctx, "."), + JS_PROP_C_W_E); + for (len = 1; FindNextFileA(h, &d); len++) { + JS_DefinePropertyValueUint32(ctx, obj, len, + JS_NewString(ctx, d.cFileName), + JS_PROP_C_W_E); + } + FindClose(h); +done: + return make_obj_error(ctx, obj, err); +#else + const char *path; + DIR *f; + struct dirent *d; + JSValue obj; + int err; + uint32_t len; + + path = JS_ToCString(ctx, argv[0]); + if (!path) + return JS_EXCEPTION; + obj = JS_NewArray(ctx); + if (JS_IsException(obj)) { + JS_FreeCString(ctx, path); + return JS_EXCEPTION; + } + f = opendir(path); + if (!f) + err = errno; + else + err = 0; + JS_FreeCString(ctx, path); + if (!f) + goto done; + len = 0; + for(;;) { + errno = 0; + d = readdir(f); + if (!d) { + err = errno; + break; + } + JS_DefinePropertyValueUint32(ctx, obj, len++, + JS_NewString(ctx, d->d_name), + JS_PROP_C_W_E); + } + closedir(f); + done: + return make_obj_error(ctx, obj, err); +#endif +} + +#if !defined(_WIN32) && !defined(__wasi__) +#define PAT "XXXXXX" +#define PSZ (sizeof(PAT)-1) +static JSValue js_os_mkdstemp(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int magic) +{ + char pat_s[32] = "tmp"PAT, *pat = pat_s; + const char *s; + size_t k, n; + JSValue val; + int err; + + if (argc > 0) { + s = JS_ToCStringLen(ctx, &n, argv[0]); + if (!s) + return JS_EXCEPTION; + k = n; + if (n < PSZ || memcmp(&s[n-PSZ], PAT, PSZ)) + k += PSZ; + if (k >= sizeof(pat_s)) + pat = js_malloc(ctx, k+1); + if (pat) { + memcpy(pat, s, n); + if (n < k) + memcpy(&pat[n], PAT, PSZ); + pat[k] = '\0'; + } + JS_FreeCString(ctx, s); + if (!pat) + return JS_EXCEPTION; + } + if (magic == 'd') { + err = 0; + if (!mkdtemp(pat)) + err = -errno; + } else { + err = js_get_errno(mkstemp(pat)); + } + val = JS_NewString(ctx, pat); + if (pat != pat_s) + js_free(ctx, pat); + return make_obj_error(ctx, val, err); +} +#undef PSZ +#undef PAT +#endif // !defined(_WIN32) && !defined(__wasi__) + +#if !defined(_WIN32) +static int64_t timespec_to_ms(const struct timespec *tv) +{ + return (int64_t)tv->tv_sec * 1000 + (tv->tv_nsec / 1000000); +} +#endif + +/* return [obj, errcode] */ +static JSValue js_os_stat(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int is_lstat) +{ + const char *path; + int err, res; + struct stat st; + JSValue obj; + + path = JS_ToCString(ctx, argv[0]); + if (!path) + return JS_EXCEPTION; +#if defined(_WIN32) + res = stat(path, &st); +#else + if (is_lstat) + res = lstat(path, &st); + else + res = stat(path, &st); +#endif + err = (res < 0) ? errno : 0; + JS_FreeCString(ctx, path); + if (res < 0) { + obj = JS_NULL; + } else { + obj = JS_NewObject(ctx); + if (JS_IsException(obj)) + return JS_EXCEPTION; + JS_DefinePropertyValueStr(ctx, obj, "dev", + JS_NewInt64(ctx, st.st_dev), + JS_PROP_C_W_E); + JS_DefinePropertyValueStr(ctx, obj, "ino", + JS_NewInt64(ctx, st.st_ino), + JS_PROP_C_W_E); + JS_DefinePropertyValueStr(ctx, obj, "mode", + JS_NewInt32(ctx, st.st_mode), + JS_PROP_C_W_E); + JS_DefinePropertyValueStr(ctx, obj, "nlink", + JS_NewInt64(ctx, st.st_nlink), + JS_PROP_C_W_E); + JS_DefinePropertyValueStr(ctx, obj, "uid", + JS_NewInt64(ctx, st.st_uid), + JS_PROP_C_W_E); + JS_DefinePropertyValueStr(ctx, obj, "gid", + JS_NewInt64(ctx, st.st_gid), + JS_PROP_C_W_E); + JS_DefinePropertyValueStr(ctx, obj, "rdev", + JS_NewInt64(ctx, st.st_rdev), + JS_PROP_C_W_E); + JS_DefinePropertyValueStr(ctx, obj, "size", + JS_NewInt64(ctx, st.st_size), + JS_PROP_C_W_E); +#if !defined(_WIN32) + JS_DefinePropertyValueStr(ctx, obj, "blocks", + JS_NewInt64(ctx, st.st_blocks), + JS_PROP_C_W_E); +#endif +#if defined(_WIN32) + JS_DefinePropertyValueStr(ctx, obj, "atime", + JS_NewInt64(ctx, (int64_t)st.st_atime * 1000), + JS_PROP_C_W_E); + JS_DefinePropertyValueStr(ctx, obj, "mtime", + JS_NewInt64(ctx, (int64_t)st.st_mtime * 1000), + JS_PROP_C_W_E); + JS_DefinePropertyValueStr(ctx, obj, "ctime", + JS_NewInt64(ctx, (int64_t)st.st_ctime * 1000), + JS_PROP_C_W_E); +#elif defined(__APPLE__) + JS_DefinePropertyValueStr(ctx, obj, "atime", + JS_NewInt64(ctx, timespec_to_ms(&st.st_atimespec)), + JS_PROP_C_W_E); + JS_DefinePropertyValueStr(ctx, obj, "mtime", + JS_NewInt64(ctx, timespec_to_ms(&st.st_mtimespec)), + JS_PROP_C_W_E); + JS_DefinePropertyValueStr(ctx, obj, "ctime", + JS_NewInt64(ctx, timespec_to_ms(&st.st_ctimespec)), + JS_PROP_C_W_E); +#else + JS_DefinePropertyValueStr(ctx, obj, "atime", + JS_NewInt64(ctx, timespec_to_ms(&st.st_atim)), + JS_PROP_C_W_E); + JS_DefinePropertyValueStr(ctx, obj, "mtime", + JS_NewInt64(ctx, timespec_to_ms(&st.st_mtim)), + JS_PROP_C_W_E); + JS_DefinePropertyValueStr(ctx, obj, "ctime", + JS_NewInt64(ctx, timespec_to_ms(&st.st_ctim)), + JS_PROP_C_W_E); +#endif + } + return make_obj_error(ctx, obj, err); +} + +#if !defined(_WIN32) +static void ms_to_timeval(struct timeval *tv, uint64_t v) +{ + tv->tv_sec = v / 1000; + tv->tv_usec = (v % 1000) * 1000; +} +#endif + +static JSValue js_os_utimes(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *path; + int64_t atime, mtime; + int ret; + + if (JS_ToInt64(ctx, &atime, argv[1])) + return JS_EXCEPTION; + if (JS_ToInt64(ctx, &mtime, argv[2])) + return JS_EXCEPTION; + path = JS_ToCString(ctx, argv[0]); + if (!path) + return JS_EXCEPTION; +#if defined(_WIN32) + { + struct _utimbuf times; + times.actime = atime / 1000; + times.modtime = mtime / 1000; + ret = js_get_errno(_utime(path, ×)); + } +#else + { + struct timeval times[2]; + ms_to_timeval(×[0], atime); + ms_to_timeval(×[1], mtime); + ret = js_get_errno(utimes(path, times)); + } +#endif + JS_FreeCString(ctx, path); + return JS_NewInt32(ctx, ret); +} + +/* sleep(delay_ms) */ +static JSValue js_os_sleep(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int64_t delay; + int ret; + + if (JS_ToInt64(ctx, &delay, argv[0])) + return JS_EXCEPTION; + if (delay < 0) + delay = 0; +#if defined(_WIN32) + { + if (delay > INT32_MAX) + delay = INT32_MAX; + Sleep(delay); + ret = 0; + } +#else + { + struct timespec ts; + + ts.tv_sec = delay / 1000; + ts.tv_nsec = (delay % 1000) * 1000000; + ret = js_get_errno(nanosleep(&ts, NULL)); + } +#endif + return JS_NewInt32(ctx, ret); +} + +#if defined(_WIN32) +static char *realpath(const char *path, char *buf) +{ + if (!_fullpath(buf, path, JS__PATH_MAX)) { + errno = ENOENT; + return NULL; + } else { + return buf; + } +} +#endif + +#if !defined(__wasi__) +/* return [path, errorcode] */ +static JSValue js_os_realpath(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *path; + char buf[JS__PATH_MAX], *res; + int err; + + path = JS_ToCString(ctx, argv[0]); + if (!path) + return JS_EXCEPTION; + res = realpath(path, buf); + JS_FreeCString(ctx, path); + if (!res) { + buf[0] = '\0'; + err = errno; + } else { + err = 0; + } + return make_string_error(ctx, buf, err); +} +#endif + +#if !defined(_WIN32) && !defined(__wasi__) && !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)) +static JSValue js_os_symlink(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *target, *linkpath; + int err; + + target = JS_ToCString(ctx, argv[0]); + if (!target) + return JS_EXCEPTION; + linkpath = JS_ToCString(ctx, argv[1]); + if (!linkpath) { + JS_FreeCString(ctx, target); + return JS_EXCEPTION; + } + err = js_get_errno(symlink(target, linkpath)); + JS_FreeCString(ctx, target); + JS_FreeCString(ctx, linkpath); + return JS_NewInt32(ctx, err); +} + +/* return [path, errorcode] */ +static JSValue js_os_readlink(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + const char *path; + char buf[JS__PATH_MAX]; + int err; + ssize_t res; + + path = JS_ToCString(ctx, argv[0]); + if (!path) + return JS_EXCEPTION; + res = readlink(path, buf, sizeof(buf) - 1); + if (res < 0) { + buf[0] = '\0'; + err = errno; + } else { + buf[res] = '\0'; + err = 0; + } + JS_FreeCString(ctx, path); + return make_string_error(ctx, buf, err); +} + +static char **build_envp(JSContext *ctx, JSValue obj) +{ + uint32_t len, i; + JSPropertyEnum *tab; + char **envp, *pair; + const char *key, *str; + JSValue val; + size_t key_len, str_len; + + if (JS_GetOwnPropertyNames(ctx, &tab, &len, obj, + JS_GPN_STRING_MASK | JS_GPN_ENUM_ONLY) < 0) + return NULL; + envp = js_mallocz(ctx, sizeof(envp[0]) * ((size_t)len + 1)); + if (!envp) + goto fail; + for(i = 0; i < len; i++) { + val = JS_GetProperty(ctx, obj, tab[i].atom); + if (JS_IsException(val)) + goto fail; + str = JS_ToCString(ctx, val); + JS_FreeValue(ctx, val); + if (!str) + goto fail; + key = JS_AtomToCString(ctx, tab[i].atom); + if (!key) { + JS_FreeCString(ctx, str); + goto fail; + } + key_len = strlen(key); + str_len = strlen(str); + pair = js_malloc(ctx, key_len + str_len + 2); + if (!pair) { + JS_FreeCString(ctx, key); + JS_FreeCString(ctx, str); + goto fail; + } + memcpy(pair, key, key_len); + pair[key_len] = '='; + memcpy(pair + key_len + 1, str, str_len); + pair[key_len + 1 + str_len] = '\0'; + envp[i] = pair; + JS_FreeCString(ctx, key); + JS_FreeCString(ctx, str); + } + done: + for(i = 0; i < len; i++) + JS_FreeAtom(ctx, tab[i].atom); + js_free(ctx, tab); + return envp; + fail: + if (envp) { + for(i = 0; i < len; i++) + js_free(ctx, envp[i]); + js_free(ctx, envp); + envp = NULL; + } + goto done; +} + +/* execvpe is not available on non GNU systems */ +static int my_execvpe(const char *filename, char **argv, char **envp) +{ + char *path, *p, *p_next, *p1; + char buf[JS__PATH_MAX]; + size_t filename_len, path_len; + bool eacces_error; + + filename_len = strlen(filename); + if (filename_len == 0) { + errno = ENOENT; + return -1; + } + if (strchr(filename, '/')) + return execve(filename, argv, envp); + + path = getenv("PATH"); + if (!path) + path = (char *)"/bin:/usr/bin"; + eacces_error = false; + p = path; + for(p = path; p != NULL; p = p_next) { + p1 = strchr(p, ':'); + if (!p1) { + p_next = NULL; + path_len = strlen(p); + } else { + p_next = p1 + 1; + path_len = p1 - p; + } + /* path too long */ + if ((path_len + 1 + filename_len + 1) > JS__PATH_MAX) + continue; + memcpy(buf, p, path_len); + buf[path_len] = '/'; + memcpy(buf + path_len + 1, filename, filename_len); + buf[path_len + 1 + filename_len] = '\0'; + + execve(buf, argv, envp); + + switch(errno) { + case EACCES: + eacces_error = true; + break; + case ENOENT: + case ENOTDIR: + break; + default: + return -1; + } + } + if (eacces_error) + errno = EACCES; + return -1; +} + +static void (*js_os_exec_closefrom)(int); + +#if !defined(EMSCRIPTEN) && !defined(__wasi__) + +static js_once_t js_os_exec_once = JS_ONCE_INIT; + +static void js_os_exec_once_init(void) +{ + *(void **) (&js_os_exec_closefrom) = dlsym(RTLD_DEFAULT, "closefrom"); +} + +#endif + +/* exec(args[, options]) -> exitcode */ +static JSValue js_os_exec(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValueConst options, args = argv[0]; + JSValue val, ret_val; + const char **exec_argv, *file = NULL, *str, *cwd = NULL; + char **envp = environ; + uint32_t exec_argc, i; + int ret, pid, status; + bool block_flag = true, use_path = true; + static const char *std_name[3] = { "stdin", "stdout", "stderr" }; + int std_fds[3]; + uint32_t uid = -1, gid = -1; + int ngroups = -1; + gid_t groups[64]; + + val = JS_GetPropertyStr(ctx, args, "length"); + if (JS_IsException(val)) + return JS_EXCEPTION; + ret = JS_ToUint32(ctx, &exec_argc, val); + JS_FreeValue(ctx, val); + if (ret) + return JS_EXCEPTION; + /* arbitrary limit to avoid overflow */ + if (exec_argc < 1 || exec_argc > 65535) { + return JS_ThrowTypeError(ctx, "invalid number of arguments"); + } + exec_argv = js_mallocz(ctx, sizeof(exec_argv[0]) * (exec_argc + 1)); + if (!exec_argv) + return JS_EXCEPTION; + for(i = 0; i < exec_argc; i++) { + val = JS_GetPropertyUint32(ctx, args, i); + if (JS_IsException(val)) + goto exception; + str = JS_ToCString(ctx, val); + JS_FreeValue(ctx, val); + if (!str) + goto exception; + exec_argv[i] = str; + } + exec_argv[exec_argc] = NULL; + + for(i = 0; i < 3; i++) + std_fds[i] = i; + + /* get the options, if any */ + if (argc >= 2) { + options = argv[1]; + + if (get_bool_option(ctx, &block_flag, options, "block")) + goto exception; + if (get_bool_option(ctx, &use_path, options, "usePath")) + goto exception; + + val = JS_GetPropertyStr(ctx, options, "file"); + if (JS_IsException(val)) + goto exception; + if (!JS_IsUndefined(val)) { + file = JS_ToCString(ctx, val); + JS_FreeValue(ctx, val); + if (!file) + goto exception; + } + + val = JS_GetPropertyStr(ctx, options, "cwd"); + if (JS_IsException(val)) + goto exception; + if (!JS_IsUndefined(val)) { + cwd = JS_ToCString(ctx, val); + JS_FreeValue(ctx, val); + if (!cwd) + goto exception; + } + + /* stdin/stdout/stderr handles */ + for(i = 0; i < 3; i++) { + val = JS_GetPropertyStr(ctx, options, std_name[i]); + if (JS_IsException(val)) + goto exception; + if (!JS_IsUndefined(val)) { + int fd; + ret = JS_ToInt32(ctx, &fd, val); + JS_FreeValue(ctx, val); + if (ret) + goto exception; + std_fds[i] = fd; + } + } + + val = JS_GetPropertyStr(ctx, options, "env"); + if (JS_IsException(val)) + goto exception; + if (!JS_IsUndefined(val)) { + envp = build_envp(ctx, val); + JS_FreeValue(ctx, val); + if (!envp) + goto exception; + } + + val = JS_GetPropertyStr(ctx, options, "uid"); + if (JS_IsException(val)) + goto exception; + if (!JS_IsUndefined(val)) { + ret = JS_ToUint32(ctx, &uid, val); + JS_FreeValue(ctx, val); + if (ret) + goto exception; + } + + val = JS_GetPropertyStr(ctx, options, "gid"); + if (JS_IsException(val)) + goto exception; + if (!JS_IsUndefined(val)) { + ret = JS_ToUint32(ctx, &gid, val); + JS_FreeValue(ctx, val); + if (ret) + goto exception; + } + + val = JS_GetPropertyStr(ctx, options, "groups"); + if (JS_IsException(val)) + goto exception; + if (!JS_IsUndefined(val)) { + int64_t idx, len; + JSValue prop; + uint32_t id; + ngroups = 0; + if (JS_GetLength(ctx, val, &len)) { + JS_FreeValue(ctx, val); + goto exception; + } + for (idx = 0; idx < len; idx++) { + prop = JS_GetPropertyInt64(ctx, val, idx); + if (JS_IsException(prop)) + break; + if (JS_IsUndefined(prop)) + continue; + ret = JS_ToUint32(ctx, &id, prop); + JS_FreeValue(ctx, prop); + if (ret) + break; + if (ngroups == countof(groups)) { + JS_ThrowRangeError(ctx, "too many groups"); + break; + } + groups[ngroups++] = id; + } + JS_FreeValue(ctx, val); + if (idx < len) + goto exception; + } + + } + +#if !defined(EMSCRIPTEN) && !defined(__wasi__) + // should happen pre-fork because it calls dlsym() + // and that's not an async-signal-safe function + js_once(&js_os_exec_once, js_os_exec_once_init); +#endif + + pid = fork(); + if (pid < 0) { + JS_ThrowTypeError(ctx, "fork error"); + goto exception; + } + if (pid == 0) { + /* child */ + /* remap the stdin/stdout/stderr handles if necessary */ + for(i = 0; i < 3; i++) { + if (std_fds[i] != i) { + if (dup2(std_fds[i], i) < 0) + _exit(127); + } + } + + if (js_os_exec_closefrom) { + js_os_exec_closefrom(3); + } else { + int fd_max = sysconf(_SC_OPEN_MAX); + for(i = 3; i < fd_max; i++) + close(i); + } + + if (cwd) { + if (chdir(cwd) < 0) + _exit(127); + } + if (ngroups != -1) { + if (setgroups(ngroups, groups) < 0) + _exit(127); + } + if (uid != -1) { + if (setuid(uid) < 0) + _exit(127); + } + if (gid != -1) { + if (setgid(gid) < 0) + _exit(127); + } + + if (!file) + file = exec_argv[0]; + if (use_path) + ret = my_execvpe(file, (char **)exec_argv, envp); + else + ret = execve(file, (char **)exec_argv, envp); + _exit(127); + } + /* parent */ + if (block_flag) { + for(;;) { + ret = waitpid(pid, &status, 0); + if (ret == pid) { + if (WIFEXITED(status)) { + ret = WEXITSTATUS(status); + break; + } else if (WIFSIGNALED(status)) { + ret = -WTERMSIG(status); + break; + } + } + } + } else { + ret = pid; + } + ret_val = JS_NewInt32(ctx, ret); + done: + JS_FreeCString(ctx, file); + JS_FreeCString(ctx, cwd); + for(i = 0; i < exec_argc; i++) + JS_FreeCString(ctx, exec_argv[i]); + js_free(ctx, exec_argv); + if (envp != environ) { + char **p; + p = envp; + while (*p != NULL) { + js_free(ctx, *p); + p++; + } + js_free(ctx, envp); + } + return ret_val; + exception: + ret_val = JS_EXCEPTION; + goto done; +} + +/* getpid() -> pid */ +static JSValue js_os_getpid(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + return JS_NewInt32(ctx, getpid()); +} + +/* waitpid(pid, block) -> [pid, status] */ +static JSValue js_os_waitpid(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int pid, status, options, ret; + JSValue obj; + + if (JS_ToInt32(ctx, &pid, argv[0])) + return JS_EXCEPTION; + if (JS_ToInt32(ctx, &options, argv[1])) + return JS_EXCEPTION; + + ret = waitpid(pid, &status, options); + if (ret < 0) { + ret = -errno; + status = 0; + } + + obj = JS_NewArray(ctx); + if (JS_IsException(obj)) + return obj; + JS_DefinePropertyValueUint32(ctx, obj, 0, JS_NewInt32(ctx, ret), + JS_PROP_C_W_E); + JS_DefinePropertyValueUint32(ctx, obj, 1, JS_NewInt32(ctx, status), + JS_PROP_C_W_E); + return obj; +} + +/* pipe() -> [read_fd, write_fd] or null if error */ +static JSValue js_os_pipe(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int pipe_fds[2], ret; + JSValue obj; + + ret = pipe(pipe_fds); + if (ret < 0) + return JS_NULL; + obj = JS_NewArray(ctx); + if (JS_IsException(obj)) + return obj; + JS_DefinePropertyValueUint32(ctx, obj, 0, JS_NewInt32(ctx, pipe_fds[0]), + JS_PROP_C_W_E); + JS_DefinePropertyValueUint32(ctx, obj, 1, JS_NewInt32(ctx, pipe_fds[1]), + JS_PROP_C_W_E); + return obj; +} + +/* kill(pid, sig) */ +static JSValue js_os_kill(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int pid, sig, ret; + + if (JS_ToInt32(ctx, &pid, argv[0])) + return JS_EXCEPTION; + if (JS_ToInt32(ctx, &sig, argv[1])) + return JS_EXCEPTION; + ret = js_get_errno(kill(pid, sig)); + return JS_NewInt32(ctx, ret); +} + +/* dup(fd) */ +static JSValue js_os_dup(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int fd, ret; + + if (JS_ToInt32(ctx, &fd, argv[0])) + return JS_EXCEPTION; + ret = js_get_errno(dup(fd)); + return JS_NewInt32(ctx, ret); +} + +/* dup2(fd) */ +static JSValue js_os_dup2(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int fd, fd2, ret; + + if (JS_ToInt32(ctx, &fd, argv[0])) + return JS_EXCEPTION; + if (JS_ToInt32(ctx, &fd2, argv[1])) + return JS_EXCEPTION; + ret = js_get_errno(dup2(fd, fd2)); + return JS_NewInt32(ctx, ret); +} + +#endif /* !_WIN32 */ + +#ifdef USE_WORKER + +/* Worker */ + +typedef struct { + JSWorkerMessagePipe *recv_pipe; + JSWorkerMessagePipe *send_pipe; + JSWorkerMessageHandler *msg_handler; +} JSWorkerData; + +typedef struct { + char *filename; /* module filename */ + char *basename; /* module base name */ + JSWorkerMessagePipe *recv_pipe, *send_pipe; +} WorkerFuncArgs; + +typedef struct { + int ref_count; + uint64_t buf[]; +} JSSABHeader; + +static JSRuntime *(*js_worker_new_runtime_func)(void); +static JSContext *(*js_worker_new_context_func)(JSRuntime *rt); + +static int atomic_add_int(int *ptr, int v) +{ + return atomic_fetch_add((_Atomic uint32_t*)ptr, v) + v; +} + +/* shared array buffer allocator */ +static void *js_sab_alloc(void *opaque, size_t size) +{ + JSSABHeader *sab; + sab = malloc(sizeof(JSSABHeader) + size); + if (!sab) + return NULL; + sab->ref_count = 1; + return sab->buf; +} + +static void js_sab_free(void *opaque, void *ptr) +{ + JSSABHeader *sab; + int ref_count; + sab = (JSSABHeader *)((uint8_t *)ptr - sizeof(JSSABHeader)); + ref_count = atomic_add_int(&sab->ref_count, -1); + assert(ref_count >= 0); + if (ref_count == 0) { + free(sab); + } +} + +static void js_sab_dup(void *opaque, void *ptr) +{ + JSSABHeader *sab; + sab = (JSSABHeader *)((uint8_t *)ptr - sizeof(JSSABHeader)); + atomic_add_int(&sab->ref_count, 1); +} + +static JSWorkerMessagePipe *js_new_message_pipe(void) +{ + JSWorkerMessagePipe *ps; + + ps = malloc(sizeof(*ps)); + if (!ps) + return NULL; + if (js_waker_init(&ps->waker)) { + free(ps); + return NULL; + } + ps->ref_count = 1; + init_list_head(&ps->msg_queue); + js_mutex_init(&ps->mutex); + return ps; +} + +static JSWorkerMessagePipe *js_dup_message_pipe(JSWorkerMessagePipe *ps) +{ + atomic_add_int(&ps->ref_count, 1); + return ps; +} + +static void js_free_message(JSWorkerMessage *msg) +{ + size_t i; + /* free the SAB */ + for(i = 0; i < msg->sab_tab_len; i++) { + js_sab_free(NULL, msg->sab_tab[i]); + } + free(msg->sab_tab); + free(msg->data); + free(msg); +} + +static void js_free_message_pipe(JSWorkerMessagePipe *ps) +{ + struct list_head *el, *el1; + JSWorkerMessage *msg; + int ref_count; + + if (!ps) + return; + + ref_count = atomic_add_int(&ps->ref_count, -1); + assert(ref_count >= 0); + if (ref_count == 0) { + list_for_each_safe(el, el1, &ps->msg_queue) { + msg = list_entry(el, JSWorkerMessage, link); + js_free_message(msg); + } + js_mutex_destroy(&ps->mutex); + js_waker_close(&ps->waker); + free(ps); + } +} + +static void js_free_port(JSRuntime *rt, JSWorkerMessageHandler *port) +{ + if (port) { + js_free_message_pipe(port->recv_pipe); + JS_FreeValueRT(rt, port->on_message_func); + list_del(&port->link); + js_free_rt(rt, port); + } +} + +static void js_worker_finalizer(JSRuntime *rt, JSValueConst val) +{ + JSThreadState *ts = js_get_thread_state(rt); + JSWorkerData *worker = JS_GetOpaque(val, ts->worker_class_id); + if (worker) { + js_free_message_pipe(worker->recv_pipe); + js_free_message_pipe(worker->send_pipe); + js_free_port(rt, worker->msg_handler); + js_free_rt(rt, worker); + } +} + +static JSClassDef js_worker_class = { + "Worker", + .finalizer = js_worker_finalizer, +}; + +static void worker_func(void *opaque) +{ + JSRuntime *(*new_runtime_func)(void); + JSContext *(*new_context_func)(JSRuntime *); + WorkerFuncArgs *args = opaque; + JSRuntime *rt; + JSThreadState *ts; + JSContext *ctx; + JSValue val; + + new_runtime_func = js_worker_new_runtime_func; + if (!new_runtime_func) + new_runtime_func = JS_NewRuntime; + rt = new_runtime_func(); + if (rt == NULL) { + fprintf(stderr, "JS_NewRuntime failure"); + exit(1); + } + js_std_init_handlers(rt); + + JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader, js_module_check_attributes, NULL); + + /* set the pipe to communicate with the parent */ + ts = js_get_thread_state(rt); + ts->recv_pipe = args->recv_pipe; + ts->send_pipe = args->send_pipe; + + /* function pointer to avoid linking the whole JS_NewContext() if + not needed */ + new_context_func = js_worker_new_context_func; + if (!new_context_func) + new_context_func = JS_NewContext; + ctx = new_context_func(rt); + if (ctx == NULL) { + fprintf(stderr, "JS_NewContext failure"); + exit(1); + } + + JS_SetCanBlock(rt, true); + + js_std_add_helpers(ctx, -1, NULL); + + val = JS_LoadModule(ctx, args->basename, args->filename, JS_UNDEFINED); + free(args->filename); + free(args->basename); + free(args); + val = js_std_await(ctx, val); + if (JS_IsException(val)) + js_std_dump_error(ctx); + JS_FreeValue(ctx, val); + + js_std_loop(ctx); + + js_std_free_handlers(rt); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +static JSValue js_worker_ctor_internal(JSContext *ctx, JSValueConst new_target, + JSWorkerMessagePipe *recv_pipe, + JSWorkerMessagePipe *send_pipe) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + JSValue obj = JS_UNDEFINED, proto; + JSWorkerData *s; + + /* create the object */ + if (JS_IsUndefined(new_target)) { + proto = JS_GetClassProto(ctx, ts->worker_class_id); + } else { + proto = JS_GetPropertyStr(ctx, new_target, "prototype"); + if (JS_IsException(proto)) + goto fail; + } + obj = JS_NewObjectProtoClass(ctx, proto, ts->worker_class_id); + JS_FreeValue(ctx, proto); + if (JS_IsException(obj)) + goto fail; + s = js_mallocz(ctx, sizeof(*s)); + if (!s) + goto fail; + s->recv_pipe = js_dup_message_pipe(recv_pipe); + s->send_pipe = js_dup_message_pipe(send_pipe); + + JS_SetOpaque(obj, s); + return obj; + fail: + JS_FreeValue(ctx, obj); + return JS_EXCEPTION; +} + +static JSValue js_worker_ctor(JSContext *ctx, JSValueConst new_target, + int argc, JSValueConst *argv) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + WorkerFuncArgs *args = NULL; + js_thread_t thr; + JSValue obj = JS_UNDEFINED; + int ret; + const char *filename = NULL, *basename; + JSAtom basename_atom; + + /* XXX: in order to avoid problems with resource liberation, we + don't support creating workers inside workers */ + if (!is_main_thread(rt)) + return JS_ThrowTypeError(ctx, "cannot create a worker inside a worker"); + + /* base name, assuming the calling function is a normal JS + function */ + basename_atom = JS_GetScriptOrModuleName(ctx, 1); + if (basename_atom == JS_ATOM_NULL) { + return JS_ThrowTypeError(ctx, "could not determine calling script or module name"); + } + basename = JS_AtomToCString(ctx, basename_atom); + JS_FreeAtom(ctx, basename_atom); + if (!basename) + goto fail; + + /* module name */ + filename = JS_ToCString(ctx, argv[0]); + if (!filename) + goto fail; + + args = malloc(sizeof(*args)); + if (!args) + goto oom_fail; + memset(args, 0, sizeof(*args)); + args->filename = strdup(filename); + args->basename = strdup(basename); + + /* ports */ + args->recv_pipe = js_new_message_pipe(); + if (!args->recv_pipe) + goto oom_fail; + args->send_pipe = js_new_message_pipe(); + if (!args->send_pipe) + goto oom_fail; + + obj = js_worker_ctor_internal(ctx, new_target, + args->send_pipe, args->recv_pipe); + if (JS_IsException(obj)) + goto fail; + + ret = js_thread_create(&thr, worker_func, args, JS_THREAD_CREATE_DETACHED); + if (ret != 0) { + JS_ThrowTypeError(ctx, "could not create worker"); + goto fail; + } + JS_FreeCString(ctx, basename); + JS_FreeCString(ctx, filename); + return obj; + oom_fail: + JS_ThrowOutOfMemory(ctx); + fail: + JS_FreeCString(ctx, basename); + JS_FreeCString(ctx, filename); + if (args) { + free(args->filename); + free(args->basename); + js_free_message_pipe(args->recv_pipe); + js_free_message_pipe(args->send_pipe); + free(args); + } + JS_FreeValue(ctx, obj); + return JS_EXCEPTION; +} + +static JSValue js_worker_postMessage(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + JSWorkerData *worker = JS_GetOpaque2(ctx, this_val, ts->worker_class_id); + JSWorkerMessagePipe *ps; + size_t data_len, i; + uint8_t *data; + JSWorkerMessage *msg; + JSSABTab sab_tab; + + if (!worker) + return JS_EXCEPTION; + + data = JS_WriteObject2(ctx, &data_len, argv[0], + JS_WRITE_OBJ_SAB | JS_WRITE_OBJ_REFERENCE, + &sab_tab); + if (!data) + return JS_EXCEPTION; + + msg = malloc(sizeof(*msg)); + if (!msg) + goto fail; + msg->data = NULL; + msg->sab_tab = NULL; + + /* must reallocate because the allocator may be different */ + msg->data = malloc(data_len); + if (!msg->data) + goto fail; + memcpy(msg->data, data, data_len); + msg->data_len = data_len; + + if (sab_tab.len > 0) { + msg->sab_tab = malloc(sizeof(msg->sab_tab[0]) * sab_tab.len); + if (!msg->sab_tab) + goto fail; + memcpy(msg->sab_tab, sab_tab.tab, sizeof(msg->sab_tab[0]) * sab_tab.len); + } + msg->sab_tab_len = sab_tab.len; + + js_free(ctx, data); + js_free(ctx, sab_tab.tab); + + /* increment the SAB reference counts */ + for(i = 0; i < msg->sab_tab_len; i++) { + js_sab_dup(NULL, msg->sab_tab[i]); + } + + ps = worker->send_pipe; + js_mutex_lock(&ps->mutex); + /* indicate that data is present */ + if (list_empty(&ps->msg_queue)) + js_waker_signal(&ps->waker); + list_add_tail(&msg->link, &ps->msg_queue); + js_mutex_unlock(&ps->mutex); + return JS_UNDEFINED; + fail: + if (msg) { + free(msg->data); + free(msg->sab_tab); + free(msg); + } + js_free(ctx, data); + js_free(ctx, sab_tab.tab); + return JS_EXCEPTION; + +} + +static JSValue js_worker_set_onmessage(JSContext *ctx, JSValueConst this_val, + JSValueConst func) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + JSWorkerData *worker = JS_GetOpaque2(ctx, this_val, ts->worker_class_id); + JSWorkerMessageHandler *port; + + if (!worker) + return JS_EXCEPTION; + + port = worker->msg_handler; + if (JS_IsNull(func)) { + if (port) { + js_free_port(rt, port); + worker->msg_handler = NULL; + } + } else { + if (!JS_IsFunction(ctx, func)) + return JS_ThrowTypeError(ctx, "not a function"); + if (!port) { + port = js_mallocz(ctx, sizeof(*port)); + if (!port) + return JS_EXCEPTION; + port->recv_pipe = js_dup_message_pipe(worker->recv_pipe); + port->on_message_func = JS_NULL; + list_add_tail(&port->link, &ts->port_list); + worker->msg_handler = port; + } + JS_FreeValue(ctx, port->on_message_func); + port->on_message_func = JS_DupValue(ctx, func); + } + return JS_UNDEFINED; +} + +static JSValue js_worker_get_onmessage(JSContext *ctx, JSValueConst this_val) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + JSWorkerData *worker = JS_GetOpaque2(ctx, this_val, ts->worker_class_id); + JSWorkerMessageHandler *port; + if (!worker) + return JS_EXCEPTION; + port = worker->msg_handler; + if (port) { + return JS_DupValue(ctx, port->on_message_func); + } else { + return JS_NULL; + } +} + +static const JSCFunctionListEntry js_worker_proto_funcs[] = { + JS_CFUNC_DEF("postMessage", 1, js_worker_postMessage ), + JS_CGETSET_DEF("onmessage", js_worker_get_onmessage, js_worker_set_onmessage ), +}; + +#endif /* USE_WORKER */ + +void js_std_set_worker_new_runtime_func(JSRuntime *(*func)(void)) +{ +#ifdef USE_WORKER + js_worker_new_runtime_func = func; +#endif +} + +void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt)) +{ +#ifdef USE_WORKER + js_worker_new_context_func = func; +#endif +} + +#if defined(_WIN32) +#define OS_PLATFORM "win32" +#elif defined(__APPLE__) +#define OS_PLATFORM "darwin" +#elif defined(EMSCRIPTEN) +#define OS_PLATFORM "js" +#elif defined(__CYGWIN__) +#define OS_PLATFORM "cygwin" +#elif defined(__linux__) +#define OS_PLATFORM "linux" +#elif defined(__OpenBSD__) +#define OS_PLATFORM "openbsd" +#elif defined(__NetBSD__) +#define OS_PLATFORM "netbsd" +#elif defined(__FreeBSD__) +#define OS_PLATFORM "freebsd" +#elif defined(__wasi__) +#define OS_PLATFORM "wasi" +#elif defined(__GNU__) +#define OS_PLATFORM "hurd" +#else +#define OS_PLATFORM "unknown" +#endif + +#define OS_FLAG(x) JS_PROP_INT32_DEF(#x, x, JS_PROP_CONFIGURABLE ) + +static const JSCFunctionListEntry js_os_funcs[] = { + JS_CFUNC_DEF("open", 2, js_os_open ), + OS_FLAG(O_RDONLY), + OS_FLAG(O_WRONLY), + OS_FLAG(O_RDWR), + OS_FLAG(O_APPEND), + OS_FLAG(O_CREAT), + OS_FLAG(O_EXCL), + OS_FLAG(O_TRUNC), +#if defined(_WIN32) + OS_FLAG(O_BINARY), + OS_FLAG(O_TEXT), +#endif + JS_CFUNC_DEF("close", 1, js_os_close ), + JS_CFUNC_DEF("seek", 3, js_os_seek ), + JS_CFUNC_MAGIC_DEF("read", 4, js_os_read_write, 0 ), + JS_CFUNC_MAGIC_DEF("write", 4, js_os_read_write, 1 ), + JS_CFUNC_DEF("isatty", 1, js_os_isatty ), +#if !defined(__wasi__) + JS_CFUNC_DEF("ttyGetWinSize", 1, js_os_ttyGetWinSize ), + JS_CFUNC_DEF("ttySetRaw", 1, js_os_ttySetRaw ), +#endif + JS_CFUNC_DEF("remove", 1, js_os_remove ), + JS_CFUNC_DEF("rename", 2, js_os_rename ), + JS_CFUNC_MAGIC_DEF("setReadHandler", 2, js_os_setReadHandler, 0 ), + JS_CFUNC_MAGIC_DEF("setWriteHandler", 2, js_os_setReadHandler, 1 ), + JS_CFUNC_DEF("signal", 2, js_os_signal ), + OS_FLAG(SIGINT), + OS_FLAG(SIGABRT), + OS_FLAG(SIGFPE), + OS_FLAG(SIGILL), + OS_FLAG(SIGSEGV), + OS_FLAG(SIGTERM), +#if !defined(_WIN32) && !defined(__wasi__) + OS_FLAG(SIGQUIT), + OS_FLAG(SIGPIPE), + OS_FLAG(SIGALRM), + OS_FLAG(SIGUSR1), + OS_FLAG(SIGUSR2), + OS_FLAG(SIGCHLD), + OS_FLAG(SIGCONT), + OS_FLAG(SIGSTOP), + OS_FLAG(SIGTSTP), + OS_FLAG(SIGTTIN), + OS_FLAG(SIGTTOU), + JS_CFUNC_DEF("cputime", 0, js_os_cputime ), +#endif + JS_CFUNC_DEF("exePath", 0, js_os_exepath ), + JS_CFUNC_DEF("now", 0, js_os_now ), + JS_CFUNC_MAGIC_DEF("setTimeout", 2, js_os_setTimeout, 0 ), + JS_CFUNC_MAGIC_DEF("setInterval", 2, js_os_setTimeout, 1 ), + // per spec: both functions can cancel timeouts and intervals + JS_CFUNC_DEF("clearTimeout", 1, js_os_clearTimeout ), + JS_CFUNC_DEF("clearInterval", 1, js_os_clearTimeout ), + JS_CFUNC_DEF("sleepAsync", 1, js_os_sleepAsync ), + JS_PROP_STRING_DEF("platform", OS_PLATFORM, 0 ), + JS_CFUNC_DEF("getcwd", 0, js_os_getcwd ), + JS_CFUNC_DEF("chdir", 1, js_os_chdir ), + JS_CFUNC_DEF("mkdir", 1, js_os_mkdir ), + JS_CFUNC_DEF("readdir", 1, js_os_readdir ), +#if !defined(_WIN32) && !defined(__wasi__) + JS_CFUNC_MAGIC_DEF("mkdtemp", 0, js_os_mkdstemp, 'd' ), + JS_CFUNC_MAGIC_DEF("mkstemp", 0, js_os_mkdstemp, 's' ), +#endif + /* st_mode constants */ + OS_FLAG(S_IFMT), + OS_FLAG(S_IFIFO), + OS_FLAG(S_IFCHR), + OS_FLAG(S_IFDIR), + OS_FLAG(S_IFBLK), + OS_FLAG(S_IFREG), +#if !defined(_WIN32) + OS_FLAG(S_IFSOCK), + OS_FLAG(S_IFLNK), + OS_FLAG(S_ISGID), + OS_FLAG(S_ISUID), +#endif + JS_CFUNC_MAGIC_DEF("stat", 1, js_os_stat, 0 ), + JS_CFUNC_DEF("utimes", 3, js_os_utimes ), + JS_CFUNC_DEF("sleep", 1, js_os_sleep ), +#if !defined(__wasi__) + JS_CFUNC_DEF("realpath", 1, js_os_realpath ), +#endif +#if !defined(_WIN32) && !defined(__wasi__) && !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)) + JS_CFUNC_MAGIC_DEF("lstat", 1, js_os_stat, 1 ), + JS_CFUNC_DEF("symlink", 2, js_os_symlink ), + JS_CFUNC_DEF("readlink", 1, js_os_readlink ), + JS_CFUNC_DEF("exec", 1, js_os_exec ), + JS_CFUNC_DEF("getpid", 0, js_os_getpid ), + JS_CFUNC_DEF("waitpid", 2, js_os_waitpid ), + OS_FLAG(WNOHANG), + JS_CFUNC_DEF("pipe", 0, js_os_pipe ), + JS_CFUNC_DEF("kill", 2, js_os_kill ), + JS_CFUNC_DEF("dup", 1, js_os_dup ), + JS_CFUNC_DEF("dup2", 2, js_os_dup2 ), +#endif +}; + +static int js_os_init(JSContext *ctx, JSModuleDef *m) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + + ts->can_js_os_poll = true; + +#ifdef USE_WORKER + { + JSValue proto, obj; + /* Worker class */ + JS_NewClassID(rt, &ts->worker_class_id); + JS_NewClass(rt, ts->worker_class_id, &js_worker_class); + proto = JS_NewObject(ctx); + JS_SetPropertyFunctionList(ctx, proto, js_worker_proto_funcs, countof(js_worker_proto_funcs)); + + obj = JS_NewCFunction2(ctx, js_worker_ctor, "Worker", 1, + JS_CFUNC_constructor, 0); + JS_SetConstructor(ctx, obj, proto); + + JS_SetClassProto(ctx, ts->worker_class_id, proto); + + /* set 'Worker.parent' if necessary */ + if (ts->recv_pipe && ts->send_pipe) { + JS_DefinePropertyValueStr(ctx, obj, "parent", + js_worker_ctor_internal(ctx, JS_UNDEFINED, ts->recv_pipe, ts->send_pipe), + JS_PROP_C_W_E); + } + + JS_SetModuleExport(ctx, m, "Worker", obj); + } +#endif /* USE_WORKER */ + + if (JS_SetModuleExportList(ctx, m, js_os_funcs, countof(js_os_funcs))) + return -1; + +#ifdef __COSMOPOLITAN__ + const char *platform; + if (IsLinux()) { + platform = "linux"; + } else if (IsNetbsd()) { + platform = "netbsd"; + } else if (IsOpenbsd()) { + platform = "openbsd"; + } else if (IsWindows()) { + platform = "win32"; + } else if (IsXnu()) { + platform = "darwin"; + } else { + platform = "unknown"; + } + if (JS_SetModuleExport(ctx, m, "platform", JS_NewString(ctx, platform))) + return -1; +#endif /* __COSMOPOLITAN__ */ + + return 0; +} + +JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name) +{ + JSModuleDef *m; + m = JS_NewCModule(ctx, module_name, js_os_init); + if (!m) + return NULL; + JS_AddModuleExportList(ctx, m, js_os_funcs, countof(js_os_funcs)); +#ifdef USE_WORKER + JS_AddModuleExport(ctx, m, "Worker"); +#endif + return m; +} + +/**********************************************************/ + +static JSValue js_print(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ +#ifdef _WIN32 + HANDLE handle; + DWORD mode; +#endif + const char *s; + JSValueConst v; + DynBuf b; + int i; + + dbuf_init(&b); + for(i = 0; i < argc; i++) { + v = argv[i]; + s = JS_ToCString(ctx, v); + if (!s && JS_IsObject(v)) { + JS_FreeValue(ctx, JS_GetException(ctx)); + JSValue t = JS_ToObjectString(ctx, v); + s = JS_ToCString(ctx, t); + JS_FreeValue(ctx, t); + } + if (s) { + dbuf_printf(&b, "%s%s", &" "[!i], s); + JS_FreeCString(ctx, s); + } else { + dbuf_printf(&b, "%s", &" "[!i]); + JS_FreeValue(ctx, JS_GetException(ctx)); + } + } + dbuf_putc(&b, '\n'); +#ifdef _WIN32 + // use WriteConsoleA with CP_UTF8 for better Unicode handling vis-a-vis + // the mangling that happens when going through msvcrt's stdio layer, + // *except* when stdout is redirected to something that is not a console + handle = (HANDLE)_get_osfhandle(/*STDOUT_FILENO*/1); // don't CloseHandle + if (GetFileType(handle) != FILE_TYPE_CHAR) + goto fallback; + if (!GetConsoleMode(handle, &mode)) + goto fallback; + handle = GetStdHandle(STD_OUTPUT_HANDLE); + if (handle == INVALID_HANDLE_VALUE) + goto fallback; + mode = GetConsoleOutputCP(); + SetConsoleOutputCP(CP_UTF8); + WriteConsoleA(handle, b.buf, b.size, NULL, NULL); + SetConsoleOutputCP(mode); + FlushFileBuffers(handle); + goto done; +fallback: +#endif + fwrite(b.buf, 1, b.size, stdout); + fflush(stdout); + goto done; // avoid unused label warning +done: + dbuf_free(&b); + return JS_UNDEFINED; +} + +void js_std_add_helpers(JSContext *ctx, int argc, char **argv) +{ + JSValue global_obj, console, args; + int i; + + /* XXX: should these global definitions be enumerable? */ + global_obj = JS_GetGlobalObject(ctx); + + console = JS_NewObject(ctx); + JS_SetPropertyStr(ctx, console, "log", + JS_NewCFunction(ctx, js_print, "log", 1)); + JS_SetPropertyStr(ctx, global_obj, "console", console); + + /* same methods as the mozilla JS shell */ + if (argc >= 0) { + args = JS_NewArray(ctx); + for(i = 0; i < argc; i++) { + JS_SetPropertyUint32(ctx, args, i, JS_NewString(ctx, argv[i])); + } + JS_SetPropertyStr(ctx, global_obj, "scriptArgs", args); + } + + JS_SetPropertyStr(ctx, global_obj, "print", + JS_NewCFunction(ctx, js_print, "print", 1)); + + JS_FreeValue(ctx, global_obj); +} + +static void js_std_finalize(JSRuntime *rt, void *arg) +{ + JSThreadState *ts = arg; + js_set_thread_state(rt, NULL); + js_free_rt(rt, ts); +} + +void js_std_init_handlers(JSRuntime *rt) +{ + JSThreadState *ts; + + ts = js_mallocz_rt(rt, sizeof(*ts)); + if (!ts) { + fprintf(stderr, "Could not allocate memory for the worker"); + exit(1); + } + init_list_head(&ts->os_rw_handlers); + init_list_head(&ts->os_signal_handlers); + init_list_head(&ts->os_timers); + init_list_head(&ts->port_list); + init_list_head(&ts->rejected_promise_list); + + ts->next_timer_id = 1; + + js_set_thread_state(rt, ts); + JS_AddRuntimeFinalizer(rt, js_std_finalize, ts); + +#ifdef USE_WORKER + /* set the SharedArrayBuffer memory handlers */ + { + JSSharedArrayBufferFunctions sf; + memset(&sf, 0, sizeof(sf)); + sf.sab_alloc = js_sab_alloc; + sf.sab_free = js_sab_free; + sf.sab_dup = js_sab_dup; + JS_SetSharedArrayBufferFunctions(rt, &sf); + } +#endif +} + +static void free_rp(JSRuntime *rt, JSRejectedPromiseEntry *rp) +{ + list_del(&rp->link); + JS_FreeValueRT(rt, rp->promise); + JS_FreeValueRT(rt, rp->reason); + js_free_rt(rt, rp); +} + +void js_std_free_handlers(JSRuntime *rt) +{ + JSThreadState *ts = js_get_thread_state(rt); + struct list_head *el, *el1; + + list_for_each_safe(el, el1, &ts->os_rw_handlers) { + JSOSRWHandler *rh = list_entry(el, JSOSRWHandler, link); + free_rw_handler(rt, rh); + } + + list_for_each_safe(el, el1, &ts->os_signal_handlers) { + JSOSSignalHandler *sh = list_entry(el, JSOSSignalHandler, link); + free_sh(rt, sh); + } + + list_for_each_safe(el, el1, &ts->os_timers) { + JSOSTimer *th = list_entry(el, JSOSTimer, link); + free_timer(rt, th); + } + + list_for_each_safe(el, el1, &ts->rejected_promise_list) { + JSRejectedPromiseEntry *rp = list_entry(el, JSRejectedPromiseEntry, link); + free_rp(rt, rp); + } + +#ifdef USE_WORKER + /* XXX: free port_list ? */ + js_free_message_pipe(ts->recv_pipe); + js_free_message_pipe(ts->send_pipe); +#endif +} + +static void js_dump_obj(JSContext *ctx, FILE *f, JSValueConst val) +{ + const char *str; + + str = JS_ToCString(ctx, val); + if (str) { + fprintf(f, "%s\n", str); + JS_FreeCString(ctx, str); + } else { + fprintf(f, "[exception]\n"); + } +} + +#define JS_DUMP_ERROR_MAX_CAUSE_DEPTH 10 + +static void js_std_dump_error1(JSContext *ctx, JSValueConst exception_val) +{ + JSValue val, current; + bool is_error; + int depth; + + current = JS_DupValue(ctx, exception_val); + for (depth = 0; ; depth++) { + is_error = JS_IsError(current); + js_dump_obj(ctx, stderr, current); + if (is_error) { + val = JS_GetPropertyStr(ctx, current, "stack"); + } else if (depth == 0) { + js_std_cmd(/*ErrorBackTrace*/2, ctx, &val); + } else { + val = JS_UNDEFINED; + } + if (!JS_IsUndefined(val)) { + js_dump_obj(ctx, stderr, val); + JS_FreeValue(ctx, val); + } + if (!is_error || depth >= JS_DUMP_ERROR_MAX_CAUSE_DEPTH) + break; + val = JS_GetPropertyStr(ctx, current, "cause"); + if (JS_IsUndefined(val)) { + JS_FreeValue(ctx, val); + break; + } + fputs("Caused by: ", stderr); + JS_FreeValue(ctx, current); + current = val; + } + JS_FreeValue(ctx, current); +} + +void js_std_dump_error(JSContext *ctx) +{ + JSValue exception_val; + + exception_val = JS_GetException(ctx); + js_std_dump_error1(ctx, exception_val); + JS_FreeValue(ctx, exception_val); +} + +static JSRejectedPromiseEntry *find_rejected_promise(JSContext *ctx, JSThreadState *ts, + JSValueConst promise) +{ + struct list_head *el; + + list_for_each(el, &ts->rejected_promise_list) { + JSRejectedPromiseEntry *rp = list_entry(el, JSRejectedPromiseEntry, link); + if (JS_IsSameValue(ctx, rp->promise, promise)) + return rp; + } + return NULL; +} + +void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise, + JSValueConst reason, + bool is_handled, void *opaque) +{ + + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + JSRejectedPromiseEntry *rp = find_rejected_promise(ctx, ts, promise); + + if (is_handled) { + /* the rejection is handled, so the entry can be removed if present */ + if (rp) + free_rp(rt, rp); + } else { + /* add a new entry if needed */ + if (!rp) { + rp = js_malloc_rt(rt, sizeof(*rp)); + if (rp) { + rp->promise = JS_DupValue(ctx, promise); + rp->reason = JS_DupValue(ctx, reason); + list_add_tail(&rp->link, &ts->rejected_promise_list); + } + } + } +} + +/* check if there are pending promise rejections. It must be done + asynchrously in case a rejected promise is handled later. Currently + we do it once the application is about to sleep. It could be done + more often if needed. */ +static void js_std_promise_rejection_check(JSContext *ctx) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + struct list_head *el; + + if (unlikely(!list_empty(&ts->rejected_promise_list))) { + list_for_each(el, &ts->rejected_promise_list) { + JSRejectedPromiseEntry *rp = list_entry(el, JSRejectedPromiseEntry, link); + fprintf(stderr, "Possibly unhandled promise rejection: "); + js_std_dump_error1(ctx, rp->reason); + fflush(stderr); + } + exit(1); + } +} + +/* main loop which calls the user JS callbacks */ +int js_std_loop(JSContext *ctx) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + JSContext *ctx1; + int err; + + for(;;) { + /* execute the pending jobs */ + for(;;) { + err = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1); + if (err <= 0) { + if (err < 0) + goto done; + break; + } + } + + js_std_promise_rejection_check(ctx); + + if (!ts->can_js_os_poll || js_os_poll(ctx)) + break; + } +done: + return JS_HasException(ctx); +} + +int js_std_loop_once(JSContext *ctx) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + JSContext *ctx1; + int err, min_delay; + + /* execute all pending jobs */ + for(;;) { + err = JS_ExecutePendingJob(rt, &ctx1); + if (err < 0) + return -2; /* error */ + if (err == 0) + break; + } + + /* run at most one expired timer */ + if (js_os_run_timers(rt, ctx, ts, &min_delay) < 0) + return -2; /* error in timer callback */ + + /* check if more work is pending */ + if (JS_IsJobPending(rt)) + return 0; /* more microtasks pending */ + + if (min_delay == 0) + return 0; /* timer ready to fire immediately */ + + if (min_delay > 0) + return min_delay; /* next timer delay in ms */ + + return -1; /* idle, no pending work */ +} + +/* Wait for a promise and execute pending jobs while waiting for + it. Return the promise result or JS_EXCEPTION in case of promise + rejection. */ +JSValue js_std_await(JSContext *ctx, JSValue obj) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = js_get_thread_state(rt); + JSValue ret; + int state; + + for(;;) { + state = JS_PromiseState(ctx, obj); + if (state == JS_PROMISE_FULFILLED) { + ret = JS_PromiseResult(ctx, obj); + JS_FreeValue(ctx, obj); + break; + } else if (state == JS_PROMISE_REJECTED) { + ret = JS_Throw(ctx, JS_PromiseResult(ctx, obj)); + JS_FreeValue(ctx, obj); + break; + } else if (state == JS_PROMISE_PENDING) { + JSContext *ctx1; + int err; + err = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1); + if (err < 0) { + js_std_dump_error(ctx1); + } + if (err == 0) + js_std_promise_rejection_check(ctx); + if (ts->can_js_os_poll) + js_os_poll(ctx); + } else { + /* not a promise */ + ret = obj; + break; + } + } + return ret; +} + +void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len, + int load_only) +{ + JSValue obj, val; + obj = JS_ReadObject(ctx, buf, buf_len, JS_READ_OBJ_BYTECODE); + if (JS_IsException(obj)) + goto exception; + if (load_only) { + if (JS_VALUE_GET_TAG(obj) == JS_TAG_MODULE) { + if (js_module_set_import_meta(ctx, obj, false, false) < 0) + goto exception; + } + JS_FreeValue(ctx, obj); + } else { + if (JS_VALUE_GET_TAG(obj) == JS_TAG_MODULE) { + if (JS_ResolveModule(ctx, obj) < 0) { + JS_FreeValue(ctx, obj); + goto exception; + } + if (js_module_set_import_meta(ctx, obj, false, true) < 0) + goto exception; + val = JS_EvalFunction(ctx, obj); + val = js_std_await(ctx, val); + } else { + val = JS_EvalFunction(ctx, obj); + } + if (JS_IsException(val)) { + exception: + js_std_dump_error(ctx); + exit(1); + } + JS_FreeValue(ctx, val); + } +} + +static JSValue js_bjson_read(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + uint8_t *buf; + uint64_t pos, len; + JSValue obj; + size_t size; + int flags; + + if (JS_ToIndex(ctx, &pos, argv[1])) + return JS_EXCEPTION; + if (JS_ToIndex(ctx, &len, argv[2])) + return JS_EXCEPTION; + if (JS_ToInt32(ctx, &flags, argv[3])) + return JS_EXCEPTION; + flags &= ~JS_READ_OBJ_SAB; + buf = JS_GetArrayBuffer(ctx, &size, argv[0]); + if (!buf) + return JS_EXCEPTION; + if (pos + len > size) + return JS_ThrowRangeError(ctx, "array buffer overflow"); + obj = JS_ReadObject(ctx, buf + pos, len, flags); + return obj; +} + +static JSValue js_bjson_write(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + size_t len; + uint8_t *buf; + JSValue array; + int flags; + + if (JS_ToInt32(ctx, &flags, argv[1])) + return JS_EXCEPTION; + flags &= ~JS_WRITE_OBJ_SAB; + buf = JS_WriteObject(ctx, &len, argv[0], flags); + if (!buf) + return JS_EXCEPTION; + array = JS_NewArrayBufferCopy(ctx, buf, len); + js_free(ctx, buf); + return array; +} + + +static const JSCFunctionListEntry js_bjson_funcs[] = { + JS_CFUNC_DEF("read", 4, js_bjson_read ), + JS_CFUNC_DEF("write", 2, js_bjson_write ), +#define DEF(x) JS_PROP_INT32_DEF(#x, JS_##x, JS_PROP_CONFIGURABLE) + DEF(READ_OBJ_BYTECODE), + DEF(READ_OBJ_REFERENCE), + DEF(WRITE_OBJ_BYTECODE), + DEF(WRITE_OBJ_REFERENCE), + DEF(WRITE_OBJ_STRIP_DEBUG), + DEF(WRITE_OBJ_STRIP_SOURCE), +#undef DEF +}; + +static int js_bjson_init(JSContext *ctx, JSModuleDef *m) +{ + return JS_SetModuleExportList(ctx, m, js_bjson_funcs, + countof(js_bjson_funcs)); +} + +JSModuleDef *js_init_module_bjson(JSContext *ctx, const char *module_name) +{ + JSModuleDef *m; + m = JS_NewCModule(ctx, module_name, js_bjson_init); + if (!m) + return NULL; + JS_AddModuleExportList(ctx, m, js_bjson_funcs, countof(js_bjson_funcs)); + return m; +} diff --git a/userland/qjs/source/quickjs-libc.h b/userland/qjs/source/quickjs-libc.h new file mode 100644 index 0000000..fd91a2f --- /dev/null +++ b/userland/qjs/source/quickjs-libc.h @@ -0,0 +1,87 @@ +/* + * QuickJS C library + * + * Copyright (c) 2017-2018 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef QUICKJS_LIBC_H +#define QUICKJS_LIBC_H + +#include +#include +#include +#include + +#include "quickjs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint8_t *JSLoadFileFunc(JSContext *ctx, size_t *pbuf_len, + const char *filename); + +JS_LIBC_EXTERN JSModuleDef *js_init_module_std(JSContext *ctx, + const char *module_name); +JS_LIBC_EXTERN JSModuleDef *js_init_module_os(JSContext *ctx, + const char *module_name); +JS_LIBC_EXTERN JSModuleDef *js_init_module_bjson(JSContext *ctx, + const char *module_name); +JS_LIBC_EXTERN void js_std_add_helpers(JSContext *ctx, int argc, char **argv); +JS_LIBC_EXTERN int js_std_loop(JSContext *ctx); +JS_LIBC_EXTERN int js_std_loop_once(JSContext *ctx); +JS_LIBC_EXTERN int js_std_poll_io(JSContext *ctx, int timeout_ms); +JS_LIBC_EXTERN JSValue js_std_await(JSContext *ctx, JSValue obj); +JS_LIBC_EXTERN void js_std_init_handlers(JSRuntime *rt); +JS_LIBC_EXTERN void js_std_free_handlers(JSRuntime *rt); +JS_LIBC_EXTERN void js_std_dump_error(JSContext *ctx); +JS_LIBC_EXTERN uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, + const char *filename); +JS_LIBC_EXTERN int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val, + bool use_realpath, bool is_main); +JS_LIBC_EXTERN JSModuleDef *js_module_loader(JSContext *ctx, + const char *module_name, void *opaque, + JSValueConst attributes); +// like js_module_loader but does not load .so objects and the file reader +// is pluggable; js_module_loader is implemented in terms of js_module_load +JS_LIBC_EXTERN JSModuleDef *js_module_load(JSContext *ctx, const char *module_name, + void *opaque, JSValueConst attributes, + JSLoadFileFunc *load_file); +JS_LIBC_EXTERN int js_module_check_attributes(JSContext *ctx, void *opaque, + JSValueConst attributes); +JS_LIBC_EXTERN void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, + size_t buf_len, int flags); +JS_LIBC_EXTERN void js_std_promise_rejection_tracker(JSContext *ctx, + JSValueConst promise, + JSValueConst reason, + bool is_handled, + void *opaque); +// Defaults to JS_NewRuntime, no-op if compiled without worker support. +// Call before creating the first worker thread. +JS_LIBC_EXTERN void js_std_set_worker_new_runtime_func(JSRuntime *(*func)(void)); +// Defaults to JS_NewContext, no-op if compiled without worker support. +// Call before creating the first worker thread. +JS_LIBC_EXTERN void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt)); + +#ifdef __cplusplus +} /* extern "C" { */ +#endif + +#endif /* QUICKJS_LIBC_H */ diff --git a/userland/qjs/source/quickjs-opcode.h b/userland/qjs/source/quickjs-opcode.h new file mode 100644 index 0000000..ec2a5ad --- /dev/null +++ b/userland/qjs/source/quickjs-opcode.h @@ -0,0 +1,377 @@ +/* + * QuickJS opcode definitions + * + * Copyright (c) 2017-2018 Fabrice Bellard + * Copyright (c) 2017-2018 Charlie Gordon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifdef FMT +FMT(none) +FMT(none_int) +FMT(none_loc) +FMT(none_arg) +FMT(none_var_ref) +FMT(u8) +FMT(i8) +FMT(loc8) +FMT(const8) +FMT(label8) +FMT(u16) +FMT(i16) +FMT(label16) +FMT(npop) +FMT(npopx) +FMT(npop_u16) +FMT(loc) +FMT(arg) +FMT(var_ref) +FMT(u32) +FMT(u32x2) +FMT(i32) +FMT(const) +FMT(label) +FMT(atom) +FMT(atom_u8) +FMT(atom_u16) +FMT(atom_label_u8) +FMT(atom_label_u16) +FMT(label_u16) +#undef FMT +#endif /* FMT */ + +#ifdef DEF + +#ifndef def +#define def(id, size, n_pop, n_push, f) DEF(id, size, n_pop, n_push, f) +#endif + +DEF(invalid, 1, 0, 0, none) /* never emitted */ + +/* push values */ +DEF( push_i32, 5, 0, 1, i32) +DEF( push_const, 5, 0, 1, const) +DEF( fclosure, 5, 0, 1, const) /* must follow push_const */ +DEF(push_atom_value, 5, 0, 1, atom) +DEF( private_symbol, 5, 0, 1, atom) +DEF( undefined, 1, 0, 1, none) +DEF( null, 1, 0, 1, none) +DEF( push_this, 1, 0, 1, none) /* only used at the start of a function */ +DEF( push_false, 1, 0, 1, none) +DEF( push_true, 1, 0, 1, none) +DEF( object, 1, 0, 1, none) +DEF( special_object, 2, 0, 1, u8) /* only used at the start of a function */ +DEF( rest, 3, 0, 1, u16) /* only used at the start of a function */ + +DEF( drop, 1, 1, 0, none) /* a -> */ +DEF( nip, 1, 2, 1, none) /* a b -> b */ +DEF( nip1, 1, 3, 2, none) /* a b c -> b c */ +DEF( dup, 1, 1, 2, none) /* a -> a a */ +DEF( dup1, 1, 2, 3, none) /* a b -> a a b */ +DEF( dup2, 1, 2, 4, none) /* a b -> a b a b */ +DEF( dup3, 1, 3, 6, none) /* a b c -> a b c a b c */ +DEF( insert2, 1, 2, 3, none) /* obj a -> a obj a (dup_x1) */ +DEF( insert3, 1, 3, 4, none) /* obj prop a -> a obj prop a (dup_x2) */ +DEF( insert4, 1, 4, 5, none) /* this obj prop a -> a this obj prop a */ +DEF( perm3, 1, 3, 3, none) /* obj a b -> a obj b */ +DEF( perm4, 1, 4, 4, none) /* obj prop a b -> a obj prop b */ +DEF( perm5, 1, 5, 5, none) /* this obj prop a b -> a this obj prop b */ +DEF( swap, 1, 2, 2, none) /* a b -> b a */ +DEF( swap2, 1, 4, 4, none) /* a b c d -> c d a b */ +DEF( rot3l, 1, 3, 3, none) /* x a b -> a b x */ +DEF( rot3r, 1, 3, 3, none) /* a b x -> x a b */ +DEF( rot4l, 1, 4, 4, none) /* x a b c -> a b c x */ +DEF( rot5l, 1, 5, 5, none) /* x a b c d -> a b c d x */ + +DEF(call_constructor, 3, 2, 1, npop) /* func new.target args -> ret. arguments are not counted in n_pop */ +DEF( call, 3, 1, 1, npop) /* arguments are not counted in n_pop */ +DEF( tail_call, 3, 1, 0, npop) /* arguments are not counted in n_pop */ +DEF( call_method, 3, 2, 1, npop) /* arguments are not counted in n_pop */ +DEF(tail_call_method, 3, 2, 0, npop) /* arguments are not counted in n_pop */ +DEF( array_from, 3, 0, 1, npop) /* arguments are not counted in n_pop */ +DEF( apply, 3, 3, 1, u16) +DEF( return, 1, 1, 0, none) +DEF( return_undef, 1, 0, 0, none) +DEF(check_ctor_return, 1, 1, 2, none) +DEF( check_ctor, 1, 0, 0, none) +DEF( init_ctor, 1, 0, 1, none) +DEF( check_brand, 1, 2, 2, none) /* this_obj func -> this_obj func */ +DEF( add_brand, 1, 2, 0, none) /* this_obj home_obj -> */ +DEF( return_async, 1, 1, 0, none) +DEF( throw, 1, 1, 0, none) +DEF( throw_error, 6, 0, 0, atom_u8) +DEF( eval, 5, 1, 1, npop_u16) /* func args... -> ret_val */ +DEF( apply_eval, 3, 2, 1, u16) /* func array -> ret_eval */ +DEF( regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a + bytecode string */ +DEF( get_super, 1, 1, 1, none) +DEF( import, 1, 2, 1, none) /* dynamic module import */ + +DEF( get_var_undef, 5, 0, 1, atom) /* push undefined if the variable does not exist */ +DEF( get_var, 5, 0, 1, atom) /* throw an exception if the variable does not exist */ +DEF( put_var, 5, 1, 0, atom) /* must come after get_var */ +DEF( put_var_init, 5, 1, 0, atom) /* must come after put_var. Used to initialize a global lexical variable */ + +DEF( get_ref_value, 1, 2, 3, none) +DEF( put_ref_value, 1, 3, 0, none) + +DEF( define_var, 6, 0, 0, atom_u8) +DEF(check_define_var, 6, 0, 0, atom_u8) +DEF( define_func, 6, 1, 0, atom_u8) + +// order matters, see IC counterparts +DEF( get_field, 5, 1, 1, atom) +DEF( get_field2, 5, 1, 2, atom) +DEF( put_field, 5, 2, 0, atom) + +DEF( get_private_field, 1, 2, 1, none) /* obj prop -> value */ +DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */ +DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */ +DEF( get_array_el, 1, 2, 1, none) +DEF( get_array_el2, 1, 2, 2, none) /* obj prop -> obj value */ +DEF( put_array_el, 1, 3, 0, none) +DEF(get_super_value, 1, 3, 1, none) /* this obj prop -> value */ +DEF(put_super_value, 1, 4, 0, none) /* this obj prop value -> */ +DEF( define_field, 5, 2, 1, atom) +DEF( set_name, 5, 1, 1, atom) +DEF(set_name_computed, 1, 2, 2, none) +DEF( set_proto, 1, 2, 1, none) +DEF(set_home_object, 1, 2, 2, none) +DEF(define_array_el, 1, 3, 2, none) +DEF( append, 1, 3, 2, none) /* append enumerated object, update length */ +DEF(copy_data_properties, 2, 3, 3, u8) +DEF( define_method, 6, 2, 1, atom_u8) +DEF(define_method_computed, 2, 3, 1, u8) /* must come after define_method */ +DEF( define_class, 6, 2, 2, atom_u8) /* parent ctor -> ctor proto */ +DEF( define_class_computed, 6, 3, 3, atom_u8) /* field_name parent ctor -> field_name ctor proto (class with computed name) */ + +DEF( get_loc, 3, 0, 1, loc) +DEF( put_loc, 3, 1, 0, loc) /* must come after get_loc */ +DEF( set_loc, 3, 1, 1, loc) /* must come after put_loc */ +DEF( get_arg, 3, 0, 1, arg) +DEF( put_arg, 3, 1, 0, arg) /* must come after get_arg */ +DEF( set_arg, 3, 1, 1, arg) /* must come after put_arg */ +DEF( get_var_ref, 3, 0, 1, var_ref) +DEF( put_var_ref, 3, 1, 0, var_ref) /* must come after get_var_ref */ +DEF( set_var_ref, 3, 1, 1, var_ref) /* must come after put_var_ref */ +DEF(set_loc_uninitialized, 3, 0, 0, loc) +DEF( get_loc_check, 3, 0, 1, loc) +DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */ +DEF( put_loc_check_init, 3, 1, 0, loc) +DEF(get_var_ref_check, 3, 0, 1, var_ref) +DEF(put_var_ref_check, 3, 1, 0, var_ref) /* must come after get_var_ref_check */ +DEF(put_var_ref_check_init, 3, 1, 0, var_ref) +DEF( close_loc, 3, 0, 0, loc) +DEF( if_false, 5, 1, 0, label) +DEF( if_true, 5, 1, 0, label) /* must come after if_false */ +DEF( goto, 5, 0, 0, label) /* must come after if_true */ +DEF( catch, 5, 0, 1, label) +DEF( gosub, 5, 0, 0, label) /* used to execute the finally block */ +DEF( ret, 1, 1, 0, none) /* used to return from the finally block */ +DEF( nip_catch, 1, 2, 1, none) /* catch ... a -> a */ + +DEF( check_object, 1, 1, 1, none) +DEF( to_object, 1, 1, 1, none) +//DEF( to_string, 1, 1, 1, none) +DEF( to_propkey, 1, 1, 1, none) +DEF( to_propkey2, 1, 2, 2, none) + +DEF( with_get_var, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ +DEF( with_put_var, 10, 2, 1, atom_label_u8) /* must be in the same order as scope_xxx */ +DEF(with_delete_var, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ +DEF( with_make_ref, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ +DEF( with_get_ref, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ +DEF(with_get_ref_undef, 10, 1, 0, atom_label_u8) + +DEF( make_loc_ref, 7, 0, 2, atom_u16) +DEF( make_arg_ref, 7, 0, 2, atom_u16) +DEF(make_var_ref_ref, 7, 0, 2, atom_u16) +DEF( make_var_ref, 5, 0, 2, atom) + +DEF( for_in_start, 1, 1, 1, none) +DEF( for_of_start, 1, 1, 3, none) +DEF(for_await_of_start, 1, 1, 3, none) +DEF( for_in_next, 1, 1, 3, none) +DEF( for_of_next, 2, 3, 5, u8) +DEF(iterator_get_value_done, 1, 1, 2, none) +DEF( iterator_close, 1, 3, 0, none) +DEF( iterator_next, 1, 4, 4, none) +DEF( iterator_call, 2, 4, 5, u8) +DEF( initial_yield, 1, 0, 0, none) +DEF( yield, 1, 1, 2, none) +DEF( yield_star, 1, 1, 2, none) +DEF(async_yield_star, 1, 1, 2, none) +DEF( await, 1, 1, 1, none) + +/* arithmetic/logic operations */ +DEF( neg, 1, 1, 1, none) +DEF( plus, 1, 1, 1, none) +DEF( dec, 1, 1, 1, none) +DEF( inc, 1, 1, 1, none) +DEF( post_dec, 1, 1, 2, none) +DEF( post_inc, 1, 1, 2, none) +DEF( dec_loc, 2, 0, 0, loc8) +DEF( inc_loc, 2, 0, 0, loc8) +DEF( add_loc, 2, 1, 0, loc8) +DEF( not, 1, 1, 1, none) +DEF( lnot, 1, 1, 1, none) +DEF( typeof, 1, 1, 1, none) +DEF( delete, 1, 2, 1, none) +DEF( delete_var, 5, 0, 1, atom) + +/* warning: order matters (see js_parse_assign_expr) */ +DEF( mul, 1, 2, 1, none) +DEF( div, 1, 2, 1, none) +DEF( mod, 1, 2, 1, none) +DEF( add, 1, 2, 1, none) +DEF( sub, 1, 2, 1, none) +DEF( shl, 1, 2, 1, none) +DEF( sar, 1, 2, 1, none) +DEF( shr, 1, 2, 1, none) +DEF( and, 1, 2, 1, none) +DEF( xor, 1, 2, 1, none) +DEF( or, 1, 2, 1, none) +DEF( pow, 1, 2, 1, none) + +DEF( lt, 1, 2, 1, none) +DEF( lte, 1, 2, 1, none) +DEF( gt, 1, 2, 1, none) +DEF( gte, 1, 2, 1, none) +DEF( instanceof, 1, 2, 1, none) +DEF( in, 1, 2, 1, none) +DEF( eq, 1, 2, 1, none) +DEF( neq, 1, 2, 1, none) +DEF( strict_eq, 1, 2, 1, none) +DEF( strict_neq, 1, 2, 1, none) +DEF(is_undefined_or_null, 1, 1, 1, none) +DEF( private_in, 1, 2, 1, none) +DEF(push_bigint_i32, 5, 0, 1, i32) +DEF( using_dispose_init, 1, 0, 1, none) +DEF( using_dispose, 3, 1, 1, loc) +DEF(using_dispose_async, 3, 0, 1, loc) +DEF(using_dispose_merge, 1, 2, 1, none) +DEF( using_dispose_end, 1, 1, 0, none) +DEF( using_check, 2, 1, 2, u8) +/* must be the last non short and non temporary opcode */ +DEF( nop, 1, 0, 0, none) + +/* temporary opcodes: never emitted in the final bytecode */ + +def( enter_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */ +def( leave_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */ + +def( label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */ + +def(scope_get_var_undef, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ +def( scope_get_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ +def( scope_put_var, 7, 1, 0, atom_u16) /* emitted in phase 1, removed in phase 2 */ +def(scope_delete_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ +def( scope_make_ref, 11, 0, 2, atom_label_u16) /* emitted in phase 1, removed in phase 2 */ +def( scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */ +def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */ +def(scope_get_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */ +def(scope_get_private_field2, 7, 1, 2, atom_u16) /* obj -> obj value, emitted in phase 1, removed in phase 2 */ +def(scope_put_private_field, 7, 2, 0, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */ +def(scope_in_private_field, 7, 1, 1, atom_u16) /* obj -> res emitted in phase 1, removed in phase 2 */ +def(get_field_opt_chain, 5, 1, 1, atom) /* emitted in phase 1, removed in phase 2 */ +def(get_array_el_opt_chain, 1, 2, 1, none) /* emitted in phase 1, removed in phase 2 */ +def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */ + +def( dispose_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */ + +def( source_loc, 9, 0, 0, u32x2) /* emitted in phase 1, removed in phase 3 */ + +DEF( push_minus1, 1, 0, 1, none_int) +DEF( push_0, 1, 0, 1, none_int) +DEF( push_1, 1, 0, 1, none_int) +DEF( push_2, 1, 0, 1, none_int) +DEF( push_3, 1, 0, 1, none_int) +DEF( push_4, 1, 0, 1, none_int) +DEF( push_5, 1, 0, 1, none_int) +DEF( push_6, 1, 0, 1, none_int) +DEF( push_7, 1, 0, 1, none_int) +DEF( push_i8, 2, 0, 1, i8) +DEF( push_i16, 3, 0, 1, i16) +DEF( push_const8, 2, 0, 1, const8) +DEF( fclosure8, 2, 0, 1, const8) /* must follow push_const8 */ +DEF(push_empty_string, 1, 0, 1, none) + +DEF( get_loc8, 2, 0, 1, loc8) +DEF( put_loc8, 2, 1, 0, loc8) +DEF( set_loc8, 2, 1, 1, loc8) + +DEF( get_loc0_loc1, 1, 0, 2, none_loc) +DEF( get_loc0, 1, 0, 1, none_loc) +DEF( get_loc1, 1, 0, 1, none_loc) +DEF( get_loc2, 1, 0, 1, none_loc) +DEF( get_loc3, 1, 0, 1, none_loc) +DEF( put_loc0, 1, 1, 0, none_loc) +DEF( put_loc1, 1, 1, 0, none_loc) +DEF( put_loc2, 1, 1, 0, none_loc) +DEF( put_loc3, 1, 1, 0, none_loc) +DEF( set_loc0, 1, 1, 1, none_loc) +DEF( set_loc1, 1, 1, 1, none_loc) +DEF( set_loc2, 1, 1, 1, none_loc) +DEF( set_loc3, 1, 1, 1, none_loc) +DEF( get_arg0, 1, 0, 1, none_arg) +DEF( get_arg1, 1, 0, 1, none_arg) +DEF( get_arg2, 1, 0, 1, none_arg) +DEF( get_arg3, 1, 0, 1, none_arg) +DEF( put_arg0, 1, 1, 0, none_arg) +DEF( put_arg1, 1, 1, 0, none_arg) +DEF( put_arg2, 1, 1, 0, none_arg) +DEF( put_arg3, 1, 1, 0, none_arg) +DEF( set_arg0, 1, 1, 1, none_arg) +DEF( set_arg1, 1, 1, 1, none_arg) +DEF( set_arg2, 1, 1, 1, none_arg) +DEF( set_arg3, 1, 1, 1, none_arg) +DEF( get_var_ref0, 1, 0, 1, none_var_ref) +DEF( get_var_ref1, 1, 0, 1, none_var_ref) +DEF( get_var_ref2, 1, 0, 1, none_var_ref) +DEF( get_var_ref3, 1, 0, 1, none_var_ref) +DEF( put_var_ref0, 1, 1, 0, none_var_ref) +DEF( put_var_ref1, 1, 1, 0, none_var_ref) +DEF( put_var_ref2, 1, 1, 0, none_var_ref) +DEF( put_var_ref3, 1, 1, 0, none_var_ref) +DEF( set_var_ref0, 1, 1, 1, none_var_ref) +DEF( set_var_ref1, 1, 1, 1, none_var_ref) +DEF( set_var_ref2, 1, 1, 1, none_var_ref) +DEF( set_var_ref3, 1, 1, 1, none_var_ref) + +DEF( get_length, 1, 1, 1, none) + +DEF( if_false8, 2, 1, 0, label8) +DEF( if_true8, 2, 1, 0, label8) /* must come after if_false8 */ +DEF( goto8, 2, 0, 0, label8) /* must come after if_true8 */ +DEF( goto16, 3, 0, 0, label16) + +DEF( call0, 1, 1, 1, npopx) +DEF( call1, 1, 1, 1, npopx) +DEF( call2, 1, 1, 1, npopx) +DEF( call3, 1, 1, 1, npopx) + +DEF( is_undefined, 1, 1, 1, none) +DEF( is_null, 1, 1, 1, none) +DEF(typeof_is_undefined, 1, 1, 1, none) +DEF( typeof_is_function, 1, 1, 1, none) + +#undef DEF +#undef def +#endif /* DEF */ diff --git a/userland/qjs/source/quickjs.c b/userland/qjs/source/quickjs.c new file mode 100644 index 0000000..8cbc85e --- /dev/null +++ b/userland/qjs/source/quickjs.c @@ -0,0 +1,65028 @@ +/* + * QuickJS Javascript Engine + * + * Copyright (c) 2017-2026 Fabrice Bellard + * Copyright (c) 2017-2025 Charlie Gordon + * Copyright (c) 2023-2026 Ben Noordhuis + * Copyright (c) 2023-2026 Saúl Ibarra Corretgé + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#if !defined(_MSC_VER) +#include +#if defined(_WIN32) +#include +#endif +#endif +#if defined(_WIN32) +#include +#endif +#include +#include + +#include "cutils.h" +#include "list.h" +#include "quickjs.h" +#include "libregexp.h" +#include "dtoa.h" + +#if defined(EMSCRIPTEN) || defined(_MSC_VER) +#define DIRECT_DISPATCH 0 +#else +#define DIRECT_DISPATCH 1 +#endif + +#if defined(__APPLE__) +#define MALLOC_OVERHEAD 0 +#else +#define MALLOC_OVERHEAD 8 +#endif + +#if defined(__NEWLIB__) +#define NO_TM_GMTOFF +#endif + +#if defined(__sun) +#include +#define NO_TM_GMTOFF +#endif + +// atomic_store etc. are completely busted in recent versions of tcc; +// somehow the compiler forgets to load |ptr| into %rdi when calling +// the __atomic_*() helpers in its lib/stdatomic.c and lib/atomic.S +#if !defined(__TINYC__) && !defined(EMSCRIPTEN) && !defined(__wasi__) && !__STDC_NO_ATOMICS__ && !defined(__DJGPP) +#include "quickjs-c-atomics.h" +#define CONFIG_ATOMICS +#endif + +#ifndef __GNUC__ +#define __extension__ +#endif + +#ifndef NDEBUG +#define ENABLE_DUMPS +#endif + +//#define FORCE_GC_AT_MALLOC /* test the GC by forcing it before each object allocation */ + +#define check_dump_flag(rt, flag) ((rt->dump_flags & (flag +0)) == (flag +0)) + +#define STRINGIFY_(x) #x +#define STRINGIFY(x) STRINGIFY_(x) + +#define QJS_VERSION_STRING \ + STRINGIFY(QJS_VERSION_MAJOR) "." STRINGIFY(QJS_VERSION_MINOR) "." STRINGIFY(QJS_VERSION_PATCH) QJS_VERSION_SUFFIX + +const char* JS_GetVersion(void) { + return QJS_VERSION_STRING; +} + +#undef STRINFIGY_ +#undef STRINGIFY + +static inline JSValueConst *vc(JSValue *vals) +{ + return (JSValueConst *)vals; +} + +static inline JSValue unsafe_unconst(JSValueConst v) +{ +#ifdef JS_CHECK_JSVALUE + return (JSValue)v; +#else + return v; +#endif +} + +static inline JSValueConst safe_const(JSValue v) +{ +#ifdef JS_CHECK_JSVALUE + return (JSValueConst)v; +#else + return v; +#endif +} + +enum { + /* classid tag */ /* union usage | properties */ + JS_CLASS_OBJECT = 1, /* must be first */ + JS_CLASS_ARRAY, /* u.array | length */ + JS_CLASS_ERROR, + JS_CLASS_NUMBER, /* u.object_data */ + JS_CLASS_STRING, /* u.object_data */ + JS_CLASS_BOOLEAN, /* u.object_data */ + JS_CLASS_SYMBOL, /* u.object_data */ + JS_CLASS_ARGUMENTS, /* u.array | length */ + JS_CLASS_MAPPED_ARGUMENTS, /* | length */ + JS_CLASS_DATE, /* u.object_data */ + JS_CLASS_MODULE_NS, + JS_CLASS_C_FUNCTION, /* u.cfunc */ + JS_CLASS_BYTECODE_FUNCTION, /* u.func */ + JS_CLASS_BOUND_FUNCTION, /* u.bound_function */ + JS_CLASS_C_FUNCTION_DATA, /* u.c_function_data_record */ + JS_CLASS_C_CLOSURE, /* u.c_closure_record */ + JS_CLASS_GENERATOR_FUNCTION, /* u.func */ + JS_CLASS_FOR_IN_ITERATOR, /* u.for_in_iterator */ + JS_CLASS_REGEXP, /* u.regexp */ + JS_CLASS_ARRAY_BUFFER, /* u.array_buffer */ + JS_CLASS_SHARED_ARRAY_BUFFER, /* u.array_buffer */ + JS_CLASS_UINT8C_ARRAY, /* u.array (typed_array) */ + JS_CLASS_INT8_ARRAY, /* u.array (typed_array) */ + JS_CLASS_UINT8_ARRAY, /* u.array (typed_array) */ + JS_CLASS_INT16_ARRAY, /* u.array (typed_array) */ + JS_CLASS_UINT16_ARRAY, /* u.array (typed_array) */ + JS_CLASS_INT32_ARRAY, /* u.array (typed_array) */ + JS_CLASS_UINT32_ARRAY, /* u.array (typed_array) */ + JS_CLASS_BIG_INT64_ARRAY, /* u.array (typed_array) */ + JS_CLASS_BIG_UINT64_ARRAY, /* u.array (typed_array) */ + JS_CLASS_FLOAT16_ARRAY, /* u.array (typed_array) */ + JS_CLASS_FLOAT32_ARRAY, /* u.array (typed_array) */ + JS_CLASS_FLOAT64_ARRAY, /* u.array (typed_array) */ + JS_CLASS_DATAVIEW, /* u.typed_array */ + JS_CLASS_BIG_INT, /* u.object_data */ + JS_CLASS_MAP, /* u.map_state */ + JS_CLASS_SET, /* u.map_state */ + JS_CLASS_WEAKMAP, /* u.map_state */ + JS_CLASS_WEAKSET, /* u.map_state */ + JS_CLASS_ITERATOR, + JS_CLASS_ITERATOR_CONCAT, /* u.iterator_concat_data */ + JS_CLASS_ITERATOR_HELPER, /* u.iterator_helper_data */ + JS_CLASS_ITERATOR_WRAP, /* u.iterator_wrap_data */ + JS_CLASS_MAP_ITERATOR, /* u.map_iterator_data */ + JS_CLASS_SET_ITERATOR, /* u.map_iterator_data */ + JS_CLASS_ARRAY_ITERATOR, /* u.array_iterator_data */ + JS_CLASS_STRING_ITERATOR, /* u.array_iterator_data */ + JS_CLASS_REGEXP_STRING_ITERATOR, /* u.regexp_string_iterator_data */ + JS_CLASS_GENERATOR, /* u.generator_data */ + JS_CLASS_DISPOSABLE_STACK, + JS_CLASS_PROXY, /* u.proxy_data */ + JS_CLASS_PROMISE, /* u.promise_data */ + JS_CLASS_PROMISE_RESOLVE_FUNCTION, /* u.promise_function_data */ + JS_CLASS_PROMISE_REJECT_FUNCTION, /* u.promise_function_data */ + JS_CLASS_ASYNC_FUNCTION, /* u.func */ + JS_CLASS_ASYNC_FUNCTION_RESOLVE, /* u.async_function_data */ + JS_CLASS_ASYNC_FUNCTION_REJECT, /* u.async_function_data */ + JS_CLASS_ASYNC_FROM_SYNC_ITERATOR, /* u.async_from_sync_iterator_data */ + JS_CLASS_ASYNC_GENERATOR_FUNCTION, /* u.func */ + JS_CLASS_ASYNC_GENERATOR, /* u.async_generator_data */ + JS_CLASS_ASYNC_DISPOSABLE_STACK, + JS_CLASS_WEAK_REF, + JS_CLASS_FINALIZATION_REGISTRY, + JS_CLASS_DOM_EXCEPTION, + JS_CLASS_CALL_SITE, + JS_CLASS_RAWJSON, + + JS_CLASS_INIT_COUNT, /* last entry for predefined classes */ +}; + +/* number of typed array types */ +#define JS_TYPED_ARRAY_COUNT (JS_CLASS_FLOAT64_ARRAY - JS_CLASS_UINT8C_ARRAY + 1) +static uint8_t const typed_array_size_log2[JS_TYPED_ARRAY_COUNT]; +#define typed_array_size_log2(classid) (typed_array_size_log2[(classid)- JS_CLASS_UINT8C_ARRAY]) + +typedef enum JSErrorEnum { + JS_EVAL_ERROR, + JS_RANGE_ERROR, + JS_REFERENCE_ERROR, + JS_SYNTAX_ERROR, + JS_TYPE_ERROR, + JS_URI_ERROR, + JS_INTERNAL_ERROR, + JS_AGGREGATE_ERROR, + JS_SUPPRESSED_ERROR, + + JS_NATIVE_ERROR_COUNT, /* number of different NativeError objects */ + JS_PLAIN_ERROR = JS_NATIVE_ERROR_COUNT +} JSErrorEnum; + +#define JS_MAX_LOCAL_VARS 65535 +#define JS_STACK_SIZE_MAX 65534 +#define JS_STRING_LEN_MAX ((1 << 30) - 1) +// 1,024 bytes is about the cutoff point where it starts getting +// more profitable to ref slice than to copy +#define JS_STRING_SLICE_LEN_MAX 1024 // in bytes + +/* strings <= this length are not concatenated using ropes. if too + small, the rope memory overhead becomes high. */ +#define JS_STRING_ROPE_SHORT_LEN 512 +/* specific threshold for initial rope use */ +#define JS_STRING_ROPE_SHORT2_LEN 8192 +/* rope depth at which we rebalance */ +#define JS_STRING_ROPE_MAX_DEPTH 60 + +#define __exception __attribute__((warn_unused_result)) + +typedef struct JSShape JSShape; +typedef struct JSString JSString; +typedef struct JSString JSAtomStruct; +typedef struct JSStringRope JSStringRope; + +#define JS_VALUE_GET_OBJ(v) ((JSObject *)JS_VALUE_GET_PTR(v)) +#define JS_VALUE_GET_STRING(v) ((JSString *)JS_VALUE_GET_PTR(v)) +#define JS_VALUE_GET_STRING_ROPE(v) ((JSStringRope *)JS_VALUE_GET_PTR(v)) + +typedef enum { + JS_GC_PHASE_NONE, + JS_GC_PHASE_DECREF, + JS_GC_PHASE_REMOVE_CYCLES, +} JSGCPhaseEnum; + +typedef struct JSMallocState { + size_t malloc_count; + size_t malloc_size; + size_t malloc_limit; + void *opaque; /* user opaque */ +} JSMallocState; + +/* Small-block "arena" allocator. + js_{malloc,free,realloc,calloc}_rt serve allocations up to ~512 + bytes from size-classed 4KB arenas carved out of the underlying + JSMallocFunctions allocator, so the backing allocator (system malloc, + mimalloc, ...) sees roughly one request per arena refill instead of one per + object. */ + +#define JS_ARENA_ALIGN 8 +#define JS_ARENA_SIZE 4096 +#define JS_ARENA_BLOCK_SIZE_COUNT 31 +#define JS_ARENA_MAX_SMALL_SIZE 512 +#define JS_ARENA_FREE_NIL 0xffff + +#if defined(__SANITIZE_ADDRESS__) || defined(FORCE_GC_AT_MALLOC) +/* Route every allocation through the backing malloc so each block is seen + individually: ASan can then poison a freed block, and a GC-stress build + (FORCE_GC_AT_MALLOC) exposes prematurely-freed objects instead of the pool + silently recycling them. */ +#define JS_ARENA_LARGE_BLOCKS_ONLY 1 +#else +#define JS_ARENA_LARGE_BLOCKS_ONLY 0 +#endif + +/* 8-byte header preceding every user allocation. It carries the allocator + bookkeeping (block_idx/free_next + block_size_idx) and, the + GC/refcount fields (gc_obj_type/mark/ref_count) that would otherwise sit in + the object body. The 8-byte size keeps user_data JS_ARENA_ALIGN-aligned. */ +typedef struct JSMallocBlockHeader { + union { + uint16_t block_idx; /* JS_ARENA_FREE_NIL => large or zero-size block */ + uint16_t free_next; /* next free block index while on a free list */ + } u; + uint8_t block_size_idx; + /* GC/refcount header merged into the allocator header: + the object body keeps only JSGCObjectHeader.link (no ref_count/flags). */ + uint8_t gc_obj_type : 7; /* JSGCObjectTypeEnum for GC objects */ + uint8_t mark : 1; /* used by the cycle collector */ + int ref_count; + _Alignas(JS_ARENA_ALIGN) uint8_t user_data[]; +} JSMallocBlockHeader; + +typedef struct JSArena { + struct list_head free_link; /* in free_arena_list[idx] while not full */ + struct list_head link; /* in arena_list[idx] for the whole lifetime */ + uint8_t block_size_idx; + uint16_t n_used_blocks; + uint16_t n_blocks; + uint16_t first_free_block; /* JS_ARENA_FREE_NIL if none */ + _Alignas(JS_ARENA_ALIGN) uint8_t blocks[]; +} JSArena; + +typedef struct JSArenaState { + struct list_head arena_list[JS_ARENA_BLOCK_SIZE_COUNT]; + struct list_head free_arena_list[JS_ARENA_BLOCK_SIZE_COUNT]; + _Alignas(JS_ARENA_ALIGN) uint8_t zero_size_block[sizeof(JSMallocBlockHeader)]; +} JSArenaState; + +typedef struct JSRuntimeFinalizerState { + struct JSRuntimeFinalizerState *next; + JSRuntimeFinalizer *finalizer; + void *arg; +} JSRuntimeFinalizerState; + +typedef struct JSValueLink { + struct JSValueLink *next; + JSValueConst value; +} JSValueLink; + +typedef struct JSClass { + uint32_t class_id; /* 0 means free entry */ + JSAtom class_name; + JSClassFinalizer *finalizer; + JSClassGCMark *gc_mark; + JSClassCall *call; + /* pointers for exotic behavior, can be NULL if none are present */ + const JSClassExoticMethods *exotic; +} JSClass; + +struct JSRuntime { + JSMallocFunctions mf; + JSMallocState malloc_state; + JSArenaState arena_state; + const char *rt_info; + + int atom_hash_size; /* power of two */ + int atom_count; + int atom_size; + int atom_count_resize; /* resize hash table at this count */ + uint32_t *atom_hash; + JSAtomStruct **atom_array; + int atom_free_index; /* 0 = none */ + + JSClassID js_class_id_alloc; /* counter for user defined classes */ + int class_count; /* size of class_array */ + JSClass *class_array; + + struct list_head context_list; /* list of JSContext.link */ + /* list of JSGCObjectHeader.link. List of allocated GC objects (used + by the garbage collector) */ + struct list_head gc_obj_list; + /* list of JSGCObjectHeader.link. Used during JS_FreeValueRT() */ + struct list_head gc_zero_ref_count_list; + struct list_head tmp_obj_list; /* used during GC */ + JSGCPhaseEnum gc_phase : 8; + size_t malloc_gc_threshold; +#ifdef ENABLE_DUMPS // JS_DUMP_LEAKS + struct list_head string_list; /* list of JSString.link */ +#endif + /* stack limitation */ + uintptr_t stack_size; /* in bytes, 0 if no limit */ + uintptr_t stack_top; + uintptr_t stack_limit; /* lower stack limit */ + + JSValue current_exception; + /* true if inside an out of memory error, to avoid recursing */ + bool in_out_of_memory; + /* true if inside build_backtrace, to avoid recursing */ + bool in_build_stack_trace; + /* true if inside JS_FreeRuntime */ + bool in_free; + + struct JSStackFrame *current_stack_frame; + + JSInterruptHandler *interrupt_handler; + void *interrupt_opaque; + + JSPromiseHook *promise_hook; + void *promise_hook_opaque; + // for smuggling the parent promise from js_promise_then + // to js_promise_constructor + JSValueLink *parent_promise; + + JSHostPromiseRejectionTracker *host_promise_rejection_tracker; + void *host_promise_rejection_tracker_opaque; + + struct list_head job_list; /* list of JSJobEntry.link */ + + bool module_normalize_has_attr; + union { + JSModuleNormalizeFunc *module_normalize_func; + JSModuleNormalizeFunc2 *module_normalize_func2; + } normalize_u; + bool module_loader_has_attr; + union { + JSModuleLoaderFunc *module_loader_func; + JSModuleLoaderFunc2 *module_loader_func2; + } u; + JSModuleCheckSupportedImportAttributes *module_check_attrs; + void *module_loader_opaque; + JSDynamicImportFunc *dynamic_import; + void *dynamic_import_opaque; + /* timestamp for internal use in module evaluation */ + int64_t module_async_evaluation_next_timestamp; + + /* used to allocate, free and clone SharedArrayBuffers */ + JSSharedArrayBufferFunctions sab_funcs; + + bool can_block; /* true if Atomics.wait can block */ + uint32_t dump_flags : 24; + + /* Shape hash table */ + int shape_hash_bits; + int shape_hash_size; + int shape_hash_count; /* number of hashed shapes */ + JSShape **shape_hash; + void *user_opaque; + void *libc_opaque; + JSRuntimeFinalizerState *finalizers; +}; + +typedef struct JSStackFrame { + struct JSStackFrame *prev_frame; /* NULL if first stack frame */ + JSValue cur_func; /* current function, JS_UNDEFINED if the frame is detached */ + JSValue *arg_buf; /* arguments */ + JSValue *var_buf; /* variables */ + struct JSVarRef **var_refs; /* references to arguments or local variables */ + uint8_t *cur_pc; /* only used in bytecode functions : PC of the + instruction after the call */ + uint16_t var_ref_count; /* number of var refs */ + uint16_t arg_count; + bool is_strict_mode; + bool is_constructor; /* true if invoked as a constructor (new) */ + /* only used in generators. Current stack pointer value. NULL if + the function is running. */ + JSValue *cur_sp; + /* only set for coroutine frames (async function / generator / + async generator): the GC object owning this heap-allocated frame, + NULL for ordinary C-stack frames. Lets a var_ref capturing one of + the coroutine's locals keep the (suspended) coroutine reachable by + the cycle collector. */ + struct JSGCObjectHeader *cur_gc_obj; +} JSStackFrame; + +typedef enum { + JS_GC_OBJ_TYPE_JS_OBJECT, + JS_GC_OBJ_TYPE_FUNCTION_BYTECODE, + JS_GC_OBJ_TYPE_SHAPE, + JS_GC_OBJ_TYPE_VAR_REF, + JS_GC_OBJ_TYPE_ASYNC_FUNCTION, + JS_GC_OBJ_TYPE_JS_CONTEXT, +} JSGCObjectTypeEnum; + +/* header for GC objects. GC objects are C data structures with a + reference count that can reference other GC objects. JS Objects are + a particular type of GC object. */ +struct JSGCObjectHeader { + /* ref_count/gc_obj_type/mark live in the allocator block header (js_rc(p), + the 8 bytes before every allocation); only the GC list link remains in + the object body. */ + struct list_head link; +}; + +typedef struct JSVarRef { + JSGCObjectHeader header; /* {link}; must come first so &p->header == p */ + uint8_t is_detached; + uint8_t is_lexical; /* only used with global variables */ + uint8_t is_const; /* only used with global variables */ + /* Set at creation for an open var_ref that captures a local of a + coroutine (async function / generator / async generator): such a + var_ref holds a counted reference to that coroutine's GC object and + is itself a GC object, so the cycle collector can see the closure -> + var_ref -> coroutine edge and keep the suspended coroutine (hence the + captured variable it points into) alive. The coroutine is recovered + as stack_frame->cur_gc_obj (valid while open). This is a *snapshot* of + cur_gc_obj != NULL taken at creation, NOT rederived at read time: + cur_gc_obj transitions NULL -> owner (it is set only after a + generator's initial resume), so var_refs created during the prologue + (e.g. mapped `arguments`) must stay non-coro even though cur_gc_obj is + later set. Cleared when the var_ref is detached; the ref is released on + detach/free. */ + uint8_t is_coro; + JSValue *pvalue; /* pointer to the value, either on the stack or + to 'value' */ + union { + JSValue value; /* used when is_detached = true */ + struct { + uint16_t var_ref_idx; /* index in JSStackFrame.var_refs[] */ + JSStackFrame *stack_frame; + }; /* used when is_detached = false */ + }; +} JSVarRef; + +/* Accessors for the reference count and GC mark/type. These fields live in the + arena block header (the 8 bytes before every allocation, reached via + js_rc()), not in the object body. The macros yield lvalues, and the argument + is always the object/header pointer (whose address equals the GC header's, + since the header is the first member). */ +static inline JSMallocBlockHeader *js_rc(const void *p) { + return (JSMallocBlockHeader *)((uint8_t *)(uintptr_t)p - offsetof(JSMallocBlockHeader, user_data)); +} +#define JS_REF_COUNT(p) (js_rc(p)->ref_count) +#define JS_GC_TYPE(p) (js_rc(p)->gc_obj_type) +#define JS_GC_MARK(p) (js_rc(p)->mark) + +/* bigint */ +typedef int32_t js_slimb_t; +typedef uint32_t js_limb_t; +typedef int64_t js_sdlimb_t; +typedef uint64_t js_dlimb_t; + +#define JS_LIMB_DIGITS 9 + +/* Must match the size of short_big_int in JSValueUnion */ +#define JS_LIMB_BITS 32 +#define JS_SHORT_BIG_INT_BITS JS_LIMB_BITS +#define JS_BIGINT_MAX_SIZE ((1024 * 1024) / JS_LIMB_BITS) /* in limbs */ +#define JS_SHORT_BIG_INT_MIN INT32_MIN +#define JS_SHORT_BIG_INT_MAX INT32_MAX + + +typedef struct JSBigInt { + uint32_t len; /* number of limbs, >= 1 */ + js_limb_t tab[]; /* two's complement representation, always + normalized so that 'len' is the minimum + possible length >= 1 */ +} JSBigInt; + +/* this bigint structure can hold a 64 bit integer */ +typedef struct { + js_limb_t big_int_buf[sizeof(JSBigInt) / sizeof(js_limb_t)]; /* for JSBigInt */ + /* must come just after */ + js_limb_t tab[(64 + JS_LIMB_BITS - 1) / JS_LIMB_BITS]; +} JSBigIntBuf; + +typedef enum { + JS_AUTOINIT_ID_PROTOTYPE, + JS_AUTOINIT_ID_MODULE_NS, + JS_AUTOINIT_ID_PROP, + JS_AUTOINIT_ID_BYTECODE, +} JSAutoInitIDEnum; + +enum { + JS_BUILTIN_ARRAY_FROMASYNC = 1, + JS_BUILTIN_ITERATOR_ZIP, + JS_BUILTIN_ITERATOR_ZIP_KEYED, +}; + +/* must be large enough to have a negligible runtime cost and small + enough to call the interrupt callback often. */ +#define JS_INTERRUPT_COUNTER_INIT 10000 + +struct JSContext { + JSGCObjectHeader header; /* must come first */ + JSRuntime *rt; + struct list_head link; + + uint16_t binary_object_count; + uint32_t binary_object_size : 31; + + /* true if the array prototype is "normal": + - no small index properties which are get/set or non writable + - its prototype is Object.prototype + - Object.prototype has no small index properties which are get/set or non writable + - the prototype of Object.prototype is null (always true as it is immutable) + */ + uint8_t std_array_prototype : 1; + + JSShape *array_shape; /* initial shape for Array objects */ + JSShape *arguments_shape; /* shape for arguments objects */ + JSShape *mapped_arguments_shape; /* shape for mapped arguments objects */ + JSShape *regexp_shape; /* shape for regexp objects */ + JSShape *regexp_result_shape; /* shape for regexp result objects */ + + JSValue *class_proto; + JSValue function_proto; + JSValue function_ctor; + JSValue array_ctor; + JSValue regexp_ctor; + JSValue promise_ctor; + JSValue native_error_proto[JS_NATIVE_ERROR_COUNT]; + JSValue error_ctor; + JSValue error_back_trace; + JSValue error_prepare_stack; + JSValue error_stack_trace_limit; + JSValue iterator_ctor; + JSValue iterator_ctor_getset; + JSValue iterator_proto; + JSValue async_iterator_proto; + JSValue array_proto_values; + JSValue throw_type_error; + JSValue eval_obj; + + JSValue global_obj; /* global object */ + JSValue global_var_obj; /* contains the global let/const definitions */ + + double time_origin; + + uint64_t random_state; + uint32_t hash_seed; + + /* when the counter reaches zero, JSRutime.interrupt_handler is called */ + int interrupt_counter; + + struct list_head loaded_modules; /* list of JSModuleDef.link */ + + /* if NULL, RegExp compilation is not supported */ + JSValue (*compile_regexp)(JSContext *ctx, JSValueConst pattern, + JSValueConst flags); + /* if NULL, eval is not supported */ + JSValue (*eval_internal)(JSContext *ctx, JSValueConst this_obj, + const char *input, size_t input_len, + const char *filename, int line, int flags, int scope_idx); + void *user_opaque; +}; + +typedef union JSFloat64Union { + double d; + uint64_t u64; + uint32_t u32[2]; +} JSFloat64Union; + +typedef enum { + JS_WEAK_REF_KIND_MAP, + JS_WEAK_REF_KIND_WEAK_REF, + JS_WEAK_REF_KIND_FINALIZATION_REGISTRY_ENTRY, +} JSWeakRefKindEnum; + +typedef struct JSWeakRefRecord { + JSWeakRefKindEnum kind; + struct JSWeakRefRecord *next_weak_ref; + union { + struct JSMapRecord *map_record; + struct JSWeakRefData *weak_ref_data; + struct JSFinRecEntry *fin_rec_entry; + } u; +} JSWeakRefRecord; + +typedef struct JSMapRecord { + int ref_count; /* used during enumeration to avoid freeing the record */ + bool empty; /* true if the record is deleted */ + struct JSMapState *map; + struct list_head link; + struct list_head hash_link; + JSValue key; + JSValue value; +} JSMapRecord; + +typedef struct JSMapState { + bool is_weak; /* true if WeakSet/WeakMap */ + struct list_head records; /* list of JSMapRecord.link */ + uint32_t record_count; + struct list_head *hash_table; + uint32_t hash_size; /* must be a power of two */ + uint32_t record_count_threshold; /* count at which a hash table + resize is needed */ +} JSMapState; + +enum +{ + JS_TO_STRING_IS_PROPERTY_KEY = 1 << 0, + JS_TO_STRING_NO_SIDE_EFFECTS = 1 << 1, +}; + +enum { + JS_ATOM_TYPE_STRING = 1, + JS_ATOM_TYPE_GLOBAL_SYMBOL, + JS_ATOM_TYPE_SYMBOL, + JS_ATOM_TYPE_PRIVATE, +}; + +enum { + JS_ATOM_HASH_SYMBOL, + JS_ATOM_HASH_PRIVATE, +}; + +typedef enum { + JS_ATOM_KIND_STRING, + JS_ATOM_KIND_SYMBOL, + JS_ATOM_KIND_PRIVATE, +} JSAtomKindEnum; + +typedef enum { + JS_STRING_KIND_NORMAL, + JS_STRING_KIND_SLICE, + JS_STRING_KIND_INDIRECT, +} JSStringKind; + +#define JS_ATOM_HASH_MASK ((1 << 28) - 1) + +struct JSString { + uint32_t len : 31; + uint32_t is_wide_char : 1; /* 0 = 8 bits, 1 = 16 bits characters */ + /* for JS_ATOM_TYPE_SYMBOL: hash = 0, atom_type = 3, + for JS_ATOM_TYPE_PRIVATE: hash = 1, atom_type = 3 + XXX: could change encoding to have one more bit in hash */ + uint32_t hash : 28; + uint32_t kind : 2; + uint32_t atom_type : 2; /* != 0 if atom, JS_ATOM_TYPE_x */ + uint32_t hash_next; /* atom_index for JS_ATOM_TYPE_SYMBOL */ + JSWeakRefRecord *first_weak_ref; +#ifdef ENABLE_DUMPS // JS_DUMP_LEAKS + struct list_head link; /* string list */ +#endif +}; + +typedef struct JSStringSlice { + JSString *parent; + uint32_t start; // in bytes, not characters +} JSStringSlice; + +struct JSStringRope { + uint32_t len; + uint8_t is_wide_char; /* 0 = 8 bits, 1 = 16 bits characters */ + uint8_t depth; /* max depth of the rope tree */ + JSValue left; + JSValue right; /* might be the empty string */ +}; + +static inline void *strv(JSString *p) +{ + JSStringSlice *slice; + void **indirect; + + switch (p->kind) { + case JS_STRING_KIND_NORMAL: + return (void *)&p[1]; + case JS_STRING_KIND_SLICE: + slice = (void *)&p[1]; + return (char *)&slice->parent[1] + slice->start; + case JS_STRING_KIND_INDIRECT: + indirect = (void *)&p[1]; + return *indirect; + } + abort(); + return NULL; +} + +static inline uint8_t *str8(JSString *p) +{ + return strv(p); +} + +static inline uint16_t *str16(JSString *p) +{ + return strv(p); +} + +typedef enum { + JS_CLOSURE_LOCAL, /* 'var_idx' is the index of a local variable in the parent function */ + JS_CLOSURE_ARG, /* 'var_idx' is the index of an argument variable in the parent function */ + JS_CLOSURE_REF, /* 'var_idx' is the index of a closure variable in the parent function */ + JS_CLOSURE_GLOBAL_REF, /* 'var_idx' is the index of a closure variable in the parent + function referencing a global variable */ + JS_CLOSURE_GLOBAL_DECL, /* global variable declaration (eval code only) */ + JS_CLOSURE_GLOBAL, /* global variable (eval code only) */ + JS_CLOSURE_MODULE_DECL, /* definition of a module variable (eval code only) */ + JS_CLOSURE_MODULE_IMPORT, /* definition of a module import (eval code only) */ +} JSClosureTypeEnum; + +typedef struct JSClosureVar { + uint8_t closure_type : 3; /* see JSClosureTypeEnum */ + uint8_t is_lexical : 1; /* lexical variable */ + uint8_t is_const : 1; /* const variable (is_lexical = 1 if is_const = 1) */ + uint8_t var_kind : 4; /* see JSVarKindEnum */ + /* 7 bits available */ + uint16_t var_idx; /* JS_CLOSURE_LOCAL/JS_CLOSURE_ARG: index to a normal variable of the + parent function. otherwise: index to a closure + variable of the parent function */ + JSAtom var_name; +} JSClosureVar; + +#define ARG_SCOPE_INDEX 1 +#define ARG_SCOPE_END (-2) + +typedef struct JSVarScope { + int parent; /* index into fd->scopes of the enclosing scope */ + int first; /* index into fd->vars of the last variable in this scope */ + uint8_t has_using : 1; /* scope has using declarations */ + uint8_t is_await_using : 1; /* scope has await using declarations */ + int using_label_catch; /* label for catch handler (-1 if none) */ + int using_label_end; /* label for end of disposal block (-1 if none) */ +} JSVarScope; + +typedef enum { + /* XXX: add more variable kinds here instead of using bit fields */ + JS_VAR_NORMAL, + JS_VAR_FUNCTION_DECL, /* lexical var with function declaration */ + JS_VAR_NEW_FUNCTION_DECL, /* lexical var with async/generator + function declaration */ + JS_VAR_CATCH, + JS_VAR_FUNCTION_NAME, /* function expression name */ + JS_VAR_PRIVATE_FIELD, + JS_VAR_PRIVATE_METHOD, + JS_VAR_PRIVATE_GETTER, + JS_VAR_PRIVATE_SETTER, /* must come after JS_VAR_PRIVATE_GETTER */ + JS_VAR_PRIVATE_GETTER_SETTER, /* must come after JS_VAR_PRIVATE_SETTER */ + JS_VAR_USING, /* using declaration variable */ + JS_VAR_USING_METHOD, /* hidden local holding the cached dispose method + for the preceding JS_VAR_USING var (always + allocated immediately after it). */ +} JSVarKindEnum; + +/* XXX: could use a different structure in bytecode functions to save + memory */ +typedef struct JSVarDef { + JSAtom var_name; + /* index into fd->scopes of this variable lexical scope */ + int scope_level; + /* during compilation: + - if scope_level = 0: scope in which the variable is defined + - if scope_level != 0: index into fd->vars of the next + variable in the same or enclosing lexical scope + in a bytecode function: + index into fd->vars of the next + variable in the same or enclosing lexical scope + */ + int scope_next; + uint8_t is_const : 1; + uint8_t is_lexical : 1; + uint8_t is_captured : 1; + uint8_t is_static_private : 1; /* only used during private class field parsing */ + uint8_t var_kind : 4; /* see JSVarKindEnum */ + /* if is_captured = true, provides the index of the corresponding + JSVarRef on stack */ + uint16_t var_ref_idx; + /* only used during compilation: function pool index for lexical + variables with var_kind = + JS_VAR_FUNCTION_DECL/JS_VAR_NEW_FUNCTION_DECL or scope level of + the definition of the 'var' variables (they have scope_level = + 0) */ + int func_pool_idx; /* only used during compilation : index in + the constant pool for hoisted function + definition */ +} JSVarDef; + +/* for the encoding of the pc2line table */ +#define PC2LINE_BASE (-1) +#define PC2LINE_RANGE 5 +#define PC2LINE_OP_FIRST 1 +#define PC2LINE_DIFF_PC_MAX ((255 - PC2LINE_OP_FIRST) / PC2LINE_RANGE) + +typedef enum JSFunctionKindEnum { + JS_FUNC_NORMAL = 0, + JS_FUNC_GENERATOR = (1 << 0), + JS_FUNC_ASYNC = (1 << 1), + JS_FUNC_ASYNC_GENERATOR = (JS_FUNC_GENERATOR | JS_FUNC_ASYNC), +} JSFunctionKindEnum; + +typedef struct JSFunctionBytecode { + JSGCObjectHeader header; /* must come first */ + uint8_t is_strict_mode : 1; + uint8_t has_prototype : 1; /* true if a prototype field is necessary */ + uint8_t has_simple_parameter_list : 1; + uint8_t is_derived_class_constructor : 1; + /* true if home_object needs to be initialized */ + uint8_t need_home_object : 1; + uint8_t func_kind : 2; + uint8_t new_target_allowed : 1; + uint8_t super_call_allowed : 1; + uint8_t super_allowed : 1; + uint8_t arguments_allowed : 1; + uint8_t backtrace_barrier : 1; /* stop backtrace on this function */ + /* XXX: 5 bits available */ + uint8_t *byte_code_buf; /* (self pointer) */ + int byte_code_len; + JSAtom func_name; + JSVarDef *vardefs; /* arguments + local variables (arg_count + var_count) (self pointer) */ + JSClosureVar *closure_var; /* list of variables in the closure (self pointer) */ + uint16_t arg_count; + uint16_t var_count; + uint16_t defined_arg_count; /* for length function property */ + uint16_t stack_size; /* maximum stack size */ + uint16_t var_ref_count; /* number of local variable references */ + uint16_t closure_var_count; + int cpool_count; + JSContext *realm; /* function realm */ + JSValue *cpool; /* constant pool (self pointer) */ + JSAtom filename; + int line_num; + int col_num; + int source_len; + int pc2line_len; + uint8_t *pc2line_buf; + char *source; +} JSFunctionBytecode; + +typedef struct JSBoundFunction { + JSValue func_obj; + JSValue this_val; + int argc; + JSValue argv[]; +} JSBoundFunction; + +typedef enum JSIteratorKindEnum { + JS_ITERATOR_KIND_KEY, + JS_ITERATOR_KIND_VALUE, + JS_ITERATOR_KIND_KEY_AND_VALUE, +} JSIteratorKindEnum; + +typedef enum JSIteratorHelperKindEnum { + JS_ITERATOR_HELPER_KIND_CHUNKS, + JS_ITERATOR_HELPER_KIND_DROP, + JS_ITERATOR_HELPER_KIND_EVERY, + JS_ITERATOR_HELPER_KIND_FILTER, + JS_ITERATOR_HELPER_KIND_FIND, + JS_ITERATOR_HELPER_KIND_FLAT_MAP, + JS_ITERATOR_HELPER_KIND_FOR_EACH, + JS_ITERATOR_HELPER_KIND_MAP, + JS_ITERATOR_HELPER_KIND_SOME, + JS_ITERATOR_HELPER_KIND_TAKE, + JS_ITERATOR_HELPER_KIND_WINDOWS, +} JSIteratorHelperKindEnum; + +typedef struct JSForInIterator { + JSValue obj; + bool is_array; + uint32_t array_length; + uint32_t idx; +} JSForInIterator; + +typedef struct JSRegExp { + JSString *pattern; + JSString *bytecode; /* also contains the flags */ +} JSRegExp; + +typedef struct JSProxyData { + JSValue target; + JSValue handler; + uint8_t is_func; + uint8_t is_revoked; +} JSProxyData; + +typedef struct JSArrayBuffer { + int byte_length; /* 0 if detached */ + int max_byte_length; /* -1 if not resizable; >= byte_length otherwise */ + uint8_t detached; + uint8_t immutable; + uint8_t shared; /* if shared, the array buffer cannot be detached */ + uint8_t *data; /* NULL if detached */ + struct list_head array_list; + void *opaque; + JSReallocArrayBufferDataFunc *realloc_func; +} JSArrayBuffer; + +typedef struct JSTypedArray { + struct list_head link; /* link to arraybuffer */ + JSObject *obj; /* back pointer to the TypedArray/DataView object */ + JSObject *buffer; /* based array buffer */ + uint32_t offset; /* byte offset in the array buffer */ + uint32_t length; /* byte length in the array buffer */ + bool track_rab; /* auto-track length of backing array buffer */ +} JSTypedArray; + +typedef struct JSAsyncFunctionState { + JSValue this_val; /* 'this' generator argument */ + int argc; /* number of function arguments */ + bool throw_flag; /* used to throw an exception in JS_CallInternal() */ + JSStackFrame frame; +} JSAsyncFunctionState; + +/* XXX: could use an object instead to avoid the + JS_TAG_ASYNC_FUNCTION tag for the GC */ +typedef struct JSAsyncFunctionData { + JSGCObjectHeader header; /* must come first */ + JSValue resolving_funcs[2]; + bool is_active; /* true if the async function state is valid */ + JSAsyncFunctionState func_state; +} JSAsyncFunctionData; + +typedef struct JSReqModuleEntry { + JSAtom module_name; + JSModuleDef *module; /* used using resolution */ + JSValue attributes; /* JS_UNDEFINED or an object containing the attributes as key/value */ +} JSReqModuleEntry; + +typedef enum JSExportTypeEnum { + JS_EXPORT_TYPE_LOCAL, + JS_EXPORT_TYPE_INDIRECT, +} JSExportTypeEnum; + +typedef struct JSExportEntry { + union { + struct { + int var_idx; /* closure variable index */ + JSVarRef *var_ref; /* if != NULL, reference to the variable */ + } local; /* for local export */ + int req_module_idx; /* module for indirect export */ + } u; + JSExportTypeEnum export_type; + JSAtom local_name; /* '*' if export ns from. not used for local + export after compilation */ + JSAtom export_name; /* exported variable name */ +} JSExportEntry; + +typedef struct JSStarExportEntry { + int req_module_idx; /* in req_module_entries */ +} JSStarExportEntry; + +typedef struct JSImportEntry { + int var_idx; /* closure variable index */ + JSAtom import_name; + int req_module_idx; /* in req_module_entries */ +} JSImportEntry; + +typedef enum { + JS_MODULE_STATUS_UNLINKED, + JS_MODULE_STATUS_LINKING, + JS_MODULE_STATUS_LINKED, + JS_MODULE_STATUS_EVALUATING, + JS_MODULE_STATUS_EVALUATING_ASYNC, + JS_MODULE_STATUS_EVALUATED, +} JSModuleStatus; + +struct JSModuleDef { + JSAtom module_name; + struct list_head link; + + JSReqModuleEntry *req_module_entries; + int req_module_entries_count; + int req_module_entries_size; + + JSExportEntry *export_entries; + int export_entries_count; + int export_entries_size; + + JSStarExportEntry *star_export_entries; + int star_export_entries_count; + int star_export_entries_size; + + JSImportEntry *import_entries; + int import_entries_count; + int import_entries_size; + + /* import attributes the module was requested with, JS_UNDEFINED if + none; the same module name can be loaded with different attributes + (e.g. as both a JS module and a text module) */ + JSValue attributes; + + JSValue module_ns; + JSValue func_obj; /* only used for JS modules */ + JSModuleInitFunc *init_func; /* only used for C modules */ + bool has_tla; /* true if func_obj contains await */ + bool resolved; + bool func_created; + JSModuleStatus status : 8; + /* temp use during js_module_link() & js_module_evaluate() */ + int dfs_index, dfs_ancestor_index; + JSModuleDef *stack_prev; + /* temp use during js_module_evaluate() */ + JSModuleDef **async_parent_modules; + int async_parent_modules_count; + int async_parent_modules_size; + int pending_async_dependencies; + bool async_evaluation; + int64_t async_evaluation_timestamp; + JSModuleDef *cycle_root; + JSValue promise; /* corresponds to spec field: capability */ + JSValue resolving_funcs[2]; /* corresponds to spec field: capability */ + /* true if evaluation yielded an exception. It is saved in + eval_exception */ + bool eval_has_exception; + JSValue eval_exception; + JSValue meta_obj; /* for import.meta */ + JSValue private_value; /* private value for C modules */ +}; + +typedef struct JSJobEntry { + struct list_head link; + JSContext *ctx; + JSJobFunc *job_func; + int argc; + JSValue argv[]; +} JSJobEntry; + +typedef struct JSProperty { + union { + JSValue value; /* JS_PROP_NORMAL */ + struct { /* JS_PROP_GETSET */ + JSObject *getter; /* NULL if undefined */ + JSObject *setter; /* NULL if undefined */ + } getset; + JSVarRef *var_ref; /* JS_PROP_VARREF */ + struct { /* JS_PROP_AUTOINIT */ + /* in order to use only 2 pointers, we compress the realm + and the init function pointer */ + uintptr_t realm_and_id; /* realm and init_id (JS_AUTOINIT_ID_x) + in the 2 low bits */ + void *opaque; + } init; + } u; +} JSProperty; + +#define JS_PROP_INITIAL_SIZE 2 +#define JS_PROP_INITIAL_HASH_SIZE 4 /* must be a power of two */ + +typedef struct JSShapeProperty { + uint32_t hash_next : 26; /* 0 if last in list */ + uint32_t flags : 6; /* JS_PROP_XXX */ + JSAtom atom; /* JS_ATOM_NULL = free property entry */ +} JSShapeProperty; + +struct JSShape { + /* hash table of size hash_mask + 1 before the start of the + structure (see prop_hash_end()). */ + JSGCObjectHeader header; + /* true if the shape is inserted in the shape hash table. If not, + JSShape.hash is not valid */ + uint8_t is_hashed; + uint32_t hash; /* current hash value */ + uint32_t prop_hash_mask; + int prop_size; /* allocated properties */ + int prop_count; /* include deleted properties */ + int deleted_prop_count; + JSShape *shape_hash_next; /* in JSRuntime.shape_hash[h] list */ + JSObject *proto; + uint32_t hash_table[]; /* prop_hash_mask + 1 elements, then prop[prop_size] */ +}; + +struct JSObject { + /* ref_count/gc_obj_type/mark live in the allocator block header; the object + body keeps only the GC list link plus the object's own flags. */ + JSGCObjectHeader header; /* {link}; must come first so &p->header == p */ + uint8_t is_prototype : 1; /* object may be used as prototype */ + uint8_t extensible : 1; + uint8_t free_mark : 1; /* only used when freeing objects with cycles */ + uint8_t is_exotic : 1; /* true if object has exotic property handlers */ + uint8_t fast_array : 1; /* true if u.array is used for get/put (for JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS, JS_CLASS_MAPPED_ARGUMENTS and typed arrays) */ + uint8_t is_constructor : 1; /* true if object is a constructor function */ + uint8_t is_uncatchable_error : 1; /* if true, error is not catchable */ + uint8_t tmp_mark : 1; /* used in JS_WriteObjectRec() */ + uint8_t is_HTMLDDA : 1; /* specific annex B IsHtmlDDA behavior */ + uint16_t class_id; /* see JS_CLASS_x */ + /* byte offsets: 16/24 */ + JSShape *shape; /* prototype and property names + flag */ + JSProperty *prop; /* array of properties */ + /* byte offsets: 24/40 */ + JSWeakRefRecord *first_weak_ref; + /* byte offsets: 28/48 */ + union { + void *opaque; + struct JSBoundFunction *bound_function; /* JS_CLASS_BOUND_FUNCTION */ + struct JSCFunctionDataRecord *c_function_data_record; /* JS_CLASS_C_FUNCTION_DATA */ + struct JSCClosureRecord *c_closure_record; /* JS_CLASS_C_CLOSURE */ + struct JSForInIterator *for_in_iterator; /* JS_CLASS_FOR_IN_ITERATOR */ + struct JSArrayBuffer *array_buffer; /* JS_CLASS_ARRAY_BUFFER, JS_CLASS_SHARED_ARRAY_BUFFER */ + struct JSTypedArray *typed_array; /* JS_CLASS_UINT8C_ARRAY..JS_CLASS_DATAVIEW */ + struct JSMapState *map_state; /* JS_CLASS_MAP..JS_CLASS_WEAKSET */ + struct JSMapIteratorData *map_iterator_data; /* JS_CLASS_MAP_ITERATOR, JS_CLASS_SET_ITERATOR */ + struct JSArrayIteratorData *array_iterator_data; /* JS_CLASS_ARRAY_ITERATOR, JS_CLASS_STRING_ITERATOR */ + struct JSRegExpStringIteratorData *regexp_string_iterator_data; /* JS_CLASS_REGEXP_STRING_ITERATOR */ + struct JSGeneratorData *generator_data; /* JS_CLASS_GENERATOR */ + struct JSIteratorConcatData *iterator_concat_data; /* JS_CLASS_ITERATOR_CONCAT */ + struct JSIteratorHelperData *iterator_helper_data; /* JS_CLASS_ITERATOR_HELPER */ + struct JSIteratorWrapData *iterator_wrap_data; /* JS_CLASS_ITERATOR_WRAP */ + struct JSProxyData *proxy_data; /* JS_CLASS_PROXY */ + struct JSPromiseData *promise_data; /* JS_CLASS_PROMISE */ + struct JSPromiseFunctionData *promise_function_data; /* JS_CLASS_PROMISE_RESOLVE_FUNCTION, JS_CLASS_PROMISE_REJECT_FUNCTION */ + struct JSAsyncFunctionData *async_function_data; /* JS_CLASS_ASYNC_FUNCTION_RESOLVE, JS_CLASS_ASYNC_FUNCTION_REJECT */ + struct JSAsyncFromSyncIteratorData *async_from_sync_iterator_data; /* JS_CLASS_ASYNC_FROM_SYNC_ITERATOR */ + struct JSAsyncGeneratorData *async_generator_data; /* JS_CLASS_ASYNC_GENERATOR */ + struct { /* JS_CLASS_BYTECODE_FUNCTION: 12/24 bytes */ + /* also used by JS_CLASS_GENERATOR_FUNCTION, JS_CLASS_ASYNC_FUNCTION and JS_CLASS_ASYNC_GENERATOR_FUNCTION */ + struct JSFunctionBytecode *function_bytecode; + JSVarRef **var_refs; + JSObject *home_object; /* for 'super' access */ + } func; + struct { /* JS_CLASS_C_FUNCTION: 12/20 bytes */ + JSContext *realm; + JSCFunctionType c_function; + uint8_t length; + uint8_t cproto; + int16_t magic; + } cfunc; + /* array part for fast arrays and typed arrays */ + struct { /* JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS, JS_CLASS_MAPPED_ARGUMENTS, JS_CLASS_UINT8C_ARRAY..JS_CLASS_FLOAT64_ARRAY */ + union { + uint32_t size; /* JS_CLASS_ARRAY */ + struct JSTypedArray *typed_array; /* JS_CLASS_UINT8C_ARRAY..JS_CLASS_FLOAT64_ARRAY */ + } u1; + union { + JSValue *values; /* JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS */ + JSVarRef **var_refs; /* JS_CLASS_MAPPED_ARGUMENTS */ + void *ptr; /* JS_CLASS_UINT8C_ARRAY..JS_CLASS_FLOAT64_ARRAY */ + int8_t *int8_ptr; /* JS_CLASS_INT8_ARRAY */ + uint8_t *uint8_ptr; /* JS_CLASS_UINT8_ARRAY, JS_CLASS_UINT8C_ARRAY */ + int16_t *int16_ptr; /* JS_CLASS_INT16_ARRAY */ + uint16_t *uint16_ptr; /* JS_CLASS_UINT16_ARRAY */ + int32_t *int32_ptr; /* JS_CLASS_INT32_ARRAY */ + uint32_t *uint32_ptr; /* JS_CLASS_UINT32_ARRAY */ + int64_t *int64_ptr; /* JS_CLASS_INT64_ARRAY */ + uint64_t *uint64_ptr; /* JS_CLASS_UINT64_ARRAY */ + uint16_t *fp16_ptr; /* JS_CLASS_FLOAT16_ARRAY */ + float *float_ptr; /* JS_CLASS_FLOAT32_ARRAY */ + double *double_ptr; /* JS_CLASS_FLOAT64_ARRAY */ + } u; + uint32_t count; /* <= 2^31-1. 0 for a detached typed array */ + } array; /* 12/20 bytes */ + JSRegExp regexp; /* JS_CLASS_REGEXP: 8/16 bytes */ + JSValue object_data; /* for JS_SetObjectData(): 8/16/16 bytes */ + } u; + /* byte sizes: 40/48/72 */ +}; + +typedef struct JSCallSiteData { + JSValue filename; + JSValue func; + JSValue func_name; + bool native; + bool constructor; + int line_num; + int col_num; +} JSCallSiteData; + +enum { + __JS_ATOM_NULL = JS_ATOM_NULL, +#define DEF(name, str) JS_ATOM_ ## name, +#include "quickjs-atom.h" +#undef DEF + JS_ATOM_END, +}; +#define JS_ATOM_LAST_KEYWORD JS_ATOM_using +#define JS_ATOM_LAST_STRICT_KEYWORD JS_ATOM_yield + +static const char js_atom_init[] = +#define DEF(name, str) str "\0" +#include "quickjs-atom.h" +#undef DEF +; + +typedef enum OPCodeFormat { +#define FMT(f) OP_FMT_ ## f, +#define DEF(id, size, n_pop, n_push, f) +#include "quickjs-opcode.h" +#undef DEF +#undef FMT +} OPCodeFormat; + +typedef enum OPCodeEnum { +#define FMT(f) +#define DEF(id, size, n_pop, n_push, f) OP_ ## id, +#define def(id, size, n_pop, n_push, f) +#include "quickjs-opcode.h" +#undef def +#undef DEF +#undef FMT + OP_COUNT, /* excluding temporary opcodes */ + /* temporary opcodes : overlap with the short opcodes */ + OP_TEMP_START = OP_nop + 1, + OP___dummy = OP_TEMP_START - 1, +#define FMT(f) +#define DEF(id, size, n_pop, n_push, f) +#define def(id, size, n_pop, n_push, f) OP_ ## id, +#include "quickjs-opcode.h" +#undef def +#undef DEF +#undef FMT + OP_TEMP_END, +} OPCodeEnum; + +static int JS_InitAtoms(JSRuntime *rt); +static JSAtom __JS_NewAtomInit(JSRuntime *rt, const char *str, int len, + int atom_type); +static void JS_FreeAtomStruct(JSRuntime *rt, JSAtomStruct *p); +static void free_function_bytecode(JSRuntime *rt, JSFunctionBytecode *b); +static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj, + JSValueConst this_obj, + int argc, JSValueConst *argv, int flags); +static JSValue js_call_bound_function(JSContext *ctx, JSValueConst func_obj, + JSValueConst this_obj, + int argc, JSValueConst *argv, int flags); +static JSValue JS_CallInternal(JSContext *ctx, JSValueConst func_obj, + JSValueConst this_obj, JSValueConst new_target, + int argc, JSValueConst *argv, int flags); +static JSValue JS_CallConstructorInternal(JSContext *ctx, + JSValueConst func_obj, + JSValueConst new_target, + int argc, JSValueConst *argv, int flags); +static JSValue JS_CallFree(JSContext *ctx, JSValue func_obj, JSValueConst this_obj, + int argc, JSValueConst *argv); +static JSValue JS_InvokeFree(JSContext *ctx, JSValue this_val, JSAtom atom, + int argc, JSValueConst *argv); +static __exception int JS_ToArrayLengthFree(JSContext *ctx, uint32_t *plen, + JSValue val, bool is_array_ctor); +static JSValue JS_EvalObject(JSContext *ctx, JSValueConst this_obj, + JSValueConst val, int flags, int scope_idx); +static JSValue js_new_suppressed_error(JSContext *ctx, JSValueConst error, + JSValueConst suppressed); +static __maybe_unused void JS_DumpString(JSRuntime *rt, JSString *p); +static __maybe_unused void JS_DumpObjectHeader(JSRuntime *rt); +static __maybe_unused void JS_DumpObject(JSRuntime *rt, JSObject *p); +static __maybe_unused void JS_DumpGCObject(JSRuntime *rt, JSGCObjectHeader *p); +static __maybe_unused void JS_DumpValue(JSRuntime *rt, JSValueConst val); +static __maybe_unused void JS_DumpAtoms(JSRuntime *rt); +static __maybe_unused void JS_DumpShapes(JSRuntime *rt); + +static JSValue js_function_apply(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int magic); +static void js_array_finalizer(JSRuntime *rt, JSValueConst val); +static void js_array_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_mapped_arguments_finalizer(JSRuntime *rt, JSValueConst val); +static void js_mapped_arguments_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_object_data_finalizer(JSRuntime *rt, JSValueConst val); +static void js_object_data_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_c_function_finalizer(JSRuntime *rt, JSValueConst val); +static void js_c_function_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_bytecode_function_finalizer(JSRuntime *rt, JSValueConst val); +static void js_bytecode_function_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_bound_function_finalizer(JSRuntime *rt, JSValueConst val); +static void js_bound_function_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_for_in_iterator_finalizer(JSRuntime *rt, JSValueConst val); +static void js_for_in_iterator_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_regexp_finalizer(JSRuntime *rt, JSValueConst val); +static void js_array_buffer_finalizer(JSRuntime *rt, JSValueConst val); +static void js_typed_array_finalizer(JSRuntime *rt, JSValueConst val); +static void js_typed_array_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_proxy_finalizer(JSRuntime *rt, JSValueConst val); +static void js_proxy_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_map_finalizer(JSRuntime *rt, JSValueConst val); +static void js_map_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_map_iterator_finalizer(JSRuntime *rt, JSValueConst val); +static void js_map_iterator_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_array_iterator_finalizer(JSRuntime *rt, JSValueConst val); +static void js_array_iterator_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_iterator_concat_finalizer(JSRuntime *rt, JSValueConst val); +static void js_iterator_concat_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_iterator_helper_finalizer(JSRuntime *rt, JSValueConst val); +static void js_iterator_helper_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_iterator_wrap_finalizer(JSRuntime *rt, JSValueConst val); +static void js_iterator_wrap_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_regexp_string_iterator_finalizer(JSRuntime *rt, + JSValueConst val); +static void js_regexp_string_iterator_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_generator_finalizer(JSRuntime *rt, JSValueConst val); +static void js_generator_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_promise_finalizer(JSRuntime *rt, JSValueConst val); +static void js_promise_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_promise_resolve_function_finalizer(JSRuntime *rt, JSValueConst val); +static void js_promise_resolve_function_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static void js_disposable_stack_finalizer(JSRuntime *rt, JSValueConst val); +static void js_disposable_stack_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); + +#define HINT_STRING 0 +#define HINT_NUMBER 1 +#define HINT_NONE 2 +#define HINT_FORCE_ORDINARY (1 << 4) // don't try Symbol.toPrimitive +static JSValue JS_ToPrimitiveFree(JSContext *ctx, JSValue val, int hint); +static JSValue JS_ToStringFree(JSContext *ctx, JSValue val); +static int JS_ToBoolFree(JSContext *ctx, JSValue val); +static int JS_ToInt32Free(JSContext *ctx, int32_t *pres, JSValue val); +static int JS_ToFloat64Free(JSContext *ctx, double *pres, JSValue val); +static int JS_ToUint8ClampFree(JSContext *ctx, int32_t *pres, JSValue val); +static JSValue JS_ToPropertyKeyInternal(JSContext *ctx, JSValueConst val, + int flags); +static JSValue js_new_string8_len(JSContext *ctx, const char *buf, int len); +static JSValue js_compile_regexp(JSContext *ctx, JSValueConst pattern, + JSValueConst flags); +static JSValue js_regexp_constructor_internal(JSContext *ctx, JSValueConst ctor, + JSValue pattern, JSValue bc); +static void gc_decref(JSRuntime *rt); +static int JS_NewClass1(JSRuntime *rt, JSClassID class_id, + const JSClassDef *class_def, JSAtom name); +static JSValue js_array_push(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int unshift); +static JSValue js_array_constructor(JSContext *ctx, JSValueConst new_target, + int argc, JSValueConst *argv); +static JSValue js_error_constructor(JSContext *ctx, JSValueConst new_target, + int argc, JSValueConst *argv, int magic); +static JSValue js_object_defineProperty(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int magic); +static uint64_t xorshift64star(uint64_t *pstate); + +typedef enum JSStrictEqModeEnum { + JS_EQ_STRICT, + JS_EQ_SAME_VALUE, + JS_EQ_SAME_VALUE_ZERO, +} JSStrictEqModeEnum; + +static bool js_strict_eq2(JSContext *ctx, JSValueConst op1, JSValueConst op2, + JSStrictEqModeEnum eq_mode); +static bool js_strict_eq(JSContext *ctx, JSValueConst op1, JSValueConst op2); +static bool js_same_value(JSContext *ctx, JSValueConst op1, JSValueConst op2); +static bool js_same_value_zero(JSContext *ctx, JSValueConst op1, JSValueConst op2); +static JSValue JS_ToObjectFree(JSContext *ctx, JSValue val); +static JSProperty *add_property(JSContext *ctx, + JSObject *p, JSAtom prop, int prop_flags); +static void free_property(JSRuntime *rt, JSProperty *pr, int prop_flags); +static int JS_ToBigInt64Free(JSContext *ctx, int64_t *pres, JSValue val); +static JSValue JS_ThrowStackOverflow(JSContext *ctx); +static JSValue JS_ThrowTypeErrorRevokedProxy(JSContext *ctx); +static JSValue js_proxy_getPrototypeOf(JSContext *ctx, JSValueConst obj); +static int js_proxy_setPrototypeOf(JSContext *ctx, JSValueConst obj, + JSValueConst proto_val, bool throw_flag); +static int js_proxy_isExtensible(JSContext *ctx, JSValueConst obj); +static int js_proxy_preventExtensions(JSContext *ctx, JSValueConst obj); +static int js_proxy_isArray(JSContext *ctx, JSValueConst obj); +static int JS_CreateProperty(JSContext *ctx, JSObject *p, + JSAtom prop, JSValueConst val, + JSValueConst getter, JSValueConst setter, + int flags); +static int js_string_memcmp(JSString *p1, JSString *p2, int len); +static void reset_weak_ref(JSRuntime *rt, JSWeakRefRecord **first_weak_ref); +static bool is_valid_weakref_target(JSValueConst val); +static void insert_weakref_record(JSValueConst target, + struct JSWeakRefRecord *wr); +static JSValue js_array_buffer_constructor3(JSContext *ctx, + JSValueConst new_target, + uint64_t len, uint64_t *max_len, + JSClassID class_id, + uint8_t *buf, + JSReallocArrayBufferDataFunc *realloc_func, + void *opaque, bool alloc_flag); +static void *js_array_buffer_realloc(JSRuntime *rt, void *opaque, void *ptr, + size_t size); +static JSArrayBuffer *js_get_array_buffer(JSContext *ctx, JSValueConst obj); +static bool array_buffer_is_resizable(const JSArrayBuffer *abuf); +static JSValue js_typed_array_constructor(JSContext *ctx, + JSValueConst this_val, + int argc, JSValueConst *argv, + int classid); +static JSValue js_typed_array_constructor_ta(JSContext *ctx, + JSValueConst new_target, + JSValueConst src_obj, + int classid, uint32_t len); +static bool is_typed_array(JSClassID class_id); +static bool typed_array_is_immutable(JSObject *p); +static bool typed_array_is_oob(JSObject *p); +static uint32_t typed_array_length(JSObject *p); +static int typed_array_init(JSContext *ctx, JSValue obj, JSValue buffer, + uint64_t offset, uint64_t len, bool track_rab); +static JSValue JS_ThrowTypeErrorDetachedArrayBuffer(JSContext *ctx); +static JSValue JS_ThrowTypeErrorImmutableArrayBuffer(JSContext *ctx); +static JSValue JS_ThrowTypeErrorArrayBufferOOB(JSContext *ctx); +static JSVarRef *get_var_ref(JSContext *ctx, JSStackFrame *sf, int var_idx, + bool is_arg); +static JSVarRef *js_create_var_ref(JSContext *ctx, bool is_gc_object); +static JSValue js_call_generator_function(JSContext *ctx, JSValueConst func_obj, + JSValueConst this_obj, + int argc, JSValueConst *argv, + int flags); +static void js_async_function_resolve_finalizer(JSRuntime *rt, + JSValueConst val); +static void js_async_function_resolve_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static JSValue JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, + const char *input, size_t input_len, + const char *filename, int line, int flags, int scope_idx); +static void js_free_module_def(JSContext *ctx, JSModuleDef *m); +static int js_module_attributes_equal(JSContext *ctx, JSValueConst attr1, + JSValueConst attr2); +static void js_mark_module_def(JSRuntime *rt, JSModuleDef *m, + JS_MarkFunc *mark_func); +static JSValue js_import_meta(JSContext *ctx); +static JSValue js_dynamic_import(JSContext *ctx, JSValueConst specifier, + JSValueConst options); +static void free_var_ref(JSRuntime *rt, JSVarRef *var_ref); +static void js_async_function_free(JSRuntime *rt, JSAsyncFunctionData *s); +static void js_release_coro(JSRuntime *rt, JSGCObjectHeader *coro); +static JSValue js_new_promise_capability(JSContext *ctx, + JSValue *resolving_funcs, + JSValueConst ctor); +static __exception int perform_promise_then(JSContext *ctx, + JSValueConst promise, + JSValueConst *resolve_reject, + JSValueConst *cap_resolving_funcs); +static JSValue js_promise_resolve(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int magic); +static JSValue js_promise_then(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv); +static JSValue js_promise_resolve_thenable_job(JSContext *ctx, + int argc, JSValueConst *argv); +static bool js_string_eq(JSString *p1, JSString *p2); +static int js_string_compare(JSString *p1, JSString *p2); +static int JS_NumberIsInteger(JSContext *ctx, JSValueConst val); +static bool JS_NumberIsNegativeOrMinusZero(JSContext *ctx, JSValueConst val); +static JSValue JS_ToNumberFree(JSContext *ctx, JSValue val); +static int JS_GetOwnPropertyInternal(JSContext *ctx, JSPropertyDescriptor *desc, + JSObject *p, JSAtom prop); +static int JS_GetOwnPropertyFlagsInternal(JSContext *ctx, int *pflags, + JSObject *p, JSAtom prop); +static JSValue JS_GetOwnPropertyNames2(JSContext *ctx, JSValueConst obj1, + int flags, int kind); +static void js_free_desc(JSContext *ctx, JSPropertyDescriptor *desc); +static void async_func_mark(JSRuntime *rt, JSAsyncFunctionState *s, + JS_MarkFunc *mark_func); +static int JS_AddIntrinsicBasicObjects(JSContext *ctx); +static void js_free_shape(JSRuntime *rt, JSShape *sh); +static void js_free_shape_null(JSRuntime *rt, JSShape *sh); +static int js_shape_prepare_update(JSContext *ctx, JSObject *p, + JSShapeProperty **pprs); +static int init_shape_hash(JSRuntime *rt); +static __exception int js_get_length32(JSContext *ctx, uint32_t *pres, + JSValueConst obj); +static __exception int js_get_length64(JSContext *ctx, int64_t *pres, + JSValueConst obj); +static __exception int js_set_length64(JSContext *ctx, JSValueConst obj, + int64_t len); +static void free_arg_list(JSContext *ctx, JSValue *tab, uint32_t len); +static JSValue *build_arg_list(JSContext *ctx, uint32_t *plen, + JSValueConst array_arg); +static JSValue js_create_array(JSContext *ctx, int len, JSValueConst *tab); +static bool js_get_fast_array(JSContext *ctx, JSValue obj, + JSValue **arrpp, uint32_t *countp); +static int expand_fast_array(JSContext *ctx, JSObject *p, uint32_t new_len); +static JSValue JS_CreateAsyncFromSyncIterator(JSContext *ctx, + JSValue sync_iter); +static void js_c_function_data_finalizer(JSRuntime *rt, JSValueConst val); +static void js_c_function_data_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func); +static JSValue js_call_c_function_data(JSContext *ctx, JSValueConst func_obj, + JSValueConst this_val, + int argc, JSValueConst *argv, int flags); +static void js_c_closure_finalizer(JSRuntime *rt, JSValueConst val); +static JSValue js_call_c_closure(JSContext *ctx, JSValueConst func_obj, + JSValueConst this_val, + int argc, JSValueConst *argv, int flags); +static JSAtom JS_ValueToAtomInternal(JSContext *ctx, JSValueConst val, + int flags); +static JSAtom js_symbol_to_atom(JSContext *ctx, JSValueConst val); +static void add_gc_object(JSRuntime *rt, JSGCObjectHeader *h, + JSGCObjectTypeEnum type); +static void remove_gc_object(JSGCObjectHeader *h); +static void js_async_function_free0(JSRuntime *rt, JSAsyncFunctionData *s); +static JSValue js_instantiate_prototype(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque); +static JSValue js_module_ns_autoinit(JSContext *ctx, JSObject *p, JSAtom atom, + void *opaque); +static JSValue JS_InstantiateFunctionListItem2(JSContext *ctx, JSObject *p, + JSAtom atom, void *opaque); +static JSValue JS_NewObjectProtoList(JSContext *ctx, JSValueConst proto, + const JSCFunctionListEntry *fields, int n_fields); + +static void js_set_uncatchable_error(JSValueConst val, bool flag); + +static JSValue js_new_callsite(JSContext *ctx, JSCallSiteData *csd); +static void js_new_callsite_data(JSContext *ctx, JSCallSiteData *csd, JSStackFrame *sf); +static void js_new_callsite_data2(JSContext *ctx, JSCallSiteData *csd, const char *filename, int line_num, int col_num); +static int _JS_AddIntrinsicCallSite(JSContext *ctx); + +static void JS_SetOpaqueInternal(JSValueConst obj, void *opaque); + +static const JSClassExoticMethods js_arguments_exotic_methods; +static const JSClassExoticMethods js_string_exotic_methods; +static const JSClassExoticMethods js_proxy_exotic_methods; +static const JSClassExoticMethods js_module_ns_exotic_methods; + +static inline bool double_is_int32(double d) +{ + uint64_t u, e; + JSFloat64Union t; + + t.d = d; + u = t.u64; + + e = ((u >> 52) & 0x7FF) - 1023; + if (e > 30) { + // accept 0, INT32_MIN, reject too large, too small, nan, inf, -0 + return !u || (u == 0xc1e0000000000000); + } else { + // shift out sign, exponent and whole part bits + // value is fractional if remaining low bits are non-zero + return !(u << 12 << e); + } +} + +static JSValue js_float64(double d) +{ + return __JS_NewFloat64(d); +} + +static int compare_u32(uint32_t a, uint32_t b) +{ + return -(a < b) + (b < a); // -1, 0 or 1 +} + +static JSValue js_int32(int32_t v) +{ + return JS_MKVAL(JS_TAG_INT, v); +} + +static JSValue js_uint32(uint32_t v) +{ + if (v <= INT32_MAX) + return js_int32(v); + else + return js_float64(v); +} + +static JSValue js_int64(int64_t v) +{ + if (v >= INT32_MIN && v <= INT32_MAX) + return js_int32(v); + else + return js_float64(v); +} + +static JSValue js_number(double d) +{ + if (double_is_int32(d)) + return js_int32((int32_t)d); + else + return js_float64(d); +} + +/* If v is a number (int or float64), store it as a double and return true. + Used by the interpreter arithmetic fast paths to handle mixed int/float + operands inline instead of falling back to the slow path. */ +static inline bool js_arith_to_float64(JSValue v, double *pd) +{ + uint32_t tag = JS_VALUE_GET_TAG(v); + if (JS_TAG_IS_FLOAT64(tag)) + *pd = JS_VALUE_GET_FLOAT64(v); + else if (tag == JS_TAG_INT) + *pd = JS_VALUE_GET_INT(v); + else + return false; + return true; +} + +static JSValue __JS_NewShortBigInt(JSContext *ctx, int32_t d) +{ + (void)&ctx; + return JS_MKVAL(JS_TAG_SHORT_BIG_INT, d); +} + +JSValue JS_NewNumber(JSContext *ctx, double d) +{ + return js_number(d); +} + +static JSValue js_bool(bool v) +{ + return JS_MKVAL(JS_TAG_BOOL, (v != 0)); +} + +static JSValue js_dup(JSValueConst v) +{ + if (JS_VALUE_HAS_REF_COUNT(v)) { + void *p = JS_VALUE_GET_PTR(v); + JS_REF_COUNT(p)++; + } + return unsafe_unconst(v); +} + +JSValue JS_DupValue(JSContext *ctx, JSValueConst v) +{ + return js_dup(v); +} + +JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v) +{ + return js_dup(v); +} + +static void js_trigger_gc(JSRuntime *rt, size_t size) +{ + bool force_gc; +#ifdef FORCE_GC_AT_MALLOC + force_gc = true; +#else + force_gc = ((rt->malloc_state.malloc_size + size) > + rt->malloc_gc_threshold); +#endif + if (force_gc) { +#ifdef ENABLE_DUMPS // JS_DUMP_GC + if (check_dump_flag(rt, JS_DUMP_GC)) { + printf("GC: size=%zd\n", rt->malloc_state.malloc_size); + } +#endif + JS_RunGC(rt); + rt->malloc_gc_threshold = rt->malloc_state.malloc_size + + (rt->malloc_state.malloc_size >> 1); + } +} + +static size_t js_malloc_usable_size_unknown(const void *ptr) +{ + return 0; +} + +/* max overhead for size >= 64: 12.5% */ +static const uint16_t arena_block_sizes[JS_ARENA_BLOCK_SIZE_COUNT] = { + 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, + 144, 160, 176, 192, 208, 224, 240, 256, + 288, 320, 352, 384, 416, 448, 480, 512, +}; + +static int arena_get_size_index(size_t size) +{ + if (size <= 16) + return 0; + else if (size <= 128) + return (size + 7) / 8 - 2; + else if (size <= 256) + return (size + 15) / 16 + 6; + else if (size <= 512) + return (size + 31) / 32 + 14; + else + return JS_ARENA_BLOCK_SIZE_COUNT; +} + +static inline JSMallocBlockHeader *arena_zero_block(JSRuntime *rt) +{ + return (JSMallocBlockHeader *)rt->arena_state.zero_size_block; +} + +static void js_arena_init(JSRuntime *rt) +{ + JSArenaState *s = &rt->arena_state; + int i; + arena_zero_block(rt)->u.block_idx = JS_ARENA_FREE_NIL; + for (i = 0; i < JS_ARENA_BLOCK_SIZE_COUNT; i++) { + init_list_head(&s->arena_list[i]); + init_list_head(&s->free_arena_list[i]); + } +} + +static inline void *arena_get_block(JSArena *ar, unsigned int idx, + unsigned int block_size) +{ + return ar->blocks + (size_t)idx * block_size; +} + +static no_inline JSArena *arena_new(JSRuntime *rt, int block_size_idx) +{ + JSMallocBlockHeader *b; + JSArena *ar; + int n_blocks, block_size, i; + + block_size = arena_block_sizes[block_size_idx]; + n_blocks = (JS_ARENA_SIZE - sizeof(JSArena)) / block_size; + ar = rt->mf.js_malloc(rt->malloc_state.opaque, + sizeof(JSArena) + (size_t)n_blocks * block_size); + if (!ar) + return NULL; + ar->block_size_idx = block_size_idx; + ar->n_blocks = n_blocks; + ar->n_used_blocks = 0; + ar->first_free_block = 0; + for (i = 0; i < n_blocks - 1; i++) { + b = arena_get_block(ar, i, block_size); + b->u.free_next = i + 1; + b->block_size_idx = block_size_idx; + } + b = arena_get_block(ar, n_blocks - 1, block_size); + b->u.free_next = JS_ARENA_FREE_NIL; + b->block_size_idx = block_size_idx; + list_add(&ar->link, &rt->arena_state.arena_list[block_size_idx]); + list_add(&ar->free_link, &rt->arena_state.free_arena_list[block_size_idx]); + return ar; +} + +static no_inline void *arena_malloc_large(JSRuntime *rt, size_t size) +{ + JSMallocBlockHeader *b; + b = rt->mf.js_malloc(rt->malloc_state.opaque, + sizeof(JSMallocBlockHeader) + size); + if (!b) + return NULL; + b->u.block_idx = JS_ARENA_FREE_NIL; + b->block_size_idx = 0xff; /* fail safe */ + return b->user_data; +} + +static no_inline void *arena_calloc_large(JSRuntime *rt, size_t size) +{ + JSMallocBlockHeader *b; + b = rt->mf.js_calloc(rt->malloc_state.opaque, 1, + sizeof(JSMallocBlockHeader) + size); + if (!b) + return NULL; + b->u.block_idx = JS_ARENA_FREE_NIL; + b->block_size_idx = 0xff; /* fail safe */ + return b->user_data; +} + +static void *js_arena_malloc(JSRuntime *rt, size_t size) +{ + size_t total_size; + + if (unlikely(size == 0)) + return arena_zero_block(rt)->user_data; + total_size = ((size + JS_ARENA_ALIGN - 1) & ~(size_t)(JS_ARENA_ALIGN - 1)) + + sizeof(JSMallocBlockHeader); + if (!JS_ARENA_LARGE_BLOCKS_ONLY && total_size <= JS_ARENA_MAX_SMALL_SIZE) { + int block_size_idx; + unsigned int block_idx, block_size; + JSMallocBlockHeader *b; + JSArena *ar; + struct list_head *el, *head; + + block_size_idx = arena_get_size_index(total_size); + block_size = arena_block_sizes[block_size_idx]; + head = &rt->arena_state.free_arena_list[block_size_idx]; + el = head->next; + if (unlikely(el == head)) { + ar = arena_new(rt, block_size_idx); + if (!ar) + return NULL; + } else { + ar = list_entry(el, JSArena, free_link); + } + block_idx = ar->first_free_block; + b = arena_get_block(ar, block_idx, block_size); + ar->first_free_block = b->u.free_next; + b->u.block_idx = block_idx; + ar->n_used_blocks++; + if (unlikely(ar->n_used_blocks == ar->n_blocks)) + list_del(&ar->free_link); + return b->user_data; + } else { + return arena_malloc_large(rt, size); + } +} + +static void js_arena_free(JSRuntime *rt, void *ptr) +{ + JSMallocBlockHeader *b; + + if (!ptr) + return; + b = container_of(ptr, JSMallocBlockHeader, user_data); + if (unlikely(b->u.block_idx == JS_ARENA_FREE_NIL)) { + /* large or zero-size block */ + if (b == arena_zero_block(rt)) { + /* nothing to do */ + } else { + rt->mf.js_free(rt->malloc_state.opaque, b); + } + } else { + unsigned int block_idx = b->u.block_idx; + unsigned int block_size_idx = b->block_size_idx; + unsigned int block_size = arena_block_sizes[block_size_idx]; + JSArena *ar = (JSArena *)((uint8_t *)b - + (size_t)block_size * block_idx - + sizeof(JSArena)); + b->u.free_next = ar->first_free_block; + ar->first_free_block = block_idx; + if (unlikely(ar->n_used_blocks == ar->n_blocks)) + list_add(&ar->free_link, + &rt->arena_state.free_arena_list[block_size_idx]); + ar->n_used_blocks--; + if (unlikely(ar->n_used_blocks == 0)) { + list_del(&ar->link); + list_del(&ar->free_link); + rt->mf.js_free(rt->malloc_state.opaque, ar); + } + } +} + +static size_t js_arena_usable_size(JSRuntime *rt, const void *ptr) +{ + const JSMallocBlockHeader *b; + + if (!ptr) + return 0; + b = container_of(ptr, JSMallocBlockHeader, user_data); + if (b->u.block_idx == JS_ARENA_FREE_NIL) { + if (b == arena_zero_block(rt)) { + return 0; + } else { + size_t size = rt->mf.js_malloc_usable_size(b); + if (size != 0) + size -= sizeof(JSMallocBlockHeader); + return size; + } + } else { + return arena_block_sizes[b->block_size_idx] - sizeof(JSMallocBlockHeader); + } +} + +static void *js_arena_realloc(JSRuntime *rt, void *ptr, size_t size) +{ + JSMallocBlockHeader *b; + + /* js_realloc_rt already handles ptr == NULL and size == 0 */ + b = container_of(ptr, JSMallocBlockHeader, user_data); + if (b->u.block_idx == JS_ARENA_FREE_NIL) { + if (b == arena_zero_block(rt)) { + return js_arena_malloc(rt, size); + } else { + JSMallocBlockHeader *nb; + nb = rt->mf.js_realloc(rt->malloc_state.opaque, b, + sizeof(JSMallocBlockHeader) + size); + if (!nb) + return NULL; + nb->u.block_idx = JS_ARENA_FREE_NIL; + nb->block_size_idx = 0xff; + return nb->user_data; + } + } else { + unsigned int block_size = arena_block_sizes[b->block_size_idx]; + size_t total_size, old_usable; + void *new_ptr; + + total_size = ((size + JS_ARENA_ALIGN - 1) & ~(size_t)(JS_ARENA_ALIGN - 1)) + + sizeof(JSMallocBlockHeader); + if (total_size <= block_size) + return ptr; /* still fits the current size class */ + new_ptr = js_arena_malloc(rt, size); + if (!new_ptr) + return NULL; + { + /* carry the merged GC/refcount fields to the relocated block */ + JSMallocBlockHeader *nb = container_of(new_ptr, JSMallocBlockHeader, user_data); + nb->gc_obj_type = b->gc_obj_type; + nb->mark = b->mark; + nb->ref_count = b->ref_count; + } + old_usable = block_size - sizeof(JSMallocBlockHeader); + if (size > old_usable) + size = old_usable; + memcpy(new_ptr, ptr, size); + js_arena_free(rt, ptr); + return new_ptr; + } +} + +static void *js_arena_calloc(JSRuntime *rt, size_t count, size_t size) +{ + size_t n = count * size; /* overflow already checked by js_calloc_rt */ + size_t total_size = ((n + JS_ARENA_ALIGN - 1) & ~(size_t)(JS_ARENA_ALIGN - 1)) + + sizeof(JSMallocBlockHeader); + if (!JS_ARENA_LARGE_BLOCKS_ONLY && total_size <= JS_ARENA_MAX_SMALL_SIZE) { + /* Small blocks are carved from recycled (dirty) arena memory, so they + must be zeroed explicitly. */ + void *ptr = js_arena_malloc(rt, n); + if (unlikely(!ptr)) + return NULL; + return memset(ptr, 0, n); + } + /* Large blocks come straight from the backing allocator, so let js_calloc + do the zeroing. */ + return arena_calloc_large(rt, n); +} + +/* free any arenas still mapped at runtime teardown (normally none: empty + arenas are released eagerly as their last block is freed) */ +static void js_arena_free_all(JSRuntime *rt) +{ + JSArenaState *s = &rt->arena_state; + struct list_head *el, *el1; + int i; + for (i = 0; i < JS_ARENA_BLOCK_SIZE_COUNT; i++) { + list_for_each_safe(el, el1, &s->arena_list[i]) { + JSArena *ar = list_entry(el, JSArena, link); + rt->mf.js_free(rt->malloc_state.opaque, ar); + } + init_list_head(&s->arena_list[i]); + init_list_head(&s->free_arena_list[i]); + } +} + +void *js_calloc_rt(JSRuntime *rt, size_t count, size_t size) +{ + void *ptr; + JSMallocState *s; + + /* Do not allocate zero bytes: behavior is platform dependent */ + assert(count != 0 && size != 0); + + if (size > 0) + if (unlikely(count != (count * size) / size)) + return NULL; + + s = &rt->malloc_state; + /* When malloc_limit is 0 (unlimited), malloc_limit - 1 will be SIZE_MAX. */ + if (unlikely(s->malloc_size + (count * size) > s->malloc_limit - 1)) + return NULL; + + ptr = js_arena_calloc(rt, count, size); + if (!ptr) + return NULL; + + s->malloc_count++; + s->malloc_size += js_arena_usable_size(rt, ptr) + MALLOC_OVERHEAD; + return ptr; +} + +void *js_malloc_rt(JSRuntime *rt, size_t size) +{ + void *ptr; + JSMallocState *s; + + /* Do not allocate zero bytes: behavior is platform dependent */ + if (unlikely(size == 0)) + return NULL; + + s = &rt->malloc_state; + /* When malloc_limit is 0 (unlimited), malloc_limit - 1 will be SIZE_MAX. */ + if (unlikely(s->malloc_size + size > s->malloc_limit - 1)) + return NULL; + + ptr = js_arena_malloc(rt, size); + if (!ptr) + return NULL; + + s->malloc_count++; + s->malloc_size += js_arena_usable_size(rt, ptr) + MALLOC_OVERHEAD; + return ptr; +} + +void js_free_rt(JSRuntime *rt, void *ptr) +{ + JSMallocState *s; + + if (!ptr) + return; + + s = &rt->malloc_state; + size_t free_size = js_arena_usable_size(rt, ptr) + MALLOC_OVERHEAD; + if (unlikely(free_size > s->malloc_size)) { + printf("js_free_rt: malloc_size underflow: freeing %zu but only %zu tracked\n", free_size, s->malloc_size); + abort(); + } + s->malloc_count--; + s->malloc_size -= free_size; + js_arena_free(rt, ptr); +} + +void *js_realloc_rt(JSRuntime *rt, void *ptr, size_t size) +{ + size_t old_size; + JSMallocState *s; + + if (!ptr) { + if (size == 0) + return NULL; + return js_malloc_rt(rt, size); + } + if (unlikely(size == 0)) { + js_free_rt(rt, ptr); + return NULL; + } + old_size = js_arena_usable_size(rt, ptr); + s = &rt->malloc_state; + /* When malloc_limit is 0 (unlimited), malloc_limit - 1 will be SIZE_MAX. */ + if (s->malloc_size + size - old_size > s->malloc_limit - 1) + return NULL; + + ptr = js_arena_realloc(rt, ptr, size); + if (!ptr) + return NULL; + + s->malloc_size += js_arena_usable_size(rt, ptr) - old_size; + return ptr; +} + +size_t js_malloc_usable_size_rt(JSRuntime *rt, const void *ptr) +{ + return js_arena_usable_size(rt, ptr); +} + +/** + * This used to be implemented as malloc + memset, but using calloc + * yields better performance in initial, bursty allocations, something useful + * for QuickJS. + * + * More information: https://github.com/quickjs-ng/quickjs/pull/519 + */ +void *js_mallocz_rt(JSRuntime *rt, size_t size) +{ + return js_calloc_rt(rt, 1, size); +} + +/* Throw out of memory in case of error */ +void *js_calloc(JSContext *ctx, size_t count, size_t size) +{ + void *ptr; + ptr = js_calloc_rt(ctx->rt, count, size); + if (unlikely(!ptr)) { + JS_ThrowOutOfMemory(ctx); + return NULL; + } + return ptr; +} + +/* Throw out of memory in case of error */ +void *js_malloc(JSContext *ctx, size_t size) +{ + void *ptr; + ptr = js_malloc_rt(ctx->rt, size); + if (unlikely(!ptr)) { + JS_ThrowOutOfMemory(ctx); + return NULL; + } + return ptr; +} + +/* Throw out of memory in case of error */ +void *js_mallocz(JSContext *ctx, size_t size) +{ + void *ptr; + ptr = js_mallocz_rt(ctx->rt, size); + if (unlikely(!ptr)) { + JS_ThrowOutOfMemory(ctx); + return NULL; + } + return ptr; +} + +void js_free(JSContext *ctx, void *ptr) +{ + js_free_rt(ctx->rt, ptr); +} + +/* Throw out of memory in case of error */ +void *js_realloc(JSContext *ctx, void *ptr, size_t size) +{ + void *ret; + ret = js_realloc_rt(ctx->rt, ptr, size); + if (unlikely(!ret && size != 0)) { + JS_ThrowOutOfMemory(ctx); + return NULL; + } + return ret; +} + +size_t js_malloc_usable_size(JSContext *ctx, const void *ptr) +{ + return js_malloc_usable_size_rt(ctx->rt, ptr); +} + +/* Throw out of memory exception in case of error */ +char *js_strndup(JSContext *ctx, const char *s, size_t n) +{ + char *ptr; + ptr = js_malloc(ctx, n + 1); + if (ptr) { + memcpy(ptr, s, n); + ptr[n] = '\0'; + } + return ptr; +} + +char *js_strdup(JSContext *ctx, const char *str) +{ + return js_strndup(ctx, str, strlen(str)); +} + +static no_inline int js_realloc_array(JSContext *ctx, void **parray, + int elem_size, int *psize, int req_size) +{ + int new_size; + void *new_array; + /* XXX: potential arithmetic overflow */ + new_size = max_int(req_size, *psize * 3 / 2); + assert(elem_size > 0 && new_size > 0); + new_array = js_realloc(ctx, *parray, (size_t)new_size * (size_t)elem_size); + if (!new_array) + return -1; + *psize = new_size; + *parray = new_array; + return 0; +} + +/* resize the array and update its size if req_size > *psize */ +static inline int js_resize_array(JSContext *ctx, void **parray, int elem_size, + int *psize, int req_size) +{ + if (unlikely(req_size > *psize)) + return js_realloc_array(ctx, parray, elem_size, psize, req_size); + else + return 0; +} + +static void *js_dbuf_realloc(void *ctx, void *ptr, size_t size) +{ + return js_realloc(ctx, ptr, size); +} + +static inline void js_dbuf_init(JSContext *ctx, DynBuf *s) +{ + dbuf_init2(s, ctx, js_dbuf_realloc); +} + +static inline int is_digit(int c) { + return c >= '0' && c <= '9'; +} + +static inline int string_get(JSString *p, int idx) { + return p->is_wide_char ? str16(p)[idx] : str8(p)[idx]; +} + +typedef struct JSClassShortDef { + JSAtom class_name; + JSClassFinalizer *finalizer; + JSClassGCMark *gc_mark; +} JSClassShortDef; + +static JSClassShortDef const js_std_class_def[] = { + { JS_ATOM_Object, NULL, NULL }, /* JS_CLASS_OBJECT */ + { JS_ATOM_Array, js_array_finalizer, js_array_mark }, /* JS_CLASS_ARRAY */ + { JS_ATOM_Error, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_ERROR */ + { JS_ATOM_Number, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_NUMBER */ + { JS_ATOM_String, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_STRING */ + { JS_ATOM_Boolean, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BOOLEAN */ + { JS_ATOM_Symbol, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_SYMBOL */ + { JS_ATOM_Arguments, js_array_finalizer, js_array_mark }, /* JS_CLASS_ARGUMENTS */ + { JS_ATOM_Arguments, js_mapped_arguments_finalizer, js_mapped_arguments_mark }, /* JS_CLASS_MAPPED_ARGUMENTS */ + { JS_ATOM_Date, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_DATE */ + { JS_ATOM_Object, NULL, NULL }, /* JS_CLASS_MODULE_NS */ + { JS_ATOM_Function, js_c_function_finalizer, js_c_function_mark }, /* JS_CLASS_C_FUNCTION */ + { JS_ATOM_Function, js_bytecode_function_finalizer, js_bytecode_function_mark }, /* JS_CLASS_BYTECODE_FUNCTION */ + { JS_ATOM_Function, js_bound_function_finalizer, js_bound_function_mark }, /* JS_CLASS_BOUND_FUNCTION */ + { JS_ATOM_Function, js_c_function_data_finalizer, js_c_function_data_mark }, /* JS_CLASS_C_FUNCTION_DATA */ + { JS_ATOM_Function, js_c_closure_finalizer, NULL}, /* JS_CLASS_C_CLOSURE */ + { JS_ATOM_GeneratorFunction, js_bytecode_function_finalizer, js_bytecode_function_mark }, /* JS_CLASS_GENERATOR_FUNCTION */ + { JS_ATOM_ForInIterator, js_for_in_iterator_finalizer, js_for_in_iterator_mark }, /* JS_CLASS_FOR_IN_ITERATOR */ + { JS_ATOM_RegExp, js_regexp_finalizer, NULL }, /* JS_CLASS_REGEXP */ + { JS_ATOM_ArrayBuffer, js_array_buffer_finalizer, NULL }, /* JS_CLASS_ARRAY_BUFFER */ + { JS_ATOM_SharedArrayBuffer, js_array_buffer_finalizer, NULL }, /* JS_CLASS_SHARED_ARRAY_BUFFER */ + { JS_ATOM_Uint8ClampedArray, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_UINT8C_ARRAY */ + { JS_ATOM_Int8Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_INT8_ARRAY */ + { JS_ATOM_Uint8Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_UINT8_ARRAY */ + { JS_ATOM_Int16Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_INT16_ARRAY */ + { JS_ATOM_Uint16Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_UINT16_ARRAY */ + { JS_ATOM_Int32Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_INT32_ARRAY */ + { JS_ATOM_Uint32Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_UINT32_ARRAY */ + { JS_ATOM_BigInt64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_BIG_INT64_ARRAY */ + { JS_ATOM_BigUint64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_BIG_UINT64_ARRAY */ + { JS_ATOM_Float16Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_FLOAT16_ARRAY */ + { JS_ATOM_Float32Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_FLOAT32_ARRAY */ + { JS_ATOM_Float64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_FLOAT64_ARRAY */ + { JS_ATOM_DataView, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_DATAVIEW */ + { JS_ATOM_BigInt, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BIG_INT */ + { JS_ATOM_Map, js_map_finalizer, js_map_mark }, /* JS_CLASS_MAP */ + { JS_ATOM_Set, js_map_finalizer, js_map_mark }, /* JS_CLASS_SET */ + { JS_ATOM_WeakMap, js_map_finalizer, NULL }, /* JS_CLASS_WEAKMAP */ + { JS_ATOM_WeakSet, js_map_finalizer, NULL }, /* JS_CLASS_WEAKSET */ + { JS_ATOM_Iterator, NULL, NULL }, /* JS_CLASS_ITERATOR */ + { JS_ATOM_IteratorConcat, js_iterator_concat_finalizer, js_iterator_concat_mark }, /* JS_CLASS_ITERATOR_CONCAT */ + { JS_ATOM_IteratorHelper, js_iterator_helper_finalizer, js_iterator_helper_mark }, /* JS_CLASS_ITERATOR_HELPER */ + { JS_ATOM_IteratorWrap, js_iterator_wrap_finalizer, js_iterator_wrap_mark }, /* JS_CLASS_ITERATOR_WRAP */ + { JS_ATOM_Map_Iterator, js_map_iterator_finalizer, js_map_iterator_mark }, /* JS_CLASS_MAP_ITERATOR */ + { JS_ATOM_Set_Iterator, js_map_iterator_finalizer, js_map_iterator_mark }, /* JS_CLASS_SET_ITERATOR */ + { JS_ATOM_Array_Iterator, js_array_iterator_finalizer, js_array_iterator_mark }, /* JS_CLASS_ARRAY_ITERATOR */ + { JS_ATOM_String_Iterator, js_array_iterator_finalizer, js_array_iterator_mark }, /* JS_CLASS_STRING_ITERATOR */ + { JS_ATOM_RegExp_String_Iterator, js_regexp_string_iterator_finalizer, js_regexp_string_iterator_mark }, /* JS_CLASS_REGEXP_STRING_ITERATOR */ + { JS_ATOM_Generator, js_generator_finalizer, js_generator_mark }, /* JS_CLASS_GENERATOR */ + { JS_ATOM_DisposableStack, js_disposable_stack_finalizer, js_disposable_stack_mark }, /* JS_CLASS_DISPOSABLE_STACK */ +}; + +static int init_class_range(JSRuntime *rt, JSClassShortDef const *tab, + int start, int count) +{ + JSClassDef cm_s, *cm = &cm_s; + int i, class_id; + + for(i = 0; i < count; i++) { + class_id = i + start; + memset(cm, 0, sizeof(*cm)); + cm->finalizer = tab[i].finalizer; + cm->gc_mark = tab[i].gc_mark; + if (JS_NewClass1(rt, class_id, cm, tab[i].class_name) < 0) + return -1; + } + return 0; +} + +/* Uses code from LLVM project. */ +static inline uintptr_t js_get_stack_pointer(void) +{ +#if defined(__clang__) || defined(__GNUC__) + return (uintptr_t)__builtin_frame_address(0); +#elif defined(_MSC_VER) + return (uintptr_t)_AddressOfReturnAddress(); +#else + char CharOnStack = 0; + // The volatile store here is intended to escape the local variable, to + // prevent the compiler from optimizing CharOnStack into anything other + // than a char on the stack. + // + // Tested on: MSVC 2015 - 2019, GCC 4.9 - 9, Clang 3.2 - 9, ICC 13 - 19. + char *volatile Ptr = &CharOnStack; + return (uintptr_t) Ptr; +#endif +} + +static inline bool js_check_stack_overflow(JSRuntime *rt, size_t alloca_size) +{ + uintptr_t sp; + sp = js_get_stack_pointer() - alloca_size; + return unlikely(sp < rt->stack_limit); +} + +JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque) +{ + JSRuntime *rt; + JSMallocState ms; + + memset(&ms, 0, sizeof(ms)); + ms.opaque = opaque; + ms.malloc_limit = 0; + + rt = mf->js_calloc(opaque, 1, sizeof(JSRuntime)); + if (!rt) + return NULL; + rt->mf = *mf; + if (!rt->mf.js_malloc_usable_size) { + /* use dummy function if none provided */ + rt->mf.js_malloc_usable_size = js_malloc_usable_size_unknown; + } + /* Inline what js_malloc_rt does since we cannot use it here. */ + ms.malloc_count++; + ms.malloc_size += rt->mf.js_malloc_usable_size(rt) + MALLOC_OVERHEAD; + rt->malloc_state = ms; + js_arena_init(rt); + rt->malloc_gc_threshold = 256 * 1024; + + init_list_head(&rt->context_list); + init_list_head(&rt->gc_obj_list); + init_list_head(&rt->gc_zero_ref_count_list); + rt->gc_phase = JS_GC_PHASE_NONE; + +#ifdef ENABLE_DUMPS // JS_DUMP_LEAKS + init_list_head(&rt->string_list); +#endif + init_list_head(&rt->job_list); + + if (JS_InitAtoms(rt)) + goto fail; + + /* create the object, array and function classes */ + if (init_class_range(rt, js_std_class_def, JS_CLASS_OBJECT, + countof(js_std_class_def)) < 0) + goto fail; + rt->class_array[JS_CLASS_ARGUMENTS].exotic = &js_arguments_exotic_methods; + rt->class_array[JS_CLASS_MAPPED_ARGUMENTS].exotic = &js_arguments_exotic_methods; + rt->class_array[JS_CLASS_STRING].exotic = &js_string_exotic_methods; + rt->class_array[JS_CLASS_MODULE_NS].exotic = &js_module_ns_exotic_methods; + + rt->class_array[JS_CLASS_C_FUNCTION].call = js_call_c_function; + rt->class_array[JS_CLASS_C_FUNCTION_DATA].call = js_call_c_function_data; + rt->class_array[JS_CLASS_C_CLOSURE].call = js_call_c_closure; + rt->class_array[JS_CLASS_BOUND_FUNCTION].call = js_call_bound_function; + rt->class_array[JS_CLASS_GENERATOR_FUNCTION].call = js_call_generator_function; + if (init_shape_hash(rt)) + goto fail; + + rt->js_class_id_alloc = JS_CLASS_INIT_COUNT; + + rt->stack_size = JS_DEFAULT_STACK_SIZE; + + JS_UpdateStackTop(rt); + + rt->current_exception = JS_UNINITIALIZED; + + return rt; + fail: + JS_FreeRuntime(rt); + return NULL; +} + +void *JS_GetRuntimeOpaque(JSRuntime *rt) +{ + return rt->user_opaque; +} + +void JS_SetRuntimeOpaque(JSRuntime *rt, void *opaque) +{ + rt->user_opaque = opaque; +} + +int JS_AddRuntimeFinalizer(JSRuntime *rt, JSRuntimeFinalizer *finalizer, + void *arg) +{ + JSRuntimeFinalizerState *fs = js_malloc_rt(rt, sizeof(*fs)); + if (!fs) + return -1; + fs->next = rt->finalizers; + fs->finalizer = finalizer; + fs->arg = arg; + rt->finalizers = fs; + return 0; +} + +static void *js_def_calloc(void *opaque, size_t count, size_t size) +{ + return calloc(count, size); +} + +static void *js_def_malloc(void *opaque, size_t size) +{ + return malloc(size); +} + +static void js_def_free(void *opaque, void *ptr) +{ + free(ptr); +} + +static void *js_def_realloc(void *opaque, void *ptr, size_t size) +{ + return realloc(ptr, size); +} + +static const JSMallocFunctions def_malloc_funcs = { + js_def_calloc, + js_def_malloc, + js_def_free, + js_def_realloc, + js__malloc_usable_size +}; + +JSRuntime *JS_NewRuntime(void) +{ + return JS_NewRuntime2(&def_malloc_funcs, NULL); +} + +void JS_SetMemoryLimit(JSRuntime *rt, size_t limit) +{ + rt->malloc_state.malloc_limit = limit; +} + +void JS_SetDumpFlags(JSRuntime *rt, uint64_t flags) +{ +#ifdef ENABLE_DUMPS + rt->dump_flags = flags; +#endif +} + +uint64_t JS_GetDumpFlags(JSRuntime *rt) +{ +#ifdef ENABLE_DUMPS + return rt->dump_flags; +#else + return 0; +#endif +} + +size_t JS_GetGCThreshold(JSRuntime *rt) { + return rt->malloc_gc_threshold; +} + +/* use -1 to disable automatic GC */ +void JS_SetGCThreshold(JSRuntime *rt, size_t gc_threshold) +{ + rt->malloc_gc_threshold = gc_threshold; +} + +#define malloc(s) malloc_is_forbidden(s) +#define free(p) free_is_forbidden(p) +#define realloc(p,s) realloc_is_forbidden(p,s) + +void JS_SetInterruptHandler(JSRuntime *rt, JSInterruptHandler *cb, void *opaque) +{ + rt->interrupt_handler = cb; + rt->interrupt_opaque = opaque; +} + +void JS_SetCanBlock(JSRuntime *rt, bool can_block) +{ + rt->can_block = can_block; +} + +void JS_SetSharedArrayBufferFunctions(JSRuntime *rt, + const JSSharedArrayBufferFunctions *sf) +{ + rt->sab_funcs = *sf; +} + +/* return 0 if OK, < 0 if exception */ +int JS_EnqueueJob(JSContext *ctx, JSJobFunc *job_func, + int argc, JSValueConst *argv) +{ + JSRuntime *rt = ctx->rt; + JSJobEntry *e; + int i; + + assert(!rt->in_free); + + e = js_malloc(ctx, sizeof(*e) + argc * sizeof(JSValue)); + if (!e) + return -1; + e->ctx = ctx; + e->job_func = job_func; + e->argc = argc; + for(i = 0; i < argc; i++) { + e->argv[i] = js_dup(argv[i]); + } + list_add_tail(&e->link, &rt->job_list); + return 0; +} + +bool JS_IsJobPending(JSRuntime *rt) +{ + return !list_empty(&rt->job_list); +} + +JSContext *JS_GetPendingJobContext(JSRuntime *rt) +{ + if (JS_IsJobPending(rt)) { + return list_entry(rt->job_list.next, JSJobEntry, link)->ctx; + } + return NULL; +} + +/* return < 0 if exception, 0 if no job pending, 1 if a job was + executed successfully. the context of the job is stored in '*pctx' */ +int JS_ExecutePendingJob(JSRuntime *rt, JSContext **pctx) +{ + JSContext *ctx; + JSJobEntry *e; + JSValue res; + int i, ret; + + if (list_empty(&rt->job_list)) { + *pctx = NULL; + return 0; + } + + /* get the first pending job and execute it */ + e = list_entry(rt->job_list.next, JSJobEntry, link); + list_del(&e->link); + ctx = e->ctx; + res = e->job_func(e->ctx, e->argc, vc(e->argv)); + for(i = 0; i < e->argc; i++) + JS_FreeValue(ctx, e->argv[i]); + if (JS_IsException(res)) + ret = -1; + else + ret = 1; + JS_FreeValue(ctx, res); + js_free(ctx, e); + *pctx = ctx; + return ret; +} + +static inline uint32_t atom_get_free(const JSAtomStruct *p) +{ + return (uintptr_t)p >> 1; +} + +static inline bool atom_is_free(const JSAtomStruct *p) +{ + return (uintptr_t)p & 1; +} + +static inline JSAtomStruct *atom_set_free(uint32_t v) +{ + return (JSAtomStruct *)(((uintptr_t)v << 1) | 1); +} + +/* Note: the string contents are uninitialized */ +static JSString *js_alloc_string_rt(JSRuntime *rt, int max_len, int is_wide_char) +{ + JSString *str; + str = js_malloc_rt(rt, sizeof(JSString) + (max_len << is_wide_char) + 1 - is_wide_char); + if (unlikely(!str)) + return NULL; + JS_REF_COUNT(str) = 1; + str->is_wide_char = is_wide_char; + str->len = max_len; + str->kind = JS_STRING_KIND_NORMAL; + str->atom_type = 0; + str->hash = 0; /* optional but costless */ + str->hash_next = 0; /* optional */ +#ifdef ENABLE_DUMPS // JS_DUMP_LEAKS + list_add_tail(&str->link, &rt->string_list); +#endif + return str; +} + +static JSString *js_alloc_string(JSContext *ctx, int max_len, int is_wide_char) +{ + JSString *p; + p = js_alloc_string_rt(ctx->rt, max_len, is_wide_char); + if (unlikely(!p)) { + JS_ThrowOutOfMemory(ctx); + return NULL; + } + return p; +} + +static inline void js_free_string0(JSRuntime *rt, JSString *str); + +/* same as JS_FreeValueRT() but faster */ +static inline void js_free_string(JSRuntime *rt, JSString *str) +{ + if (--JS_REF_COUNT(str) <= 0) + js_free_string0(rt, str); +} + +static inline void js_free_string0(JSRuntime *rt, JSString *str) +{ + JSStringSlice *slice; + + if (str->atom_type) { + JS_FreeAtomStruct(rt, str); + } else { +#ifdef ENABLE_DUMPS // JS_DUMP_LEAKS + list_del(&str->link); +#endif + switch (str->kind) { + case JS_STRING_KIND_SLICE: + slice = (void *)&str[1]; + js_free_string(rt, slice->parent); // safe, recurses only 1 level + break; + case JS_STRING_KIND_INDIRECT: + js_free_rt(rt, strv(str)); + break; + } + js_free_rt(rt, str); + } +} + +void JS_SetRuntimeInfo(JSRuntime *rt, const char *s) +{ + if (rt) + rt->rt_info = s; +} + +void JS_FreeRuntime(JSRuntime *rt) +{ + struct list_head *el, *el1; + bool leak = false; + int i; + + rt->in_free = true; + JS_FreeValueRT(rt, rt->current_exception); + + list_for_each_safe(el, el1, &rt->job_list) { + JSJobEntry *e = list_entry(el, JSJobEntry, link); + for(i = 0; i < e->argc; i++) + JS_FreeValueRT(rt, e->argv[i]); + js_free_rt(rt, e); + } + init_list_head(&rt->job_list); + + JS_RunGC(rt); + +#ifdef ENABLE_DUMPS // JS_DUMP_LEAKS + /* leaking objects */ + if (check_dump_flag(rt, JS_DUMP_LEAKS)) { + bool header_done; + JSGCObjectHeader *p; + int count; + + /* remove the internal refcounts to display only the object + referenced externally */ + list_for_each(el, &rt->gc_obj_list) { + p = list_entry(el, JSGCObjectHeader, link); + JS_GC_MARK(p) = 0; + } + gc_decref(rt); + + header_done = false; + list_for_each(el, &rt->gc_obj_list) { + p = list_entry(el, JSGCObjectHeader, link); + if (JS_REF_COUNT(p) != 0) { + if (!header_done) { + printf("Object leaks:\n"); + JS_DumpObjectHeader(rt); + header_done = true; + } + JS_DumpGCObject(rt, p); + leak = true; + } + } + + count = 0; + list_for_each(el, &rt->gc_obj_list) { + p = list_entry(el, JSGCObjectHeader, link); + if (JS_REF_COUNT(p) == 0) { + count++; + } + } + if (count != 0) + printf("Secondary object leaks: %d\n", count); + } +#endif + + assert(list_empty(&rt->gc_obj_list)); + + /* free the classes */ + for(i = 0; i < rt->class_count; i++) { + JSClass *cl = &rt->class_array[i]; + if (cl->class_id != 0) { + JS_FreeAtomRT(rt, cl->class_name); + } + } + js_free_rt(rt, rt->class_array); + +#ifdef ENABLE_DUMPS // JS_DUMP_ATOM_LEAKS + /* only the atoms defined in JS_InitAtoms() should be left */ + if (check_dump_flag(rt, JS_DUMP_ATOM_LEAKS)) { + bool header_done = false; + + for(i = 0; i < rt->atom_size; i++) { + JSAtomStruct *p = rt->atom_array[i]; + if (!atom_is_free(p) /* && p->str*/) { + if (i >= JS_ATOM_END || JS_REF_COUNT(p) != 1) { + if (!header_done) { + header_done = true; + if (rt->rt_info) { + printf("%s:1: atom leakage:", rt->rt_info); + } else { + printf("Atom leaks:\n" + " %6s %6s %s\n", + "ID", "REFCNT", "NAME"); + } + } + if (rt->rt_info) { + printf(" "); + } else { + printf(" %6u %6u ", i, JS_REF_COUNT(p)); + } + switch (p->atom_type) { + case JS_ATOM_TYPE_STRING: + JS_DumpString(rt, p); + break; + case JS_ATOM_TYPE_GLOBAL_SYMBOL: + printf("Symbol.for("); + JS_DumpString(rt, p); + printf(")"); + break; + case JS_ATOM_TYPE_SYMBOL: + if (p->hash == JS_ATOM_HASH_SYMBOL) { + printf("Symbol("); + JS_DumpString(rt, p); + printf(")"); + } else { + printf("Private("); + JS_DumpString(rt, p); + printf(")"); + } + break; + } + if (rt->rt_info) { + printf(":%u", JS_REF_COUNT(p)); + } else { + printf("\n"); + } + leak = true; + } + } + } + if (rt->rt_info && header_done) + printf("\n"); + } +#endif + + /* free the atoms */ + for(i = 0; i < rt->atom_size; i++) { + JSAtomStruct *p = rt->atom_array[i]; + if (!atom_is_free(p)) { +#ifdef ENABLE_DUMPS // JS_DUMP_LEAKS + list_del(&p->link); +#endif + js_free_rt(rt, p); + } + } + js_free_rt(rt, rt->atom_array); + js_free_rt(rt, rt->atom_hash); + js_free_rt(rt, rt->shape_hash); +#ifdef ENABLE_DUMPS // JS_DUMP_LEAKS + if (check_dump_flag(rt, JS_DUMP_LEAKS) && !list_empty(&rt->string_list)) { + if (rt->rt_info) { + printf("%s:1: string leakage:", rt->rt_info); + } else { + printf("String leaks:\n" + " %6s %s\n", + "REFCNT", "VALUE"); + } + list_for_each_safe(el, el1, &rt->string_list) { + JSString *str = list_entry(el, JSString, link); + if (rt->rt_info) { + printf(" "); + } else { + printf(" %6u ", JS_REF_COUNT(str)); + } + JS_DumpString(rt, str); + if (rt->rt_info) { + printf(":%u", JS_REF_COUNT(str)); + } else { + printf("\n"); + } + list_del(&str->link); + js_free_rt(rt, str); + } + if (rt->rt_info) + printf("\n"); + leak = true; + } +#endif + + while (rt->finalizers) { + JSRuntimeFinalizerState *fs = rt->finalizers; + rt->finalizers = fs->next; + fs->finalizer(rt, fs->arg); + js_free_rt(rt, fs); + } + +#ifdef ENABLE_DUMPS // JS_DUMP_LEAKS + if (check_dump_flag(rt, JS_DUMP_LEAKS)) { + JSMallocState *s = &rt->malloc_state; + if (s->malloc_count > 1) { + if (rt->rt_info) + printf("%s:1: ", rt->rt_info); + printf("Memory leak: %zd bytes lost in %zd block%s\n", + s->malloc_size - sizeof(JSRuntime), + s->malloc_count - 1, &"s"[s->malloc_count == 2]); + leak = true; + } + } +#endif + + leak &= check_dump_flag(rt, JS_ABORT_ON_LEAKS); + + js_arena_free_all(rt); + + { + JSMallocState *ms = &rt->malloc_state; + rt->mf.js_free(ms->opaque, rt); + } + + if (leak) + abort(); +} + +JSContext *JS_NewContextRaw(JSRuntime *rt) +{ + JSContext *ctx; + int i; + + ctx = js_mallocz_rt(rt, sizeof(JSContext)); + if (!ctx) + return NULL; + JS_REF_COUNT(ctx) = 1; + add_gc_object(rt, &ctx->header, JS_GC_OBJ_TYPE_JS_CONTEXT); + + ctx->class_proto = js_malloc_rt(rt, sizeof(ctx->class_proto[0]) * + rt->class_count); + if (!ctx->class_proto) { + remove_gc_object(&ctx->header); + js_free_rt(rt, ctx); + return NULL; + } + ctx->rt = rt; + list_add_tail(&ctx->link, &rt->context_list); + for(i = 0; i < rt->class_count; i++) + ctx->class_proto[i] = JS_NULL; + ctx->array_ctor = JS_NULL; + ctx->iterator_ctor = JS_NULL; + ctx->iterator_ctor_getset = JS_NULL; + ctx->regexp_ctor = JS_NULL; + ctx->promise_ctor = JS_NULL; + ctx->error_ctor = JS_NULL; + ctx->error_back_trace = JS_UNDEFINED; + ctx->error_prepare_stack = JS_UNDEFINED; + ctx->error_stack_trace_limit = js_int32(10); + init_list_head(&ctx->loaded_modules); + // TODO(bnoordhuis) use getrandom() etc. + ctx->random_state = js__gettimeofday_us(); + // the state must be non zero + if (ctx->random_state == 0) + ctx->random_state = 1; + ctx->hash_seed = xorshift64star(&ctx->random_state); + + if (JS_AddIntrinsicBasicObjects(ctx)) { + JS_FreeContext(ctx); + return NULL; + } + return ctx; +} + +JSContext *JS_NewContext(JSRuntime *rt) +{ + JSContext *ctx; + ctx = JS_NewContextRaw(rt); + if (!ctx) + return NULL; + + if (JS_AddIntrinsicBaseObjects(ctx) || + JS_AddIntrinsicDate(ctx) || + JS_AddIntrinsicEval(ctx) || + JS_AddIntrinsicRegExp(ctx) || + JS_AddIntrinsicJSON(ctx) || + JS_AddIntrinsicProxy(ctx) || + JS_AddIntrinsicMapSet(ctx) || + JS_AddIntrinsicTypedArrays(ctx) || + JS_AddIntrinsicPromise(ctx) || + JS_AddIntrinsicWeakRef(ctx) || + JS_AddIntrinsicAToB(ctx) || + JS_AddPerformance(ctx)) { + JS_FreeContext(ctx); + return NULL; + } + + return ctx; +} + +void *JS_GetContextOpaque(JSContext *ctx) +{ + return ctx->user_opaque; +} + +void JS_SetContextOpaque(JSContext *ctx, void *opaque) +{ + ctx->user_opaque = opaque; +} + +/* set the new value and free the old value after (freeing the value + can reallocate the object data) */ +static inline void set_value(JSContext *ctx, JSValue *pval, JSValue new_val) +{ + JSValue old_val; + old_val = *pval; + *pval = new_val; + JS_FreeValue(ctx, old_val); +} + +void JS_SetClassProto(JSContext *ctx, JSClassID class_id, JSValue obj) +{ + assert(class_id < ctx->rt->class_count); + set_value(ctx, &ctx->class_proto[class_id], obj); +} + +JSValue JS_GetClassProto(JSContext *ctx, JSClassID class_id) +{ + assert(class_id < ctx->rt->class_count); + return js_dup(ctx->class_proto[class_id]); +} + +JSValue JS_GetFunctionProto(JSContext *ctx) +{ + return js_dup(ctx->function_proto); +} + +typedef enum JSFreeModuleEnum { + JS_FREE_MODULE_ALL, + JS_FREE_MODULE_NOT_RESOLVED, +} JSFreeModuleEnum; + +/* XXX: would be more efficient with separate module lists */ +static void js_free_modules(JSContext *ctx, JSFreeModuleEnum flag) +{ + struct list_head *el, *el1; + list_for_each_safe(el, el1, &ctx->loaded_modules) { + JSModuleDef *m = list_entry(el, JSModuleDef, link); + if (flag == JS_FREE_MODULE_ALL || + (flag == JS_FREE_MODULE_NOT_RESOLVED && !m->resolved)) { + js_free_module_def(ctx, m); + } + } +} + +JSContext *JS_DupContext(JSContext *ctx) +{ + JS_REF_COUNT(ctx)++; + return ctx; +} + +/* used by the GC */ +static void JS_MarkContext(JSRuntime *rt, JSContext *ctx, + JS_MarkFunc *mark_func) +{ + int i; + struct list_head *el; + + /* modules are not seen by the GC, so we directly mark the objects + referenced by each module */ + list_for_each(el, &ctx->loaded_modules) { + JSModuleDef *m = list_entry(el, JSModuleDef, link); + js_mark_module_def(rt, m, mark_func); + } + + JS_MarkValue(rt, ctx->global_obj, mark_func); + JS_MarkValue(rt, ctx->global_var_obj, mark_func); + + JS_MarkValue(rt, ctx->throw_type_error, mark_func); + JS_MarkValue(rt, ctx->eval_obj, mark_func); + + JS_MarkValue(rt, ctx->array_proto_values, mark_func); + for(i = 0; i < JS_NATIVE_ERROR_COUNT; i++) { + JS_MarkValue(rt, ctx->native_error_proto[i], mark_func); + } + JS_MarkValue(rt, ctx->error_ctor, mark_func); + JS_MarkValue(rt, ctx->error_back_trace, mark_func); + JS_MarkValue(rt, ctx->error_prepare_stack, mark_func); + JS_MarkValue(rt, ctx->error_stack_trace_limit, mark_func); + for(i = 0; i < rt->class_count; i++) { + JS_MarkValue(rt, ctx->class_proto[i], mark_func); + } + JS_MarkValue(rt, ctx->iterator_ctor, mark_func); + JS_MarkValue(rt, ctx->iterator_ctor_getset, mark_func); + JS_MarkValue(rt, ctx->async_iterator_proto, mark_func); + JS_MarkValue(rt, ctx->promise_ctor, mark_func); + JS_MarkValue(rt, ctx->array_ctor, mark_func); + JS_MarkValue(rt, ctx->regexp_ctor, mark_func); + JS_MarkValue(rt, ctx->function_ctor, mark_func); + JS_MarkValue(rt, ctx->function_proto, mark_func); + + if (ctx->array_shape) + mark_func(rt, &ctx->array_shape->header); + + if (ctx->arguments_shape) + mark_func(rt, &ctx->arguments_shape->header); + + if (ctx->mapped_arguments_shape) + mark_func(rt, &ctx->mapped_arguments_shape->header); + + if (ctx->regexp_shape) + mark_func(rt, &ctx->regexp_shape->header); + + if (ctx->regexp_result_shape) + mark_func(rt, &ctx->regexp_result_shape->header); +} + +void JS_FreeContext(JSContext *ctx) +{ + JSRuntime *rt = ctx->rt; + int i; + + if (--JS_REF_COUNT(ctx) > 0) + return; + assert(JS_REF_COUNT(ctx) == 0); + +#ifdef ENABLE_DUMPS // JS_DUMP_ATOMS + if (check_dump_flag(rt, JS_DUMP_ATOMS)) + JS_DumpAtoms(ctx->rt); +#endif +#ifdef ENABLE_DUMPS // JS_DUMP_SHAPES + if (check_dump_flag(rt, JS_DUMP_SHAPES)) + JS_DumpShapes(ctx->rt); +#endif +#ifdef ENABLE_DUMPS // JS_DUMP_OBJECTS + if (check_dump_flag(rt, JS_DUMP_OBJECTS)) { + struct list_head *el; + JSGCObjectHeader *p; + printf("JSObjects: {\n"); + JS_DumpObjectHeader(ctx->rt); + list_for_each(el, &rt->gc_obj_list) { + p = list_entry(el, JSGCObjectHeader, link); + JS_DumpGCObject(rt, p); + } + printf("}\n"); + } +#endif +#ifdef ENABLE_DUMPS // JS_DUMP_MEM + if (check_dump_flag(rt, JS_DUMP_MEM)) { + JSMemoryUsage stats; + JS_ComputeMemoryUsage(rt, &stats); + JS_DumpMemoryUsage(stdout, &stats, rt); + } +#endif + + js_free_modules(ctx, JS_FREE_MODULE_ALL); + + JS_FreeValue(ctx, ctx->global_obj); + JS_FreeValue(ctx, ctx->global_var_obj); + + JS_FreeValue(ctx, ctx->throw_type_error); + JS_FreeValue(ctx, ctx->eval_obj); + + JS_FreeValue(ctx, ctx->array_proto_values); + for(i = 0; i < JS_NATIVE_ERROR_COUNT; i++) { + JS_FreeValue(ctx, ctx->native_error_proto[i]); + } + JS_FreeValue(ctx, ctx->error_ctor); + JS_FreeValue(ctx, ctx->error_back_trace); + JS_FreeValue(ctx, ctx->error_prepare_stack); + JS_FreeValue(ctx, ctx->error_stack_trace_limit); + for(i = 0; i < rt->class_count; i++) { + JS_FreeValue(ctx, ctx->class_proto[i]); + } + js_free_rt(rt, ctx->class_proto); + JS_FreeValue(ctx, ctx->iterator_ctor); + JS_FreeValue(ctx, ctx->iterator_ctor_getset); + JS_FreeValue(ctx, ctx->async_iterator_proto); + JS_FreeValue(ctx, ctx->promise_ctor); + JS_FreeValue(ctx, ctx->array_ctor); + JS_FreeValue(ctx, ctx->regexp_ctor); + JS_FreeValue(ctx, ctx->function_ctor); + JS_FreeValue(ctx, ctx->function_proto); + + js_free_shape_null(ctx->rt, ctx->array_shape); + js_free_shape_null(ctx->rt, ctx->arguments_shape); + js_free_shape_null(ctx->rt, ctx->mapped_arguments_shape); + js_free_shape_null(ctx->rt, ctx->regexp_shape); + js_free_shape_null(ctx->rt, ctx->regexp_result_shape); + + list_del(&ctx->link); + remove_gc_object(&ctx->header); + js_free_rt(ctx->rt, ctx); +} + +JSRuntime *JS_GetRuntime(JSContext *ctx) +{ + return ctx->rt; +} + +static void update_stack_limit(JSRuntime *rt) +{ + if (rt->stack_size == 0 || rt->stack_top < rt->stack_size) { + rt->stack_limit = 0; /* no limit */ + } else { + rt->stack_limit = rt->stack_top - rt->stack_size; + } +} + +void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size) +{ + rt->stack_size = stack_size; + update_stack_limit(rt); +} + +void JS_UpdateStackTop(JSRuntime *rt) +{ + rt->stack_top = js_get_stack_pointer(); + update_stack_limit(rt); +} + +static inline bool is_strict_mode(JSContext *ctx) +{ + JSStackFrame *sf = ctx->rt->current_stack_frame; + return sf && sf->is_strict_mode; +} + +/* JSAtom support */ + +#define JS_ATOM_TAG_INT (1U << 31) +#define JS_ATOM_MAX_INT (JS_ATOM_TAG_INT - 1) +#define JS_ATOM_MAX ((1U << 30) - 1) + +/* return the max count from the hash size */ +#define JS_ATOM_COUNT_RESIZE(n) ((n) * 2) + +static inline bool __JS_AtomIsConst(JSAtom v) +{ + return (int32_t)v < JS_ATOM_END; +} + +static inline bool __JS_AtomIsTaggedInt(JSAtom v) +{ + return (v & JS_ATOM_TAG_INT) != 0; +} + +static inline JSAtom __JS_AtomFromUInt32(uint32_t v) +{ + return v | JS_ATOM_TAG_INT; +} + +static inline uint32_t __JS_AtomToUInt32(JSAtom atom) +{ + return atom & ~JS_ATOM_TAG_INT; +} + +static inline int is_num(int c) +{ + return c >= '0' && c <= '9'; +} + +/* return true if the string is a number n with 0 <= n <= 2^32-1 */ +static inline bool is_num_string(uint32_t *pval, JSString *p) +{ + uint32_t n; + uint64_t n64; + int c, i, len; + + len = p->len; + if (len == 0 || len > 10) + return false; + c = string_get(p, 0); + if (is_num(c)) { + if (c == '0') { + if (len != 1) + return false; + n = 0; + } else { + n = c - '0'; + for(i = 1; i < len; i++) { + c = string_get(p, i); + if (!is_num(c)) + return false; + n64 = (uint64_t)n * 10 + (c - '0'); + if ((n64 >> 32) != 0) + return false; + n = n64; + } + } + *pval = n; + return true; + } else { + return false; + } +} + +/* XXX: could use faster version ? */ +static inline uint32_t hash_string8(const uint8_t *str, size_t len, uint32_t h) +{ + size_t i; + + for(i = 0; i < len; i++) + h = h * 263 + str[i]; + return h ^ hash32(len); +} + +static inline uint32_t hash_string16(const uint16_t *str, + size_t len, uint32_t h) +{ + size_t i; + + for(i = 0; i < len; i++) + h = h * 263 + str[i]; + return h ^ hash32(len); +} + +static uint32_t hash_string(JSString *str, uint32_t h) +{ + if (str->is_wide_char) + h = hash_string16(str16(str), str->len, h); + else + h = hash_string8(str8(str), str->len, h); + return h; +} + +static uint32_t hash_string_rope(JSValueConst val, uint32_t h) +{ + if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING) { + return hash_string(JS_VALUE_GET_STRING(val), h); + } else { + JSStringRope *r = JS_VALUE_GET_STRING_ROPE(val); + h = hash_string_rope(r->left, h); + return hash_string_rope(r->right, h); + } +} + +static __maybe_unused void JS_DumpString(JSRuntime *rt, JSString *p) +{ + int i, c, sep; + + if (p == NULL) { + printf(""); + return; + } + if (JS_REF_COUNT(p) != 1) + printf("%d", JS_REF_COUNT(p)); + if (p->is_wide_char) + putchar('L'); + sep = '\"'; + putchar(sep); + for(i = 0; i < p->len; i++) { + c = string_get(p, i); + if (c == sep || c == '\\') { + putchar('\\'); + putchar(c); + } else if (c >= ' ' && c <= 126) { + putchar(c); + } else if (c == '\n') { + putchar('\\'); + putchar('n'); + } else { + printf("\\u%04x", c); + } + } + putchar(sep); +} + +static __maybe_unused void JS_DumpAtoms(JSRuntime *rt) +{ + JSAtomStruct *p; + int h, i; + /* This only dumps hashed atoms, not JS_ATOM_TYPE_SYMBOL atoms */ + printf("JSAtom count=%d size=%d hash_size=%d:\n", + rt->atom_count, rt->atom_size, rt->atom_hash_size); + printf("JSAtom hash table: {\n"); + for(i = 0; i < rt->atom_hash_size; i++) { + h = rt->atom_hash[i]; + if (h) { + printf(" %d:", i); + while (h) { + p = rt->atom_array[h]; + printf(" "); + JS_DumpString(rt, p); + h = p->hash_next; + } + printf("\n"); + } + } + printf("}\n"); + printf("JSAtom table: {\n"); + for(i = 0; i < rt->atom_size; i++) { + p = rt->atom_array[i]; + if (!atom_is_free(p)) { + printf(" %d: { %d %08x ", i, p->atom_type, p->hash); + if (!(p->len == 0 && p->is_wide_char != 0)) + JS_DumpString(rt, p); + printf(" %d }\n", p->hash_next); + } + } + printf("}\n"); +} + +static int JS_ResizeAtomHash(JSRuntime *rt, int new_hash_size) +{ + JSAtomStruct *p; + uint32_t new_hash_mask, h, i, hash_next1, j, *new_hash; + + assert((new_hash_size & (new_hash_size - 1)) == 0); /* power of two */ + new_hash_mask = new_hash_size - 1; + new_hash = js_mallocz_rt(rt, sizeof(rt->atom_hash[0]) * new_hash_size); + if (!new_hash) + return -1; + for(i = 0; i < rt->atom_hash_size; i++) { + h = rt->atom_hash[i]; + while (h != 0) { + p = rt->atom_array[h]; + hash_next1 = p->hash_next; + /* add in new hash table */ + j = p->hash & new_hash_mask; + p->hash_next = new_hash[j]; + new_hash[j] = h; + h = hash_next1; + } + } + js_free_rt(rt, rt->atom_hash); + rt->atom_hash = new_hash; + rt->atom_hash_size = new_hash_size; + rt->atom_count_resize = JS_ATOM_COUNT_RESIZE(new_hash_size); + // JS_DumpAtoms(rt); + return 0; +} + +static int JS_InitAtoms(JSRuntime *rt) +{ + int i, len, atom_type; + const char *p; + + rt->atom_hash_size = 0; + rt->atom_hash = NULL; + rt->atom_count = 0; + rt->atom_size = 0; + rt->atom_free_index = 0; + if (JS_ResizeAtomHash(rt, 1024)) // there are at least 587 predefined atoms + return -1; + + p = js_atom_init; + for(i = 1; i < JS_ATOM_END; i++) { + if (i == JS_ATOM_Private_brand) + atom_type = JS_ATOM_TYPE_PRIVATE; + else if (i >= JS_ATOM_Symbol_toPrimitive) + atom_type = JS_ATOM_TYPE_SYMBOL; + else + atom_type = JS_ATOM_TYPE_STRING; + len = strlen(p); + if (__JS_NewAtomInit(rt, p, len, atom_type) == JS_ATOM_NULL) + return -1; + p = p + len + 1; + } + return 0; +} + +JSAtom JS_DupAtomRT(JSRuntime *rt, JSAtom v) +{ + JSAtomStruct *p; + + if (!__JS_AtomIsConst(v)) { + p = rt->atom_array[v]; + JS_REF_COUNT(p)++; + } + return v; +} + +JSAtom JS_DupAtom(JSContext *ctx, JSAtom v) +{ + JSRuntime *rt; + JSAtomStruct *p; + + if (!__JS_AtomIsConst(v)) { + rt = ctx->rt; + p = rt->atom_array[v]; + JS_REF_COUNT(p)++; + } + return v; +} + +static JSAtomKindEnum JS_AtomGetKind(JSContext *ctx, JSAtom v) +{ + JSRuntime *rt; + JSAtomStruct *p; + + rt = ctx->rt; + if (__JS_AtomIsTaggedInt(v)) + return JS_ATOM_KIND_STRING; + p = rt->atom_array[v]; + switch(p->atom_type) { + case JS_ATOM_TYPE_STRING: + return JS_ATOM_KIND_STRING; + case JS_ATOM_TYPE_GLOBAL_SYMBOL: + return JS_ATOM_KIND_SYMBOL; + case JS_ATOM_TYPE_SYMBOL: + switch(p->hash) { + case JS_ATOM_HASH_SYMBOL: + return JS_ATOM_KIND_SYMBOL; + case JS_ATOM_HASH_PRIVATE: + return JS_ATOM_KIND_PRIVATE; + default: + abort(); + } + default: + abort(); + } + return (JSAtomKindEnum){-1}; // pacify compiler +} + +static JSAtom js_get_atom_index(JSRuntime *rt, JSAtomStruct *p) +{ + uint32_t i = p->hash_next; /* atom_index */ + if (p->atom_type != JS_ATOM_TYPE_SYMBOL) { + JSAtomStruct *p1; + + i = rt->atom_hash[p->hash & (rt->atom_hash_size - 1)]; + p1 = rt->atom_array[i]; + while (p1 != p) { + assert(i != 0); + i = p1->hash_next; + p1 = rt->atom_array[i]; + } + } + return i; +} + +/* string case (internal). Return JS_ATOM_NULL if error. 'str' is + freed. */ +static JSAtom __JS_NewAtom(JSRuntime *rt, JSString *str, int atom_type) +{ + uint32_t h, h1, i; + JSAtomStruct *p; + int len; + + if (atom_type < JS_ATOM_TYPE_SYMBOL) { + /* str is not NULL */ + if (str->atom_type == atom_type) { + /* str is the atom, return its index */ + i = js_get_atom_index(rt, str); + /* reduce string refcount and increase atom's unless constant */ + if (__JS_AtomIsConst(i)) + JS_REF_COUNT(str)--; + return i; + } + /* try and locate an already registered atom */ + len = str->len; + h = hash_string(str, atom_type); + h &= JS_ATOM_HASH_MASK; + h1 = h & (rt->atom_hash_size - 1); + i = rt->atom_hash[h1]; + while (i != 0) { + p = rt->atom_array[i]; + if (p->hash == h && + p->atom_type == atom_type && + p->len == len && + js_string_memcmp(p, str, len) == 0) { + if (!__JS_AtomIsConst(i)) + JS_REF_COUNT(p)++; + goto done; + } + i = p->hash_next; + } + } else { + h1 = 0; /* avoid warning */ + if (atom_type == JS_ATOM_TYPE_SYMBOL) { + h = JS_ATOM_HASH_SYMBOL; + } else { + h = JS_ATOM_HASH_PRIVATE; + atom_type = JS_ATOM_TYPE_SYMBOL; + } + } + + if (rt->atom_free_index == 0) { + /* allow new atom entries */ + uint32_t new_size, start; + JSAtomStruct **new_array; + + /* alloc new with size progression 3/2: + 4 6 9 13 19 28 42 63 94 141 211 316 474 711 1066 1599 2398 3597 5395 8092 + preallocating space for predefined atoms (at least 504). + */ + new_size = max_int(711, rt->atom_size * 3 / 2); + if (new_size > JS_ATOM_MAX) + goto fail; + new_array = js_realloc_rt(rt, rt->atom_array, sizeof(*new_array) * new_size); + if (!new_array) + goto fail; + /* Note: the atom 0 is not used */ + start = rt->atom_size; + if (start == 0) { + /* JS_ATOM_NULL entry */ + p = js_mallocz_rt(rt, sizeof(JSAtomStruct)); + if (!p) { + js_free_rt(rt, new_array); + goto fail; + } + JS_REF_COUNT(p) = 1; /* not refcounted */ + p->atom_type = JS_ATOM_TYPE_SYMBOL; +#ifdef ENABLE_DUMPS // JS_DUMP_LEAKS + list_add_tail(&p->link, &rt->string_list); +#endif + new_array[0] = p; + rt->atom_count++; + start = 1; + } + rt->atom_size = new_size; + rt->atom_array = new_array; + rt->atom_free_index = start; + for(i = start; i < new_size; i++) { + uint32_t next; + if (i == (new_size - 1)) + next = 0; + else + next = i + 1; + rt->atom_array[i] = atom_set_free(next); + } + } + + if (str) { + if (str->atom_type == 0) { + p = str; + p->atom_type = atom_type; + } else { + p = js_malloc_rt(rt, sizeof(JSString) + + (str->len << str->is_wide_char) + + 1 - str->is_wide_char); + if (unlikely(!p)) + goto fail; + JS_REF_COUNT(p) = 1; + p->is_wide_char = str->is_wide_char; + p->len = str->len; + p->kind = JS_STRING_KIND_NORMAL; +#ifdef ENABLE_DUMPS // JS_DUMP_LEAKS + list_add_tail(&p->link, &rt->string_list); +#endif + memcpy(str8(p), str8(str), (str->len << str->is_wide_char) + + 1 - str->is_wide_char); + js_free_string(rt, str); + } + } else { + p = js_malloc_rt(rt, sizeof(JSAtomStruct)); /* empty wide string */ + if (!p) + return JS_ATOM_NULL; + JS_REF_COUNT(p) = 1; + p->is_wide_char = 1; /* Hack to represent NULL as a JSString */ + p->len = 0; + p->kind = JS_STRING_KIND_NORMAL; +#ifdef ENABLE_DUMPS // JS_DUMP_LEAKS + list_add_tail(&p->link, &rt->string_list); +#endif + } + + /* use an already free entry */ + i = rt->atom_free_index; + rt->atom_free_index = atom_get_free(rt->atom_array[i]); + rt->atom_array[i] = p; + + p->hash = h; + p->hash_next = i; /* atom_index */ + p->atom_type = atom_type; + p->first_weak_ref = NULL; + + rt->atom_count++; + + if (atom_type != JS_ATOM_TYPE_SYMBOL) { + p->hash_next = rt->atom_hash[h1]; + rt->atom_hash[h1] = i; + if (unlikely(rt->atom_count >= rt->atom_count_resize)) + JS_ResizeAtomHash(rt, rt->atom_hash_size * 2); + } + + // JS_DumpAtoms(rt); + return i; + + fail: + i = JS_ATOM_NULL; + done: + if (str) + js_free_string(rt, str); + return i; +} + +// XXX: `str` must be pure ASCII. No UTF-8 encoded strings +// XXX: `str` must not be the string representation of a small integer +static JSAtom __JS_NewAtomInit(JSRuntime *rt, const char *str, int len, + int atom_type) +{ + JSString *p; + p = js_alloc_string_rt(rt, len, 0); + if (!p) + return JS_ATOM_NULL; + memcpy(str8(p), str, len); + str8(p)[len] = '\0'; + return __JS_NewAtom(rt, p, atom_type); +} + +// XXX: `str` must be raw 8-bit contents. No UTF-8 encoded strings +static JSAtom __JS_FindAtom(JSRuntime *rt, const char *str, size_t len, + int atom_type) +{ + uint32_t h, h1, i; + JSAtomStruct *p; + + h = hash_string8((const uint8_t *)str, len, JS_ATOM_TYPE_STRING); + h &= JS_ATOM_HASH_MASK; + h1 = h & (rt->atom_hash_size - 1); + i = rt->atom_hash[h1]; + while (i != 0) { + p = rt->atom_array[i]; + if (p->hash == h && + p->atom_type == JS_ATOM_TYPE_STRING && + p->len == len && + p->is_wide_char == 0 && + memcmp(str8(p), str, len) == 0) { + if (!__JS_AtomIsConst(i)) + JS_REF_COUNT(p)++; + return i; + } + i = p->hash_next; + } + return JS_ATOM_NULL; +} + +static void JS_FreeAtomStruct(JSRuntime *rt, JSAtomStruct *p) +{ + uint32_t i = p->hash_next; /* atom_index */ + if (p->atom_type != JS_ATOM_TYPE_SYMBOL) { + JSAtomStruct *p0, *p1; + uint32_t h0; + + h0 = p->hash & (rt->atom_hash_size - 1); + i = rt->atom_hash[h0]; + p1 = rt->atom_array[i]; + if (p1 == p) { + rt->atom_hash[h0] = p1->hash_next; + } else { + for(;;) { + assert(i != 0); + p0 = p1; + i = p1->hash_next; + p1 = rt->atom_array[i]; + if (p1 == p) { + p0->hash_next = p1->hash_next; + break; + } + } + } + } + /* insert in free atom list */ + rt->atom_array[i] = atom_set_free(rt->atom_free_index); + rt->atom_free_index = i; + if (unlikely(p->first_weak_ref)) { + reset_weak_ref(rt, &p->first_weak_ref); + } + /* free the string structure */ +#ifdef ENABLE_DUMPS // JS_DUMP_LEAKS + list_del(&p->link); +#endif + js_free_rt(rt, p); + rt->atom_count--; + assert(rt->atom_count >= 0); +} + +static void __JS_FreeAtom(JSRuntime *rt, uint32_t i) +{ + JSAtomStruct *p; + + p = rt->atom_array[i]; + if (--JS_REF_COUNT(p) > 0) + return; + JS_FreeAtomStruct(rt, p); +} + +/* Warning: 'p' is freed */ +static JSAtom JS_NewAtomStr(JSContext *ctx, JSString *p) +{ + JSRuntime *rt = ctx->rt; + uint32_t n; + if (is_num_string(&n, p)) { + if (n <= JS_ATOM_MAX_INT) { + js_free_string(rt, p); + return __JS_AtomFromUInt32(n); + } + } + /* XXX: should generate an exception */ + return __JS_NewAtom(rt, p, JS_ATOM_TYPE_STRING); +} + +/* `str` may be pure ASCII or UTF-8 encoded */ +JSAtom JS_NewAtomLen(JSContext *ctx, const char *str, size_t len) +{ + JSValue val; + + if (len == 0 || !is_digit(*str)) { + // TODO(chqrlie): this does not work if `str` has UTF-8 encoded contents + // bug example: `({ "\u00c3\u00a9": 1 }).\u00e9` evaluates to `1`. + JSAtom atom = __JS_FindAtom(ctx->rt, str, len, JS_ATOM_TYPE_STRING); + if (atom) + return atom; + } + val = JS_NewStringLen(ctx, str, len); + if (JS_IsException(val)) + return JS_ATOM_NULL; + return JS_NewAtomStr(ctx, JS_VALUE_GET_STRING(val)); +} + +/* `str` may be pure ASCII or UTF-8 encoded */ +JSAtom JS_NewAtom(JSContext *ctx, const char *str) +{ + return JS_NewAtomLen(ctx, str, strlen(str)); +} + +JSAtom JS_NewAtomUInt32(JSContext *ctx, uint32_t n) +{ + if (n <= JS_ATOM_MAX_INT) { + return __JS_AtomFromUInt32(n); + } else { + char buf[16]; + size_t len = u32toa(buf, n); + JSValue val = js_new_string8_len(ctx, buf, len); + if (JS_IsException(val)) + return JS_ATOM_NULL; + return __JS_NewAtom(ctx->rt, JS_VALUE_GET_STRING(val), + JS_ATOM_TYPE_STRING); + } +} + +static JSAtom JS_NewAtomInt64(JSContext *ctx, int64_t n) +{ + if ((uint64_t)n <= JS_ATOM_MAX_INT) { + return __JS_AtomFromUInt32((uint32_t)n); + } else { + char buf[24]; + size_t len = i64toa(buf, n); + JSValue val = js_new_string8_len(ctx, buf, len); + if (JS_IsException(val)) + return JS_ATOM_NULL; + return __JS_NewAtom(ctx->rt, JS_VALUE_GET_STRING(val), + JS_ATOM_TYPE_STRING); + } +} + +/* 'p' is freed */ +static JSValue JS_NewSymbolInternal(JSContext *ctx, JSString *p, int atom_type) +{ + JSRuntime *rt = ctx->rt; + JSAtom atom; + atom = __JS_NewAtom(rt, p, atom_type); + if (atom == JS_ATOM_NULL) + return JS_ThrowOutOfMemory(ctx); + return JS_MKPTR(JS_TAG_SYMBOL, rt->atom_array[atom]); +} + +/* descr must be a non-numeric string atom */ +static JSValue JS_NewSymbolFromAtom(JSContext *ctx, JSAtom descr, + int atom_type) +{ + JSRuntime *rt = ctx->rt; + JSString *p; + + assert(!__JS_AtomIsTaggedInt(descr)); + assert(descr < rt->atom_size); + p = rt->atom_array[descr]; + js_dup(JS_MKPTR(JS_TAG_STRING, p)); + return JS_NewSymbolInternal(ctx, p, atom_type); +} + +/* `description` may be pure ASCII or UTF-8 encoded */ +static JSValue js_new_symbol(JSContext *ctx, const char *description, + int atom_type) +{ + if (description == NULL) { + if (atom_type != JS_ATOM_TYPE_GLOBAL_SYMBOL) { + /* Local symbol without description: Symbol() */ + return JS_NewSymbolInternal(ctx, NULL, atom_type); + } + /* Global symbol without description: Symbol.for() + Per ES spec, ToString(undefined) becomes "undefined" */ + description = "undefined"; + } + JSAtom atom = JS_NewAtom(ctx, description); + if (atom == JS_ATOM_NULL) + return JS_EXCEPTION; + JSValue symbol = JS_NewSymbolFromAtom(ctx, atom, atom_type); + JS_FreeAtom(ctx, atom); + return symbol; +} + +JSValue JS_NewSymbol(JSContext *ctx, const char *description, bool is_global) +{ + int atom_type; + + atom_type = JS_ATOM_TYPE_SYMBOL; + if (is_global) + atom_type = JS_ATOM_TYPE_GLOBAL_SYMBOL; + return js_new_symbol(ctx, description, atom_type); +} + +JSValue JS_NewPrivateSymbol(JSContext *ctx, const char *description) +{ + return js_new_symbol(ctx, description, JS_ATOM_TYPE_PRIVATE); +} + +#define ATOM_GET_STR_BUF_SIZE 64 + +static const char *JS_AtomGetStrRT(JSRuntime *rt, char *buf, int buf_size, + JSAtom atom) +{ + if (__JS_AtomIsTaggedInt(atom)) { + snprintf(buf, buf_size, "%u", __JS_AtomToUInt32(atom)); + } else if (atom == JS_ATOM_NULL) { + snprintf(buf, buf_size, ""); + } else if (atom >= rt->atom_size) { + assert(atom < rt->atom_size); + snprintf(buf, buf_size, "", atom); + } else { + JSAtomStruct *p = rt->atom_array[atom]; + *buf = '\0'; + if (atom_is_free(p)) { + snprintf(buf, buf_size, "", atom); + } else if (p != NULL) { + JSString *str = p; + if (str->is_wide_char) { + /* encode surrogates correctly */ + utf8_encode_buf16(buf, buf_size, str16(str), str->len); + } else { + utf8_encode_buf8(buf, buf_size, str8(str), str->len); + } + } + } + return buf; +} + +static const char *JS_AtomGetStr(JSContext *ctx, char *buf, int buf_size, JSAtom atom) +{ + return JS_AtomGetStrRT(ctx->rt, buf, buf_size, atom); +} + +static JSValue __JS_AtomToValue(JSContext *ctx, JSAtom atom, bool force_string) +{ + char buf[ATOM_GET_STR_BUF_SIZE]; + + if (__JS_AtomIsTaggedInt(atom)) { + size_t len = u32toa(buf, __JS_AtomToUInt32(atom)); + return js_new_string8_len(ctx, buf, len); + } else { + JSRuntime *rt = ctx->rt; + JSAtomStruct *p; + assert(atom < rt->atom_size); + p = rt->atom_array[atom]; + if (p->atom_type == JS_ATOM_TYPE_STRING) { + goto ret_string; + } else if (force_string) { + if (p->len == 0 && p->is_wide_char != 0) { + /* no description string */ + p = rt->atom_array[JS_ATOM_empty_string]; + } + ret_string: + return js_dup(JS_MKPTR(JS_TAG_STRING, p)); + } else { + return js_dup(JS_MKPTR(JS_TAG_SYMBOL, p)); + } + } +} + +JSValue JS_AtomToValue(JSContext *ctx, JSAtom atom) +{ + return __JS_AtomToValue(ctx, atom, false); +} + +JSValue JS_AtomToString(JSContext *ctx, JSAtom atom) +{ + return __JS_AtomToValue(ctx, atom, true); +} + +/* return true if the atom is an array index (i.e. 0 <= index <= + 2^32-2 and return its value */ +static bool JS_AtomIsArrayIndex(JSContext *ctx, uint32_t *pval, JSAtom atom) +{ + if (__JS_AtomIsTaggedInt(atom)) { + *pval = __JS_AtomToUInt32(atom); + return true; + } else { + JSRuntime *rt = ctx->rt; + JSAtomStruct *p; + uint32_t val; + + assert(atom < rt->atom_size); + p = rt->atom_array[atom]; + if (p->atom_type == JS_ATOM_TYPE_STRING && + is_num_string(&val, p) && val != -1) { + *pval = val; + return true; + } else { + *pval = 0; + return false; + } + } +} + +/* This test must be fast if atom is not a numeric index (e.g. a + method name). Return JS_UNDEFINED if not a numeric + index. JS_EXCEPTION can also be returned. */ +static JSValue JS_AtomIsNumericIndex1(JSContext *ctx, JSAtom atom) +{ + JSRuntime *rt = ctx->rt; + JSAtomStruct *p1; + JSString *p; + int c, len, ret; + JSValue num, str; + + if (__JS_AtomIsTaggedInt(atom)) + return js_int32(__JS_AtomToUInt32(atom)); + assert(atom < rt->atom_size); + p1 = rt->atom_array[atom]; + if (p1->atom_type != JS_ATOM_TYPE_STRING) + return JS_UNDEFINED; + p = p1; + len = p->len; + if (p->is_wide_char) { + const uint16_t *r = str16(p), *r_end = str16(p) + len; + if (r >= r_end) + return JS_UNDEFINED; + c = *r; + if (c == '-') { + if (r >= r_end) + return JS_UNDEFINED; + r++; + c = *r; + /* -0 case is specific */ + if (c == '0' && len == 2) + goto minus_zero; + } + /* XXX: should test NaN, but the tests do not check it */ + if (!is_num(c)) { + /* XXX: String should be normalized, therefore 8-bit only */ + const uint16_t nfinity16[7] = { 'n', 'f', 'i', 'n', 'i', 't', 'y' }; + if (!(c =='I' && (r_end - r) == 8 && + !memcmp(r + 1, nfinity16, sizeof(nfinity16)))) + return JS_UNDEFINED; + } + } else { + const uint8_t *r = str8(p), *r_end = str8(p) + len; + if (r >= r_end) + return JS_UNDEFINED; + c = *r; + if (c == '-') { + if (r >= r_end) + return JS_UNDEFINED; + r++; + c = *r; + /* -0 case is specific */ + if (c == '0' && len == 2) { + minus_zero: + return js_float64(-0.0); + } + } + if (!is_num(c)) { + if (!(c =='I' && (r_end - r) == 8 && + !memcmp(r + 1, "nfinity", 7))) + return JS_UNDEFINED; + } + } + /* this is ECMA CanonicalNumericIndexString primitive */ + num = JS_ToNumber(ctx, JS_MKPTR(JS_TAG_STRING, p)); + if (JS_IsException(num)) + return num; + str = JS_ToString(ctx, num); + if (JS_IsException(str)) { + JS_FreeValue(ctx, num); + return str; + } + ret = js_string_eq(p, JS_VALUE_GET_STRING(str)); + JS_FreeValue(ctx, str); + if (ret) { + return num; + } else { + JS_FreeValue(ctx, num); + return JS_UNDEFINED; + } +} + +/* return -1 if exception or true/false */ +static int JS_AtomIsNumericIndex(JSContext *ctx, JSAtom atom) +{ + JSValue num; + num = JS_AtomIsNumericIndex1(ctx, atom); + if (likely(JS_IsUndefined(num))) + return false; + if (JS_IsException(num)) + return -1; + JS_FreeValue(ctx, num); + return true; +} + +void JS_FreeAtom(JSContext *ctx, JSAtom v) +{ + if (!__JS_AtomIsConst(v)) + __JS_FreeAtom(ctx->rt, v); +} + +void JS_FreeAtomRT(JSRuntime *rt, JSAtom v) +{ + if (!__JS_AtomIsConst(v)) + __JS_FreeAtom(rt, v); +} + +/* return true if 'v' is a symbol with a string description */ +static bool JS_AtomSymbolHasDescription(JSContext *ctx, JSAtom v) +{ + JSRuntime *rt; + JSAtomStruct *p; + + rt = ctx->rt; + if (__JS_AtomIsTaggedInt(v)) + return false; + p = rt->atom_array[v]; + return (((p->atom_type == JS_ATOM_TYPE_SYMBOL && + p->hash == JS_ATOM_HASH_SYMBOL) || + p->atom_type == JS_ATOM_TYPE_GLOBAL_SYMBOL) && + !(p->len == 0 && p->is_wide_char != 0)); +} + +static __maybe_unused void print_atom(JSContext *ctx, JSAtom atom) +{ + char buf[ATOM_GET_STR_BUF_SIZE]; + const char *p; + int i; + + /* XXX: should handle embedded null characters */ + /* XXX: should move encoding code to JS_AtomGetStr */ + p = JS_AtomGetStr(ctx, buf, sizeof(buf), atom); + for (i = 0; p[i]; i++) { + int c = (unsigned char)p[i]; + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c == '_' || c == '$') || (c >= '0' && c <= '9' && i > 0))) + break; + } + if (i > 0 && p[i] == '\0') { + printf("%s", p); + } else { + putchar('"'); + printf("%.*s", i, p); + for (; p[i]; i++) { + int c = (unsigned char)p[i]; + if (c == '\"' || c == '\\') { + putchar('\\'); + putchar(c); + } else if (c >= ' ' && c <= 126) { + putchar(c); + } else if (c == '\n') { + putchar('\\'); + putchar('n'); + } else { + printf("\\u%04x", c); + } + } + putchar('\"'); + } +} + +/* free with JS_FreeCString() */ +const char *JS_AtomToCStringLen(JSContext *ctx, size_t *plen, JSAtom atom) +{ + JSValue str; + const char *cstr; + + str = JS_AtomToString(ctx, atom); + if (JS_IsException(str)) { + if (plen) + *plen = 0; + return NULL; + } + cstr = JS_ToCStringLen(ctx, plen, str); + JS_FreeValue(ctx, str); + return cstr; +} + +#ifndef QJS_DISABLE_PARSER + +/* return a string atom containing name concatenated with str1 */ +/* `str1` may be pure ASCII or UTF-8 encoded */ +// TODO(chqrlie): use string concatenation instead of UTF-8 conversion +static JSAtom js_atom_concat_str(JSContext *ctx, JSAtom name, const char *str1) +{ + JSValue str; + JSAtom atom; + const char *cstr; + char *cstr2; + size_t len, len1; + + str = JS_AtomToString(ctx, name); + if (JS_IsException(str)) + return JS_ATOM_NULL; + cstr = JS_ToCStringLen(ctx, &len, str); + if (!cstr) + goto fail; + len1 = strlen(str1); + cstr2 = js_malloc(ctx, len + len1 + 1); + if (!cstr2) + goto fail; + memcpy(cstr2, cstr, len); + memcpy(cstr2 + len, str1, len1); + cstr2[len + len1] = '\0'; + atom = JS_NewAtomLen(ctx, cstr2, len + len1); + js_free(ctx, cstr2); + JS_FreeCString(ctx, cstr); + JS_FreeValue(ctx, str); + return atom; + fail: + JS_FreeCString(ctx, cstr); + JS_FreeValue(ctx, str); + return JS_ATOM_NULL; +} + +static JSAtom js_atom_concat_num(JSContext *ctx, JSAtom name, uint32_t n) +{ + char buf[16]; + size_t len; + + len = u32toa(buf, n); + buf[len] = '\0'; + return js_atom_concat_str(ctx, name, buf); +} + +#endif // QJS_DISABLE_PARSER + +static inline bool JS_IsEmptyString(JSValueConst v) +{ + return JS_VALUE_GET_TAG(v) == JS_TAG_STRING && JS_VALUE_GET_STRING(v)->len == 0; +} + +/* JSClass support */ + +/* a new class ID is allocated if *pclass_id == 0, otherwise *pclass_id is left unchanged */ +JSClassID JS_NewClassID(JSRuntime *rt, JSClassID *pclass_id) +{ + JSClassID class_id = *pclass_id; + if (class_id == 0) { + class_id = rt->js_class_id_alloc++; + *pclass_id = class_id; + } + return class_id; +} + +JSClassID JS_GetClassID(JSValueConst v) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(v) != JS_TAG_OBJECT) + return JS_INVALID_CLASS_ID; + p = JS_VALUE_GET_OBJ(v); + return p->class_id; +} + +bool JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id) +{ + return (class_id < rt->class_count && + rt->class_array[class_id].class_id != 0); +} + +JSAtom JS_GetClassName(JSRuntime *rt, JSClassID class_id) +{ + if (JS_IsRegisteredClass(rt, class_id)) { + return JS_DupAtomRT(rt, rt->class_array[class_id].class_name); + } else { + return JS_ATOM_NULL; + } +} + +/* create a new object internal class. Return -1 if error, 0 if + OK. The finalizer can be NULL if none is needed. */ +static int JS_NewClass1(JSRuntime *rt, JSClassID class_id, + const JSClassDef *class_def, JSAtom name) +{ + int new_size, i; + JSClass *cl, *new_class_array; + struct list_head *el; + + if (class_id >= (1 << 16)) + return -1; + if (class_id < rt->class_count && + rt->class_array[class_id].class_id != 0) + return -1; + + if (class_id >= rt->class_count) { + new_size = max_int(JS_CLASS_INIT_COUNT, + max_int(class_id + 1, rt->class_count * 3 / 2)); + + /* reallocate the context class prototype array, if any */ + list_for_each(el, &rt->context_list) { + JSContext *ctx = list_entry(el, JSContext, link); + JSValue *new_tab; + new_tab = js_realloc_rt(rt, ctx->class_proto, + sizeof(ctx->class_proto[0]) * new_size); + if (!new_tab) + return -1; + for(i = rt->class_count; i < new_size; i++) + new_tab[i] = JS_NULL; + ctx->class_proto = new_tab; + } + /* reallocate the class array */ + new_class_array = js_realloc_rt(rt, rt->class_array, + sizeof(JSClass) * new_size); + if (!new_class_array) + return -1; + memset(new_class_array + rt->class_count, 0, + (new_size - rt->class_count) * sizeof(JSClass)); + rt->class_array = new_class_array; + rt->class_count = new_size; + } + cl = &rt->class_array[class_id]; + cl->class_id = class_id; + cl->class_name = JS_DupAtomRT(rt, name); + cl->finalizer = class_def->finalizer; + cl->gc_mark = class_def->gc_mark; + cl->call = class_def->call; + cl->exotic = class_def->exotic; + return 0; +} + +int JS_NewClass(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def) +{ + int ret, len; + JSAtom name; + + // XXX: class_def->class_name must be raw 8-bit contents. No UTF-8 encoded strings + len = strlen(class_def->class_name); + name = __JS_FindAtom(rt, class_def->class_name, len, JS_ATOM_TYPE_STRING); + if (name == JS_ATOM_NULL) { + name = __JS_NewAtomInit(rt, class_def->class_name, len, JS_ATOM_TYPE_STRING); + if (name == JS_ATOM_NULL) + return -1; + } + ret = JS_NewClass1(rt, class_id, class_def, name); + JS_FreeAtomRT(rt, name); + return ret; +} + +static inline JSValue js_empty_string(JSRuntime *rt) +{ + JSAtomStruct *p = rt->atom_array[JS_ATOM_empty_string]; + return js_dup(JS_MKPTR(JS_TAG_STRING, p)); +} + +// XXX: `buf` contains raw 8-bit data, no UTF-8 decoding is performed +// XXX: no special case for len == 0 +static JSValue js_new_string8_len(JSContext *ctx, const char *buf, int len) +{ + JSString *str; + str = js_alloc_string(ctx, len, 0); + if (!str) + return JS_EXCEPTION; + memcpy(str8(str), buf, len); + str8(str)[len] = '\0'; + return JS_MKPTR(JS_TAG_STRING, str); +} + +// XXX: `buf` contains raw 8-bit data, no UTF-8 decoding is performed +// XXX: no special case for the empty string +static inline JSValue js_new_string8(JSContext *ctx, const char *str) +{ + return js_new_string8_len(ctx, str, strlen(str)); +} + +static JSValue js_new_string16_len(JSContext *ctx, const uint16_t *buf, int len) +{ + JSString *str; + str = js_alloc_string(ctx, len, 1); + if (!str) + return JS_EXCEPTION; + memcpy(str16(str), buf, len * 2); + return JS_MKPTR(JS_TAG_STRING, str); +} + +static JSValue js_new_string_char(JSContext *ctx, uint16_t c) +{ + if (c < 0x100) { + char ch8 = c; + return js_new_string8_len(ctx, &ch8, 1); + } else { + uint16_t ch16 = c; + return js_new_string16_len(ctx, &ch16, 1); + } +} + +static JSValue js_sub_string(JSContext *ctx, JSString *p, int start, int end) +{ + JSStringSlice *slice; + JSString *q; + int len; + + len = end - start; + if (start == 0 && end == p->len) { + return js_dup(JS_MKPTR(JS_TAG_STRING, p)); + } + if (len <= 0) { + return js_empty_string(ctx->rt); + } + if (len > (JS_STRING_SLICE_LEN_MAX >> p->is_wide_char)) { + if (p->kind == JS_STRING_KIND_SLICE) { + slice = (void *)&p[1]; + p = slice->parent; + start += slice->start >> p->is_wide_char; // bytes -> chars + } + // allocate as 16 bit wide string to avoid wastage; + // js_alloc_string allocates 1 byte extra for 8 bit strings; + q = js_alloc_string(ctx, sizeof(*slice)/2, /*is_wide_char*/true); + if (!q) + return JS_EXCEPTION; + q->is_wide_char = p->is_wide_char; + q->kind = JS_STRING_KIND_SLICE; + q->len = len; + slice = (void *)&q[1]; + slice->parent = p; + slice->start = start << p->is_wide_char; // chars -> bytes + JS_REF_COUNT(p)++; + return JS_MKPTR(JS_TAG_STRING, q); + } + if (p->is_wide_char) { + JSString *str; + int i; + uint16_t c = 0; + for (i = start; i < end; i++) { + c |= str16(p)[i]; + } + if (c > 0xFF) + return js_new_string16_len(ctx, str16(p) + start, len); + + str = js_alloc_string(ctx, len, 0); + if (!str) + return JS_EXCEPTION; + for (i = 0; i < len; i++) { + str8(str)[i] = str16(p)[start + i]; + } + str8(str)[len] = '\0'; + return JS_MKPTR(JS_TAG_STRING, str); + } else { + return js_new_string8_len(ctx, (const char *)(str8(p) + start), len); + } +} + +typedef struct StringBuffer { + JSContext *ctx; + JSString *str; + int len; + int size; + int is_wide_char; + int error_status; +} StringBuffer; + +/* It is valid to call string_buffer_end() and all string_buffer functions even + if string_buffer_init() or another string_buffer function returns an error. + If the error_status is set, string_buffer_end() returns JS_EXCEPTION. + */ +static int string_buffer_init2(JSContext *ctx, StringBuffer *s, int size, + int is_wide) +{ + s->ctx = ctx; + s->size = size; + s->len = 0; + s->is_wide_char = is_wide; + s->error_status = 0; + s->str = js_alloc_string(ctx, size, is_wide); + if (unlikely(!s->str)) { + s->size = 0; + return s->error_status = -1; + } +#ifdef ENABLE_DUMPS // JS_DUMP_LEAKS + /* the StringBuffer may reallocate the JSString, only link it at the end */ + list_del(&s->str->link); +#endif + return 0; +} + +static inline int string_buffer_init(JSContext *ctx, StringBuffer *s, int size) +{ + return string_buffer_init2(ctx, s, size, 0); +} + +static void string_buffer_free(StringBuffer *s) +{ + js_free(s->ctx, s->str); + s->str = NULL; +} + +static int string_buffer_set_error(StringBuffer *s) +{ + js_free(s->ctx, s->str); + s->str = NULL; + s->size = 0; + s->len = 0; + return s->error_status = -1; +} + +static no_inline int string_buffer_widen(StringBuffer *s, int size) +{ + JSString *str; + int i; + + if (s->error_status) + return -1; + + str = js_realloc(s->ctx, s->str, sizeof(JSString) + (size << 1)); + if (!str) + return string_buffer_set_error(s); + for(i = s->len; i-- > 0;) { + str16(str)[i] = str8(str)[i]; + } + s->is_wide_char = 1; + s->size = size; + s->str = str; + return 0; +} + +static no_inline int string_buffer_realloc(StringBuffer *s, int new_len, int c) +{ + JSString *new_str; + int new_size; + size_t new_size_bytes; + + if (s->error_status) + return -1; + + if (new_len > JS_STRING_LEN_MAX) { + JS_ThrowRangeError(s->ctx, "invalid string length"); + return string_buffer_set_error(s); + } + new_size = min_int(max_int(new_len, s->size * 3 / 2), JS_STRING_LEN_MAX); + if (!s->is_wide_char && c >= 0x100) { + return string_buffer_widen(s, new_size); + } + new_size_bytes = sizeof(JSString) + (new_size << s->is_wide_char) + 1 - s->is_wide_char; + new_str = js_realloc(s->ctx, s->str, new_size_bytes); + if (!new_str) + return string_buffer_set_error(s); + s->size = new_size; + s->str = new_str; + return 0; +} + +static no_inline int string_buffer_putc16_slow(StringBuffer *s, uint32_t c) +{ + if (unlikely(s->len >= s->size)) { + if (string_buffer_realloc(s, s->len + 1, c)) + return -1; + } + if (s->is_wide_char) { + str16(s->str)[s->len++] = c; + } else if (c < 0x100) { + str8(s->str)[s->len++] = c; + } else { + if (string_buffer_widen(s, s->size)) + return -1; + str16(s->str)[s->len++] = c; + } + return 0; +} + +/* 0 <= c <= 0xff */ +static int string_buffer_putc8(StringBuffer *s, uint32_t c) +{ + if (unlikely(s->len >= s->size)) { + if (string_buffer_realloc(s, s->len + 1, c)) + return -1; + } + if (s->is_wide_char) { + str16(s->str)[s->len++] = c; + } else { + str8(s->str)[s->len++] = c; + } + return 0; +} + +/* 0 <= c <= 0xffff */ +static int string_buffer_putc16(StringBuffer *s, uint32_t c) +{ + if (likely(s->len < s->size)) { + if (s->is_wide_char) { + str16(s->str)[s->len++] = c; + return 0; + } else if (c < 0x100) { + str8(s->str)[s->len++] = c; + return 0; + } + } + return string_buffer_putc16_slow(s, c); +} + +/* 0 <= c <= 0x10ffff */ +static no_inline int string_buffer_putc_slow(StringBuffer *s, uint32_t c) +{ + if (c >= 0x10000) { + /* surrogate pair */ + if (string_buffer_putc16(s, get_hi_surrogate(c))) + return -1; + c = get_lo_surrogate(c); + } + return string_buffer_putc16(s, c); +} + +/* 0 <= c <= 0x10ffff */ +static inline int string_buffer_putc(StringBuffer *s, uint32_t c) +{ + if (likely(s->len < s->size)) { + if (s->is_wide_char) { + if (c < 0x10000) { + str16(s->str)[s->len++] = c; + return 0; + } else if (s->len + 1 < s->size) { + /* surrogate pair */ + str16(s->str)[s->len++] = get_hi_surrogate(c); + str16(s->str)[s->len++] = get_lo_surrogate(c); + return 0; + } + } else if (c < 0x100) { + str8(s->str)[s->len++] = c; + return 0; + } + } + return string_buffer_putc_slow(s, c); +} + +static int string_getc(JSString *p, int *pidx) +{ + int idx, c, c1; + idx = *pidx; + if (p->is_wide_char) { + c = str16(p)[idx++]; + if (is_hi_surrogate(c) && idx < p->len) { + c1 = str16(p)[idx]; + if (is_lo_surrogate(c1)) { + c = from_surrogate(c, c1); + idx++; + } + } + } else { + c = str8(p)[idx++]; + } + *pidx = idx; + return c; +} + +static int string_buffer_write8(StringBuffer *s, const uint8_t *p, int len) +{ + int i; + + if (s->len + len > s->size) { + if (string_buffer_realloc(s, s->len + len, 0)) + return -1; + } + if (s->is_wide_char) { + for (i = 0; i < len; i++) { + str16(s->str)[s->len + i] = p[i]; + } + s->len += len; + } else { + memcpy(&str8(s->str)[s->len], p, len); + s->len += len; + } + return 0; +} + +static int string_buffer_write16(StringBuffer *s, const uint16_t *p, int len) +{ + int c = 0, i; + + for (i = 0; i < len; i++) { + c |= p[i]; + } + if (s->len + len > s->size) { + if (string_buffer_realloc(s, s->len + len, c)) + return -1; + } else if (!s->is_wide_char && c >= 0x100) { + if (string_buffer_widen(s, s->size)) + return -1; + } + if (s->is_wide_char) { + memcpy(&str16(s->str)[s->len], p, len << 1); + s->len += len; + } else { + for (i = 0; i < len; i++) { + str8(s->str)[s->len + i] = p[i]; + } + s->len += len; + } + return 0; +} + +/* appending an ASCII string */ +static int string_buffer_puts8(StringBuffer *s, const char *str) +{ + return string_buffer_write8(s, (const uint8_t *)str, strlen(str)); +} + +static int string_buffer_concat(StringBuffer *s, JSString *p, + uint32_t from, uint32_t to) +{ + if (to <= from) + return 0; + if (p->is_wide_char) + return string_buffer_write16(s, str16(p) + from, to - from); + else + return string_buffer_write8(s, str8(p) + from, to - from); +} + +static int string_buffer_concat_value(StringBuffer *s, JSValueConst v) +{ + JSString *p; + JSValue v1; + int res; + int tag; + + if (s->error_status) { + /* prevent exception overload */ + return -1; + } + tag = JS_VALUE_GET_TAG(v); + if (tag == JS_TAG_STRING_ROPE) { + /* recursively concatenate rope children */ + JSStringRope *r = JS_VALUE_GET_STRING_ROPE(v); + if (string_buffer_concat_value(s, r->left)) + return -1; + return string_buffer_concat_value(s, r->right); + } + if (unlikely(tag != JS_TAG_STRING)) { + v1 = JS_ToString(s->ctx, v); + if (JS_IsException(v1)) + return string_buffer_set_error(s); + p = JS_VALUE_GET_STRING(v1); + res = string_buffer_concat(s, p, 0, p->len); + JS_FreeValue(s->ctx, v1); + return res; + } + p = JS_VALUE_GET_STRING(v); + return string_buffer_concat(s, p, 0, p->len); +} + +static int string_buffer_concat_value_free(StringBuffer *s, JSValue v) +{ + JSString *p; + int res; + int tag; + + if (s->error_status) { + /* prevent exception overload */ + JS_FreeValue(s->ctx, v); + return -1; + } + tag = JS_VALUE_GET_TAG(v); + if (tag == JS_TAG_STRING_ROPE) { + /* concatenate rope (don't free since concat_value doesn't free) */ + res = string_buffer_concat_value(s, v); + JS_FreeValue(s->ctx, v); + return res; + } + if (unlikely(tag != JS_TAG_STRING)) { + v = JS_ToStringFree(s->ctx, v); + if (JS_IsException(v)) + return string_buffer_set_error(s); + } + p = JS_VALUE_GET_STRING(v); + res = string_buffer_concat(s, p, 0, p->len); + JS_FreeValue(s->ctx, v); + return res; +} + +static int string_buffer_fill(StringBuffer *s, int c, int count) +{ + /* XXX: optimize */ + if (s->len + count > s->size) { + if (string_buffer_realloc(s, s->len + count, c)) + return -1; + } + while (count-- > 0) { + if (string_buffer_putc16(s, c)) + return -1; + } + return 0; +} + +static JSValue string_buffer_end(StringBuffer *s) +{ + JSString *str; + str = s->str; + if (s->error_status) + return JS_EXCEPTION; + if (s->len == 0) { + js_free(s->ctx, str); + s->str = NULL; + return js_empty_string(s->ctx->rt); + } + if (s->len < s->size) { + /* smaller size so js_realloc should not fail, but OK if it does */ + /* XXX: should add some slack to avoid unnecessary calls */ + /* XXX: might need to use malloc+free to ensure smaller size */ + str = js_realloc_rt(s->ctx->rt, str, sizeof(JSString) + + (s->len << s->is_wide_char) + 1 - s->is_wide_char); + if (str == NULL) + str = s->str; + s->str = str; + } + if (!s->is_wide_char) + str8(str)[s->len] = 0; +#ifdef ENABLE_DUMPS // JS_DUMP_LEAKS + list_add_tail(&str->link, &s->ctx->rt->string_list); +#endif + str->is_wide_char = s->is_wide_char; + str->len = s->len; + s->str = NULL; + return JS_MKPTR(JS_TAG_STRING, str); +} + +/* create a string from a UTF-8 buffer */ +JSValue JS_NewStringLen(JSContext *ctx, const char *buf, size_t buf_len) +{ + JSString *str; + size_t len; + int kind; + + if (unlikely(buf_len <= 0)) + return js_empty_string(ctx->rt); + + /* Compute string kind and length: 7-bit, 8-bit, 16-bit, 16-bit UTF-16 */ + kind = utf8_scan(buf, buf_len, &len); + if (unlikely(len > JS_STRING_LEN_MAX)) + return JS_ThrowRangeError(ctx, "invalid string length"); + + switch (kind) { + case UTF8_PLAIN_ASCII: + str = js_alloc_string(ctx, len, 0); + if (unlikely(!str)) + return JS_EXCEPTION; + memcpy(str8(str), buf, len); + str8(str)[len] = '\0'; + break; + case UTF8_NON_ASCII: + /* buf contains non-ASCII code-points, but limited to 8-bit values */ + str = js_alloc_string(ctx, len, 0); + if (unlikely(!str)) + return JS_EXCEPTION; + utf8_decode_buf8(str8(str), len + 1, buf, buf_len); + break; + default: + // This causes a potential problem in JS_ThrowError if message is invalid + //if (kind & UTF8_HAS_ERRORS) + // return JS_ThrowRangeError(ctx, "invalid UTF-8 sequence"); + str = js_alloc_string(ctx, len, 1); + if (unlikely(!str)) + return JS_EXCEPTION; + utf8_decode_buf16(str16(str), len, buf, buf_len); + break; + } + return JS_MKPTR(JS_TAG_STRING, str); +} + +JSValue JS_NewStringUTF16(JSContext *ctx, const uint16_t *buf, size_t len) +{ + JSString *str; + + if (unlikely(!len)) + return js_empty_string(ctx->rt); + if (unlikely(len > JS_STRING_LEN_MAX)) + return JS_ThrowRangeError(ctx, "invalid string length"); + + str = js_alloc_string(ctx, len, 1); + if (unlikely(!str)) + return JS_EXCEPTION; + memcpy(str16(str), buf, len * sizeof(*buf)); + return JS_MKPTR(JS_TAG_STRING, str); +} + +static JSValue JS_ConcatString3(JSContext *ctx, const char *str1, + JSValue str2, const char *str3) +{ + StringBuffer b_s, *b = &b_s; + int len1, len3; + JSString *p; + + if (unlikely(JS_VALUE_GET_TAG(str2) != JS_TAG_STRING)) { + str2 = JS_ToStringFree(ctx, str2); + if (JS_IsException(str2)) + goto fail; + } + p = JS_VALUE_GET_STRING(str2); + len1 = strlen(str1); + len3 = strlen(str3); + + if (string_buffer_init2(ctx, b, len1 + p->len + len3, p->is_wide_char)) + goto fail; + + string_buffer_write8(b, (const uint8_t *)str1, len1); + string_buffer_concat(b, p, 0, p->len); + string_buffer_write8(b, (const uint8_t *)str3, len3); + + JS_FreeValue(ctx, str2); + return string_buffer_end(b); + + fail: + JS_FreeValue(ctx, str2); + return JS_EXCEPTION; +} + +/* `str` may be pure ASCII or UTF-8 encoded */ +JSValue JS_NewAtomString(JSContext *ctx, const char *str) +{ + JSAtom atom = JS_NewAtom(ctx, str); + if (atom == JS_ATOM_NULL) + return JS_EXCEPTION; + JSValue val = JS_AtomToString(ctx, atom); + JS_FreeAtom(ctx, atom); + return val; +} + +static JSValue js_force_tostring(JSContext *ctx, JSValueConst val1) +{ + JSObject *p; + JSValue val; + + if (JS_VALUE_GET_TAG(val1) == JS_TAG_STRING) + return js_dup(val1); + val = JS_ToString(ctx, val1); + if (!JS_IsException(val)) + return val; + // Stringification can fail when there is an exception pending, + // e.g. a stack overflow InternalError. Special-case exception + // objects to make debugging easier, look up the .message property + // and stringify that. + if (JS_VALUE_GET_TAG(val1) != JS_TAG_OBJECT) + return JS_EXCEPTION; + p = JS_VALUE_GET_OBJ(val1); + if (p->class_id != JS_CLASS_ERROR) + return JS_EXCEPTION; + val = JS_GetProperty(ctx, val1, JS_ATOM_message); + if (JS_VALUE_GET_TAG(val) != JS_TAG_STRING) { + JS_FreeValue(ctx, val); + return JS_EXCEPTION; + } + return val; +} + +/* return (NULL, 0) if exception. */ +/* return pointer into a JSString with a live ref_count */ +/* cesu8 determines if non-BMP1 codepoints are encoded as 1 or 2 utf-8 sequences */ +const char *JS_ToCStringLen2(JSContext *ctx, size_t *plen, JSValueConst val1, + bool cesu8) +{ + JSValue val; + JSString *str, *str_new; + int pos, len, c, c1; + uint8_t *q; + + val = js_force_tostring(ctx, val1); + if (JS_IsException(val)) + goto fail; + str = JS_VALUE_GET_STRING(val); + len = str->len; + if (!str->is_wide_char) { + const uint8_t *src = str8(str); + int count; + + /* count the number of non-ASCII characters */ + /* Scanning the whole string is required for ASCII strings, + and computing the number of non-ASCII bytes is less expensive + than testing each byte, hence this method is faster for ASCII + strings, which is the most common case. + */ + count = 0; + for (pos = 0; pos < len; pos++) { + count += src[pos] >> 7; + } + if (count == 0 && str->kind == JS_STRING_KIND_NORMAL) { + if (plen) + *plen = len; + return (const char *)src; + } + str_new = js_alloc_string(ctx, len + count, 0); + if (!str_new) + goto fail; + q = str8(str_new); + for (pos = 0; pos < len; pos++) { + c = src[pos]; + if (c < 0x80) { + *q++ = c; + } else { + *q++ = (c >> 6) | 0xc0; + *q++ = (c & 0x3f) | 0x80; + } + } + } else { + const uint16_t *src = str16(str); + /* Allocate 3 bytes per 16 bit code point. Surrogate pairs may + produce 4 bytes but use 2 code points. + */ + str_new = js_alloc_string(ctx, len * 3, 0); + if (!str_new) + goto fail; + q = str8(str_new); + pos = 0; + while (pos < len) { + c = src[pos++]; + if (c < 0x80) { + *q++ = c; + } else { + if (is_hi_surrogate(c)) { + if (pos < len && !cesu8) { + c1 = src[pos]; + if (is_lo_surrogate(c1)) { + pos++; + c = from_surrogate(c, c1); + } else { + /* Keep unmatched surrogate code points */ + /* c = 0xfffd; */ /* error */ + } + } else { + /* Keep unmatched surrogate code points */ + /* c = 0xfffd; */ /* error */ + } + } + q += utf8_encode(q, c); + } + } + } + + *q = '\0'; + str_new->len = q - str8(str_new); + JS_FreeValue(ctx, val); + if (plen) + *plen = str_new->len; + return (const char *)str8(str_new); +fail: + if (plen) + *plen = 0; + return NULL; +} + +static void copy_str16(uint16_t *dst, JSString *p, int offset, int len) +{ + if (p->is_wide_char) { + memcpy(dst, str16(p) + offset, len * 2); + } else { + const uint8_t *src1 = str8(p) + offset; + int i; + + for(i = 0; i < len; i++) + dst[i] = src1[i]; + } +} + +const uint16_t *JS_ToCStringLenUTF16(JSContext *ctx, size_t *plen, + JSValueConst val1) +{ + JSString *p, *q; + JSValue v; + + v = js_force_tostring(ctx, val1); + if (JS_IsException(v)) + goto fail; + p = JS_VALUE_GET_STRING(v); + if (!(p->is_wide_char && p->kind == JS_STRING_KIND_NORMAL)) { + q = js_alloc_string(ctx, p->len, /*is_wide_char*/true); + if (!q) + goto fail; + copy_str16(str16(q), p, 0, p->len); + JS_FreeValue(ctx, v); + p = q; + } + if (plen) + *plen = p->len; + return str16(p); +fail: + JS_FreeValue(ctx, v); + if (plen) + *plen = 0; + return NULL; +} + +static void js_free_cstring(JSRuntime *rt, const void *ptr) +{ + if (!ptr) + return; + /* purposely removing constness */ + JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_STRING, (JSString *)ptr - 1)); +} + +void JS_FreeCString(JSContext *ctx, const char *ptr) +{ + return js_free_cstring(ctx->rt, ptr); +} + +void JS_FreeCStringRT(JSRuntime *rt, const char *ptr) +{ + return js_free_cstring(rt, ptr); +} + +void JS_FreeCStringUTF16(JSContext *ctx, const uint16_t *ptr) +{ + return js_free_cstring(ctx->rt, ptr); +} + +void JS_FreeCStringRT_UTF16(JSRuntime *rt, const uint16_t *ptr) +{ + return js_free_cstring(rt, ptr); +} + +static int memcmp16_8(const uint16_t *src1, const uint8_t *src2, int len) +{ + int c, i; + for(i = 0; i < len; i++) { + c = src1[i] - src2[i]; + if (c != 0) + return c; + } + return 0; +} + +static int memcmp16(const uint16_t *src1, const uint16_t *src2, int len) +{ + int c, i; + for(i = 0; i < len; i++) { + c = src1[i] - src2[i]; + if (c != 0) + return c; + } + return 0; +} + +static int js_string_memcmp(JSString *p1, JSString *p2, int len) +{ + int res; + + if (likely(!p1->is_wide_char)) { + if (likely(!p2->is_wide_char)) + res = memcmp(str8(p1), str8(p2), len); + else + res = -memcmp16_8(str16(p2), str8(p1), len); + } else { + if (!p2->is_wide_char) + res = memcmp16_8(str16(p1), str8(p2), len); + else + res = memcmp16(str16(p1), str16(p2), len); + } + return res; +} + +static bool js_string_eq(JSString *p1, JSString *p2) { + if (p1->len != p2->len) + return false; + return js_string_memcmp(p1, p2, p1->len) == 0; +} + +/* return < 0, 0 or > 0 */ +static int js_string_compare(JSString *p1, JSString *p2) +{ + int res, len; + len = min_int(p1->len, p2->len); + res = js_string_memcmp(p1, p2, len); + if (res == 0) + res = compare_u32(p1->len, p2->len); + return res; +} + +/* Rope string support functions */ + +static inline bool tag_is_string(int tag) +{ + return tag == JS_TAG_STRING || tag == JS_TAG_STRING_ROPE; +} + +static uint32_t string_rope_get_len(JSValueConst val) +{ + if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING) + return JS_VALUE_GET_STRING(val)->len; + else + return JS_VALUE_GET_STRING_ROPE(val)->len; +} + +static int string_rope_get(JSValueConst val, uint32_t idx) +{ + if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING) { + return string_get(JS_VALUE_GET_STRING(val), idx); + } else { + JSStringRope *r = JS_VALUE_GET_STRING_ROPE(val); + uint32_t len; + if (JS_VALUE_GET_TAG(r->left) == JS_TAG_STRING) + len = JS_VALUE_GET_STRING(r->left)->len; + else + len = JS_VALUE_GET_STRING_ROPE(r->left)->len; + if (idx < len) + return string_rope_get(r->left, idx); + else + return string_rope_get(r->right, idx - len); + } +} + +typedef struct { + JSValueConst stack[JS_STRING_ROPE_MAX_DEPTH]; + int stack_len; +} JSStringRopeIter; + +static void string_rope_iter_init(JSStringRopeIter *s, JSValueConst val) +{ + s->stack_len = 0; + s->stack[s->stack_len++] = val; +} + +/* iterate thru a rope and return the strings in order */ +static JSString *string_rope_iter_next(JSStringRopeIter *s) +{ + JSValueConst val; + JSStringRope *r; + + if (s->stack_len == 0) + return NULL; + val = s->stack[--s->stack_len]; + for(;;) { + if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING) + return JS_VALUE_GET_STRING(val); + r = JS_VALUE_GET_STRING_ROPE(val); + assert(s->stack_len < JS_STRING_ROPE_MAX_DEPTH); + s->stack[s->stack_len++] = r->right; + val = r->left; + } +} + +/* compare two string values with position offsets */ +static int js_string_memcmp_pos(JSString *p1, uint32_t pos1, + JSString *p2, uint32_t pos2, uint32_t len) +{ + int res; + + if (likely(!p1->is_wide_char)) { + if (likely(!p2->is_wide_char)) + res = memcmp(str8(p1) + pos1, str8(p2) + pos2, len); + else + res = -memcmp16_8(str16(p2) + pos2, str8(p1) + pos1, len); + } else { + if (!p2->is_wide_char) + res = memcmp16_8(str16(p1) + pos1, str8(p2) + pos2, len); + else + res = memcmp16(str16(p1) + pos1, str16(p2) + pos2, len); + } + return res; +} + +static int js_string_rope_compare(JSValueConst op1, + JSValueConst op2, bool eq_only) +{ + uint32_t len1, len2, len, pos1, pos2, l; + int res; + JSStringRopeIter it1, it2; + JSString *p1, *p2; + + len1 = string_rope_get_len(op1); + len2 = string_rope_get_len(op2); + /* no need to go further for equality test if different length */ + if (eq_only && len1 != len2) + return 1; + len = min_uint32(len1, len2); + string_rope_iter_init(&it1, op1); + string_rope_iter_init(&it2, op2); + p1 = string_rope_iter_next(&it1); + p2 = string_rope_iter_next(&it2); + pos1 = 0; + pos2 = 0; + while (len != 0) { + l = min_uint32(p1->len - pos1, p2->len - pos2); + l = min_uint32(l, len); + res = js_string_memcmp_pos(p1, pos1, p2, pos2, l); + if (res != 0) + return res; + len -= l; + pos1 += l; + if (pos1 >= p1->len) { + p1 = string_rope_iter_next(&it1); + pos1 = 0; + } + pos2 += l; + if (pos2 >= p2->len) { + p2 = string_rope_iter_next(&it2); + pos2 = 0; + } + } + + if (len1 == len2) + res = 0; + else if (len1 < len2) + res = -1; + else + res = 1; + return res; +} + +/* forward declaration */ +static int string_buffer_concat_value(StringBuffer *s, JSValueConst v); +static JSValue js_rebalance_string_rope(JSContext *ctx, JSValueConst rope); + +/* op1 and op2 must be strings or string ropes */ +static JSValue js_new_string_rope(JSContext *ctx, JSValue op1, JSValue op2) +{ + uint32_t len; + int is_wide_char, depth; + JSStringRope *r; + JSValue res; + + if (JS_VALUE_GET_TAG(op1) == JS_TAG_STRING) { + JSString *p1 = JS_VALUE_GET_STRING(op1); + len = p1->len; + is_wide_char = p1->is_wide_char; + depth = 0; + } else { + JSStringRope *r1 = JS_VALUE_GET_STRING_ROPE(op1); + len = r1->len; + is_wide_char = r1->is_wide_char; + depth = r1->depth; + } + + if (JS_VALUE_GET_TAG(op2) == JS_TAG_STRING) { + JSString *p2 = JS_VALUE_GET_STRING(op2); + len += p2->len; + is_wide_char |= p2->is_wide_char; + } else { + JSStringRope *r2 = JS_VALUE_GET_STRING_ROPE(op2); + len += r2->len; + is_wide_char |= r2->is_wide_char; + depth = max_int(depth, r2->depth); + } + if (len > JS_STRING_LEN_MAX) { + JS_ThrowInternalError(ctx, "string too long"); + goto fail; + } + r = js_malloc(ctx, sizeof(*r)); + if (!r) + goto fail; + JS_REF_COUNT(r) = 1; + r->len = len; + r->is_wide_char = is_wide_char; + r->depth = depth + 1; + r->left = op1; + r->right = op2; + res = JS_MKPTR(JS_TAG_STRING_ROPE, r); + if (r->depth > JS_STRING_ROPE_MAX_DEPTH) { + JSValue res2; +#ifdef DUMP_ROPE_REBALANCE + printf("rebalance: initial depth=%d\n", r->depth); +#endif + res2 = js_rebalance_string_rope(ctx, res); +#ifdef DUMP_ROPE_REBALANCE + if (JS_VALUE_GET_TAG(res2) == JS_TAG_STRING_ROPE) + printf("rebalance: final depth=%d\n", JS_VALUE_GET_STRING_ROPE(res2)->depth); +#endif + JS_FreeValue(ctx, res); + return res2; + } else { + return res; + } + fail: + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + return JS_EXCEPTION; +} + +#define ROPE_N_BUCKETS 44 + +/* Fibonacci numbers starting from F_2 */ +static const uint32_t rope_bucket_len[ROPE_N_BUCKETS] = { + 1, 2, 3, 5, + 8, 13, 21, 34, + 55, 89, 144, 233, + 377, 610, 987, 1597, + 2584, 4181, 6765, 10946, + 17711, 28657, 46368, 75025, + 121393, 196418, 317811, 514229, + 832040, 1346269, 2178309, 3524578, + 5702887, 9227465, 14930352, 24157817, + 39088169, 63245986, 102334155, 165580141, + 267914296, 433494437, 701408733, 1134903170, /* > JS_STRING_LEN_MAX */ +}; + +static int js_rebalance_string_rope_rec(JSContext *ctx, JSValue *buckets, + JSValueConst val) +{ + if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING) { + JSString *p = JS_VALUE_GET_STRING(val); + uint32_t len, i; + JSValue a, b; + + len = p->len; + if (len == 0) + return 0; /* nothing to do */ + /* find the bucket i so that rope_bucket_len[i] <= len < + rope_bucket_len[i + 1] and concatenate the ropes in the + buckets before */ + a = JS_NULL; + i = 0; + while (len >= rope_bucket_len[i + 1]) { + b = buckets[i]; + if (!JS_IsNull(b)) { + buckets[i] = JS_NULL; + if (JS_IsNull(a)) { + a = b; + } else { + a = js_new_string_rope(ctx, b, a); + if (JS_IsException(a)) + return -1; + } + } + i++; + } + if (!JS_IsNull(a)) { + a = js_new_string_rope(ctx, a, js_dup(val)); + if (JS_IsException(a)) + return -1; + } else { + a = js_dup(val); + } + while (!JS_IsNull(buckets[i])) { + a = js_new_string_rope(ctx, buckets[i], a); + buckets[i] = JS_NULL; + if (JS_IsException(a)) + return -1; + i++; + } + buckets[i] = a; + } else { + JSStringRope *r = JS_VALUE_GET_STRING_ROPE(val); + if (js_rebalance_string_rope_rec(ctx, buckets, r->left)) + return -1; + if (js_rebalance_string_rope_rec(ctx, buckets, r->right)) + return -1; + } + return 0; +} + +/* Return a new rope which is balanced. Algorithm from "Ropes: an + Alternative to Strings", Hans-J. Boehm, Russ Atkinson and Michael + Plass. */ +static JSValue js_rebalance_string_rope(JSContext *ctx, JSValueConst rope) +{ + JSValue buckets[ROPE_N_BUCKETS], a, b; + int i; + + for(i = 0; i < ROPE_N_BUCKETS; i++) + buckets[i] = JS_NULL; + if (js_rebalance_string_rope_rec(ctx, buckets, rope)) + goto fail; + a = JS_NULL; + for(i = 0; i < ROPE_N_BUCKETS; i++) { + b = buckets[i]; + if (!JS_IsNull(b)) { + buckets[i] = JS_NULL; + if (JS_IsNull(a)) { + a = b; + } else { + a = js_new_string_rope(ctx, b, a); + if (JS_IsException(a)) + goto fail; + } + } + } + /* fail safe */ + if (JS_IsNull(a)) + return JS_AtomToString(ctx, JS_ATOM_empty_string); + else + return a; + fail: + for(i = 0; i < ROPE_N_BUCKETS; i++) { + JS_FreeValue(ctx, buckets[i]); + } + return JS_EXCEPTION; +} + +/* 'rope' must be a rope. return a string and modify the rope so that + it won't need to be linearized again. */ +static JSValue js_linearize_string_rope(JSContext *ctx, JSValueConst rope) +{ + StringBuffer b_s, *b = &b_s; + JSStringRope *r; + JSValue ret; + + r = JS_VALUE_GET_STRING_ROPE(rope); + + /* check whether it is already linearized */ + if (JS_VALUE_GET_TAG(r->right) == JS_TAG_STRING && + JS_VALUE_GET_STRING(r->right)->len == 0) { + ret = js_dup(r->left); + return ret; + } + if (string_buffer_init2(ctx, b, r->len, r->is_wide_char)) + goto fail; + if (string_buffer_concat_value(b, rope)) + goto fail; + ret = string_buffer_end(b); + if (JS_REF_COUNT(r) > 1) { + /* update the rope so that it won't need to be linearized again */ + JS_FreeValue(ctx, r->left); + JS_FreeValue(ctx, r->right); + r->left = js_dup(ret); + r->right = JS_AtomToString(ctx, JS_ATOM_empty_string); + } + return ret; + fail: + return JS_EXCEPTION; +} + +/* flat string concatenation - used by rope when concatenating short strings */ +static JSValue JS_ConcatString2(JSContext *ctx, JSValue op1, JSValue op2); + +static JSValue JS_ConcatString1(JSContext *ctx, JSString *p1, JSString *p2) +{ + JSString *p; + uint32_t len; + int is_wide_char; + + len = p1->len + p2->len; + if (len > JS_STRING_LEN_MAX) + return JS_ThrowRangeError(ctx, "invalid string length"); + is_wide_char = p1->is_wide_char | p2->is_wide_char; + p = js_alloc_string(ctx, len, is_wide_char); + if (!p) + return JS_EXCEPTION; + if (!is_wide_char) { + memcpy(str8(p), str8(p1), p1->len); + memcpy(str8(p) + p1->len, str8(p2), p2->len); + str8(p)[len] = '\0'; + } else { + copy_str16(str16(p), p1, 0, p1->len); + copy_str16(str16(p) + p1->len, p2, 0, p2->len); + } + return JS_MKPTR(JS_TAG_STRING, p); +} + +/* flat string concatenation - op1 and op2 must be JS_TAG_STRING */ +static JSValue JS_ConcatString2(JSContext *ctx, JSValue op1, JSValue op2) +{ + JSValue ret; + JSString *p1, *p2; + + p1 = JS_VALUE_GET_STRING(op1); + p2 = JS_VALUE_GET_STRING(op2); + + /* XXX: could also check if p1 is empty */ + if (p2->len == 0) { + goto ret_op1; + } + if (JS_REF_COUNT(p1) == 1 && p1->is_wide_char == p2->is_wide_char + && js_malloc_usable_size(ctx, p1) >= sizeof(*p1) + ((p1->len + p2->len) << p2->is_wide_char) + 1 - p1->is_wide_char) { + /* Concatenate in place in available space at the end of p1 */ + if (p1->is_wide_char) { + memcpy(str16(p1) + p1->len, str16(p2), p2->len << 1); + p1->len += p2->len; + } else { + memcpy(str8(p1) + p1->len, str8(p2), p2->len); + p1->len += p2->len; + str8(p1)[p1->len] = '\0'; + } + ret_op1: + JS_FreeValue(ctx, op2); + return op1; + } + ret = JS_ConcatString1(ctx, p1, p2); + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + return ret; +} + +/* op1 and op2 are converted to strings. For convenience, op1 or op2 = + JS_EXCEPTION are accepted and return JS_EXCEPTION. */ +static JSValue JS_ConcatString(JSContext *ctx, JSValue op1, JSValue op2) +{ + JSString *p1, *p2; + + if (unlikely(!tag_is_string(JS_VALUE_GET_TAG(op1)))) { + op1 = JS_ToStringFree(ctx, op1); + if (JS_IsException(op1)) { + JS_FreeValue(ctx, op2); + return JS_EXCEPTION; + } + } + if (unlikely(!tag_is_string(JS_VALUE_GET_TAG(op2)))) { + op2 = JS_ToStringFree(ctx, op2); + if (JS_IsException(op2)) { + JS_FreeValue(ctx, op1); + return JS_EXCEPTION; + } + } + + /* normal concatenation for short strings */ + if (JS_VALUE_GET_TAG(op2) == JS_TAG_STRING) { + p2 = JS_VALUE_GET_STRING(op2); + if (p2->len == 0) { + JS_FreeValue(ctx, op2); + return op1; + } + if (p2->len <= JS_STRING_ROPE_SHORT_LEN) { + if (JS_VALUE_GET_TAG(op1) == JS_TAG_STRING) { + p1 = JS_VALUE_GET_STRING(op1); + if (p1->len <= JS_STRING_ROPE_SHORT2_LEN) { + return JS_ConcatString2(ctx, op1, op2); + } else { + return js_new_string_rope(ctx, op1, op2); + } + } else { + JSStringRope *r1; + r1 = JS_VALUE_GET_STRING_ROPE(op1); + if (JS_VALUE_GET_TAG(r1->right) == JS_TAG_STRING && + JS_VALUE_GET_STRING(r1->right)->len <= JS_STRING_ROPE_SHORT_LEN) { + JSValue val, ret; + val = JS_ConcatString2(ctx, js_dup(r1->right), op2); + if (JS_IsException(val)) { + JS_FreeValue(ctx, op1); + return JS_EXCEPTION; + } + ret = js_new_string_rope(ctx, js_dup(r1->left), val); + JS_FreeValue(ctx, op1); + return ret; + } + } + } + } else if (JS_VALUE_GET_TAG(op1) == JS_TAG_STRING) { + JSStringRope *r2; + p1 = JS_VALUE_GET_STRING(op1); + if (p1->len == 0) { + JS_FreeValue(ctx, op1); + return op2; + } + r2 = JS_VALUE_GET_STRING_ROPE(op2); + if (JS_VALUE_GET_TAG(r2->left) == JS_TAG_STRING && + JS_VALUE_GET_STRING(r2->left)->len <= JS_STRING_ROPE_SHORT_LEN) { + JSValue val, ret; + val = JS_ConcatString2(ctx, op1, js_dup(r2->left)); + if (JS_IsException(val)) { + JS_FreeValue(ctx, op2); + return JS_EXCEPTION; + } + ret = js_new_string_rope(ctx, val, js_dup(r2->right)); + JS_FreeValue(ctx, op2); + return ret; + } + } + return js_new_string_rope(ctx, op1, op2); +} + +/* Shape support */ + +static inline size_t get_shape_size(size_t hash_size, size_t prop_size) +{ + return hash_size * sizeof(uint32_t) + sizeof(JSShape) + + prop_size * sizeof(JSShapeProperty); +} + +static inline JSShape *get_shape_from_alloc(void *sh_alloc, size_t hash_size) +{ + (void)hash_size; + return (JSShape *)sh_alloc; /* shape sits at the allocation start */ +} + +/* one-past-the-end of the hash bucket array; buckets are addressed as + prop_hash_end(sh)[-h - 1] for h in [0, prop_hash_mask], in BOTH layouts. */ +static inline uint32_t *prop_hash_end(JSShape *sh) +{ + return sh->hash_table + sh->prop_hash_mask + 1; +} + +/* the JSShapeProperty array */ +static inline JSShapeProperty *get_shape_prop(JSShape *sh) +{ + return (JSShapeProperty *)(void *)(sh->hash_table + sh->prop_hash_mask + 1); +} + +static inline void *get_alloc_from_shape(JSShape *sh) +{ + return sh; /* shape sits at the allocation start */ +} + +static int init_shape_hash(JSRuntime *rt) +{ + rt->shape_hash_bits = 6; /* 64 shapes */ + rt->shape_hash_size = 1 << rt->shape_hash_bits; + rt->shape_hash_count = 0; + rt->shape_hash = js_mallocz_rt(rt, sizeof(rt->shape_hash[0]) * + rt->shape_hash_size); + if (!rt->shape_hash) + return -1; + return 0; +} + +static uintptr_t hash_atom(JSAtom atom, uintptr_t mask) +{ + int shift = 1 + clz_uintptr(mask+1); + return hash_uintptr(atom) >> shift; +} + +static uint32_t shape_hash(uint32_t h, uint32_t val) +{ + return hash32(h + val); +} + +/* truncate the shape hash to 'hash_bits' bits */ +static uint32_t get_shape_hash(uint32_t h, int hash_bits) +{ + return h >> (32 - hash_bits); +} + +static uint32_t shape_initial_hash(JSObject *proto) +{ + uint32_t h; + h = shape_hash(1, (uintptr_t)proto); + if (sizeof(proto) > 4) + h = shape_hash(h, (uint64_t)(uintptr_t)proto >> 32); + return h; +} + +static int resize_shape_hash(JSRuntime *rt, int new_shape_hash_bits) +{ + int new_shape_hash_size, i; + uint32_t h; + JSShape **new_shape_hash, *sh, *sh_next; + + new_shape_hash_size = 1 << new_shape_hash_bits; + new_shape_hash = js_mallocz_rt(rt, sizeof(rt->shape_hash[0]) * + new_shape_hash_size); + if (!new_shape_hash) + return -1; + for(i = 0; i < rt->shape_hash_size; i++) { + for(sh = rt->shape_hash[i]; sh != NULL; sh = sh_next) { + sh_next = sh->shape_hash_next; + h = get_shape_hash(sh->hash, new_shape_hash_bits); + sh->shape_hash_next = new_shape_hash[h]; + new_shape_hash[h] = sh; + } + } + js_free_rt(rt, rt->shape_hash); + rt->shape_hash_bits = new_shape_hash_bits; + rt->shape_hash_size = new_shape_hash_size; + rt->shape_hash = new_shape_hash; + return 0; +} + +static void js_shape_hash_link(JSRuntime *rt, JSShape *sh) +{ + uint32_t h; + h = get_shape_hash(sh->hash, rt->shape_hash_bits); + sh->shape_hash_next = rt->shape_hash[h]; + rt->shape_hash[h] = sh; + rt->shape_hash_count++; +} + +static void js_shape_hash_unlink(JSRuntime *rt, JSShape *sh) +{ + uint32_t h; + JSShape **psh; + + h = get_shape_hash(sh->hash, rt->shape_hash_bits); + psh = &rt->shape_hash[h]; + while (*psh != sh) + psh = &(*psh)->shape_hash_next; + *psh = sh->shape_hash_next; + rt->shape_hash_count--; +} + +/* create a new empty shape with prototype 'proto'. It is not hashed */ +static inline JSShape *js_new_shape_nohash(JSContext *ctx, JSObject *proto, + int hash_size, int prop_size) +{ + JSRuntime *rt = ctx->rt; + void *sh_alloc; + JSShape *sh; + + sh_alloc = js_malloc(ctx, get_shape_size(hash_size, prop_size)); + if (!sh_alloc) + return NULL; + sh = get_shape_from_alloc(sh_alloc, hash_size); + JS_REF_COUNT(sh) = 1; + add_gc_object(rt, &sh->header, JS_GC_OBJ_TYPE_SHAPE); + if (proto) + js_dup(JS_MKPTR(JS_TAG_OBJECT, proto)); + sh->proto = proto; + /* prop_hash_mask must be set before prop_hash_end(sh) is used, as the hash + location depends on it in the merged-header layout. */ + sh->prop_hash_mask = hash_size - 1; + memset(prop_hash_end(sh) - hash_size, 0, sizeof(prop_hash_end(sh)[0]) * + hash_size); + sh->prop_size = prop_size; + sh->prop_count = 0; + sh->deleted_prop_count = 0; + sh->is_hashed = false; + return sh; +} + +/* create a new empty shape with prototype 'proto' */ +static no_inline JSShape *js_new_shape2(JSContext *ctx, JSObject *proto, + int hash_size, int prop_size) +{ + JSRuntime *rt = ctx->rt; + JSShape *sh; + + /* resize the shape hash table if necessary */ + if (2 * (rt->shape_hash_count + 1) > rt->shape_hash_size) { + resize_shape_hash(rt, rt->shape_hash_bits + 1); + } + + sh = js_new_shape_nohash(ctx, proto, hash_size, prop_size); + if (!sh) + return NULL; + + /* insert in the hash table */ + sh->hash = shape_initial_hash(proto); + sh->is_hashed = true; + js_shape_hash_link(ctx->rt, sh); + return sh; +} + +static JSShape *js_new_shape(JSContext *ctx, JSObject *proto) +{ + return js_new_shape2(ctx, proto, JS_PROP_INITIAL_HASH_SIZE, + JS_PROP_INITIAL_SIZE); +} + +static JSObject *object_or_null(JSValueConst val) +{ + if (JS_TAG_OBJECT == JS_VALUE_GET_TAG(val)) + return JS_VALUE_GET_OBJ(val); + return NULL; +} + +static int add_shape_property(JSContext *ctx, JSShape **psh, + JSObject *p, JSAtom atom, int prop_flags); + +static JSShape *js_new_shape_with2(JSContext *ctx, JSObject *proto, + int prop_count, const JSShapeProperty props[]) { + JSShape *sh; + int i; + + sh = js_new_shape2(ctx, proto, JS_PROP_INITIAL_HASH_SIZE, prop_count); + if (sh) + for (i = 0; i < prop_count; i++) + if (add_shape_property(ctx, &sh, NULL, props[i].atom, props[i].flags)) + goto fail; + return sh; +fail: + js_free_shape(ctx->rt, sh); + return NULL; +} + +static int js_new_shape_with(JSContext *ctx, JSShape **psh, JSValueConst proto, + int prop_count, const JSShapeProperty props[]) { + *psh = js_new_shape_with2(ctx, object_or_null(proto), prop_count, props); + if (*psh) + return 0; + return -1; +} + +/* The shape is cloned. The new shape is not inserted in the shape + hash table */ +static JSShape *js_clone_shape(JSContext *ctx, JSShape *sh1) +{ + JSShape *sh; + void *sh_alloc, *sh_alloc1; + size_t size; + JSShapeProperty *pr; + uint32_t i, hash_size; + + hash_size = sh1->prop_hash_mask + 1; + size = get_shape_size(hash_size, sh1->prop_size); + sh_alloc = js_malloc(ctx, size); + if (!sh_alloc) + return NULL; + sh_alloc1 = get_alloc_from_shape(sh1); + memcpy(sh_alloc, sh_alloc1, size); + sh = get_shape_from_alloc(sh_alloc, hash_size); + JS_REF_COUNT(sh) = 1; + add_gc_object(ctx->rt, &sh->header, JS_GC_OBJ_TYPE_SHAPE); + sh->is_hashed = false; + if (sh->proto) { + js_dup(JS_MKPTR(JS_TAG_OBJECT, sh->proto)); + } + for(i = 0, pr = get_shape_prop(sh); i < sh->prop_count; i++, pr++) { + JS_DupAtom(ctx, pr->atom); + } + return sh; +} + +static JSShape *js_dup_shape(JSShape *sh) +{ + JS_REF_COUNT(sh)++; + return sh; +} + +static void js_free_shape0(JSRuntime *rt, JSShape *sh) +{ + uint32_t i; + JSShapeProperty *pr; + + assert(JS_REF_COUNT(sh) == 0); + if (sh->is_hashed) + js_shape_hash_unlink(rt, sh); + if (sh->proto != NULL) { + JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, sh->proto)); + } + pr = get_shape_prop(sh); + for(i = 0; i < sh->prop_count; i++) { + JS_FreeAtomRT(rt, pr->atom); + pr++; + } + remove_gc_object(&sh->header); + js_free_rt(rt, get_alloc_from_shape(sh)); +} + +static void js_free_shape(JSRuntime *rt, JSShape *sh) +{ + if (unlikely(--JS_REF_COUNT(sh) <= 0)) { + js_free_shape0(rt, sh); + } +} + +static void js_free_shape_null(JSRuntime *rt, JSShape *sh) +{ + if (sh) + js_free_shape(rt, sh); +} + +/* make space to hold at least 'count' properties */ +static no_inline int resize_properties(JSContext *ctx, JSShape **psh, + JSObject *p, uint32_t count) +{ + JSShape *sh; + uint32_t new_size, new_hash_size, new_hash_mask, i; + JSShapeProperty *pr; + void *sh_alloc; + intptr_t h; + + sh = *psh; + new_size = max_int(count, sh->prop_size * 3 / 2); + /* Reallocate prop array first to avoid crash or size inconsistency + in case of memory allocation failure */ + if (p) { + JSProperty *new_prop; + new_prop = js_realloc(ctx, p->prop, sizeof(new_prop[0]) * new_size); + if (unlikely(!new_prop)) + return -1; + p->prop = new_prop; + } + new_hash_size = sh->prop_hash_mask + 1; + while (new_hash_size < new_size) + new_hash_size = 2 * new_hash_size; + if (new_hash_size != (sh->prop_hash_mask + 1)) { + JSShape *old_sh; + /* resize the hash table and the properties */ + old_sh = sh; + sh_alloc = js_malloc(ctx, get_shape_size(new_hash_size, new_size)); + if (!sh_alloc) + return -1; + sh = get_shape_from_alloc(sh_alloc, new_hash_size); + list_del(&old_sh->header.link); + /* copy the shape header, then the properties. Their location relative + to the struct differs by layout, so copy via get_shape_prop(). */ + memcpy(sh, old_sh, sizeof(JSShape)); + list_add_tail(&sh->header.link, &ctx->rt->gc_obj_list); + /* the GC/refcount fields live in the block header, not the struct, so + the memcpy above did not carry them: transfer them explicitly */ + JS_REF_COUNT(sh) = JS_REF_COUNT(old_sh); + JS_GC_TYPE(sh) = JS_GC_TYPE(old_sh); + JS_GC_MARK(sh) = JS_GC_MARK(old_sh); + new_hash_mask = new_hash_size - 1; + sh->prop_hash_mask = new_hash_mask; + memcpy(get_shape_prop(sh), get_shape_prop(old_sh), + sizeof(JSShapeProperty) * old_sh->prop_count); + memset(prop_hash_end(sh) - new_hash_size, 0, + sizeof(prop_hash_end(sh)[0]) * new_hash_size); + for(i = 0, pr = get_shape_prop(sh); i < sh->prop_count; i++, pr++) { + if (pr->atom != JS_ATOM_NULL) { + h = hash_atom(pr->atom, new_hash_mask); + pr->hash_next = prop_hash_end(sh)[-h - 1]; + prop_hash_end(sh)[-h - 1] = i + 1; + } + } + js_free(ctx, get_alloc_from_shape(old_sh)); + } else { + /* only resize the properties */ + list_del(&sh->header.link); + sh_alloc = js_realloc(ctx, get_alloc_from_shape(sh), + get_shape_size(new_hash_size, new_size)); + if (unlikely(!sh_alloc)) { + /* insert again in the GC list */ + list_add_tail(&sh->header.link, &ctx->rt->gc_obj_list); + return -1; + } + sh = get_shape_from_alloc(sh_alloc, new_hash_size); + list_add_tail(&sh->header.link, &ctx->rt->gc_obj_list); + } + *psh = sh; + sh->prop_size = new_size; + return 0; +} + +/* remove the deleted properties. */ +static int compact_properties(JSContext *ctx, JSObject *p) +{ + JSShape *sh, *old_sh; + void *sh_alloc; + intptr_t h; + uint32_t new_hash_size, i, j, new_hash_mask, new_size; + JSShapeProperty *old_pr, *pr; + JSProperty *prop, *new_prop; + + sh = p->shape; + assert(!sh->is_hashed); + + new_size = max_int(JS_PROP_INITIAL_SIZE, + sh->prop_count - sh->deleted_prop_count); + assert(new_size <= sh->prop_size); + + new_hash_size = sh->prop_hash_mask + 1; + while ((new_hash_size / 2) >= new_size) + new_hash_size = new_hash_size / 2; + new_hash_mask = new_hash_size - 1; + + /* resize the hash table and the properties */ + old_sh = sh; + sh_alloc = js_malloc(ctx, get_shape_size(new_hash_size, new_size)); + if (!sh_alloc) + return -1; + sh = get_shape_from_alloc(sh_alloc, new_hash_size); + list_del(&old_sh->header.link); + memcpy(sh, old_sh, sizeof(JSShape)); + list_add_tail(&sh->header.link, &ctx->rt->gc_obj_list); + /* the GC/refcount fields live in the block header, not the struct, so the + memcpy above did not carry them: transfer them explicitly */ + JS_REF_COUNT(sh) = JS_REF_COUNT(old_sh); + JS_GC_TYPE(sh) = JS_GC_TYPE(old_sh); + JS_GC_MARK(sh) = JS_GC_MARK(old_sh); + + /* set the new hash mask before prop_hash_end()/get_shape_prop() are used, + as their locations depend on it in the merged-header layout */ + sh->prop_hash_mask = new_hash_mask; + memset(prop_hash_end(sh) - new_hash_size, 0, + sizeof(prop_hash_end(sh)[0]) * new_hash_size); + + j = 0; + old_pr = get_shape_prop(old_sh); + pr = get_shape_prop(sh); + prop = p->prop; + for(i = 0; i < sh->prop_count; i++) { + if (old_pr->atom != JS_ATOM_NULL) { + pr->atom = old_pr->atom; + pr->flags = old_pr->flags; + h = hash_atom(old_pr->atom, new_hash_mask); + pr->hash_next = prop_hash_end(sh)[-h - 1]; + prop_hash_end(sh)[-h - 1] = j + 1; + prop[j] = prop[i]; + j++; + pr++; + } + old_pr++; + } + assert(j == (sh->prop_count - sh->deleted_prop_count)); + sh->prop_hash_mask = new_hash_mask; + sh->prop_size = new_size; + sh->deleted_prop_count = 0; + sh->prop_count = j; + + p->shape = sh; + js_free(ctx, get_alloc_from_shape(old_sh)); + + /* reduce the size of the object properties */ + new_prop = js_realloc(ctx, p->prop, sizeof(new_prop[0]) * new_size); + if (new_prop) + p->prop = new_prop; + return 0; +} + +static int add_shape_property(JSContext *ctx, JSShape **psh, + JSObject *p, JSAtom atom, int prop_flags) +{ + JSRuntime *rt = ctx->rt; + JSShape *sh = *psh; + JSShapeProperty *pr, *prop; + uint32_t hash_mask, new_shape_hash = 0; + intptr_t h; + + /* update the shape hash */ + if (sh->is_hashed) { + js_shape_hash_unlink(rt, sh); + new_shape_hash = shape_hash(shape_hash(sh->hash, atom), prop_flags); + } + + if (unlikely(sh->prop_count >= sh->prop_size)) { + if (resize_properties(ctx, psh, p, sh->prop_count + 1)) { + /* in case of error, reinsert in the hash table. + sh is still valid if resize_properties() failed */ + if (sh->is_hashed) + js_shape_hash_link(rt, sh); + return -1; + } + sh = *psh; + } + if (sh->is_hashed) { + sh->hash = new_shape_hash; + js_shape_hash_link(rt, sh); + } + /* Initialize the new shape property. + The object property at p->prop[sh->prop_count] is uninitialized */ + prop = get_shape_prop(sh); + pr = &prop[sh->prop_count++]; + pr->atom = JS_DupAtom(ctx, atom); + pr->flags = prop_flags; + /* add in hash table */ + hash_mask = sh->prop_hash_mask; + h = hash_atom(atom, hash_mask); + pr->hash_next = prop_hash_end(sh)[-h - 1]; + prop_hash_end(sh)[-h - 1] = sh->prop_count; + return 0; +} + +/* find a hashed empty shape matching the prototype. Return NULL if + not found */ +static JSShape *find_hashed_shape_proto(JSRuntime *rt, JSObject *proto) +{ + JSShape *sh1; + uint32_t h, h1; + + h = shape_initial_hash(proto); + h1 = get_shape_hash(h, rt->shape_hash_bits); + for(sh1 = rt->shape_hash[h1]; sh1 != NULL; sh1 = sh1->shape_hash_next) { + if (sh1->hash == h && + sh1->proto == proto && + sh1->prop_count == 0) { + return sh1; + } + } + return NULL; +} + +/* find a hashed shape matching sh + (prop, prop_flags). Return NULL if + not found */ +static JSShape *find_hashed_shape_prop(JSRuntime *rt, JSShape *sh, + JSAtom atom, int prop_flags) +{ + JSShape *sh1; + uint32_t h, h1, i, n; + + h = sh->hash; + h = shape_hash(h, atom); + h = shape_hash(h, prop_flags); + h1 = get_shape_hash(h, rt->shape_hash_bits); + for(sh1 = rt->shape_hash[h1]; sh1 != NULL; sh1 = sh1->shape_hash_next) { + /* we test the hash first so that the rest is done only if the + shapes really match */ + if (sh1->hash == h && + sh1->proto == sh->proto && + sh1->prop_count == ((n = sh->prop_count) + 1)) { + for(i = 0; i < n; i++) { + if (unlikely(get_shape_prop(sh1)[i].atom != get_shape_prop(sh)[i].atom) || + unlikely(get_shape_prop(sh1)[i].flags != get_shape_prop(sh)[i].flags)) + goto next; + } + if (unlikely(get_shape_prop(sh1)[n].atom != atom) || + unlikely(get_shape_prop(sh1)[n].flags != prop_flags)) + goto next; + return sh1; + } + next: ; + } + return NULL; +} + +static __maybe_unused void JS_DumpShape(JSRuntime *rt, int i, JSShape *sh) +{ + char atom_buf[ATOM_GET_STR_BUF_SIZE]; + int j; + + /* XXX: should output readable class prototype */ + printf("%5d %3d%c %14p %5d %5d", i, + JS_REF_COUNT(sh), " *"[sh->is_hashed], + (void *)sh->proto, sh->prop_size, sh->prop_count); + for(j = 0; j < sh->prop_count; j++) { + printf(" %s", JS_AtomGetStrRT(rt, atom_buf, sizeof(atom_buf), + get_shape_prop(sh)[j].atom)); + } + printf("\n"); +} + +static __maybe_unused void JS_DumpShapes(JSRuntime *rt) +{ + int i; + JSShape *sh; + struct list_head *el; + JSObject *p; + JSGCObjectHeader *gp; + + printf("JSShapes: {\n"); + printf("%5s %4s %14s %5s %5s %s\n", "SLOT", "REFS", "PROTO", "SIZE", "COUNT", "PROPS"); + for(i = 0; i < rt->shape_hash_size; i++) { + for(sh = rt->shape_hash[i]; sh != NULL; sh = sh->shape_hash_next) { + JS_DumpShape(rt, i, sh); + assert(sh->is_hashed); + } + } + /* dump non-hashed shapes */ + list_for_each(el, &rt->gc_obj_list) { + gp = list_entry(el, JSGCObjectHeader, link); + if (JS_GC_TYPE(gp) == JS_GC_OBJ_TYPE_JS_OBJECT) { + p = (JSObject *)gp; + if (!p->shape->is_hashed) { + JS_DumpShape(rt, -1, p->shape); + } + } + } + printf("}\n"); +} + +/* 'props[]' is used to initialized the object properties. The number + of elements depends on the shape. */ +static JSValue JS_NewObjectFromShape(JSContext *ctx, JSShape *sh, JSClassID class_id, + JSProperty *props) +{ + JSObject *p; + int i; + + js_trigger_gc(ctx->rt, sizeof(JSObject) + sizeof(JSProperty) * sh->prop_size); + p = js_malloc(ctx, sizeof(JSObject)); + if (unlikely(!p)) + goto fail; + p->class_id = class_id; + p->extensible = true; + p->free_mark = 0; + p->is_exotic = 0; + p->fast_array = 0; + p->is_constructor = 0; + p->is_uncatchable_error = 0; + p->tmp_mark = 0; + p->is_HTMLDDA = 0; + p->is_prototype = 0; + p->first_weak_ref = NULL; + p->u.opaque = NULL; + p->shape = sh; + p->prop = js_malloc(ctx, sizeof(JSProperty) * sh->prop_size); + if (unlikely(!p->prop)) { + js_free(ctx, p); + fail: + if (props) { + JSShapeProperty *prs = get_shape_prop(sh); + for(i = 0; i < sh->prop_count; i++) { + free_property(ctx->rt, &props[i], prs->flags); + prs++; + } + } + js_free_shape(ctx->rt, sh); + return JS_EXCEPTION; + } + + switch(class_id) { + case JS_CLASS_OBJECT: + break; + case JS_CLASS_ARRAY: + { + JSProperty *pr; + p->is_exotic = 1; + p->fast_array = 1; + p->u.array.u.values = NULL; + p->u.array.count = 0; + p->u.array.u1.size = 0; + if (!props) { + /* XXX: remove */ + /* the length property is always the first one */ + if (likely(sh == ctx->array_shape)) { + pr = &p->prop[0]; + } else { + /* only used for the first array */ + /* cannot fail */ + pr = add_property(ctx, p, JS_ATOM_length, + JS_PROP_WRITABLE | JS_PROP_LENGTH); + } + pr->u.value = js_int32(0); + } + } + break; + case JS_CLASS_C_FUNCTION: + p->prop[0].u.value = JS_UNDEFINED; + break; + case JS_CLASS_ARGUMENTS: + case JS_CLASS_MAPPED_ARGUMENTS: + case JS_CLASS_UINT8C_ARRAY: + case JS_CLASS_INT8_ARRAY: + case JS_CLASS_UINT8_ARRAY: + case JS_CLASS_INT16_ARRAY: + case JS_CLASS_UINT16_ARRAY: + case JS_CLASS_INT32_ARRAY: + case JS_CLASS_UINT32_ARRAY: + case JS_CLASS_BIG_INT64_ARRAY: + case JS_CLASS_BIG_UINT64_ARRAY: + case JS_CLASS_FLOAT16_ARRAY: + case JS_CLASS_FLOAT32_ARRAY: + case JS_CLASS_FLOAT64_ARRAY: + p->is_exotic = 1; + p->fast_array = 1; + p->u.array.u.ptr = NULL; + p->u.array.count = 0; + break; + case JS_CLASS_DATAVIEW: + p->u.array.u.ptr = NULL; + p->u.array.count = 0; + break; + case JS_CLASS_ERROR: + case JS_CLASS_NUMBER: + case JS_CLASS_STRING: + case JS_CLASS_BOOLEAN: + case JS_CLASS_SYMBOL: + case JS_CLASS_DATE: + case JS_CLASS_BIG_INT: + p->u.object_data = JS_UNDEFINED; + goto set_exotic; + case JS_CLASS_REGEXP: + p->u.regexp.pattern = NULL; + p->u.regexp.bytecode = NULL; + goto set_exotic; + default: + set_exotic: + if (ctx->rt->class_array[class_id].exotic) { + p->is_exotic = 1; + } + break; + } + JS_REF_COUNT(p) = 1; + add_gc_object(ctx->rt, &p->header, JS_GC_OBJ_TYPE_JS_OBJECT); + if (props) { + for(i = 0; i < sh->prop_count; i++) + p->prop[i] = props[i]; + } + return JS_MKPTR(JS_TAG_OBJECT, p); +} + +/* WARNING: proto must be an object or JS_NULL */ +JSValue JS_NewObjectProtoClass(JSContext *ctx, JSValueConst proto_val, + JSClassID class_id) +{ + JSShape *sh; + JSObject *proto; + + proto = object_or_null(proto_val); + sh = find_hashed_shape_proto(ctx->rt, proto); + if (likely(sh)) { + sh = js_dup_shape(sh); + } else { + sh = js_new_shape(ctx, proto); + if (!sh) + return JS_EXCEPTION; + } + return JS_NewObjectFromShape(ctx, sh, class_id, NULL); +} + +/* WARNING: the shape is not hashed. It is used for objects where + factorizing the shape is not relevant (prototypes, constructors) */ +static JSValue JS_NewObjectProtoClassAlloc(JSContext *ctx, JSValueConst proto_val, + JSClassID class_id, int n_alloc_props) +{ + JSShape *sh; + JSObject *proto; + int hash_size, hash_bits; + + if (n_alloc_props <= JS_PROP_INITIAL_SIZE) { + n_alloc_props = JS_PROP_INITIAL_SIZE; + hash_size = JS_PROP_INITIAL_HASH_SIZE; + } else { + hash_bits = 32 - clz32(n_alloc_props - 1); /* ceil(log2(radix)) */ + hash_size = 1 << hash_bits; + } + proto = object_or_null(proto_val); + sh = js_new_shape_nohash(ctx, proto, hash_size, n_alloc_props); + if (!sh) + return JS_EXCEPTION; + return JS_NewObjectFromShape(ctx, sh, class_id, NULL); +} + +static int JS_SetObjectData(JSContext *ctx, JSValueConst obj, JSValue val) +{ + JSObject *p; + + if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { + p = JS_VALUE_GET_OBJ(obj); + switch(p->class_id) { + case JS_CLASS_NUMBER: + case JS_CLASS_STRING: + case JS_CLASS_BOOLEAN: + case JS_CLASS_SYMBOL: + case JS_CLASS_DATE: + case JS_CLASS_BIG_INT: + JS_FreeValue(ctx, p->u.object_data); + p->u.object_data = val; /* for JS_CLASS_STRING, 'val' must + be JS_TAG_STRING (and not a rope) */ + return 0; + } + } + JS_FreeValue(ctx, val); + if (!JS_IsException(obj)) + JS_ThrowTypeError(ctx, "invalid object type"); + return -1; +} + +JSValue JS_NewObjectClass(JSContext *ctx, JSClassID class_id) +{ + return JS_NewObjectProtoClass(ctx, ctx->class_proto[class_id], class_id); +} + +JSValue JS_NewObjectProto(JSContext *ctx, JSValueConst proto) +{ + return JS_NewObjectProtoClass(ctx, proto, JS_CLASS_OBJECT); +} + +JSValue JS_NewObjectFrom(JSContext *ctx, int count, const JSAtom *props, + const JSValue *values) +{ + JSValue obj; + int i; + + obj = JS_NewObject(ctx); + if (JS_IsException(obj)) + return JS_EXCEPTION; + for (i = 0; i < count; i++) + if (JS_SetProperty(ctx, obj, props[i], values[i]) < 0) + goto fail; + return obj; +fail: + for (/*empty*/; i < count; i++) + JS_FreeValue(ctx, values[i]); + JS_FreeValue(ctx, obj); + return JS_EXCEPTION; +} + +JSValue JS_NewObjectFromStr(JSContext *ctx, int count, const char **props, + const JSValue *values) +{ + JSAtom atoms_s[16], *atoms = atoms_s; + JSValue ret; + int i; + + i = 0; + ret = JS_EXCEPTION; + if (count < 1) + goto out; + if (count > (int)countof(atoms_s)) { + atoms = js_malloc(ctx, count * sizeof(*atoms)); + if (!atoms) + return JS_EXCEPTION; + } + for (i = 0; i < count; i++) { + atoms[i] = JS_NewAtom(ctx, props[i]); + if (atoms[i] == JS_ATOM_NULL) + goto out; + } + ret = JS_NewObjectFrom(ctx, count, atoms, values); +out: + while (i-- > 0) + JS_FreeAtom(ctx, atoms[i]); + if (atoms != atoms_s) + js_free(ctx, atoms); + return ret; +} + +JSValue JS_NewArray(JSContext *ctx) +{ + return JS_NewObjectFromShape(ctx, js_dup_shape(ctx->array_shape), + JS_CLASS_ARRAY, NULL); +} + +// note: takes ownership of |values|, unlike js_create_array +JSValue JS_NewArrayFrom(JSContext *ctx, int count, const JSValue *values) +{ + JSObject *p; + JSValue obj; + int i; + + obj = JS_NewArray(ctx); + if (JS_IsException(obj)) + goto exception; + if (count > 0) { + p = JS_VALUE_GET_OBJ(obj); + if (expand_fast_array(ctx, p, count)) { + JS_FreeValue(ctx, obj); + goto exception; + } + p->u.array.count = count; + p->prop[0].u.value = js_int32(count); + memcpy(p->u.array.u.values, values, count * sizeof(*values)); + } + return obj; +exception: + for (i = 0; i < count; i++) + JS_FreeValue(ctx, values[i]); + return JS_EXCEPTION; +} + +JSValue JS_NewObject(JSContext *ctx) +{ + /* inline JS_NewObjectClass(ctx, JS_CLASS_OBJECT); */ + return JS_NewObjectProtoClass(ctx, ctx->class_proto[JS_CLASS_OBJECT], JS_CLASS_OBJECT); +} + +static void js_function_set_properties(JSContext *ctx, JSValue func_obj, + JSAtom name, int len) +{ + /* ES6 feature non compatible with ES5.1: length is configurable */ + JS_DefinePropertyValue(ctx, func_obj, JS_ATOM_length, js_int32(len), + JS_PROP_CONFIGURABLE); + JS_DefinePropertyValue(ctx, func_obj, JS_ATOM_name, + JS_AtomToString(ctx, name), JS_PROP_CONFIGURABLE); +} + +static bool js_class_has_bytecode(JSClassID class_id) +{ + return (class_id == JS_CLASS_BYTECODE_FUNCTION || + class_id == JS_CLASS_GENERATOR_FUNCTION || + class_id == JS_CLASS_ASYNC_FUNCTION || + class_id == JS_CLASS_ASYNC_GENERATOR_FUNCTION); +} + +/* return NULL without exception if not a function or no bytecode */ +static JSFunctionBytecode *JS_GetFunctionBytecode(JSValueConst val) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) + return NULL; + p = JS_VALUE_GET_OBJ(val); + if (!js_class_has_bytecode(p->class_id)) + return NULL; + return p->u.func.function_bytecode; +} + +static void js_method_set_home_object(JSContext *ctx, JSValue func_obj, + JSValue home_obj) +{ + JSObject *p, *p1; + JSFunctionBytecode *b; + + if (JS_VALUE_GET_TAG(func_obj) != JS_TAG_OBJECT) + return; + p = JS_VALUE_GET_OBJ(func_obj); + if (!js_class_has_bytecode(p->class_id)) + return; + b = p->u.func.function_bytecode; + if (b->need_home_object) { + p1 = p->u.func.home_object; + if (p1) { + JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p1)); + } + if (JS_VALUE_GET_TAG(home_obj) == JS_TAG_OBJECT) + p1 = JS_VALUE_GET_OBJ(js_dup(home_obj)); + else + p1 = NULL; + p->u.func.home_object = p1; + } +} + +static JSValue js_get_function_name(JSContext *ctx, JSAtom name) +{ + JSValue name_str; + + name_str = JS_AtomToString(ctx, name); + if (JS_AtomSymbolHasDescription(ctx, name)) { + name_str = JS_ConcatString3(ctx, "[", name_str, "]"); + } + return name_str; +} + +/* Modify the name of a method according to the atom and + 'flags'. 'flags' is a bitmask of JS_PROP_HAS_GET and + JS_PROP_HAS_SET. Also set the home object of the method. + Return < 0 if exception. */ +static int js_method_set_properties(JSContext *ctx, JSValue func_obj, + JSAtom name, int flags, JSValue home_obj) +{ + JSValue name_str; + + name_str = js_get_function_name(ctx, name); + if (flags & JS_PROP_HAS_GET) { + name_str = JS_ConcatString3(ctx, "get ", name_str, ""); + } else if (flags & JS_PROP_HAS_SET) { + name_str = JS_ConcatString3(ctx, "set ", name_str, ""); + } + if (JS_IsException(name_str)) + return -1; + if (JS_DefinePropertyValue(ctx, func_obj, JS_ATOM_name, name_str, + JS_PROP_CONFIGURABLE) < 0) + return -1; + js_method_set_home_object(ctx, func_obj, home_obj); + return 0; +} + +/* Note: at least 'length' arguments will be readable in 'argv' */ +/* `name` may be NULL, pure ASCII or UTF-8 encoded */ +JSValue JS_NewCFunction3(JSContext *ctx, JSCFunction *func, + const char *name, + int length, JSCFunctionEnum cproto, int magic, + JSValueConst proto_val, int n_fields) +{ + JSValue func_obj; + JSObject *p; + JSAtom name_atom; + + if (n_fields > 0) { + func_obj = JS_NewObjectProtoClassAlloc(ctx, proto_val, JS_CLASS_C_FUNCTION, n_fields); + } else { + func_obj = JS_NewObjectProtoClass(ctx, proto_val, JS_CLASS_C_FUNCTION); + } + if (JS_IsException(func_obj)) + return func_obj; + p = JS_VALUE_GET_OBJ(func_obj); + p->u.cfunc.realm = JS_DupContext(ctx); + p->u.cfunc.c_function.generic = func; + p->u.cfunc.length = length; + p->u.cfunc.cproto = cproto; + p->u.cfunc.magic = magic; + p->is_constructor = (cproto == JS_CFUNC_constructor || + cproto == JS_CFUNC_constructor_magic || + cproto == JS_CFUNC_constructor_or_func || + cproto == JS_CFUNC_constructor_or_func_magic); + name_atom = JS_ATOM_empty_string; + if (name && *name) { + name_atom = JS_NewAtom(ctx, name); + if (name_atom == JS_ATOM_NULL) { + JS_FreeValue(ctx, func_obj); + return JS_EXCEPTION; + } + } + js_function_set_properties(ctx, func_obj, name_atom, length); + JS_FreeAtom(ctx, name_atom); + return func_obj; +} + +/* Note: at least 'length' arguments will be readable in 'argv' */ +JSValue JS_NewCFunction2(JSContext *ctx, JSCFunction *func, + const char *name, + int length, JSCFunctionEnum cproto, int magic) +{ + return JS_NewCFunction3(ctx, func, name, length, cproto, magic, + ctx->function_proto, 0); +} + +typedef struct JSCFunctionDataRecord { + JSCFunctionData *func; + uint8_t length; + uint8_t data_len; + uint16_t magic; + JSValue data[]; +} JSCFunctionDataRecord; + +static void js_c_function_data_finalizer(JSRuntime *rt, JSValueConst val) +{ + JSCFunctionDataRecord *s = JS_GetOpaque(val, JS_CLASS_C_FUNCTION_DATA); + int i; + + if (s) { + for(i = 0; i < s->data_len; i++) { + JS_FreeValueRT(rt, s->data[i]); + } + js_free_rt(rt, s); + } +} + +static void js_c_function_data_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func) +{ + JSCFunctionDataRecord *s = JS_GetOpaque(val, JS_CLASS_C_FUNCTION_DATA); + int i; + + if (s) { + for(i = 0; i < s->data_len; i++) { + JS_MarkValue(rt, s->data[i], mark_func); + } + } +} + +static JSValue js_call_c_function_data(JSContext *ctx, JSValueConst func_obj, + JSValueConst this_val, + int argc, JSValueConst *argv, int flags) +{ + JSRuntime *rt = ctx->rt; + JSStackFrame sf_s, *sf = &sf_s, *prev_sf; + JSCFunctionDataRecord *s; + JSValueConst *arg_buf; + JSValue ret; + size_t stack_size; + int arg_count; + int i; + + s = JS_GetOpaque(func_obj, JS_CLASS_C_FUNCTION_DATA); + if (!s) + return JS_EXCEPTION; // can't really happen + arg_buf = argv; + arg_count = s->length; + if (unlikely(argc < arg_count)) { + stack_size = arg_count * sizeof(arg_buf[0]); + if (js_check_stack_overflow(rt, stack_size)) + return JS_ThrowStackOverflow(ctx); + arg_buf = alloca(stack_size); + for(i = 0; i < argc; i++) + arg_buf[i] = argv[i]; + for(i = argc; i < arg_count; i++) + arg_buf[i] = JS_UNDEFINED; + } + prev_sf = rt->current_stack_frame; + sf->prev_frame = prev_sf; + rt->current_stack_frame = sf; + // TODO(bnoordhuis) switch realms like js_call_c_function does + sf->is_strict_mode = false; + sf->is_constructor = (flags & JS_CALL_FLAG_CONSTRUCTOR) != 0; + sf->cur_func = unsafe_unconst(func_obj); + sf->arg_count = argc; + ret = s->func(ctx, this_val, argc, arg_buf, s->magic, vc(s->data)); + rt->current_stack_frame = sf->prev_frame; + return ret; +} + +JSValue JS_NewCFunctionData2(JSContext *ctx, JSCFunctionData *func, + const char *name, + int length, int magic, int data_len, + JSValueConst *data) +{ + JSCFunctionDataRecord *s; + JSAtom name_atom; + JSValue func_obj; + int i; + + func_obj = JS_NewObjectProtoClass(ctx, ctx->function_proto, + JS_CLASS_C_FUNCTION_DATA); + if (JS_IsException(func_obj)) + return func_obj; + s = js_malloc(ctx, sizeof(*s) + data_len * sizeof(JSValue)); + if (!s) { + JS_FreeValue(ctx, func_obj); + return JS_EXCEPTION; + } + s->func = func; + s->length = length; + s->data_len = data_len; + s->magic = magic; + for(i = 0; i < data_len; i++) + s->data[i] = js_dup(data[i]); + JS_SetOpaqueInternal(func_obj, s); + name_atom = JS_ATOM_empty_string; + if (name && *name) { + name_atom = JS_NewAtom(ctx, name); + if (name_atom == JS_ATOM_NULL) { + JS_FreeValue(ctx, func_obj); + return JS_EXCEPTION; + } + } + js_function_set_properties(ctx, func_obj, name_atom, length); + JS_FreeAtom(ctx, name_atom); + return func_obj; +} + +JSValue JS_NewCFunctionData(JSContext *ctx, JSCFunctionData *func, + int length, int magic, int data_len, + JSValueConst *data) +{ + return JS_NewCFunctionData2(ctx, func, NULL, length, magic, data_len, data); +} + +static JSContext *js_autoinit_get_realm(JSProperty *pr) +{ + return (JSContext *)(pr->u.init.realm_and_id & ~3); +} + +static JSAutoInitIDEnum js_autoinit_get_id(JSProperty *pr) +{ + return pr->u.init.realm_and_id & 3; +} + +static void js_autoinit_free(JSRuntime *rt, JSProperty *pr) +{ + JS_FreeContext(js_autoinit_get_realm(pr)); +} + +static void js_autoinit_mark(JSRuntime *rt, JSProperty *pr, + JS_MarkFunc *mark_func) +{ + mark_func(rt, &js_autoinit_get_realm(pr)->header); +} + +typedef struct JSCClosureRecord { + JSCClosure *func; + uint16_t length; + uint16_t magic; + void *opaque; + void (*opaque_finalize)(void *opaque); +} JSCClosureRecord; + +static void js_c_closure_finalizer(JSRuntime *rt, JSValueConst val) +{ + JSCClosureRecord *s = JS_GetOpaque(val, JS_CLASS_C_CLOSURE); + + if (s) { + if (s->opaque_finalize) + s->opaque_finalize(s->opaque); + + js_free_rt(rt, s); + } +} + +static JSValue js_call_c_closure(JSContext *ctx, JSValueConst func_obj, + JSValueConst this_val, + int argc, JSValueConst *argv, int flags) +{ + JSRuntime *rt = ctx->rt; + JSStackFrame sf_s, *sf = &sf_s, *prev_sf; + JSCClosureRecord *s = JS_GetOpaque(func_obj, JS_CLASS_C_CLOSURE); + JSValueConst *arg_buf; + JSValue ret; + int arg_count; + int i; + size_t stack_size; + + arg_buf = argv; + arg_count = s->length; + if (unlikely(argc < arg_count)) { + stack_size = arg_count * sizeof(arg_buf[0]); + if (js_check_stack_overflow(rt, stack_size)) + return JS_ThrowStackOverflow(ctx); + arg_buf = alloca(stack_size); + for (i = 0; i < argc; i++) + arg_buf[i] = argv[i]; + for (i = argc; i < arg_count; i++) + arg_buf[i] = JS_UNDEFINED; + } + + prev_sf = rt->current_stack_frame; + sf->prev_frame = prev_sf; + rt->current_stack_frame = sf; + // TODO(bnoordhuis) switch realms like js_call_c_function does + sf->is_strict_mode = false; + sf->is_constructor = (flags & JS_CALL_FLAG_CONSTRUCTOR) != 0; + sf->cur_func = unsafe_unconst(func_obj); + sf->arg_count = argc; + ret = s->func(ctx, this_val, argc, arg_buf, s->magic, s->opaque); + rt->current_stack_frame = sf->prev_frame; + + return ret; +} + +JSValue JS_NewCClosure(JSContext *ctx, JSCClosure *func, const char *name, + JSCClosureFinalizerFunc *opaque_finalize, + int length, int magic, void *opaque) +{ + JSCClosureRecord *s; + JSAtom name_atom; + JSValue func_obj; + + func_obj = JS_NewObjectProtoClass(ctx, ctx->function_proto, + JS_CLASS_C_CLOSURE); + if (JS_IsException(func_obj)) + return func_obj; + s = js_malloc(ctx, sizeof(*s)); + if (!s) { + JS_FreeValue(ctx, func_obj); + return JS_EXCEPTION; + } + s->func = func; + s->length = length; + s->magic = magic; + s->opaque = opaque; + s->opaque_finalize = opaque_finalize; + JS_SetOpaqueInternal(func_obj, s); + name_atom = JS_ATOM_empty_string; + if (name && *name) { + name_atom = JS_NewAtom(ctx, name); + if (name_atom == JS_ATOM_NULL) { + JS_FreeValue(ctx, func_obj); + return JS_EXCEPTION; + } + } + js_function_set_properties(ctx, func_obj, name_atom, length); + JS_FreeAtom(ctx, name_atom); + return func_obj; +} + +static void free_property(JSRuntime *rt, JSProperty *pr, int prop_flags) +{ + if (unlikely(prop_flags & JS_PROP_TMASK)) { + if ((prop_flags & JS_PROP_TMASK) == JS_PROP_GETSET) { + if (pr->u.getset.getter) + JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter)); + if (pr->u.getset.setter) + JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.setter)); + } else if ((prop_flags & JS_PROP_TMASK) == JS_PROP_VARREF) { + free_var_ref(rt, pr->u.var_ref); + } else if ((prop_flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { + js_autoinit_free(rt, pr); + } + } else { + JS_FreeValueRT(rt, pr->u.value); + } +} + +static inline JSShapeProperty *find_own_property1(JSObject *p, JSAtom atom) +{ + JSShape *sh; + JSShapeProperty *pr, *prop; + intptr_t h; + sh = p->shape; + h = hash_atom(atom, sh->prop_hash_mask); + h = prop_hash_end(sh)[-h - 1]; + prop = get_shape_prop(sh); + while (h) { + pr = &prop[h - 1]; + if (likely(pr->atom == atom)) { + return pr; + } + h = pr->hash_next; + } + return NULL; +} + +static inline JSShapeProperty *find_own_property(JSProperty **ppr, + JSObject *p, + JSAtom atom) +{ + JSShape *sh; + JSShapeProperty *pr, *prop; + intptr_t h; + sh = p->shape; + h = hash_atom(atom, sh->prop_hash_mask); + h = prop_hash_end(sh)[-h - 1]; + prop = get_shape_prop(sh); + while (h) { + pr = &prop[h - 1]; + if (likely(pr->atom == atom)) { + *ppr = &p->prop[h - 1]; + /* the compiler should be able to assume that pr != NULL here */ + return pr; + } + h = pr->hash_next; + } + *ppr = NULL; + return NULL; +} + +/* Release a counted reference an open var_ref held on the coroutine + (async function / generator / async generator) owning the frame it + points into. */ +static void js_release_coro(JSRuntime *rt, JSGCObjectHeader *coro) +{ + switch (JS_GC_TYPE(coro)) { + case JS_GC_OBJ_TYPE_ASYNC_FUNCTION: + js_async_function_free(rt, (JSAsyncFunctionData *)coro); + break; + case JS_GC_OBJ_TYPE_JS_OBJECT: /* generator / async generator */ + JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, (JSObject *)coro)); + break; + default: + abort(); + } +} + +static void free_var_ref(JSRuntime *rt, JSVarRef *var_ref) +{ + if (var_ref) { + assert(JS_REF_COUNT(var_ref) > 0); + if (--JS_REF_COUNT(var_ref) == 0) { + if (var_ref->is_detached) { + JS_FreeValueRT(rt, var_ref->value); + remove_gc_object(&var_ref->header); + } else { + JSStackFrame *sf = var_ref->stack_frame; + assert(sf->var_refs[var_ref->var_ref_idx] == var_ref); + sf->var_refs[var_ref->var_ref_idx] = NULL; + /* an open coroutine var_ref is itself a GC object and holds + a counted ref to its coroutine (sf->cur_gc_obj) */ + if (var_ref->is_coro) { + js_release_coro(rt, sf->cur_gc_obj); + remove_gc_object(&var_ref->header); + } + } + js_free_rt(rt, var_ref); + } + } +} + +static void js_array_finalizer(JSRuntime *rt, JSValueConst val) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + uint32_t i; + + for(i = 0; i < p->u.array.count; i++) { + JS_FreeValueRT(rt, p->u.array.u.values[i]); + } + js_free_rt(rt, p->u.array.u.values); +} + +static void js_array_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + uint32_t i; + + for(i = 0; i < p->u.array.count; i++) { + JS_MarkValue(rt, p->u.array.u.values[i], mark_func); + } +} + +static void js_object_data_finalizer(JSRuntime *rt, JSValueConst val) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + JS_FreeValueRT(rt, p->u.object_data); + p->u.object_data = JS_UNDEFINED; +} + +static void js_object_data_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + JS_MarkValue(rt, p->u.object_data, mark_func); +} + +static void js_c_function_finalizer(JSRuntime *rt, JSValueConst val) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + + if (p->u.cfunc.realm) + JS_FreeContext(p->u.cfunc.realm); +} + +static void js_c_function_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + + if (p->u.cfunc.realm) + mark_func(rt, &p->u.cfunc.realm->header); +} + +static void js_bytecode_function_finalizer(JSRuntime *rt, JSValueConst val) +{ + JSObject *p1, *p = JS_VALUE_GET_OBJ(val); + JSFunctionBytecode *b; + JSVarRef **var_refs; + int i; + + p1 = p->u.func.home_object; + if (p1) { + JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, p1)); + } + b = p->u.func.function_bytecode; + if (b) { + var_refs = p->u.func.var_refs; + if (var_refs) { + for(i = 0; i < b->closure_var_count; i++) + free_var_ref(rt, var_refs[i]); + js_free_rt(rt, var_refs); + } + JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_FUNCTION_BYTECODE, b)); + } +} + +static void js_bytecode_function_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + JSVarRef **var_refs = p->u.func.var_refs; + JSFunctionBytecode *b = p->u.func.function_bytecode; + int i; + + if (p->u.func.home_object) { + JS_MarkValue(rt, JS_MKPTR(JS_TAG_OBJECT, p->u.func.home_object), + mark_func); + } + if (b) { + if (var_refs) { + for(i = 0; i < b->closure_var_count; i++) { + JSVarRef *var_ref = var_refs[i]; + /* Detached var_refs are GC objects; open var_refs are GC + objects only when they capture a coroutine local (see + get_var_ref). Only those may be marked. */ + if (var_ref && (var_ref->is_detached || var_ref->is_coro)) { + mark_func(rt, &var_ref->header); + } + } + } + /* must mark the function bytecode because template objects may be + part of a cycle */ + JS_MarkValue(rt, JS_MKPTR(JS_TAG_FUNCTION_BYTECODE, b), mark_func); + } +} + +static void js_bound_function_finalizer(JSRuntime *rt, JSValueConst val) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + JSBoundFunction *bf = p->u.bound_function; + int i; + + JS_FreeValueRT(rt, bf->func_obj); + JS_FreeValueRT(rt, bf->this_val); + for(i = 0; i < bf->argc; i++) { + JS_FreeValueRT(rt, bf->argv[i]); + } + js_free_rt(rt, bf); +} + +static void js_bound_function_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + JSBoundFunction *bf = p->u.bound_function; + int i; + + JS_MarkValue(rt, bf->func_obj, mark_func); + JS_MarkValue(rt, bf->this_val, mark_func); + for(i = 0; i < bf->argc; i++) + JS_MarkValue(rt, bf->argv[i], mark_func); +} + +static void js_for_in_iterator_finalizer(JSRuntime *rt, JSValueConst val) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + JSForInIterator *it = p->u.for_in_iterator; + JS_FreeValueRT(rt, it->obj); + js_free_rt(rt, it); +} + +static void js_for_in_iterator_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + JSForInIterator *it = p->u.for_in_iterator; + JS_MarkValue(rt, it->obj, mark_func); +} + +static void free_object(JSRuntime *rt, JSObject *p) +{ + int i; + JSClassFinalizer *finalizer; + JSShape *sh; + JSShapeProperty *pr; + + p->free_mark = 1; /* used to tell the object is invalid when + freeing cycles */ + /* free all the fields */ + sh = p->shape; + pr = get_shape_prop(sh); + for(i = 0; i < sh->prop_count; i++) { + free_property(rt, &p->prop[i], pr->flags); + pr++; + } + js_free_rt(rt, p->prop); + /* as an optimization we destroy the shape immediately without + putting it in gc_zero_ref_count_list */ + js_free_shape(rt, sh); + + /* fail safe */ + p->shape = NULL; + p->prop = NULL; + + if (unlikely(p->first_weak_ref)) { + reset_weak_ref(rt, &p->first_weak_ref); + } + + finalizer = rt->class_array[p->class_id].finalizer; + if (finalizer) + (*finalizer)(rt, JS_MKPTR(JS_TAG_OBJECT, p)); + + /* fail safe */ + p->class_id = 0; + p->u.opaque = NULL; + p->u.func.var_refs = NULL; + p->u.func.home_object = NULL; + + remove_gc_object(&p->header); + if (rt->gc_phase == JS_GC_PHASE_REMOVE_CYCLES && JS_REF_COUNT(p) != 0) { + list_add_tail(&p->header.link, &rt->gc_zero_ref_count_list); + } else { + js_free_rt(rt, p); + } +} + +static void free_gc_object(JSRuntime *rt, JSGCObjectHeader *gp) +{ + switch(JS_GC_TYPE(gp)) { + case JS_GC_OBJ_TYPE_JS_OBJECT: + free_object(rt, (JSObject *)gp); + break; + case JS_GC_OBJ_TYPE_FUNCTION_BYTECODE: + free_function_bytecode(rt, (JSFunctionBytecode *)gp); + break; + default: + abort(); + } +} + +static void free_zero_refcount(JSRuntime *rt) +{ + struct list_head *el; + JSGCObjectHeader *p; + + rt->gc_phase = JS_GC_PHASE_DECREF; + for(;;) { + el = rt->gc_zero_ref_count_list.next; + if (el == &rt->gc_zero_ref_count_list) + break; + p = list_entry(el, JSGCObjectHeader, link); + assert(JS_REF_COUNT(p) == 0); + free_gc_object(rt, p); + } + rt->gc_phase = JS_GC_PHASE_NONE; +} + +/* called with the ref_count of 'v' reaches zero. */ +static void js_free_value_rt(JSRuntime *rt, JSValue v) +{ + uint32_t tag = JS_VALUE_GET_TAG(v); + +#ifdef ENABLE_DUMPS // JS_DUMP_FREE + if (check_dump_flag(rt, JS_DUMP_FREE)) { + /* Prevent invalid object access during GC */ + if ((rt->gc_phase != JS_GC_PHASE_REMOVE_CYCLES) + || (tag != JS_TAG_OBJECT && tag != JS_TAG_FUNCTION_BYTECODE)) { + printf("Freeing "); + if (tag == JS_TAG_OBJECT) { + JS_DumpObject(rt, JS_VALUE_GET_OBJ(v)); + } else { + JS_DumpValue(rt, v); + printf("\n"); + } + } + } +#endif + + switch(tag) { + case JS_TAG_STRING: + js_free_string0(rt, JS_VALUE_GET_STRING(v)); + break; + case JS_TAG_STRING_ROPE: + { + JSStringRope *p = JS_VALUE_GET_STRING_ROPE(v); + JS_FreeValueRT(rt, p->left); + JS_FreeValueRT(rt, p->right); + js_free_rt(rt, p); + } + break; + case JS_TAG_OBJECT: + case JS_TAG_FUNCTION_BYTECODE: + { + JSGCObjectHeader *p = JS_VALUE_GET_PTR(v); + if (rt->gc_phase != JS_GC_PHASE_REMOVE_CYCLES) { + list_del(&p->link); + list_add(&p->link, &rt->gc_zero_ref_count_list); + if (rt->gc_phase == JS_GC_PHASE_NONE) { + free_zero_refcount(rt); + } + } + } + break; + case JS_TAG_MODULE: + abort(); /* never freed here */ + break; + case JS_TAG_BIG_INT: + { + JSBigInt *p = JS_VALUE_GET_PTR(v); + js_free_rt(rt, p); + } + break; + case JS_TAG_SYMBOL: + { + JSAtomStruct *p = JS_VALUE_GET_PTR(v); + JS_FreeAtomStruct(rt, p); + } + break; + default: + printf("js_free_value_rt: unknown tag=%d\n", tag); + abort(); + } +} + +void JS_FreeValueRT(JSRuntime *rt, JSValue v) +{ + if (JS_VALUE_HAS_REF_COUNT(v)) { + void *p = JS_VALUE_GET_PTR(v); + if (--JS_REF_COUNT(p) <= 0) { + js_free_value_rt(rt, v); + } + } +} + +void JS_FreeValue(JSContext *ctx, JSValue v) +{ + JS_FreeValueRT(ctx->rt, v); +} + +/* garbage collection */ + +static void add_gc_object(JSRuntime *rt, JSGCObjectHeader *h, + JSGCObjectTypeEnum type) +{ + JS_GC_MARK(h) = 0; + JS_GC_TYPE(h) = type; + list_add_tail(&h->link, &rt->gc_obj_list); +} + +static void remove_gc_object(JSGCObjectHeader *h) +{ + list_del(&h->link); +} + +void JS_MarkValue(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) +{ + if (JS_VALUE_HAS_REF_COUNT(val)) { + switch(JS_VALUE_GET_TAG(val)) { + case JS_TAG_OBJECT: + case JS_TAG_FUNCTION_BYTECODE: + mark_func(rt, JS_VALUE_GET_PTR(val)); + break; + default: + break; + } + } +} + +static void mark_weak_map_value(JSRuntime *rt, JSWeakRefRecord *first_weak_ref, JS_MarkFunc *mark_func) { + JSWeakRefRecord *wr; + JSMapRecord *mr; + JSMapState *s; + + for (wr = first_weak_ref; wr != NULL; wr = wr->next_weak_ref) { + if (wr->kind == JS_WEAK_REF_KIND_MAP) { + mr = wr->u.map_record; + s = mr->map; + assert(s->is_weak); + assert(!mr->empty); /* no iterator on WeakMap/WeakSet */ + JS_MarkValue(rt, mr->value, mark_func); + } + } +} + +static void mark_children(JSRuntime *rt, JSGCObjectHeader *gp, + JS_MarkFunc *mark_func) +{ + switch(JS_GC_TYPE(gp)) { + case JS_GC_OBJ_TYPE_JS_OBJECT: + { + JSObject *p = (JSObject *)gp; + JSShapeProperty *prs; + JSShape *sh; + int i; + sh = p->shape; + mark_func(rt, &sh->header); + /* mark all the fields */ + prs = get_shape_prop(sh); + for(i = 0; i < sh->prop_count; i++) { + JSProperty *pr = &p->prop[i]; + if (prs->atom != JS_ATOM_NULL) { + if (prs->flags & JS_PROP_TMASK) { + if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { + if (pr->u.getset.getter) + mark_func(rt, &pr->u.getset.getter->header); + if (pr->u.getset.setter) + mark_func(rt, &pr->u.getset.setter->header); + } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { + if (pr->u.var_ref->is_detached || + pr->u.var_ref->is_coro) { + /* Note: the tag does not matter + provided it is a GC object */ + mark_func(rt, &pr->u.var_ref->header); + } + } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { + js_autoinit_mark(rt, pr, mark_func); + } + } else { + JS_MarkValue(rt, pr->u.value, mark_func); + } + } + prs++; + } + + if (unlikely(p->first_weak_ref)) { + mark_weak_map_value(rt, p->first_weak_ref, mark_func); + } + + if (p->class_id != JS_CLASS_OBJECT) { + JSClassGCMark *gc_mark; + gc_mark = rt->class_array[p->class_id].gc_mark; + if (gc_mark) + gc_mark(rt, JS_MKPTR(JS_TAG_OBJECT, p), mark_func); + } + } + break; + case JS_GC_OBJ_TYPE_FUNCTION_BYTECODE: + /* the template objects can be part of a cycle */ + { + JSFunctionBytecode *b = (JSFunctionBytecode *)gp; + int i; + for(i = 0; i < b->cpool_count; i++) { + JS_MarkValue(rt, b->cpool[i], mark_func); + } + if (b->realm) + mark_func(rt, &b->realm->header); + } + break; + case JS_GC_OBJ_TYPE_VAR_REF: + { + JSVarRef *var_ref = (JSVarRef *)gp; + if (var_ref->is_detached) { + /* the var_ref owns its value */ + JS_MarkValue(rt, *var_ref->pvalue, mark_func); + } else { + /* open var_ref: the value lives in the coroutine's frame + and is marked by the coroutine itself; only keep that + coroutine reachable. (Open var_refs are GC objects only + when they capture a coroutine local.) */ + assert(var_ref->is_coro); + mark_func(rt, var_ref->stack_frame->cur_gc_obj); + } + } + break; + case JS_GC_OBJ_TYPE_ASYNC_FUNCTION: + { + JSAsyncFunctionData *s = (JSAsyncFunctionData *)gp; + if (s->is_active) + async_func_mark(rt, &s->func_state, mark_func); + JS_MarkValue(rt, s->resolving_funcs[0], mark_func); + JS_MarkValue(rt, s->resolving_funcs[1], mark_func); + } + break; + case JS_GC_OBJ_TYPE_SHAPE: + { + JSShape *sh = (JSShape *)gp; + if (sh->proto != NULL) { + mark_func(rt, &sh->proto->header); + } + } + break; + case JS_GC_OBJ_TYPE_JS_CONTEXT: + { + JSContext *ctx = (JSContext *)gp; + JS_MarkContext(rt, ctx, mark_func); + } + break; + default: + abort(); + } +} + +static void gc_decref_child(JSRuntime *rt, JSGCObjectHeader *p) +{ + assert(JS_REF_COUNT(p) > 0); + JS_REF_COUNT(p)--; + if (JS_REF_COUNT(p) == 0 && JS_GC_MARK(p) == 1) { + list_del(&p->link); + list_add_tail(&p->link, &rt->tmp_obj_list); + } +} + +static void gc_decref(JSRuntime *rt) +{ + struct list_head *el, *el1; + JSGCObjectHeader *p; + + init_list_head(&rt->tmp_obj_list); + + /* decrement the refcount of all the children of all the GC + objects and move the GC objects with zero refcount to + tmp_obj_list */ + list_for_each_safe(el, el1, &rt->gc_obj_list) { + p = list_entry(el, JSGCObjectHeader, link); + assert(JS_GC_MARK(p) == 0); + mark_children(rt, p, gc_decref_child); + JS_GC_MARK(p) = 1; + if (JS_REF_COUNT(p) == 0) { + list_del(&p->link); + list_add_tail(&p->link, &rt->tmp_obj_list); + } + } +} + +static void gc_scan_incref_child(JSRuntime *rt, JSGCObjectHeader *p) +{ + JS_REF_COUNT(p)++; + if (JS_REF_COUNT(p) == 1) { + /* ref_count was 0: remove from tmp_obj_list and add at the + end of gc_obj_list */ + list_del(&p->link); + list_add_tail(&p->link, &rt->gc_obj_list); + JS_GC_MARK(p) = 0; /* reset the mark for the next GC call */ + } +} + +static void gc_scan_incref_child2(JSRuntime *rt, JSGCObjectHeader *p) +{ + JS_REF_COUNT(p)++; +} + +static void gc_scan(JSRuntime *rt) +{ + struct list_head *el; + JSGCObjectHeader *p; + + /* keep the objects with a refcount > 0 and their children. */ + list_for_each(el, &rt->gc_obj_list) { + p = list_entry(el, JSGCObjectHeader, link); + assert(JS_REF_COUNT(p) > 0); + JS_GC_MARK(p) = 0; /* reset the mark for the next GC call */ + mark_children(rt, p, gc_scan_incref_child); + } + + /* restore the refcount of the objects to be deleted. */ + list_for_each(el, &rt->tmp_obj_list) { + p = list_entry(el, JSGCObjectHeader, link); + mark_children(rt, p, gc_scan_incref_child2); + } +} + +static void gc_free_cycles(JSRuntime *rt) +{ + struct list_head *el, *el1; + JSGCObjectHeader *p; +#ifdef ENABLE_DUMPS // JS_DUMP_GC_FREE + bool header_done = false; +#endif + + rt->gc_phase = JS_GC_PHASE_REMOVE_CYCLES; + + for(;;) { + el = rt->tmp_obj_list.next; + if (el == &rt->tmp_obj_list) + break; + p = list_entry(el, JSGCObjectHeader, link); + /* Only need to free the GC object associated with JS + values. The rest will be automatically removed because they + must be referenced by them. */ + switch(JS_GC_TYPE(p)) { + case JS_GC_OBJ_TYPE_JS_OBJECT: + case JS_GC_OBJ_TYPE_FUNCTION_BYTECODE: +#ifdef ENABLE_DUMPS // JS_DUMP_GC_FREE + if (check_dump_flag(rt, JS_DUMP_GC_FREE)) { + if (!header_done) { + printf("Freeing cycles:\n"); + JS_DumpObjectHeader(rt); + header_done = true; + } + JS_DumpGCObject(rt, p); + } +#endif + free_gc_object(rt, p); + break; + default: + list_del(&p->link); + list_add_tail(&p->link, &rt->gc_zero_ref_count_list); + break; + } + } + rt->gc_phase = JS_GC_PHASE_NONE; + + list_for_each_safe(el, el1, &rt->gc_zero_ref_count_list) { + p = list_entry(el, JSGCObjectHeader, link); + assert(JS_GC_TYPE(p) == JS_GC_OBJ_TYPE_JS_OBJECT || + JS_GC_TYPE(p) == JS_GC_OBJ_TYPE_FUNCTION_BYTECODE); + js_free_rt(rt, p); + } + + init_list_head(&rt->gc_zero_ref_count_list); +} + +void JS_RunGC(JSRuntime *rt) +{ + /* decrement the reference of the children of each object. mark = + 1 after this pass. */ + gc_decref(rt); + + /* keep the GC objects with a non zero refcount and their childs */ + gc_scan(rt); + + /* free the GC objects in a cycle */ + gc_free_cycles(rt); +} + +/* Return false if not an object or if the object has already been + freed (zombie objects are visible in finalizers when freeing + cycles). */ +bool JS_IsLiveObject(JSRuntime *rt, JSValueConst obj) +{ + JSObject *p; + if (!JS_IsObject(obj)) + return false; + p = JS_VALUE_GET_OBJ(obj); + return !p->free_mark; +} + +/* Compute memory used by various object types */ +/* XXX: poor man's approach to handling multiply referenced objects */ +typedef struct JSMemoryUsage_helper { + double memory_used_count; + double str_count; + double str_size; + int64_t js_func_count; + double js_func_size; + int64_t js_func_code_size; + int64_t js_func_pc2line_count; + int64_t js_func_pc2line_size; +} JSMemoryUsage_helper; + +static void compute_value_size(JSValue val, JSMemoryUsage_helper *hp); + +static void compute_jsstring_size(JSString *str, JSMemoryUsage_helper *hp) +{ + if (!str->atom_type) { /* atoms are handled separately */ + double s_ref_count = JS_REF_COUNT(str); + hp->str_count += 1 / s_ref_count; + hp->str_size += ((sizeof(*str) + (str->len << str->is_wide_char) + + 1 - str->is_wide_char) / s_ref_count); + } +} + +static void compute_bytecode_size(JSFunctionBytecode *b, JSMemoryUsage_helper *hp) +{ + int memory_used_count, js_func_size, i; + + memory_used_count = 0; + js_func_size = sizeof(*b); + if (b->vardefs) { + js_func_size += (b->arg_count + b->var_count) * sizeof(*b->vardefs); + } + if (b->cpool) { + js_func_size += b->cpool_count * sizeof(*b->cpool); + for (i = 0; i < b->cpool_count; i++) { + JSValue val = b->cpool[i]; + compute_value_size(val, hp); + } + } + if (b->closure_var) { + js_func_size += b->closure_var_count * sizeof(*b->closure_var); + } + if (b->byte_code_buf) { + hp->js_func_code_size += b->byte_code_len; + } + memory_used_count++; + js_func_size += b->source_len + 1; + if (b->pc2line_len) { + memory_used_count++; + hp->js_func_pc2line_count += 1; + hp->js_func_pc2line_size += b->pc2line_len; + } + hp->js_func_size += js_func_size; + hp->js_func_count += 1; + hp->memory_used_count += memory_used_count; +} + +static void compute_value_size(JSValue val, JSMemoryUsage_helper *hp) +{ + switch(JS_VALUE_GET_TAG(val)) { + case JS_TAG_STRING: + compute_jsstring_size(JS_VALUE_GET_STRING(val), hp); + break; + case JS_TAG_BIG_INT: + /* should track JSBigInt usage */ + break; + } +} + +void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s) +{ + struct list_head *el, *el1; + int i; + JSMemoryUsage_helper mem = { 0 }, *hp = &mem; + + memset(s, 0, sizeof(*s)); + s->malloc_count = rt->malloc_state.malloc_count; + s->malloc_size = rt->malloc_state.malloc_size; + s->malloc_limit = rt->malloc_state.malloc_limit; + + s->memory_used_count = 2; /* rt + rt->class_array */ + s->memory_used_size = sizeof(JSRuntime) + sizeof(JSClass) * rt->class_count; + + list_for_each(el, &rt->context_list) { + JSContext *ctx = list_entry(el, JSContext, link); + JSShape *sh = ctx->array_shape; + s->memory_used_count += 2; /* ctx + ctx->class_proto */ + s->memory_used_size += sizeof(JSContext) + + sizeof(JSValue) * rt->class_count; + s->binary_object_count += ctx->binary_object_count; + s->binary_object_size += ctx->binary_object_size; + + /* the hashed shapes are counted separately */ + if (sh && !sh->is_hashed) { + int hash_size = sh->prop_hash_mask + 1; + s->shape_count++; + s->shape_size += get_shape_size(hash_size, sh->prop_size); + } + list_for_each(el1, &ctx->loaded_modules) { + JSModuleDef *m = list_entry(el1, JSModuleDef, link); + s->memory_used_count += 1; + s->memory_used_size += sizeof(*m); + if (m->req_module_entries) { + s->memory_used_count += 1; + s->memory_used_size += m->req_module_entries_count * sizeof(*m->req_module_entries); + } + if (m->export_entries) { + s->memory_used_count += 1; + s->memory_used_size += m->export_entries_count * sizeof(*m->export_entries); + for (i = 0; i < m->export_entries_count; i++) { + JSExportEntry *me = &m->export_entries[i]; + if (me->export_type == JS_EXPORT_TYPE_LOCAL && me->u.local.var_ref) { + /* potential multiple count */ + s->memory_used_count += 1; + compute_value_size(me->u.local.var_ref->value, hp); + } + } + } + if (m->star_export_entries) { + s->memory_used_count += 1; + s->memory_used_size += m->star_export_entries_count * sizeof(*m->star_export_entries); + } + if (m->import_entries) { + s->memory_used_count += 1; + s->memory_used_size += m->import_entries_count * sizeof(*m->import_entries); + } + compute_value_size(m->module_ns, hp); + compute_value_size(m->func_obj, hp); + } + } + + list_for_each(el, &rt->gc_obj_list) { + JSGCObjectHeader *gp = list_entry(el, JSGCObjectHeader, link); + JSObject *p; + JSShape *sh; + JSShapeProperty *prs; + + /* XXX: could count the other GC object types too */ + if (JS_GC_TYPE(gp) == JS_GC_OBJ_TYPE_FUNCTION_BYTECODE) { + compute_bytecode_size((JSFunctionBytecode *)gp, hp); + continue; + } else if (JS_GC_TYPE(gp) != JS_GC_OBJ_TYPE_JS_OBJECT) { + continue; + } + p = (JSObject *)gp; + sh = p->shape; + s->obj_count++; + if (p->prop) { + s->memory_used_count++; + s->prop_size += sh->prop_size * sizeof(*p->prop); + s->prop_count += sh->prop_count; + prs = get_shape_prop(sh); + for(i = 0; i < sh->prop_count; i++) { + JSProperty *pr = &p->prop[i]; + if (prs->atom != JS_ATOM_NULL && !(prs->flags & JS_PROP_TMASK)) { + compute_value_size(pr->u.value, hp); + } + prs++; + } + } + /* the hashed shapes are counted separately */ + if (!sh->is_hashed) { + int hash_size = sh->prop_hash_mask + 1; + s->shape_count++; + s->shape_size += get_shape_size(hash_size, sh->prop_size); + } + + switch(p->class_id) { + case JS_CLASS_ARRAY: /* u.array | length */ + case JS_CLASS_ARGUMENTS: /* u.array | length */ + s->array_count++; + if (p->fast_array) { + s->fast_array_count++; + if (p->u.array.u.values) { + s->memory_used_count++; + s->memory_used_size += p->u.array.count * + sizeof(*p->u.array.u.values); + s->fast_array_elements += p->u.array.count; + for (i = 0; i < p->u.array.count; i++) { + compute_value_size(p->u.array.u.values[i], hp); + } + } + } + break; + case JS_CLASS_ERROR: /* u.object_data */ + case JS_CLASS_NUMBER: /* u.object_data */ + case JS_CLASS_STRING: /* u.object_data */ + case JS_CLASS_BOOLEAN: /* u.object_data */ + case JS_CLASS_SYMBOL: /* u.object_data */ + case JS_CLASS_DATE: /* u.object_data */ + case JS_CLASS_BIG_INT: /* u.object_data */ + compute_value_size(p->u.object_data, hp); + break; + case JS_CLASS_C_FUNCTION: /* u.cfunc */ + s->c_func_count++; + break; + case JS_CLASS_BYTECODE_FUNCTION: /* u.func */ + { + JSFunctionBytecode *b = p->u.func.function_bytecode; + JSVarRef **var_refs = p->u.func.var_refs; + /* home_object: object will be accounted for in list scan */ + if (var_refs) { + s->memory_used_count++; + s->js_func_size += b->closure_var_count * sizeof(*var_refs); + for (i = 0; i < b->closure_var_count; i++) { + if (var_refs[i]) { + double ref_count = JS_REF_COUNT(var_refs[i]); + s->memory_used_count += 1 / ref_count; + s->js_func_size += sizeof(*var_refs[i]) / ref_count; + /* handle non object closed values */ + if (var_refs[i]->pvalue == &var_refs[i]->value) { + /* potential multiple count */ + compute_value_size(var_refs[i]->value, hp); + } + } + } + } + } + break; + case JS_CLASS_BOUND_FUNCTION: /* u.bound_function */ + { + JSBoundFunction *bf = p->u.bound_function; + /* func_obj and this_val are objects */ + for (i = 0; i < bf->argc; i++) { + compute_value_size(bf->argv[i], hp); + } + s->memory_used_count += 1; + s->memory_used_size += sizeof(*bf) + bf->argc * sizeof(*bf->argv); + } + break; + case JS_CLASS_C_FUNCTION_DATA: /* u.c_function_data_record */ + { + JSCFunctionDataRecord *fd = p->u.c_function_data_record; + if (fd) { + for (i = 0; i < fd->data_len; i++) { + compute_value_size(fd->data[i], hp); + } + s->memory_used_count += 1; + s->memory_used_size += sizeof(*fd) + fd->data_len * sizeof(*fd->data); + } + } + break; + case JS_CLASS_C_CLOSURE: /* u.c_closure_record */ + { + JSCClosureRecord *c = p->u.c_closure_record; + if (c) { + s->memory_used_count += 1; + s->memory_used_size += sizeof(*c); + } + } + break; + case JS_CLASS_REGEXP: /* u.regexp */ + compute_jsstring_size(p->u.regexp.pattern, hp); + compute_jsstring_size(p->u.regexp.bytecode, hp); + break; + + case JS_CLASS_FOR_IN_ITERATOR: /* u.for_in_iterator */ + { + JSForInIterator *it = p->u.for_in_iterator; + if (it) { + compute_value_size(it->obj, hp); + s->memory_used_count += 1; + s->memory_used_size += sizeof(*it); + } + } + break; + case JS_CLASS_ARRAY_BUFFER: /* u.array_buffer */ + case JS_CLASS_SHARED_ARRAY_BUFFER: /* u.array_buffer */ + { + JSArrayBuffer *abuf = p->u.array_buffer; + if (abuf) { + s->memory_used_count += 1; + s->memory_used_size += sizeof(*abuf); + if (abuf->data) { + s->memory_used_count += 1; + s->memory_used_size += abuf->byte_length; + } + } + } + break; + case JS_CLASS_GENERATOR: /* u.generator_data */ + case JS_CLASS_UINT8C_ARRAY: /* u.typed_array / u.array */ + case JS_CLASS_INT8_ARRAY: /* u.typed_array / u.array */ + case JS_CLASS_UINT8_ARRAY: /* u.typed_array / u.array */ + case JS_CLASS_INT16_ARRAY: /* u.typed_array / u.array */ + case JS_CLASS_UINT16_ARRAY: /* u.typed_array / u.array */ + case JS_CLASS_INT32_ARRAY: /* u.typed_array / u.array */ + case JS_CLASS_UINT32_ARRAY: /* u.typed_array / u.array */ + case JS_CLASS_BIG_INT64_ARRAY: /* u.typed_array / u.array */ + case JS_CLASS_BIG_UINT64_ARRAY: /* u.typed_array / u.array */ + case JS_CLASS_FLOAT16_ARRAY: /* u.typed_array / u.array */ + case JS_CLASS_FLOAT32_ARRAY: /* u.typed_array / u.array */ + case JS_CLASS_FLOAT64_ARRAY: /* u.typed_array / u.array */ + case JS_CLASS_DATAVIEW: /* u.typed_array */ + case JS_CLASS_MAP: /* u.map_state */ + case JS_CLASS_SET: /* u.map_state */ + case JS_CLASS_WEAKMAP: /* u.map_state */ + case JS_CLASS_WEAKSET: /* u.map_state */ + case JS_CLASS_MAP_ITERATOR: /* u.map_iterator_data */ + case JS_CLASS_SET_ITERATOR: /* u.map_iterator_data */ + case JS_CLASS_ARRAY_ITERATOR: /* u.array_iterator_data */ + case JS_CLASS_STRING_ITERATOR: /* u.array_iterator_data */ + case JS_CLASS_PROXY: /* u.proxy_data */ + case JS_CLASS_PROMISE: /* u.promise_data */ + case JS_CLASS_PROMISE_RESOLVE_FUNCTION: /* u.promise_function_data */ + case JS_CLASS_PROMISE_REJECT_FUNCTION: /* u.promise_function_data */ + case JS_CLASS_ASYNC_FUNCTION_RESOLVE: /* u.async_function_data */ + case JS_CLASS_ASYNC_FUNCTION_REJECT: /* u.async_function_data */ + case JS_CLASS_ASYNC_FROM_SYNC_ITERATOR: /* u.async_from_sync_iterator_data */ + case JS_CLASS_ASYNC_GENERATOR: /* u.async_generator_data */ + /* TODO */ + default: + /* XXX: class definition should have an opaque block size */ + if (p->u.opaque) { + s->memory_used_count += 1; + } + break; + } + } + s->obj_size += s->obj_count * sizeof(JSObject); + + /* hashed shapes */ + s->memory_used_count++; /* rt->shape_hash */ + s->memory_used_size += sizeof(rt->shape_hash[0]) * rt->shape_hash_size; + for(i = 0; i < rt->shape_hash_size; i++) { + JSShape *sh; + for(sh = rt->shape_hash[i]; sh != NULL; sh = sh->shape_hash_next) { + int hash_size = sh->prop_hash_mask + 1; + s->shape_count++; + s->shape_size += get_shape_size(hash_size, sh->prop_size); + } + } + + /* atoms */ + s->memory_used_count += 2; /* rt->atom_array, rt->atom_hash */ + s->atom_count = rt->atom_count; + s->atom_size = sizeof(rt->atom_array[0]) * rt->atom_size + + sizeof(rt->atom_hash[0]) * rt->atom_hash_size; + for(i = 0; i < rt->atom_size; i++) { + JSAtomStruct *p = rt->atom_array[i]; + if (!atom_is_free(p)) { + s->atom_size += (sizeof(*p) + (p->len << p->is_wide_char) + + 1 - p->is_wide_char); + } + } + s->str_count = round(mem.str_count); + s->str_size = round(mem.str_size); + s->js_func_count = mem.js_func_count; + s->js_func_size = round(mem.js_func_size); + s->js_func_code_size = mem.js_func_code_size; + s->js_func_pc2line_count = mem.js_func_pc2line_count; + s->js_func_pc2line_size = mem.js_func_pc2line_size; + s->memory_used_count += round(mem.memory_used_count) + + s->atom_count + s->str_count + + s->obj_count + s->shape_count + + s->js_func_count + s->js_func_pc2line_count; + s->memory_used_size += s->atom_size + s->str_size + + s->obj_size + s->prop_size + s->shape_size + + s->js_func_size + s->js_func_code_size + s->js_func_pc2line_size; +} + +void JS_DumpMemoryUsage(FILE *fp, const JSMemoryUsage *s, JSRuntime *rt) +{ + fprintf(fp, "QuickJS-ng memory usage -- %s version, %d-bit, malloc limit: %"PRId64"\n\n", + JS_GetVersion(), (int)sizeof(void *) * 8, s->malloc_limit); + if (rt) { + static const struct { + const char *name; + size_t size; + } object_types[] = { + { "JSRuntime", sizeof(JSRuntime) }, + { "JSContext", sizeof(JSContext) }, + { "JSObject", sizeof(JSObject) }, + { "JSString", sizeof(JSString) }, + { "JSFunctionBytecode", sizeof(JSFunctionBytecode) }, + }; + int i, usage_size_ok = 0; + for(i = 0; i < countof(object_types); i++) { + unsigned int size = object_types[i].size; + void *p = js_malloc_rt(rt, size); + if (p) { + unsigned int size1 = js_malloc_usable_size_rt(rt, p); + if (size1 >= size) { + usage_size_ok = 1; + fprintf(fp, " %3u + %-2u %s\n", + size, size1 - size, object_types[i].name); + } + js_free_rt(rt, p); + } + } + if (!usage_size_ok) { + fprintf(fp, " malloc_usable_size unavailable\n"); + } + { + int obj_classes[JS_CLASS_INIT_COUNT + 1] = { 0 }; + int class_id; + struct list_head *el; + list_for_each(el, &rt->gc_obj_list) { + JSGCObjectHeader *gp = list_entry(el, JSGCObjectHeader, link); + JSObject *p; + if (JS_GC_TYPE(gp) == JS_GC_OBJ_TYPE_JS_OBJECT) { + p = (JSObject *)gp; + obj_classes[min_uint32(p->class_id, JS_CLASS_INIT_COUNT)]++; + } + } + fprintf(fp, "\n" "JSObject classes\n"); + if (obj_classes[0]) + fprintf(fp, " %5d %2.0d %s\n", obj_classes[0], 0, "none"); + for (class_id = 1; class_id < JS_CLASS_INIT_COUNT; class_id++) { + if (obj_classes[class_id] && class_id < rt->class_count) { + char buf[ATOM_GET_STR_BUF_SIZE]; + fprintf(fp, " %5d %2.0d %s\n", obj_classes[class_id], class_id, + JS_AtomGetStrRT(rt, buf, sizeof(buf), rt->class_array[class_id].class_name)); + } + } + if (obj_classes[JS_CLASS_INIT_COUNT]) + fprintf(fp, " %5d %2.0d %s\n", obj_classes[JS_CLASS_INIT_COUNT], 0, "other"); + } + fprintf(fp, "\n"); + } + fprintf(fp, "%-20s %8s %8s\n", "NAME", "COUNT", "SIZE"); + + if (s->malloc_count) { + fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per block)\n", + "memory allocated", s->malloc_count, s->malloc_size, + (double)s->malloc_size / s->malloc_count); + fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%d overhead, %0.1f average slack)\n", + "memory used", s->memory_used_count, s->memory_used_size, + MALLOC_OVERHEAD, ((double)(s->malloc_size - s->memory_used_size) / + s->memory_used_count)); + } + if (s->atom_count) { + fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per atom)\n", + "atoms", s->atom_count, s->atom_size, + (double)s->atom_size / s->atom_count); + } + if (s->str_count) { + fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per string)\n", + "strings", s->str_count, s->str_size, + (double)s->str_size / s->str_count); + } + if (s->obj_count) { + fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per object)\n", + "objects", s->obj_count, s->obj_size, + (double)s->obj_size / s->obj_count); + fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per object)\n", + " properties", s->prop_count, s->prop_size, + (double)s->prop_count / s->obj_count); + fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per shape)\n", + " shapes", s->shape_count, s->shape_size, + (double)s->shape_size / s->shape_count); + } + if (s->js_func_count) { + fprintf(fp, "%-20s %8"PRId64" %8"PRId64"\n", + "bytecode functions", s->js_func_count, s->js_func_size); + fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per function)\n", + " bytecode", s->js_func_count, s->js_func_code_size, + (double)s->js_func_code_size / s->js_func_count); + if (s->js_func_pc2line_count) { + fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per function)\n", + " pc2line", s->js_func_pc2line_count, + s->js_func_pc2line_size, + (double)s->js_func_pc2line_size / s->js_func_pc2line_count); + } + } + if (s->c_func_count) { + fprintf(fp, "%-20s %8"PRId64"\n", "C functions", s->c_func_count); + } + if (s->array_count) { + fprintf(fp, "%-20s %8"PRId64"\n", "arrays", s->array_count); + if (s->fast_array_count) { + fprintf(fp, "%-20s %8"PRId64"\n", " fast arrays", s->fast_array_count); + fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per fast array)\n", + " elements", s->fast_array_elements, + s->fast_array_elements * (int)sizeof(JSValue), + (double)s->fast_array_elements / s->fast_array_count); + } + } + if (s->binary_object_count) { + fprintf(fp, "%-20s %8"PRId64" %8"PRId64"\n", + "binary objects", s->binary_object_count, s->binary_object_size); + } +} + +JSValue JS_GetGlobalObject(JSContext *ctx) +{ + return js_dup(ctx->global_obj); +} + +/* WARNING: obj is freed */ +JSValue JS_Throw(JSContext *ctx, JSValue obj) +{ + JSRuntime *rt = ctx->rt; + JS_FreeValue(ctx, rt->current_exception); + rt->current_exception = obj; + return JS_EXCEPTION; +} + +/* return the pending exception (cannot be called twice). */ +JSValue JS_GetException(JSContext *ctx) +{ + JSValue val; + JSRuntime *rt = ctx->rt; + val = rt->current_exception; + rt->current_exception = JS_UNINITIALIZED; + return val; +} + +bool JS_HasException(JSContext *ctx) +{ + return !JS_IsUninitialized(ctx->rt->current_exception); +} + +static void dbuf_put_leb128(DynBuf *s, uint32_t v) +{ + uint32_t a; + for(;;) { + a = v & 0x7f; + v >>= 7; + if (v != 0) { + dbuf_putc(s, a | 0x80); + } else { + dbuf_putc(s, a); + break; + } + } +} + +static void dbuf_put_sleb128(DynBuf *s, int32_t v1) +{ + uint32_t v = v1; + dbuf_put_leb128(s, (2 * v) ^ -(v >> 31)); +} + +static int get_leb128(uint32_t *pval, const uint8_t *buf, + const uint8_t *buf_end) +{ + const uint8_t *ptr = buf; + uint32_t v, a, i; + v = 0; + for(i = 0; i < 5; i++) { + if (unlikely(ptr >= buf_end)) + break; + a = *ptr++; + v |= (a & 0x7f) << (i * 7); + if (!(a & 0x80)) { + *pval = v; + return ptr - buf; + } + } + *pval = 0; + return -1; +} + +static int get_sleb128(int32_t *pval, const uint8_t *buf, + const uint8_t *buf_end) +{ + int ret; + uint32_t val; + ret = get_leb128(&val, buf, buf_end); + if (ret < 0) { + *pval = 0; + return -1; + } + *pval = (val >> 1) ^ -(val & 1); + return ret; +} + +static int find_line_num(JSContext *ctx, JSFunctionBytecode *b, + uint32_t pc_value, int *col) +{ + const uint8_t *p_end, *p; + int new_line_num, new_col_num, line_num, col_num, pc, ret; + int32_t v; + unsigned int op; + + *col = 1; + p = b->pc2line_buf; + if (!p) + goto fail; + p_end = p + b->pc2line_len; + pc = 0; + line_num = b->line_num; + col_num = b->col_num; + while (p < p_end) { + op = *p++; + if (op == 0) { + uint32_t val; + ret = get_leb128(&val, p, p_end); + if (ret < 0) + goto fail; + pc += val; + p += ret; + ret = get_sleb128(&v, p, p_end); + if (ret < 0) + goto fail; + p += ret; + new_line_num = line_num + v; + } else { + op -= PC2LINE_OP_FIRST; + pc += (op / PC2LINE_RANGE); + new_line_num = line_num + (op % PC2LINE_RANGE) + PC2LINE_BASE; + } + ret = get_sleb128(&v, p, p_end); + if (ret < 0) + goto fail; + p += ret; + new_col_num = col_num + v; + if (pc_value < pc) + break; + line_num = new_line_num; + col_num = new_col_num; + } + *col = col_num; + return line_num; +fail: + /* should never happen */ + return b->line_num; +} + +/* in order to avoid executing arbitrary code during the stack trace + generation, we only look at simple 'name' properties containing a + string. */ +static const char *get_func_name(JSContext *ctx, JSValueConst func) +{ + JSProperty *pr; + JSShapeProperty *prs; + JSValue val; + + if (JS_VALUE_GET_TAG(func) != JS_TAG_OBJECT) + return NULL; + prs = find_own_property(&pr, JS_VALUE_GET_OBJ(func), JS_ATOM_name); + if (!prs) + return NULL; + if ((prs->flags & JS_PROP_TMASK) != JS_PROP_NORMAL) + return NULL; + val = pr->u.value; + if (JS_VALUE_GET_TAG(val) != JS_TAG_STRING) + return NULL; + return JS_ToCString(ctx, val); +} + +/* Note: it is important that no exception is returned by this function */ +static bool can_add_backtrace(JSValueConst obj) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) + return false; + p = JS_VALUE_GET_OBJ(obj); + if (p->class_id != JS_CLASS_DOM_EXCEPTION) + return false; + if (find_own_property1(p, JS_ATOM_stack)) + return false; + return true; +} + +/* Note: it is important that no exception is returned by this function */ +static bool can_store_error_stack(JSValueConst obj) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) + return false; + p = JS_VALUE_GET_OBJ(obj); + if (p->class_id != JS_CLASS_ERROR) + return false; + if (!JS_IsUndefined(p->u.object_data)) + return false; + if (find_own_property1(p, JS_ATOM_stack)) + return false; + return true; +} + +#define JS_BACKTRACE_FLAG_SKIP_FIRST_LEVEL (1 << 0) +/* only taken into account if filename is provided */ +#define JS_BACKTRACE_FLAG_SINGLE_LEVEL (1 << 1) +#define JS_BACKTRACE_FLAG_FILTER_FUNC (1 << 2) + +/* if filename != NULL, an additional level is added with the filename + and line number information (used for parse error). */ +static void build_backtrace(JSContext *ctx, JSValueConst error_val, + JSValueConst filter_func, const char *filename, + int line_num, int col_num, int backtrace_flags) +{ + JSStackFrame *sf, *sf_start; + JSValue stack, prepare, saved_exception, error_obj; + DynBuf dbuf; + const char *func_name_str; + const char *str1; + JSObject *p; + JSFunctionBytecode *b; + bool backtrace_barrier, has_prepare, has_filter_func; + JSRuntime *rt; + JSCallSiteData csd[64]; + uint32_t i; + double d; + int stack_trace_limit; + + rt = ctx->rt; + if (rt->in_build_stack_trace) + return; + rt->in_build_stack_trace = true; + error_obj = js_dup(error_val); + + // Save exception because conversion to double may fail. + saved_exception = JS_GetException(ctx); + + // Extract stack trace limit. + // Ignore error since it sets d to NAN anyway. + // coverity[check_return] + JS_ToFloat64(ctx, &d, ctx->error_stack_trace_limit); + if (isnan(d) || d < 0.0) + stack_trace_limit = 0; + else if (d > INT32_MAX) + stack_trace_limit = INT32_MAX; + else + stack_trace_limit = fabs(d); + + // Restore current exception. + JS_Throw(ctx, saved_exception); + saved_exception = JS_UNINITIALIZED; + + stack_trace_limit = min_int(stack_trace_limit, countof(csd)); + stack_trace_limit = max_int(stack_trace_limit, 0); + has_prepare = false; + has_filter_func = backtrace_flags & JS_BACKTRACE_FLAG_FILTER_FUNC; + i = 0; + + if (!JS_IsNull(ctx->error_ctor)) { + prepare = js_dup(ctx->error_prepare_stack); + has_prepare = JS_IsFunction(ctx, prepare); + } + + if (has_prepare) { + saved_exception = JS_GetException(ctx); + if (stack_trace_limit == 0) + goto done; + if (filename) + js_new_callsite_data2(ctx, &csd[i++], filename, line_num, col_num); + } else { + js_dbuf_init(ctx, &dbuf); + if (stack_trace_limit == 0) + goto done; + if (filename) { + i++; + dbuf_printf(&dbuf, " at %s", filename); + if (line_num != -1) + dbuf_printf(&dbuf, ":%d:%d", line_num, col_num); + dbuf_putc(&dbuf, '\n'); + } + } + + if (filename && (backtrace_flags & JS_BACKTRACE_FLAG_SINGLE_LEVEL)) + goto done; + + sf_start = rt->current_stack_frame; + + /* Find the frame we want to start from. Note that when a filter is used the filter + function will be the first, but we also specify we want to skip the first one. */ + if (has_filter_func) { + for (sf = sf_start; sf != NULL && i < stack_trace_limit; sf = sf->prev_frame) { + if (js_same_value(ctx, sf->cur_func, filter_func)) { + sf_start = sf; + break; + } + } + } + + for (sf = sf_start; sf != NULL && i < stack_trace_limit; sf = sf->prev_frame) { + if (backtrace_flags & JS_BACKTRACE_FLAG_SKIP_FIRST_LEVEL) { + backtrace_flags &= ~JS_BACKTRACE_FLAG_SKIP_FIRST_LEVEL; + continue; + } + + p = JS_VALUE_GET_OBJ(sf->cur_func); + b = NULL; + backtrace_barrier = false; + + if (js_class_has_bytecode(p->class_id)) { + b = p->u.func.function_bytecode; + backtrace_barrier = b->backtrace_barrier; + } + + if (has_prepare) { + js_new_callsite_data(ctx, &csd[i], sf); + } else { + /* func_name_str is UTF-8 encoded if needed */ + func_name_str = get_func_name(ctx, sf->cur_func); + if (!func_name_str || func_name_str[0] == '\0') + str1 = ""; + else + str1 = func_name_str; + dbuf_printf(&dbuf, " at %s", str1); + JS_FreeCString(ctx, func_name_str); + + if (b && sf->cur_pc) { + const char *atom_str; + int line_num1, col_num1; + uint32_t pc; + + pc = sf->cur_pc - b->byte_code_buf - 1; + line_num1 = find_line_num(ctx, b, pc, &col_num1); + atom_str = b->filename ? JS_AtomToCString(ctx, b->filename) : NULL; + dbuf_printf(&dbuf, " (%s", atom_str ? atom_str : ""); + JS_FreeCString(ctx, atom_str); + if (line_num1 != -1) + dbuf_printf(&dbuf, ":%d:%d", line_num1, col_num1); + dbuf_putc(&dbuf, ')'); + } else if (b) { + // FIXME(bnoordhuis) Missing `sf->cur_pc = pc` in bytecode + // handler in JS_CallInternal. Almost never user observable + // except with intercepting JS proxies that throw exceptions. + dbuf_printf(&dbuf, " (missing)"); + } else { + dbuf_printf(&dbuf, " (native)"); + } + dbuf_putc(&dbuf, '\n'); + } + i++; + + /* stop backtrace if JS_EVAL_FLAG_BACKTRACE_BARRIER was used */ + if (backtrace_barrier) + break; + } + done: + if (has_prepare) { + int j = 0, k; + stack = JS_NewArray(ctx); + if (JS_IsException(stack)) { + stack = JS_NULL; + } else { + for (; j < i; j++) { + JSValue v = js_new_callsite(ctx, &csd[j]); + if (JS_IsException(v)) + break; + if (JS_DefinePropertyValueUint32(ctx, stack, j, v, JS_PROP_C_W_E) < 0) + break; + } + } + // Clear the csd's we didn't use in case of error. + for (k = j; k < i; k++) { + JS_FreeValue(ctx, csd[k].filename); + JS_FreeValue(ctx, csd[k].func); + JS_FreeValue(ctx, csd[k].func_name); + } + JSValueConst args[] = { + error_obj, + stack, + }; + JSValue stack2 = JS_Call(ctx, prepare, ctx->error_ctor, countof(args), args); + JS_FreeValue(ctx, stack); + if (JS_IsException(stack2)) + stack = JS_NULL; + else + stack = stack2; + JS_FreeValue(ctx, prepare); + JS_Throw(ctx, saved_exception); + } else { + if (dbuf_error(&dbuf)) + stack = JS_NULL; + else + stack = JS_NewStringLen(ctx, (char *)dbuf.buf, dbuf.size); + dbuf_free(&dbuf); + } + + if (JS_IsUndefined(ctx->error_back_trace)) + ctx->error_back_trace = js_dup(stack); + if (has_filter_func) { + /* Error.captureStackTrace(target, ...): install an own data property + on the (possibly non-Error) target, shadowing the accessor */ + JS_DefinePropertyValue(ctx, error_obj, JS_ATOM_stack, stack, + JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); + } else if (can_store_error_stack(error_obj)) { + /* genuine Error instance: store as the [[ErrorData]] stack value */ + p = JS_VALUE_GET_OBJ(error_obj); + JS_FreeValue(ctx, p->u.object_data); + p->u.object_data = stack; + } else if (can_add_backtrace(error_obj)) { + /* DOMException and the like keep an own "stack" data property */ + JS_DefinePropertyValue(ctx, error_obj, JS_ATOM_stack, stack, + JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); + } else { + JS_FreeValue(ctx, stack); + } + + JS_FreeValue(ctx, error_obj); + rt->in_build_stack_trace = false; +} + +JSValue JS_NewError(JSContext *ctx) +{ + JSValue obj = JS_NewObjectClass(ctx, JS_CLASS_ERROR); + if (JS_IsException(obj)) + return JS_EXCEPTION; + build_backtrace(ctx, obj, JS_UNDEFINED, NULL, 0, 0, 0); + return obj; +} + +static JSValue JS_MakeError2(JSContext *ctx, JSErrorEnum error_num, + bool add_backtrace, const char *message) +{ + JSValue obj, msg; + + if (error_num == JS_PLAIN_ERROR) { + obj = JS_NewObjectClass(ctx, JS_CLASS_ERROR); + } else { + obj = JS_NewObjectProtoClass(ctx, ctx->native_error_proto[error_num], + JS_CLASS_ERROR); + } + if (JS_IsException(obj)) + return JS_EXCEPTION; + msg = JS_NewString(ctx, message); + if (JS_IsException(msg)) + msg = JS_NewString(ctx, "Invalid error message"); + if (!JS_IsException(msg)) { + JS_DefinePropertyValue(ctx, obj, JS_ATOM_message, msg, + JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); + } + if (add_backtrace) + build_backtrace(ctx, obj, JS_UNDEFINED, NULL, 0, 0, 0); + return obj; +} + +static JSValue JS_PRINTF_FORMAT_ATTR(4, 0) +JS_MakeError(JSContext *ctx, JSErrorEnum error_num, bool add_backtrace, + JS_PRINTF_FORMAT const char *fmt, va_list ap) +{ + char buf[256]; + + vsnprintf(buf, sizeof(buf), fmt, ap); + return JS_MakeError2(ctx, error_num, add_backtrace, buf); +} + +/* fmt and arguments may be pure ASCII or UTF-8 encoded contents */ +static JSValue JS_PRINTF_FORMAT_ATTR(4, 0) +JS_ThrowError2(JSContext *ctx, JSErrorEnum error_num, bool add_backtrace, + JS_PRINTF_FORMAT const char *fmt, va_list ap) +{ + JSValue obj; + + obj = JS_MakeError(ctx, error_num, add_backtrace, fmt, ap); + if (unlikely(JS_IsException(obj))) { + /* out of memory: throw JS_NULL to avoid recursing */ + obj = JS_NULL; + } + return JS_Throw(ctx, obj); +} + +static JSValue JS_PRINTF_FORMAT_ATTR(3, 0) +JS_ThrowError(JSContext *ctx, JSErrorEnum error_num, + JS_PRINTF_FORMAT const char *fmt, va_list ap) +{ + JSRuntime *rt = ctx->rt; + JSStackFrame *sf; + bool add_backtrace; + + /* the backtrace is added later if called from a bytecode function */ + sf = rt->current_stack_frame; + add_backtrace = !rt->in_out_of_memory && + (!sf || (JS_GetFunctionBytecode(sf->cur_func) == NULL)); + return JS_ThrowError2(ctx, error_num, add_backtrace, fmt, ap); +} + +#define JS_ERROR_MAP(X) \ + X(Internal, INTERNAL) \ + X(Plain, PLAIN) \ + X(Range, RANGE) \ + X(Reference, REFERENCE) \ + X(Syntax, SYNTAX) \ + X(Type, TYPE) \ + +#define X(lc, uc) \ + JSValue JS_PRINTF_FORMAT_ATTR(2, 3) \ + JS_New##lc##Error(JSContext *ctx, \ + JS_PRINTF_FORMAT const char *fmt, ...) \ + { \ + JSValue val; \ + va_list ap; \ + \ + va_start(ap, fmt); \ + val = JS_MakeError(ctx, JS_##uc##_ERROR, \ + /*add_backtrace*/true, fmt, ap); \ + va_end(ap); \ + if (JS_##uc##_ERROR == JS_INTERNAL_ERROR) \ + js_set_uncatchable_error(val, true); \ + return val; \ + } \ + JSValue JS_PRINTF_FORMAT_ATTR(2, 3) \ + JS_Throw##lc##Error(JSContext *ctx, \ + JS_PRINTF_FORMAT const char *fmt, ...) \ + { \ + JSValue val; \ + va_list ap; \ + \ + va_start(ap, fmt); \ + val = JS_ThrowError(ctx, JS_##uc##_ERROR, fmt, ap); \ + va_end(ap); \ + if (JS_##uc##_ERROR == JS_INTERNAL_ERROR) \ + js_set_uncatchable_error(ctx->rt->current_exception, true); \ + return val; \ + } \ + +JS_ERROR_MAP(X) + +#undef X +#undef JS_ERROR_MAP + +static int JS_PRINTF_FORMAT_ATTR(3, 4) JS_ThrowTypeErrorOrFalse(JSContext *ctx, int flags, JS_PRINTF_FORMAT const char *fmt, ...) +{ + va_list ap; + + if ((flags & JS_PROP_THROW) || + ((flags & JS_PROP_THROW_STRICT) && is_strict_mode(ctx))) { + va_start(ap, fmt); + JS_ThrowError(ctx, JS_TYPE_ERROR, fmt, ap); + va_end(ap); + return -1; + } else { + return false; + } +} + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +#endif // __GNUC__ +static JSValue JS_ThrowTypeErrorAtom(JSContext *ctx, const char *fmt, JSAtom atom) +{ + char buf[ATOM_GET_STR_BUF_SIZE]; + JS_AtomGetStr(ctx, buf, sizeof(buf), atom); + return JS_ThrowTypeError(ctx, fmt, buf); +} + +static JSValue JS_ThrowSyntaxErrorAtom(JSContext *ctx, const char *fmt, JSAtom atom) +{ + char buf[ATOM_GET_STR_BUF_SIZE]; + JS_AtomGetStr(ctx, buf, sizeof(buf), atom); + return JS_ThrowSyntaxError(ctx, fmt, buf); +} +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop // ignored "-Wformat-nonliteral" +#endif // __GNUC__ + +static int JS_ThrowTypeErrorReadOnly(JSContext *ctx, int flags, JSAtom atom) +{ + if ((flags & JS_PROP_THROW) || + ((flags & JS_PROP_THROW_STRICT) && is_strict_mode(ctx))) { + JS_ThrowTypeErrorAtom(ctx, "'%s' is read-only", atom); + return -1; + } else { + return false; + } +} + +JSValue JS_ThrowOutOfMemory(JSContext *ctx) +{ + JSRuntime *rt = ctx->rt; + if (!rt->in_out_of_memory) { + rt->in_out_of_memory = true; + JS_ThrowInternalError(ctx, "out of memory"); + rt->in_out_of_memory = false; + } + return JS_EXCEPTION; +} + +static JSValue JS_ThrowStackOverflow(JSContext *ctx) +{ + return JS_ThrowRangeError(ctx, "Maximum call stack size exceeded"); +} + +static JSValue JS_ThrowTypeErrorNotAConstructor(JSContext *ctx, + JSValueConst func_obj) +{ + JSObject *p; + JSAtom name; + + if (JS_TAG_OBJECT != JS_VALUE_GET_TAG(func_obj)) + goto fini; + p = JS_VALUE_GET_OBJ(func_obj); + if (!js_class_has_bytecode(p->class_id)) + goto fini; + name = p->u.func.function_bytecode->func_name; + if (name == JS_ATOM_NULL) + goto fini; + return JS_ThrowTypeErrorAtom(ctx, "%s is not a constructor", name); +fini: + return JS_ThrowTypeError(ctx, "not a constructor"); +} + +static JSValue JS_ThrowTypeErrorNotAFunction(JSContext *ctx) +{ + return JS_ThrowTypeError(ctx, "not a function"); +} + +static JSValue JS_ThrowTypeErrorNotAnObject(JSContext *ctx) +{ + return JS_ThrowTypeError(ctx, "not an object"); +} + +static JSValue JS_ThrowTypeErrorNotASymbol(JSContext *ctx) +{ + return JS_ThrowTypeError(ctx, "not a symbol"); +} + +static JSValue JS_ThrowReferenceErrorNotDefined(JSContext *ctx, JSAtom name) +{ + char buf[ATOM_GET_STR_BUF_SIZE]; + return JS_ThrowReferenceError(ctx, "%s is not defined", + JS_AtomGetStr(ctx, buf, sizeof(buf), name)); +} + +static JSValue JS_ThrowReferenceErrorUninitialized(JSContext *ctx, JSAtom name) +{ + char buf[ATOM_GET_STR_BUF_SIZE]; + return JS_ThrowReferenceError(ctx, "%s is not initialized", + name == JS_ATOM_NULL ? "lexical variable" : + JS_AtomGetStr(ctx, buf, sizeof(buf), name)); +} + +static JSValue JS_ThrowReferenceErrorUninitialized2(JSContext *ctx, + JSFunctionBytecode *b, + int idx, bool is_ref) +{ + JSAtom atom = JS_ATOM_NULL; + if (is_ref) { + atom = b->closure_var[idx].var_name; + } else { + /* not present if the function is stripped and contains no eval() */ + if (b->vardefs) + atom = b->vardefs[b->arg_count + idx].var_name; + } + return JS_ThrowReferenceErrorUninitialized(ctx, atom); +} + +static JSValue JS_ThrowTypeErrorInvalidClass(JSContext *ctx, int class_id) +{ + JSRuntime *rt = ctx->rt; + JSAtom name; + name = rt->class_array[class_id].class_name; + return JS_ThrowTypeErrorAtom(ctx, "%s object expected", name); +} + +static void JS_ThrowInterrupted(JSContext *ctx) +{ + JS_ThrowInternalError(ctx, "interrupted"); + JS_SetUncatchableError(ctx, ctx->rt->current_exception); +} + +static no_inline __exception int __js_poll_interrupts(JSContext *ctx) +{ + JSRuntime *rt = ctx->rt; + ctx->interrupt_counter = JS_INTERRUPT_COUNTER_INIT; + if (rt->interrupt_handler) { + if (rt->interrupt_handler(ctx, rt->interrupt_opaque)) { + JS_ThrowInterrupted(ctx); + return -1; + } + } + return 0; +} + +static inline __exception int js_poll_interrupts(JSContext *ctx) +{ + if (unlikely(--ctx->interrupt_counter <= 0)) { + return __js_poll_interrupts(ctx); + } else { + return 0; + } +} + +/* return -1 (exception) or true/false */ +static int JS_SetPrototypeInternal(JSContext *ctx, JSValueConst obj, + JSValueConst proto_val, bool throw_flag) +{ + JSObject *proto, *p, *p1; + JSShape *sh; + + if (throw_flag) { + if (JS_VALUE_GET_TAG(obj) == JS_TAG_NULL || + JS_VALUE_GET_TAG(obj) == JS_TAG_UNDEFINED) + goto not_obj; + } else { + if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) + goto not_obj; + } + p = JS_VALUE_GET_OBJ(obj); + if (JS_VALUE_GET_TAG(proto_val) != JS_TAG_OBJECT) { + if (JS_VALUE_GET_TAG(proto_val) != JS_TAG_NULL) { + not_obj: + JS_ThrowTypeErrorNotAnObject(ctx); + return -1; + } + proto = NULL; + } else { + proto = JS_VALUE_GET_OBJ(proto_val); + } + + if (throw_flag && JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) + return true; + + if (unlikely(p->class_id == JS_CLASS_PROXY)) + return js_proxy_setPrototypeOf(ctx, obj, proto_val, throw_flag); + sh = p->shape; + if (sh->proto == proto) + return true; + if (p == JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_OBJECT])) { + if (throw_flag) { + JS_ThrowTypeError(ctx, "'Immutable prototype object \'Object.prototype\' cannot have their prototype set'"); + return -1; + } + return false; + } + if (!p->extensible) { + if (throw_flag) { + JS_ThrowTypeError(ctx, "object is not extensible"); + return -1; + } else { + return false; + } + } + if (proto) { + /* check if there is a cycle */ + p1 = proto; + do { + if (p1 == p) { + if (throw_flag) { + JS_ThrowTypeError(ctx, "circular prototype chain"); + return -1; + } else { + return false; + } + } + /* Note: for Proxy objects, proto is NULL */ + p1 = p1->shape->proto; + } while (p1 != NULL); + js_dup(proto_val); + } + + if (js_shape_prepare_update(ctx, p, NULL)) + return -1; + sh = p->shape; + if (sh->proto) + JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, sh->proto)); + sh->proto = proto; + if (proto) + proto->is_prototype = true; + if (p->is_prototype) { + /* track modification of Array.prototype */ + if (unlikely(p == JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_ARRAY]))) { + ctx->std_array_prototype = false; + } + } + return true; +} + +/* return -1 (exception) or true/false */ +int JS_SetPrototype(JSContext *ctx, JSValueConst obj, JSValueConst proto_val) +{ + return JS_SetPrototypeInternal(ctx, obj, proto_val, true); +} + +/* Only works for primitive types, otherwise return JS_NULL. */ +static JSValueConst JS_GetPrototypePrimitive(JSContext *ctx, JSValueConst val) +{ + JSValue ret; + switch(JS_VALUE_GET_NORM_TAG(val)) { + case JS_TAG_SHORT_BIG_INT: + case JS_TAG_BIG_INT: + ret = ctx->class_proto[JS_CLASS_BIG_INT]; + break; + case JS_TAG_INT: + case JS_TAG_FLOAT64: + ret = ctx->class_proto[JS_CLASS_NUMBER]; + break; + case JS_TAG_BOOL: + ret = ctx->class_proto[JS_CLASS_BOOLEAN]; + break; + case JS_TAG_STRING: + case JS_TAG_STRING_ROPE: + ret = ctx->class_proto[JS_CLASS_STRING]; + break; + case JS_TAG_SYMBOL: + ret = ctx->class_proto[JS_CLASS_SYMBOL]; + break; + case JS_TAG_OBJECT: + case JS_TAG_NULL: + case JS_TAG_UNDEFINED: + default: + ret = JS_NULL; + break; + } + return ret; +} + +/* Return an Object, JS_NULL or JS_EXCEPTION in case of Proxy object. */ +JSValue JS_GetPrototype(JSContext *ctx, JSValueConst obj) +{ + JSValue val; + if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { + JSObject *p; + p = JS_VALUE_GET_OBJ(obj); + if (unlikely(p->class_id == JS_CLASS_PROXY)) { + val = js_proxy_getPrototypeOf(ctx, obj); + } else { + p = p->shape->proto; + if (!p) + val = JS_NULL; + else + val = js_dup(JS_MKPTR(JS_TAG_OBJECT, p)); + } + } else { + val = js_dup(JS_GetPrototypePrimitive(ctx, obj)); + } + return val; +} + +static JSValue JS_GetPrototypeFree(JSContext *ctx, JSValue obj) +{ + JSValue obj1; + obj1 = JS_GetPrototype(ctx, obj); + JS_FreeValue(ctx, obj); + return obj1; +} + +int JS_GetLength(JSContext *ctx, JSValueConst obj, int64_t *pres) { + return js_get_length64(ctx, pres, obj); +} + +int JS_SetLength(JSContext *ctx, JSValueConst obj, int64_t len) { + return js_set_length64(ctx, obj, len); +} + +/* return true, false or (-1) in case of exception */ +static int JS_OrdinaryIsInstanceOf(JSContext *ctx, JSValueConst val, + JSValueConst obj) +{ + JSValue obj_proto; + JSObject *proto; + const JSObject *p, *proto1; + int ret; + + if (!JS_IsFunction(ctx, obj)) + return false; + p = JS_VALUE_GET_OBJ(obj); + if (p->class_id == JS_CLASS_BOUND_FUNCTION) { + JSBoundFunction *s = p->u.bound_function; + return JS_IsInstanceOf(ctx, val, s->func_obj); + } + + /* Only explicitly boxed values are instances of constructors */ + if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) + return false; + obj_proto = JS_GetProperty(ctx, obj, JS_ATOM_prototype); + if (JS_VALUE_GET_TAG(obj_proto) != JS_TAG_OBJECT) { + if (!JS_IsException(obj_proto)) + JS_ThrowTypeError(ctx, "operand 'prototype' property is not an object"); + ret = -1; + goto done; + } + proto = JS_VALUE_GET_OBJ(obj_proto); + p = JS_VALUE_GET_OBJ(val); + for(;;) { + proto1 = p->shape->proto; + if (!proto1) { + /* slow case if proxy in the prototype chain */ + if (unlikely(p->class_id == JS_CLASS_PROXY)) { + JSValue obj1; + obj1 = js_dup(JS_MKPTR(JS_TAG_OBJECT, (JSObject *)p)); + for(;;) { + obj1 = JS_GetPrototypeFree(ctx, obj1); + if (JS_IsException(obj1)) { + ret = -1; + break; + } + if (JS_IsNull(obj1)) { + ret = false; + break; + } + if (proto == JS_VALUE_GET_OBJ(obj1)) { + JS_FreeValue(ctx, obj1); + ret = true; + break; + } + /* must check for timeout to avoid infinite loop */ + if (js_poll_interrupts(ctx)) { + JS_FreeValue(ctx, obj1); + ret = -1; + break; + } + } + } else { + ret = false; + } + break; + } + p = proto1; + if (proto == p) { + ret = true; + break; + } + } +done: + JS_FreeValue(ctx, obj_proto); + return ret; +} + +/* return true, false or (-1) in case of exception */ +int JS_IsInstanceOf(JSContext *ctx, JSValueConst val, JSValueConst obj) +{ + JSValue method; + + if (!JS_IsObject(obj)) + goto fail; + method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_hasInstance); + if (JS_IsException(method)) + return -1; + if (!JS_IsNull(method) && !JS_IsUndefined(method)) { + JSValue ret; + ret = JS_CallFree(ctx, method, obj, 1, &val); + return JS_ToBoolFree(ctx, ret); + } + + /* legacy case */ + if (!JS_IsFunction(ctx, obj)) { + fail: + JS_ThrowTypeError(ctx, "invalid 'instanceof' right operand"); + return -1; + } + return JS_OrdinaryIsInstanceOf(ctx, val, obj); +} + +#include "builtin-array-fromasync.h" +#include "builtin-iterator-zip-keyed.h" +#include "builtin-iterator-zip.h" + +// like Function.prototype.call but monkey patch-proof +static JSValue js_call_function(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + return JS_Call(ctx, argv[1], argv[0], argc-2, argv+2); +} + +// returns enumerable and non-enumerable strings *and* symbols +static JSValue js_getOwnPropertyKeys(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + int flags = JS_GPN_STRING_MASK|JS_GPN_SYMBOL_MASK; + return JS_GetOwnPropertyNames2(ctx, argv[0], flags, JS_ITERATOR_KIND_KEY); +} + +static JSValue js_hasOwnEnumProperty(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSObject *p; + JSAtom key; + int flags, res; + + if (JS_TAG_OBJECT != JS_VALUE_GET_TAG(argv[0])) + return JS_ThrowTypeErrorNotAnObject(ctx); + p = JS_VALUE_GET_OBJ(argv[0]); + key = JS_ValueToAtomInternal(ctx, argv[1], JS_TO_STRING_NO_SIDE_EFFECTS); + if (key == JS_ATOM_NULL) + return JS_EXCEPTION; + res = JS_GetOwnPropertyFlagsInternal(ctx, &flags, p, key); + JS_FreeAtom(ctx, key); + if (res < 0) + return JS_EXCEPTION; + if (res > 0 && (flags & JS_PROP_ENUMERABLE)) + return JS_TRUE; + return JS_FALSE; +} + +// note: takes ownership of |argv| +static JSValue js_bytecode_eval(JSContext *ctx, const uint8_t *bytecode, + size_t len, int argc, JSValue *argv) +{ + JSValue obj, fun, result; + int i; + + obj = JS_ReadObject(ctx, bytecode, len, JS_READ_OBJ_BYTECODE); + if (JS_IsException(obj)) + return JS_EXCEPTION; + fun = JS_EvalFunction(ctx, obj); + if (JS_IsException(fun)) + return JS_EXCEPTION; + assert(JS_IsFunction(ctx, fun)); + result = JS_Call(ctx, fun, JS_UNDEFINED, argc, vc(argv)); + for (i = 0; i < argc; i++) + JS_FreeValue(ctx, argv[i]); + JS_FreeValue(ctx, fun); + if (JS_SetPrototypeInternal(ctx, result, ctx->function_proto, + /*throw_flag*/true) < 0) { + JS_FreeValue(ctx, result); + return JS_EXCEPTION; + } + return result; +} + +static JSValue js_bytecode_autoinit(JSContext *ctx, JSObject *p, JSAtom atom, + void *opaque) +{ + switch ((uintptr_t)opaque) { + default: + abort(); + case JS_BUILTIN_ARRAY_FROMASYNC: + { + JSValue argv[] = { + JS_NewCFunction(ctx, js_array_constructor, "Array", 0), + JS_NewCFunctionMagic(ctx, js_error_constructor, "TypeError", + 1, JS_CFUNC_constructor_or_func_magic, + JS_TYPE_ERROR), + JS_AtomToValue(ctx, JS_ATOM_Symbol_asyncIterator), + JS_NewCFunctionMagic(ctx, js_object_defineProperty, + "Object.defineProperty", 3, + JS_CFUNC_generic_magic, 0), + JS_AtomToValue(ctx, JS_ATOM_Symbol_iterator), + JS_NewCFunction(ctx, js_call_function, "call", 2), + }; + return js_bytecode_eval(ctx, qjsc_builtin_array_fromasync, + sizeof(qjsc_builtin_array_fromasync), + countof(argv), argv); + } + case JS_BUILTIN_ITERATOR_ZIP: + { + JSValue argv[] = { + js_dup(ctx->class_proto[JS_CLASS_ITERATOR_HELPER]), + JS_NewCFunctionMagic(ctx, js_error_constructor, "InternalError", + 1, JS_CFUNC_constructor_or_func_magic, + JS_INTERNAL_ERROR), + JS_NewCFunctionMagic(ctx, js_error_constructor, "TypeError", + 1, JS_CFUNC_constructor_or_func_magic, + JS_TYPE_ERROR), + JS_NewCFunction(ctx, js_call_function, "call", 2), + JS_AtomToValue(ctx, JS_ATOM_Symbol_iterator), + }; + JSValue result = js_bytecode_eval(ctx, qjsc_builtin_iterator_zip, + sizeof(qjsc_builtin_iterator_zip), + countof(argv), argv); + JS_SetConstructorBit(ctx, result, false); + return result; + } + case JS_BUILTIN_ITERATOR_ZIP_KEYED: + { + JSValue argv[] = { + js_dup(ctx->class_proto[JS_CLASS_ITERATOR_HELPER]), + JS_NewCFunctionMagic(ctx, js_error_constructor, "InternalError", + 1, JS_CFUNC_constructor_or_func_magic, + JS_INTERNAL_ERROR), + JS_NewCFunctionMagic(ctx, js_error_constructor, "TypeError", + 1, JS_CFUNC_constructor_or_func_magic, + JS_TYPE_ERROR), + JS_NewCFunction(ctx, js_call_function, "call", 2), + JS_NewCFunction(ctx, js_hasOwnEnumProperty, + "hasOwnEnumProperty", 2), + JS_NewCFunction(ctx, js_getOwnPropertyKeys, + "getOwnPropertyKeys", 1), + JS_AtomToValue(ctx, JS_ATOM_Symbol_iterator), + }; + JSValue result = js_bytecode_eval(ctx, qjsc_builtin_iterator_zip_keyed, + sizeof(qjsc_builtin_iterator_zip_keyed), + countof(argv), argv); + JS_SetConstructorBit(ctx, result, false); + return result; + } + } + return JS_UNDEFINED; +} + +/* return the value associated to the autoinit property or an exception */ +typedef JSValue JSAutoInitFunc(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque); + +static JSAutoInitFunc *const js_autoinit_func_table[] = { + js_instantiate_prototype, /* JS_AUTOINIT_ID_PROTOTYPE */ + js_module_ns_autoinit, /* JS_AUTOINIT_ID_MODULE_NS */ + JS_InstantiateFunctionListItem2, /* JS_AUTOINIT_ID_PROP */ + js_bytecode_autoinit, /* JS_AUTOINIT_ID_BYTECODE */ +}; + +/* warning: 'prs' is reallocated after it */ +static int JS_AutoInitProperty(JSContext *ctx, JSObject *p, JSAtom prop, + JSProperty *pr, JSShapeProperty *prs) +{ + JSValue val; + JSContext *realm; + JSAutoInitFunc *func; + + if (js_shape_prepare_update(ctx, p, &prs)) + return -1; + + realm = js_autoinit_get_realm(pr); + func = js_autoinit_func_table[js_autoinit_get_id(pr)]; + /* 'func' shall not modify the object properties 'pr' */ + val = func(realm, p, prop, pr->u.init.opaque); + js_autoinit_free(ctx->rt, pr); + prs->flags &= ~JS_PROP_TMASK; + pr->u.value = JS_UNDEFINED; + if (JS_IsException(val)) + return -1; + pr->u.value = val; + return 0; +} + +static JSValue JS_GetPropertyInternal(JSContext *ctx, JSValueConst obj, + JSAtom prop, JSValueConst this_obj, + bool throw_ref_error) +{ + JSObject *p; + JSProperty *pr; + JSShapeProperty *prs; + uint32_t tag; + + tag = JS_VALUE_GET_TAG(obj); + if (unlikely(tag != JS_TAG_OBJECT)) { + switch(tag) { + case JS_TAG_NULL: + return JS_ThrowTypeErrorAtom(ctx, "cannot read property '%s' of null", prop); + case JS_TAG_UNDEFINED: + return JS_ThrowTypeErrorAtom(ctx, "cannot read property '%s' of undefined", prop); + case JS_TAG_EXCEPTION: + return JS_EXCEPTION; + case JS_TAG_STRING: + { + JSString *p1 = JS_VALUE_GET_STRING(obj); + if (__JS_AtomIsTaggedInt(prop)) { + uint32_t idx, ch; + idx = __JS_AtomToUInt32(prop); + if (idx < p1->len) { + ch = string_get(p1, idx); + return js_new_string_char(ctx, ch); + } + } else if (prop == JS_ATOM_length) { + return js_int32(p1->len); + } + } + break; + case JS_TAG_STRING_ROPE: + { + JSStringRope *r = JS_VALUE_GET_STRING_ROPE(obj); + if (__JS_AtomIsTaggedInt(prop)) { + uint32_t idx, ch; + idx = __JS_AtomToUInt32(prop); + if (idx < r->len) { + ch = string_rope_get(obj, idx); + return js_new_string_char(ctx, ch); + } + } else if (prop == JS_ATOM_length) { + return js_int32(r->len); + } + } + break; + default: + break; + } + /* cannot raise an exception */ + p = JS_VALUE_GET_OBJ(JS_GetPrototypePrimitive(ctx, obj)); + if (!p) + return JS_UNDEFINED; + } else { + p = JS_VALUE_GET_OBJ(obj); + } + + for(;;) { + prs = find_own_property(&pr, p, prop); + if (prs) { + /* found */ + if (unlikely(prs->flags & JS_PROP_TMASK)) { + if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { + if (unlikely(!pr->u.getset.getter)) { + return JS_UNDEFINED; + } else { + JSValue func = JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter); + /* Note: the field could be removed in the getter */ + func = js_dup(func); + return JS_CallFree(ctx, func, this_obj, 0, NULL); + } + } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { + JSValue val = *pr->u.var_ref->pvalue; + if (unlikely(JS_IsUninitialized(val))) + return JS_ThrowReferenceErrorUninitialized(ctx, prs->atom); + return js_dup(val); + } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { + /* Instantiate property and retry */ + if (JS_AutoInitProperty(ctx, p, prop, pr, prs)) + return JS_EXCEPTION; + continue; + } + } else { + return js_dup(pr->u.value); + } + } + if (unlikely(p->is_exotic)) { + /* exotic behaviors */ + if (p->fast_array) { + if (__JS_AtomIsTaggedInt(prop)) { + uint32_t idx = __JS_AtomToUInt32(prop); + if (idx < p->u.array.count) { + /* we avoid duplicating the code */ + return JS_GetPropertyUint32(ctx, JS_MKPTR(JS_TAG_OBJECT, p), idx); + } else if (is_typed_array(p->class_id)) { + return JS_UNDEFINED; + } + } else if (is_typed_array(p->class_id)) { + int ret; + ret = JS_AtomIsNumericIndex(ctx, prop); + if (ret != 0) { + if (ret < 0) + return JS_EXCEPTION; + return JS_UNDEFINED; + } + } + } else { + const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; + if (em) { + if (em->get_property) { + JSValue obj1, retval; + /* XXX: should pass throw_ref_error */ + /* Note: if 'p' is a prototype, it can be + freed in the called function */ + obj1 = js_dup(JS_MKPTR(JS_TAG_OBJECT, p)); + retval = em->get_property(ctx, obj1, prop, this_obj); + JS_FreeValue(ctx, obj1); + return retval; + } + if (em->get_own_property) { + JSPropertyDescriptor desc; + int ret; + JSValue obj1; + + /* Note: if 'p' is a prototype, it can be + freed in the called function */ + obj1 = js_dup(JS_MKPTR(JS_TAG_OBJECT, p)); + ret = em->get_own_property(ctx, &desc, obj1, prop); + JS_FreeValue(ctx, obj1); + if (ret < 0) + return JS_EXCEPTION; + if (ret) { + if (desc.flags & JS_PROP_GETSET) { + JS_FreeValue(ctx, desc.setter); + return JS_CallFree(ctx, desc.getter, this_obj, 0, NULL); + } else { + return desc.value; + } + } + } + } + } + } + p = p->shape->proto; + if (!p) + break; + } + if (unlikely(throw_ref_error)) { + return JS_ThrowReferenceErrorNotDefined(ctx, prop); + } else { + return JS_UNDEFINED; + } +} + +JSValue JS_GetProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop) +{ + return JS_GetPropertyInternal(ctx, this_obj, prop, this_obj, false); +} + +static JSValue JS_ThrowTypeErrorPrivateNotFound(JSContext *ctx, JSAtom atom) +{ + return JS_ThrowTypeErrorAtom(ctx, "private class field '%s' does not exist", + atom); +} + +/* Per the nonextensible-applies-to-private proposal, private fields cannot + be added to non-extensible objects. Note that a Proxy's JSObject stays + extensible (its trap reflects the target), so private fields can still be + stamped onto Proxies. */ +static int JS_DefinePrivateField(JSContext *ctx, JSValueConst obj, + JSValue name, JSValue val) +{ + JSObject *p; + JSShapeProperty *prs; + JSProperty *pr; + JSAtom prop; + + if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) { + JS_ThrowTypeErrorNotAnObject(ctx); + goto fail; + } + /* safety check */ + if (unlikely(JS_VALUE_GET_TAG(name) != JS_TAG_SYMBOL)) { + JS_ThrowTypeErrorNotASymbol(ctx); + goto fail; + } + prop = js_symbol_to_atom(ctx, name); + p = JS_VALUE_GET_OBJ(obj); + if (unlikely(!p->extensible)) { + JS_ThrowTypeError(ctx, "object is not extensible"); + goto fail; + } + prs = find_own_property(&pr, p, prop); + if (prs) { + JS_ThrowTypeErrorAtom(ctx, "private class field '%s' already exists", + prop); + goto fail; + } + pr = add_property(ctx, p, prop, JS_PROP_C_W_E); + if (unlikely(!pr)) { + fail: + JS_FreeValue(ctx, val); + return -1; + } + pr->u.value = val; + return 0; +} + +static JSValue JS_GetPrivateField(JSContext *ctx, JSValueConst obj, + JSValueConst name) +{ + JSObject *p; + JSShapeProperty *prs; + JSProperty *pr; + JSAtom prop; + + if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) + return JS_ThrowTypeErrorNotAnObject(ctx); + /* safety check */ + if (unlikely(JS_VALUE_GET_TAG(name) != JS_TAG_SYMBOL)) + return JS_ThrowTypeErrorNotASymbol(ctx); + prop = js_symbol_to_atom(ctx, name); + p = JS_VALUE_GET_OBJ(obj); + prs = find_own_property(&pr, p, prop); + if (!prs) { + JS_ThrowTypeErrorPrivateNotFound(ctx, prop); + return JS_EXCEPTION; + } + return js_dup(pr->u.value); +} + +static int JS_SetPrivateField(JSContext *ctx, JSValueConst obj, + JSValueConst name, JSValue val) +{ + JSObject *p; + JSShapeProperty *prs; + JSProperty *pr; + JSAtom prop; + + if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) { + JS_ThrowTypeErrorNotAnObject(ctx); + goto fail; + } + /* safety check */ + if (unlikely(JS_VALUE_GET_TAG(name) != JS_TAG_SYMBOL)) { + JS_ThrowTypeErrorNotASymbol(ctx); + goto fail; + } + prop = js_symbol_to_atom(ctx, name); + p = JS_VALUE_GET_OBJ(obj); + prs = find_own_property(&pr, p, prop); + if (!prs) { + JS_ThrowTypeErrorPrivateNotFound(ctx, prop); + fail: + JS_FreeValue(ctx, val); + return -1; + } + set_value(ctx, &pr->u.value, val); + return 0; +} + +/* add a private brand field to 'home_obj' if not already present and + if obj is != null add a private brand to it */ +static int JS_AddBrand(JSContext *ctx, JSValueConst obj, JSValueConst home_obj) +{ + JSObject *p, *p1; + JSShapeProperty *prs; + JSProperty *pr; + JSValue brand; + JSAtom brand_atom; + + if (unlikely(JS_VALUE_GET_TAG(home_obj) != JS_TAG_OBJECT)) { + JS_ThrowTypeErrorNotAnObject(ctx); + return -1; + } + p = JS_VALUE_GET_OBJ(home_obj); + prs = find_own_property(&pr, p, JS_ATOM_Private_brand); + if (!prs) { + /* if the brand is not present, add it */ + brand = JS_NewSymbolFromAtom(ctx, JS_ATOM_brand, JS_ATOM_TYPE_PRIVATE); + if (JS_IsException(brand)) + return -1; + pr = add_property(ctx, p, JS_ATOM_Private_brand, JS_PROP_C_W_E); + if (!pr) { + JS_FreeValue(ctx, brand); + return -1; + } + pr->u.value = js_dup(brand); + } else { + brand = js_dup(pr->u.value); + } + brand_atom = js_symbol_to_atom(ctx, brand); + + if (JS_IsObject(obj)) { + p1 = JS_VALUE_GET_OBJ(obj); + if (unlikely(!p1->extensible)) { + JS_FreeAtom(ctx, brand_atom); + JS_ThrowTypeError(ctx, "object is not extensible"); + return -1; + } + prs = find_own_property(&pr, p1, brand_atom); + if (unlikely(prs)) { + JS_FreeAtom(ctx, brand_atom); + JS_ThrowTypeError(ctx, "private method is already present"); + return -1; + } + pr = add_property(ctx, p1, brand_atom, JS_PROP_C_W_E); + JS_FreeAtom(ctx, brand_atom); + if (!pr) + return -1; + pr->u.value = JS_UNDEFINED; + } else { + JS_FreeAtom(ctx, brand_atom); + } + + return 0; +} + +/* return a boolean telling if the brand of the home object of 'func' + is present on 'obj' or -1 in case of exception */ +static int JS_CheckBrand(JSContext *ctx, JSValue obj, JSValue func) +{ + JSObject *p, *p1, *home_obj; + JSShapeProperty *prs; + JSProperty *pr; + JSValue brand; + + /* get the home object of 'func' */ + if (unlikely(JS_VALUE_GET_TAG(func) != JS_TAG_OBJECT)) + goto not_obj; + p1 = JS_VALUE_GET_OBJ(func); + if (!js_class_has_bytecode(p1->class_id)) + goto not_obj; + home_obj = p1->u.func.home_object; + if (!home_obj) + goto not_obj; + prs = find_own_property(&pr, home_obj, JS_ATOM_Private_brand); + if (!prs) { + JS_ThrowTypeError(ctx, "expecting private field"); + return -1; + } + brand = pr->u.value; + /* safety check */ + if (unlikely(JS_VALUE_GET_TAG(brand) != JS_TAG_SYMBOL)) + goto not_obj; + + /* get the brand array of 'obj' */ + if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) { + not_obj: + JS_ThrowTypeErrorNotAnObject(ctx); + return -1; + } + p = JS_VALUE_GET_OBJ(obj); + prs = find_own_property(&pr, p, js_symbol_to_atom(ctx, brand)); + return (prs != NULL); +} + +static uint32_t js_string_obj_get_length(JSContext *ctx, JSValueConst obj) +{ + JSObject *p; + JSString *p1; + uint32_t len = 0; + + /* This is a class exotic method: obj class_id is JS_CLASS_STRING */ + p = JS_VALUE_GET_OBJ(obj); + if (JS_VALUE_GET_TAG(p->u.object_data) == JS_TAG_STRING) { + p1 = JS_VALUE_GET_STRING(p->u.object_data); + len = p1->len; + } + return len; +} + +static int num_keys_cmp(const void *p1, const void *p2, void *opaque) +{ + JSContext *ctx = opaque; + JSAtom atom1 = ((const JSPropertyEnum *)p1)->atom; + JSAtom atom2 = ((const JSPropertyEnum *)p2)->atom; + uint32_t v1, v2; + bool atom1_is_integer, atom2_is_integer; + + atom1_is_integer = JS_AtomIsArrayIndex(ctx, &v1, atom1); + atom2_is_integer = JS_AtomIsArrayIndex(ctx, &v2, atom2); + assert(atom1_is_integer && atom2_is_integer); + if (v1 < v2) + return -1; + else if (v1 == v2) + return 0; + else + return 1; +} + +static void js_free_prop_enum(JSContext *ctx, JSPropertyEnum *tab, uint32_t len) +{ + uint32_t i; + if (tab) { + for(i = 0; i < len; i++) + JS_FreeAtom(ctx, tab[i].atom); + js_free(ctx, tab); + } +} + +/* return < 0 in case if exception, 0 if OK. ptab and its atoms must + be freed by the user. */ +static int __exception JS_GetOwnPropertyNamesInternal(JSContext *ctx, + JSPropertyEnum **ptab, + uint32_t *plen, + JSObject *p, int flags) +{ + int i, j; + JSShape *sh; + JSShapeProperty *prs; + JSPropertyEnum *tab_atom, *tab_exotic; + JSAtom atom; + uint32_t num_keys_count, str_keys_count, sym_keys_count, atom_count; + uint32_t num_index, str_index, sym_index, exotic_count, exotic_keys_count; + bool is_enumerable, num_sorted; + uint32_t num_key; + JSAtomKindEnum kind; + + /* clear pointer for consistency in case of failure */ + *ptab = NULL; + *plen = 0; + + /* compute the number of returned properties */ + num_keys_count = 0; + str_keys_count = 0; + sym_keys_count = 0; + exotic_keys_count = 0; + exotic_count = 0; + tab_exotic = NULL; + sh = p->shape; + for(i = 0, prs = get_shape_prop(sh); i < sh->prop_count; i++, prs++) { + atom = prs->atom; + if (atom != JS_ATOM_NULL) { + is_enumerable = ((prs->flags & JS_PROP_ENUMERABLE) != 0); + kind = JS_AtomGetKind(ctx, atom); + if ((!(flags & JS_GPN_ENUM_ONLY) || is_enumerable) && + ((flags >> kind) & 1) != 0) { + /* need to raise an exception in case of the module + name space (implicit GetOwnProperty) */ + if (unlikely((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) && + (flags & (JS_GPN_SET_ENUM | JS_GPN_ENUM_ONLY))) { + JSVarRef *var_ref = p->prop[i].u.var_ref; + if (unlikely(JS_IsUninitialized(*var_ref->pvalue))) { + JS_ThrowReferenceErrorUninitialized(ctx, prs->atom); + return -1; + } + } + if (JS_AtomIsArrayIndex(ctx, &num_key, atom)) { + num_keys_count++; + } else if (kind == JS_ATOM_KIND_STRING) { + str_keys_count++; + } else { + sym_keys_count++; + } + } + } + } + + if (p->is_exotic) { + if (p->fast_array) { + if (flags & JS_GPN_STRING_MASK) { + num_keys_count += p->u.array.count; + } + } else if (p->class_id == JS_CLASS_STRING) { + if (flags & JS_GPN_STRING_MASK) { + num_keys_count += js_string_obj_get_length(ctx, JS_MKPTR(JS_TAG_OBJECT, p)); + } + } else { + const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; + if (em && em->get_own_property_names) { + if (em->get_own_property_names(ctx, &tab_exotic, &exotic_count, + JS_MKPTR(JS_TAG_OBJECT, p))) + return -1; + for(i = 0; i < exotic_count; i++) { + atom = tab_exotic[i].atom; + kind = JS_AtomGetKind(ctx, atom); + if (((flags >> kind) & 1) != 0) { + is_enumerable = false; + if (flags & (JS_GPN_SET_ENUM | JS_GPN_ENUM_ONLY)) { + int desc_flags, res; + /* set the "is_enumerable" field if necessary */ + res = JS_GetOwnPropertyFlagsInternal(ctx, &desc_flags, p, atom); + if (res < 0) { + js_free_prop_enum(ctx, tab_exotic, exotic_count); + return -1; + } + if (res) { + is_enumerable = + ((desc_flags & JS_PROP_ENUMERABLE) != 0); + } + tab_exotic[i].is_enumerable = is_enumerable; + } + if (!(flags & JS_GPN_ENUM_ONLY) || is_enumerable) { + exotic_keys_count++; + } + } + } + } + } + } + + /* fill them */ + + atom_count = num_keys_count + str_keys_count + sym_keys_count + exotic_keys_count; + /* avoid allocating 0 bytes */ + tab_atom = js_malloc(ctx, sizeof(tab_atom[0]) * max_int(atom_count, 1)); + if (!tab_atom) { + js_free_prop_enum(ctx, tab_exotic, exotic_count); + return -1; + } + + num_index = 0; + str_index = num_keys_count; + sym_index = str_index + str_keys_count; + + num_sorted = true; + sh = p->shape; + for(i = 0, prs = get_shape_prop(sh); i < sh->prop_count; i++, prs++) { + atom = prs->atom; + if (atom != JS_ATOM_NULL) { + is_enumerable = ((prs->flags & JS_PROP_ENUMERABLE) != 0); + kind = JS_AtomGetKind(ctx, atom); + if ((!(flags & JS_GPN_ENUM_ONLY) || is_enumerable) && + ((flags >> kind) & 1) != 0) { + if (JS_AtomIsArrayIndex(ctx, &num_key, atom)) { + j = num_index++; + num_sorted = false; + } else if (kind == JS_ATOM_KIND_STRING) { + j = str_index++; + } else { + j = sym_index++; + } + tab_atom[j].atom = JS_DupAtom(ctx, atom); + tab_atom[j].is_enumerable = is_enumerable; + } + } + } + + if (p->is_exotic) { + int len; + if (p->fast_array) { + if (flags & JS_GPN_STRING_MASK) { + len = p->u.array.count; + goto add_array_keys; + } + } else if (p->class_id == JS_CLASS_STRING) { + if (flags & JS_GPN_STRING_MASK) { + len = js_string_obj_get_length(ctx, JS_MKPTR(JS_TAG_OBJECT, p)); + add_array_keys: + for(i = 0; i < len; i++) { + tab_atom[num_index].atom = __JS_AtomFromUInt32(i); + if (tab_atom[num_index].atom == JS_ATOM_NULL) { + js_free_prop_enum(ctx, tab_atom, num_index); + return -1; + } + tab_atom[num_index].is_enumerable = true; + num_index++; + } + } + } else { + /* Note: exotic keys are not reordered and comes after the object own properties. */ + for(i = 0; i < exotic_count; i++) { + atom = tab_exotic[i].atom; + is_enumerable = tab_exotic[i].is_enumerable; + kind = JS_AtomGetKind(ctx, atom); + if ((!(flags & JS_GPN_ENUM_ONLY) || is_enumerable) && + ((flags >> kind) & 1) != 0) { + tab_atom[sym_index].atom = atom; + tab_atom[sym_index].is_enumerable = is_enumerable; + sym_index++; + } else { + JS_FreeAtom(ctx, atom); + } + } + js_free(ctx, tab_exotic); + } + } + + assert(num_index == num_keys_count); + assert(str_index == num_keys_count + str_keys_count); + assert(sym_index == atom_count); + + if (num_keys_count != 0 && !num_sorted) { + rqsort(tab_atom, num_keys_count, sizeof(tab_atom[0]), num_keys_cmp, + ctx); + } + *ptab = tab_atom; + *plen = atom_count; + return 0; +} + +int JS_GetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab, + uint32_t *plen, JSValueConst obj, int flags) +{ + if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) { + JS_ThrowTypeErrorNotAnObject(ctx); + return -1; + } + return JS_GetOwnPropertyNamesInternal(ctx, ptab, plen, + JS_VALUE_GET_OBJ(obj), flags); +} + +/* Return -1 if exception, + false if the property does not exist, true if it exists. If true is + returned, the property descriptor 'desc' is filled present. */ +static int JS_GetOwnPropertyInternal2(JSContext *ctx, JSPropertyDescriptor *desc, + JSObject *p, JSAtom prop, int *pflags) +{ + JSShapeProperty *prs; + JSProperty *pr; + int flags_only = (desc == NULL && pflags != NULL); + +retry: + prs = find_own_property(&pr, p, prop); + if (prs) { + if (desc) { + desc->flags = prs->flags & JS_PROP_C_W_E; + desc->getter = JS_UNDEFINED; + desc->setter = JS_UNDEFINED; + desc->value = JS_UNDEFINED; + if (unlikely(prs->flags & JS_PROP_TMASK)) { + if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { + desc->flags |= JS_PROP_GETSET; + if (pr->u.getset.getter) + desc->getter = js_dup(JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter)); + if (pr->u.getset.setter) + desc->setter = js_dup(JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.setter)); + } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { + JSValue val = *pr->u.var_ref->pvalue; + if (unlikely(JS_IsUninitialized(val))) { + JS_ThrowReferenceErrorUninitialized(ctx, prs->atom); + return -1; + } + desc->value = js_dup(val); + } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { + /* Instantiate property and retry */ + if (JS_AutoInitProperty(ctx, p, prop, pr, prs)) + return -1; + goto retry; + } + } else { + desc->value = js_dup(pr->u.value); + } + } else { + if (pflags) { + *pflags = prs->flags & JS_PROP_C_W_E; + if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) + *pflags |= JS_PROP_GETSET; + } + /* for consistency, send the exception even if desc is NULL */ + if (unlikely((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF)) { + if (unlikely(JS_IsUninitialized(*pr->u.var_ref->pvalue))) { + JS_ThrowReferenceErrorUninitialized(ctx, prs->atom); + return -1; + } + } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { + /* nothing to do: delay instantiation until actual value and/or attributes are read */ + } + } + return true; + } + if (p->is_exotic) { + if (p->fast_array) { + /* specific case for fast arrays */ + if (__JS_AtomIsTaggedInt(prop)) { + uint32_t idx; + idx = __JS_AtomToUInt32(prop); + if (idx < p->u.array.count) { + if (desc) { + desc->flags = JS_PROP_WRITABLE | JS_PROP_ENUMERABLE | + JS_PROP_CONFIGURABLE; + desc->getter = JS_UNDEFINED; + desc->setter = JS_UNDEFINED; + desc->value = JS_GetPropertyUint32(ctx, JS_MKPTR(JS_TAG_OBJECT, p), idx); + } else if (flags_only) { + *pflags = JS_PROP_WRITABLE | JS_PROP_ENUMERABLE | + JS_PROP_CONFIGURABLE; + } + return true; + } + } + } else { + const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; + if (em && em->get_own_property) { + if (flags_only) { + /* Call the exotic handler with a temporary desc, + extract flags, and free the values. For Proxy + objects, the JS trap runs regardless, so the + dup+free overhead is negligible. */ + JSPropertyDescriptor d; + int ret = em->get_own_property(ctx, &d, + JS_MKPTR(JS_TAG_OBJECT, p), prop); + if (ret > 0) { + *pflags = d.flags; + js_free_desc(ctx, &d); + } + return ret; + } + return em->get_own_property(ctx, desc, + JS_MKPTR(JS_TAG_OBJECT, p), prop); + } + } + } + return false; +} + +static int JS_GetOwnPropertyInternal(JSContext *ctx, JSPropertyDescriptor *desc, + JSObject *p, JSAtom prop) +{ + return JS_GetOwnPropertyInternal2(ctx, desc, p, prop, NULL); +} + +/* Same as JS_GetOwnPropertyInternal but only returns flags, not + value/getter/setter. Avoids unnecessary js_dup() for callers that + only need the property flags. */ +static int JS_GetOwnPropertyFlagsInternal(JSContext *ctx, int *pflags, + JSObject *p, JSAtom prop) +{ + return JS_GetOwnPropertyInternal2(ctx, NULL, p, prop, pflags); +} + +int JS_GetOwnProperty(JSContext *ctx, JSPropertyDescriptor *desc, + JSValueConst obj, JSAtom prop) +{ + if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) { + JS_ThrowTypeErrorNotAnObject(ctx); + return -1; + } + return JS_GetOwnPropertyInternal(ctx, desc, JS_VALUE_GET_OBJ(obj), prop); +} + +void JS_FreePropertyEnum(JSContext *ctx, JSPropertyEnum *tab, + uint32_t len) +{ + js_free_prop_enum(ctx, tab, len); +} + +/* return -1 if exception (Proxy object only) or true/false */ +int JS_IsExtensible(JSContext *ctx, JSValueConst obj) +{ + JSObject *p; + + if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) + return false; + p = JS_VALUE_GET_OBJ(obj); + if (unlikely(p->class_id == JS_CLASS_PROXY)) + return js_proxy_isExtensible(ctx, obj); + else + return p->extensible; +} + +/* return -1 if exception (Proxy object only) or true/false */ +int JS_PreventExtensions(JSContext *ctx, JSValueConst obj) +{ + JSObject *p; + + if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) + return false; + p = JS_VALUE_GET_OBJ(obj); + if (unlikely(p->class_id == JS_CLASS_PROXY)) + return js_proxy_preventExtensions(ctx, obj); + if (is_typed_array(p->class_id)) { + JSTypedArray *ta = p->u.typed_array; + JSArrayBuffer *abuf = ta->buffer->u.array_buffer; + if (ta->track_rab || + (array_buffer_is_resizable(abuf) && !abuf->shared)) + { + return false; + } + } + p->extensible = false; + return true; +} + +/* return -1 if exception otherwise true or false */ +int JS_HasProperty(JSContext *ctx, JSValueConst obj, JSAtom prop) +{ + JSObject *p; + int ret; + JSValue obj1; + + if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) + return false; + p = JS_VALUE_GET_OBJ(obj); + for(;;) { + if (p->is_exotic) { + const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; + if (em && em->has_property) { + /* has_property can free the prototype */ + obj1 = js_dup(JS_MKPTR(JS_TAG_OBJECT, p)); + ret = em->has_property(ctx, obj1, prop); + JS_FreeValue(ctx, obj1); + return ret; + } + } + /* JS_GetOwnPropertyInternal can free the prototype */ + js_dup(JS_MKPTR(JS_TAG_OBJECT, p)); + ret = JS_GetOwnPropertyInternal(ctx, NULL, p, prop); + JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p)); + if (ret != 0) + return ret; + if (is_typed_array(p->class_id)) { + ret = JS_AtomIsNumericIndex(ctx, prop); + if (ret != 0) { + if (ret < 0) + return -1; + return false; + } + } + p = p->shape->proto; + if (!p) + break; + } + return false; +} + +/* val must be a symbol */ +static JSAtom js_symbol_to_atom(JSContext *ctx, JSValueConst val) +{ + JSAtomStruct *p = JS_VALUE_GET_PTR(val); + return js_get_atom_index(ctx->rt, p); +} + +/* return JS_ATOM_NULL in case of exception */ +static JSAtom JS_ValueToAtomInternal(JSContext *ctx, JSValueConst val, + int flags) +{ + JSAtom atom; + uint32_t tag; + tag = JS_VALUE_GET_TAG(val); + if (tag == JS_TAG_INT && + (uint32_t)JS_VALUE_GET_INT(val) <= JS_ATOM_MAX_INT) { + /* fast path for integer values */ + atom = __JS_AtomFromUInt32(JS_VALUE_GET_INT(val)); + } else if (tag == JS_TAG_SYMBOL) { + JSAtomStruct *p = JS_VALUE_GET_PTR(val); + atom = JS_DupAtom(ctx, js_get_atom_index(ctx->rt, p)); + } else { + JSValue str; + str = JS_ToPropertyKeyInternal(ctx, val, flags); + if (JS_IsException(str)) + return JS_ATOM_NULL; + if (JS_VALUE_GET_TAG(str) == JS_TAG_SYMBOL) { + atom = js_symbol_to_atom(ctx, str); + } else { + atom = JS_NewAtomStr(ctx, JS_VALUE_GET_STRING(str)); + } + } + return atom; +} + +JSAtom JS_ValueToAtom(JSContext *ctx, JSValueConst val) +{ + return JS_ValueToAtomInternal(ctx, val, /*flags*/0); +} + +static bool js_get_fast_array_element(JSContext *ctx, JSObject *p, + uint32_t idx, JSValue *pval) +{ + switch(p->class_id) { + case JS_CLASS_ARRAY: + case JS_CLASS_ARGUMENTS: + if (unlikely(idx >= p->u.array.count)) return false; + *pval = js_dup(p->u.array.u.values[idx]); + return true; + case JS_CLASS_MAPPED_ARGUMENTS: + if (unlikely(idx >= p->u.array.count)) return false; + *pval = js_dup(*p->u.array.u.var_refs[idx]->pvalue); + return true; + case JS_CLASS_INT8_ARRAY: + if (unlikely(idx >= p->u.array.count)) return false; + *pval = js_int32(p->u.array.u.int8_ptr[idx]); + return true; + case JS_CLASS_UINT8C_ARRAY: + case JS_CLASS_UINT8_ARRAY: + if (unlikely(idx >= p->u.array.count)) return false; + *pval = js_int32(p->u.array.u.uint8_ptr[idx]); + return true; + case JS_CLASS_INT16_ARRAY: + if (unlikely(idx >= p->u.array.count)) return false; + *pval = js_int32(p->u.array.u.int16_ptr[idx]); + return true; + case JS_CLASS_UINT16_ARRAY: + if (unlikely(idx >= p->u.array.count)) return false; + *pval = js_int32(p->u.array.u.uint16_ptr[idx]); + return true; + case JS_CLASS_INT32_ARRAY: + if (unlikely(idx >= p->u.array.count)) return false; + *pval = js_int32(p->u.array.u.int32_ptr[idx]); + return true; + case JS_CLASS_UINT32_ARRAY: + if (unlikely(idx >= p->u.array.count)) return false; + *pval = js_uint32(p->u.array.u.uint32_ptr[idx]); + return true; + case JS_CLASS_BIG_INT64_ARRAY: + if (unlikely(idx >= p->u.array.count)) return false; + *pval = JS_NewBigInt64(ctx, p->u.array.u.int64_ptr[idx]); + return true; + case JS_CLASS_BIG_UINT64_ARRAY: + if (unlikely(idx >= p->u.array.count)) return false; + *pval = JS_NewBigUint64(ctx, p->u.array.u.uint64_ptr[idx]); + return true; + case JS_CLASS_FLOAT16_ARRAY: + if (unlikely(idx >= p->u.array.count)) return false; + *pval = js_float64(fromfp16(p->u.array.u.fp16_ptr[idx])); + return true; + case JS_CLASS_FLOAT32_ARRAY: + if (unlikely(idx >= p->u.array.count)) return false; + *pval = js_float64(p->u.array.u.float_ptr[idx]); + return true; + case JS_CLASS_FLOAT64_ARRAY: + if (unlikely(idx >= p->u.array.count)) return false; + *pval = js_float64(p->u.array.u.double_ptr[idx]); + return true; + default: + return false; + } +} + +JSValue JS_GetPropertyValue(JSContext *ctx, JSValueConst this_obj, + JSValue prop) +{ + JSAtom atom; + JSValue ret; + uint32_t tag; + + tag = JS_VALUE_GET_TAG(this_obj); + if (likely(tag == JS_TAG_OBJECT)) { + if (JS_VALUE_GET_TAG(prop) == JS_TAG_INT) { + JSObject *p = JS_VALUE_GET_OBJ(this_obj); + uint32_t idx = JS_VALUE_GET_INT(prop); + JSValue val; + /* fast path for array and typed array access */ + if (js_get_fast_array_element(ctx, p, idx, &val)) + return val; + } + } else if (unlikely(tag == JS_TAG_NULL || tag == JS_TAG_UNDEFINED)) { + // per spec: not allowed to call ToPropertyKey before ToObject + // so we must ensure to not invoke JS anything that's observable + // from JS code + atom = JS_ValueToAtomInternal(ctx, prop, JS_TO_STRING_NO_SIDE_EFFECTS); + JS_FreeValue(ctx, prop); + if (unlikely(atom == JS_ATOM_NULL)) + return JS_EXCEPTION; + if (tag == JS_TAG_NULL) { + JS_ThrowTypeErrorAtom(ctx, "cannot read property '%s' of null", atom); + } else { + JS_ThrowTypeErrorAtom(ctx, "cannot read property '%s' of undefined", atom); + } + JS_FreeAtom(ctx, atom); + return JS_EXCEPTION; + } + atom = JS_ValueToAtom(ctx, prop); + JS_FreeValue(ctx, prop); + if (unlikely(atom == JS_ATOM_NULL)) + return JS_EXCEPTION; + ret = JS_GetProperty(ctx, this_obj, atom); + JS_FreeAtom(ctx, atom); + return ret; +} + +JSValue JS_GetPropertyUint32(JSContext *ctx, JSValueConst this_obj, + uint32_t idx) +{ + return JS_GetPropertyInt64(ctx, this_obj, idx); +} + +/* Check if an object has a generalized numeric property. Return value: + -1 for exception, *pval set to JS_EXCEPTION + true if property exists, stored into *pval, + false if property does not exist. *pval set to JS_UNDEFINED. + */ +static int JS_TryGetPropertyInt64(JSContext *ctx, JSValueConst obj, int64_t idx, JSValue *pval) +{ + JSValue val; + JSAtom prop; + int present; + + if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT && + (uint64_t)idx <= INT32_MAX)) { + /* fast path for array and typed array access */ + JSObject *p = JS_VALUE_GET_OBJ(obj); + if (js_get_fast_array_element(ctx, p, idx, pval)) + return true; + } + val = JS_EXCEPTION; + present = -1; + prop = JS_NewAtomInt64(ctx, idx); + if (likely(prop != JS_ATOM_NULL)) { + present = JS_HasProperty(ctx, obj, prop); + if (present > 0) { + val = JS_GetProperty(ctx, obj, prop); + if (unlikely(JS_IsException(val))) + present = -1; + } else if (present == false) { + val = JS_UNDEFINED; + } + JS_FreeAtom(ctx, prop); + } + *pval = val; + return present; +} + +JSValue JS_GetPropertyInt64(JSContext *ctx, JSValueConst obj, int64_t idx) +{ + JSAtom prop; + JSValue val; + + if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT && + (uint64_t)idx <= INT32_MAX)) { + /* fast path for array and typed array access */ + JSObject *p = JS_VALUE_GET_OBJ(obj); + if (js_get_fast_array_element(ctx, p, idx, &val)) + return val; + } + prop = JS_NewAtomInt64(ctx, idx); + if (prop == JS_ATOM_NULL) + return JS_EXCEPTION; + + val = JS_GetProperty(ctx, obj, prop); + JS_FreeAtom(ctx, prop); + return val; +} + +/* `prop` may be pure ASCII or UTF-8 encoded */ +JSValue JS_GetPropertyStr(JSContext *ctx, JSValueConst this_obj, + const char *prop) +{ + JSAtom atom; + JSValue ret; + atom = JS_NewAtom(ctx, prop); + if (atom == JS_ATOM_NULL) + return JS_EXCEPTION; + ret = JS_GetProperty(ctx, this_obj, atom); + JS_FreeAtom(ctx, atom); + return ret; +} + +/* Note: the property value is not initialized. Return NULL if memory + error. */ +static JSProperty *add_property(JSContext *ctx, + JSObject *p, JSAtom prop, int prop_flags) +{ + JSShape *sh, *new_sh; + + if (unlikely(p->is_prototype)) { + /* track addition of small integer properties to + Array.prototype and Object.prototype */ + if (unlikely((p == JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_ARRAY]) || + p == JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_OBJECT])) && + __JS_AtomIsTaggedInt(prop))) { + ctx->std_array_prototype = false; + } + } + sh = p->shape; + if (sh->is_hashed) { + /* try to find an existing shape */ + new_sh = find_hashed_shape_prop(ctx->rt, sh, prop, prop_flags); + if (new_sh) { + /* matching shape found: use it */ + /* the property array may need to be resized */ + if (new_sh->prop_size != sh->prop_size) { + JSProperty *new_prop; + new_prop = js_realloc(ctx, p->prop, sizeof(p->prop[0]) * + new_sh->prop_size); + if (!new_prop) + return NULL; + p->prop = new_prop; + } + p->shape = js_dup_shape(new_sh); + js_free_shape(ctx->rt, sh); + return &p->prop[new_sh->prop_count - 1]; + } else if (JS_REF_COUNT(sh) != 1) { + /* if the shape is shared, clone it */ + new_sh = js_clone_shape(ctx, sh); + if (!new_sh) + return NULL; + /* hash the cloned shape */ + new_sh->is_hashed = true; + js_shape_hash_link(ctx->rt, new_sh); + js_free_shape(ctx->rt, p->shape); + p->shape = new_sh; + } + } + assert(JS_REF_COUNT(p->shape) == 1); + if (add_shape_property(ctx, &p->shape, p, prop, prop_flags)) + return NULL; + return &p->prop[p->shape->prop_count - 1]; +} + +/* can be called on JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS or + JS_CLASS_MAPPED_ARGUMENTS objects. return < 0 if memory alloc + error. */ +static no_inline __exception int convert_fast_array_to_array(JSContext *ctx, + JSObject *p) +{ + JSProperty *pr; + JSShape *sh; + uint32_t i, len, new_count; + + /* track modification of Array.prototype */ + if (unlikely(p == JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_ARRAY]))) { + ctx->std_array_prototype = false; + } + if (js_shape_prepare_update(ctx, p, NULL)) + return -1; + len = p->u.array.count; + /* resize the properties once to simplify the error handling */ + sh = p->shape; + new_count = sh->prop_count + len; + if (new_count > sh->prop_size) { + if (resize_properties(ctx, &p->shape, p, new_count)) + return -1; + } + + if (p->class_id == JS_CLASS_MAPPED_ARGUMENTS) { + JSVarRef **tab = p->u.array.u.var_refs; + for(i = 0; i < len; i++) { + /* add_property cannot fail here but + __JS_AtomFromUInt32(i) fails for i > INT32_MAX */ + pr = add_property(ctx, p, __JS_AtomFromUInt32(i), JS_PROP_C_W_E | JS_PROP_VARREF); + pr->u.var_ref = *tab++; + } + } else { + JSValue *tab = p->u.array.u.values; + for(i = 0; i < len; i++) { + /* add_property cannot fail here but + __JS_AtomFromUInt32(i) fails for i > INT32_MAX */ + pr = add_property(ctx, p, __JS_AtomFromUInt32(i), JS_PROP_C_W_E); + pr->u.value = *tab++; + } + } + js_free(ctx, p->u.array.u.values); + p->u.array.count = 0; + p->u.array.u.values = NULL; /* fail safe */ + p->u.array.u1.size = 0; + p->fast_array = 0; + return 0; +} + +static int delete_property(JSContext *ctx, JSObject *p, JSAtom atom) +{ + JSShape *sh; + JSShapeProperty *pr, *lpr, *prop; + JSProperty *pr1; + uint32_t lpr_idx; + intptr_t h, h1; + + redo: + sh = p->shape; + h1 = hash_atom(atom, sh->prop_hash_mask); + h = prop_hash_end(sh)[-h1 - 1]; + prop = get_shape_prop(sh); + lpr = NULL; + lpr_idx = 0; /* prevent warning */ + while (h != 0) { + pr = &prop[h - 1]; + if (likely(pr->atom == atom)) { + /* found ! */ + if (!(pr->flags & JS_PROP_CONFIGURABLE)) + return false; + /* realloc the shape if needed */ + if (lpr) + lpr_idx = lpr - get_shape_prop(sh); + if (js_shape_prepare_update(ctx, p, &pr)) + return -1; + sh = p->shape; + /* remove property */ + if (lpr) { + lpr = &get_shape_prop(sh)[lpr_idx]; + lpr->hash_next = pr->hash_next; + } else { + prop_hash_end(sh)[-h1 - 1] = pr->hash_next; + } + sh->deleted_prop_count++; + /* free the entry */ + pr1 = &p->prop[h - 1]; + free_property(ctx->rt, pr1, pr->flags); + JS_FreeAtom(ctx, pr->atom); + /* put default values */ + pr->flags = 0; + pr->atom = JS_ATOM_NULL; + pr1->u.value = JS_UNDEFINED; + + /* compact the properties if too many deleted properties */ + if (sh->deleted_prop_count >= 8 && + sh->deleted_prop_count >= ((unsigned)sh->prop_count / 2)) { + compact_properties(ctx, p); + } + return true; + } + lpr = pr; + h = pr->hash_next; + } + + if (p->is_exotic) { + if (p->fast_array) { + uint32_t idx; + if (JS_AtomIsArrayIndex(ctx, &idx, atom) && + idx < p->u.array.count) { + if (p->class_id == JS_CLASS_ARRAY || + p->class_id == JS_CLASS_ARGUMENTS || + p->class_id == JS_CLASS_MAPPED_ARGUMENTS) { + if (convert_fast_array_to_array(ctx, p)) + return -1; + goto redo; + } else { + return false; + } + } + } else { + const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; + if (em && em->delete_property) { + return em->delete_property(ctx, JS_MKPTR(JS_TAG_OBJECT, p), atom); + } + } + } + /* not found */ + return true; +} + +static int call_setter(JSContext *ctx, JSObject *setter, + JSValueConst this_obj, JSValue val, int flags) +{ + JSValue ret, func; + if (likely(setter)) { + func = JS_MKPTR(JS_TAG_OBJECT, setter); + /* Note: the field could be removed in the setter */ + func = js_dup(func); + ret = JS_CallFree(ctx, func, this_obj, 1, vc(&val)); + JS_FreeValue(ctx, val); + if (JS_IsException(ret)) + return -1; + JS_FreeValue(ctx, ret); + return true; + } else { + JS_FreeValue(ctx, val); + if ((flags & JS_PROP_THROW) || + ((flags & JS_PROP_THROW_STRICT) && is_strict_mode(ctx))) { + JS_ThrowTypeError(ctx, "no setter for property"); + return -1; + } + return false; + } +} + +/* set the array length and remove the array elements if necessary. */ +static int set_array_length(JSContext *ctx, JSObject *p, JSValue val, + int flags) +{ + uint32_t len, idx, cur_len; + int i, ret; + + /* Note: this call can reallocate the properties of 'p' */ + ret = JS_ToArrayLengthFree(ctx, &len, val, false); + if (ret) + return -1; + /* JS_ToArrayLengthFree() must be done before the read-only test */ + if (unlikely(!(get_shape_prop(p->shape)[0].flags & JS_PROP_WRITABLE))) + return JS_ThrowTypeErrorReadOnly(ctx, flags, JS_ATOM_length); + + if (likely(p->fast_array)) { + uint32_t old_len = p->u.array.count; + if (len < old_len) { + for(i = len; i < old_len; i++) { + JS_FreeValue(ctx, p->u.array.u.values[i]); + p->u.array.u.values[i] = JS_UNDEFINED; + } + p->u.array.count = len; + } + p->prop[0].u.value = js_uint32(len); + } else { + /* Note: length is always a uint32 because the object is an + array */ + JS_ToUint32(ctx, &cur_len, p->prop[0].u.value); + if (len < cur_len) { + uint32_t d; + JSShape *sh; + JSShapeProperty *pr; + + d = cur_len - len; + sh = p->shape; + if (d <= sh->prop_count) { + JSAtom atom; + + /* faster to iterate */ + while (cur_len > len) { + atom = JS_NewAtomUInt32(ctx, cur_len - 1); + ret = delete_property(ctx, p, atom); + JS_FreeAtom(ctx, atom); + if (unlikely(!ret)) { + /* unlikely case: property is not + configurable */ + break; + } + cur_len--; + } + } else { + /* faster to iterate thru all the properties. Need two + passes in case one of the property is not + configurable */ + cur_len = len; + for(i = 0, pr = get_shape_prop(sh); i < sh->prop_count; + i++, pr++) { + if (pr->atom != JS_ATOM_NULL && + JS_AtomIsArrayIndex(ctx, &idx, pr->atom)) { + if (idx >= cur_len && + !(pr->flags & JS_PROP_CONFIGURABLE)) { + cur_len = idx + 1; + } + } + } + + for(i = 0, pr = get_shape_prop(sh); i < sh->prop_count; + i++, pr++) { + if (pr->atom != JS_ATOM_NULL && + JS_AtomIsArrayIndex(ctx, &idx, pr->atom)) { + if (idx >= cur_len) { + /* remove the property */ + delete_property(ctx, p, pr->atom); + /* WARNING: the shape may have been modified */ + sh = p->shape; + pr = &get_shape_prop(sh)[i]; + } + } + } + } + } else { + cur_len = len; + } + set_value(ctx, &p->prop[0].u.value, js_uint32(cur_len)); + if (unlikely(cur_len > len)) { + return JS_ThrowTypeErrorOrFalse(ctx, flags, "not configurable"); + } + } + return true; +} + +/* return -1 if exception */ +static int expand_fast_array(JSContext *ctx, JSObject *p, uint32_t new_len) +{ + uint32_t old_size, new_size; + JSValue *new_array_prop; + + if (unlikely(new_len > (uint32_t)INT32_MAX)) { + JS_ThrowOutOfMemory(ctx); + return -1; + } + + old_size = p->u.array.u1.size; + new_size = old_size + old_size/2; + if (new_size < old_size) { + JS_ThrowOutOfMemory(ctx); + return -1; + } + new_size = max_uint32(new_len, new_size); + new_array_prop = js_realloc(ctx, p->u.array.u.values, sizeof(JSValue) * new_size); + if (!new_array_prop) + return -1; + p->u.array.u.values = new_array_prop; + p->u.array.u1.size = new_size; + return 0; +} + +/* Preconditions: 'p' must be of class JS_CLASS_ARRAY, p->fast_array = + true and p->extensible = true */ +static int add_fast_array_element(JSContext *ctx, JSObject *p, + JSValue val, int flags) +{ + uint32_t new_len, array_len; + /* extend the array by one */ + /* XXX: convert to slow array if new_len > 2^31-1 elements */ + new_len = p->u.array.count + 1; + /* update the length if necessary. We assume that if the length is + not an integer, then if it >= 2^31. */ + if (likely(JS_VALUE_GET_TAG(p->prop[0].u.value) == JS_TAG_INT)) { + array_len = JS_VALUE_GET_INT(p->prop[0].u.value); + if (new_len > array_len) { + if (unlikely(!(get_shape_prop(p->shape)->flags & JS_PROP_WRITABLE))) { + JS_FreeValue(ctx, val); + return JS_ThrowTypeErrorReadOnly(ctx, flags, JS_ATOM_length); + } + p->prop[0].u.value = js_int32(new_len); + } + } + if (unlikely(new_len > p->u.array.u1.size)) { + if (expand_fast_array(ctx, p, new_len)) { + JS_FreeValue(ctx, val); + return -1; + } + } + p->u.array.u.values[new_len - 1] = val; + p->u.array.count = new_len; + return true; +} + +/* Allocate a new fast array initialized to JS_UNDEFINED. Its maximum + size is 2^31-1 elements. For convenience, 'len' is a 64 bit + integer. */ +static JSValue js_allocate_fast_array(JSContext *ctx, int64_t len) +{ + JSValue arr; + JSObject *p; + int i; + + if (len > INT32_MAX) + return JS_ThrowRangeError(ctx, "invalid array length"); + arr = JS_NewArray(ctx); + if (JS_IsException(arr)) + return arr; + if (len > 0) { + p = JS_VALUE_GET_OBJ(arr); + if (expand_fast_array(ctx, p, len) < 0) { + JS_FreeValue(ctx, arr); + return JS_EXCEPTION; + } + p->u.array.count = len; + for(i = 0; i < len; i++) + p->u.array.u.values[i] = JS_UNDEFINED; + /* update the 'length' field */ + set_value(ctx, &p->prop[0].u.value, js_int32(len)); + } + return arr; +} + +static void js_free_desc(JSContext *ctx, JSPropertyDescriptor *desc) +{ + JS_FreeValue(ctx, desc->getter); + JS_FreeValue(ctx, desc->setter); + JS_FreeValue(ctx, desc->value); +} + +/* return -1 in case of exception or true or false. Warning: 'val' is + freed by the function. 'flags' is a bitmask of JS_PROP_NO_ADD, + JS_PROP_THROW or JS_PROP_THROW_STRICT. If JS_PROP_NO_ADD is set, + the new property is not added and an error is raised. + 'obj' must be an object when obj != this_obj. + */ +static int JS_SetPropertyInternal2(JSContext *ctx, JSValueConst obj, JSAtom prop, + JSValue val, JSValueConst this_obj, int flags) +{ + JSObject *p, *p1; + JSShapeProperty *prs; + JSProperty *pr; + JSPropertyDescriptor desc; + int desc_flags; + int ret; + + switch(JS_VALUE_GET_TAG(this_obj)) { + case JS_TAG_NULL: + if (JS_IsObject(obj)) { + goto primitive_receiver; + } + JS_ThrowTypeErrorAtom(ctx, "cannot set property '%s' of null", prop); + goto fail; + case JS_TAG_UNDEFINED: + if (JS_IsObject(obj)) { + goto primitive_receiver; + } + JS_ThrowTypeErrorAtom(ctx, "cannot set property '%s' of undefined", prop); + goto fail; + case JS_TAG_OBJECT: + p = JS_VALUE_GET_OBJ(this_obj); + p1 = JS_VALUE_GET_OBJ(obj); + if (p == p1) + break; + goto retry2; + default: + if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) + obj = JS_GetPrototypePrimitive(ctx, obj); + + primitive_receiver: + p = NULL; + p1 = JS_VALUE_GET_OBJ(obj); + goto prototype_lookup; + } + +retry: + prs = find_own_property(&pr, p1, prop); + if (prs) { + if (likely((prs->flags & (JS_PROP_TMASK | JS_PROP_WRITABLE | + JS_PROP_LENGTH)) == JS_PROP_WRITABLE)) { + /* fast case */ + set_value(ctx, &pr->u.value, val); + return true; + } else if (prs->flags & JS_PROP_LENGTH) { + assert(p->class_id == JS_CLASS_ARRAY); + assert(prop == JS_ATOM_length); + return set_array_length(ctx, p, val, flags); + } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { + return call_setter(ctx, pr->u.getset.setter, this_obj, val, flags); + } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { + /* JS_PROP_WRITABLE is always true for variable + references, but they are write protected in module name + spaces. */ + if (p->class_id == JS_CLASS_MODULE_NS) + goto read_only_prop; + set_value(ctx, pr->u.var_ref->pvalue, val); + return true; + } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { + /* Instantiate property and retry (potentially useless) */ + if (JS_AutoInitProperty(ctx, p, prop, pr, prs)) + goto fail; + goto retry; + } else { + goto read_only_prop; + } + } + + for(;;) { + if (p1->is_exotic) { + if (p1->fast_array) { + if (__JS_AtomIsTaggedInt(prop)) { + uint32_t idx = __JS_AtomToUInt32(prop); + if (idx < p1->u.array.count) { + if (unlikely(p == p1)) + return JS_SetPropertyValue(ctx, this_obj, js_int32(idx), val, flags); + else + break; + } else if (is_typed_array(p1->class_id)) { + goto typed_array_oob; + } + } else if (is_typed_array(p1->class_id)) { + ret = JS_AtomIsNumericIndex(ctx, prop); + if (ret != 0) { + if (ret < 0) + goto fail; + typed_array_oob: + /* [[Set]] (10.4.5.5): an out-of-bounds or non-canonical + integer index only coerces the value (step i, via + TypedArraySetElement) when the receiver is the typed + array itself. With any other receiver the invalid + index is dropped (step ii) without evaluating the + value. p is the receiver object (NULL for a primitive + receiver), p1 is the typed array. */ + if (p == p1) { + // evaluate value for side effects + if (p1->class_id == JS_CLASS_BIG_INT64_ARRAY || + p1->class_id == JS_CLASS_BIG_UINT64_ARRAY) { + int64_t v; + if (JS_ToBigInt64Free(ctx, &v, val)) + return -1; + } else { + val = JS_ToNumberFree(ctx, val); + JS_FreeValue(ctx, val); + if (JS_IsException(val)) + return -1; + } + } else { + JS_FreeValue(ctx, val); + } + return true; + } + } + } else { + const JSClassExoticMethods *em = ctx->rt->class_array[p1->class_id].exotic; + if (em) { + JSValue obj1; + if (em->set_property) { + /* set_property can free the prototype */ + obj1 = js_dup(JS_MKPTR(JS_TAG_OBJECT, p1)); + ret = em->set_property(ctx, obj1, prop, + val, this_obj, flags); + JS_FreeValue(ctx, obj1); + JS_FreeValue(ctx, val); + return ret; + } + if (em->get_own_property) { + /* get_own_property can free the prototype */ + obj1 = js_dup(JS_MKPTR(JS_TAG_OBJECT, p1)); + ret = em->get_own_property(ctx, &desc, + obj1, prop); + JS_FreeValue(ctx, obj1); + if (ret < 0) + goto fail; + if (ret) { + if (desc.flags & JS_PROP_GETSET) { + JSObject *setter; + if (JS_IsUndefined(desc.setter)) + setter = NULL; + else + setter = JS_VALUE_GET_OBJ(desc.setter); + ret = call_setter(ctx, setter, this_obj, val, flags); + JS_FreeValue(ctx, desc.getter); + JS_FreeValue(ctx, desc.setter); + return ret; + } else { + JS_FreeValue(ctx, desc.value); + if (!(desc.flags & JS_PROP_WRITABLE)) + goto read_only_prop; + if (likely(p == p1)) { + ret = JS_DefineProperty(ctx, this_obj, prop, val, + JS_UNDEFINED, JS_UNDEFINED, + JS_PROP_HAS_VALUE); + JS_FreeValue(ctx, val); + return ret; + } else { + break; + } + } + } + } + } + } + } + p1 = p1->shape->proto; + prototype_lookup: + if (!p1) + break; + + retry2: + prs = find_own_property(&pr, p1, prop); + if (prs) { + if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { + return call_setter(ctx, pr->u.getset.setter, this_obj, val, flags); + } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { + /* Instantiate property and retry (potentially useless) */ + if (JS_AutoInitProperty(ctx, p1, prop, pr, prs)) + return -1; + goto retry2; + } else if (!(prs->flags & JS_PROP_WRITABLE)) { + goto read_only_prop; + } else { + break; + } + } + } + + if (unlikely(flags & JS_PROP_NO_ADD)) { + JS_ThrowReferenceErrorNotDefined(ctx, prop); + goto fail; + } + + if (unlikely(!p)) { + ret = JS_ThrowTypeErrorOrFalse(ctx, flags, "not an object"); + goto done; + } + + if (p == JS_VALUE_GET_OBJ(obj)) { + if (unlikely(!p->extensible)) { + ret = JS_ThrowTypeErrorOrFalse(ctx, flags, "object is not extensible"); + goto done; + } + if (p->is_exotic) { + if (p->class_id == JS_CLASS_ARRAY && p->fast_array && + __JS_AtomIsTaggedInt(prop)) { + uint32_t idx = __JS_AtomToUInt32(prop); + if (idx == p->u.array.count) { + /* fast case */ + return add_fast_array_element(ctx, p, val, flags); + } + } + goto generic_create_prop; + } else { + pr = add_property(ctx, p, prop, JS_PROP_C_W_E); + if (!pr) + goto fail; + pr->u.value = val; + return true; + } + } + + // TODO(bnoordhuis) return JSProperty slot and update in place + // when plain property (not is_exotic/setter/etc.) to avoid + // calling find_own_property() thrice? + ret = JS_GetOwnPropertyFlagsInternal(ctx, &desc_flags, p, prop); + if (ret < 0) + goto fail; + + if (ret) { + if (desc_flags & JS_PROP_GETSET) { + ret = JS_ThrowTypeErrorOrFalse(ctx, flags, "setter is forbidden"); + goto done; + } else if (!(desc_flags & JS_PROP_WRITABLE) || + p->class_id == JS_CLASS_MODULE_NS) { + read_only_prop: + ret = JS_ThrowTypeErrorReadOnly(ctx, flags, prop); + goto done; + } + ret = JS_DefineProperty(ctx, this_obj, prop, val, + JS_UNDEFINED, JS_UNDEFINED, + JS_PROP_HAS_VALUE); + } else { + if (unlikely(!p->extensible)) { + ret = JS_ThrowTypeErrorOrFalse(ctx, flags, "object is not extensible"); + goto done; + } + generic_create_prop: + ret = JS_CreateProperty(ctx, p, prop, val, JS_UNDEFINED, JS_UNDEFINED, + flags | + JS_PROP_HAS_VALUE | + JS_PROP_HAS_ENUMERABLE | + JS_PROP_HAS_WRITABLE | + JS_PROP_HAS_CONFIGURABLE | + JS_PROP_C_W_E); + } + +done: + JS_FreeValue(ctx, val); + return ret; +fail: + JS_FreeValue(ctx, val); + return -1; +} + +static int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj, JSAtom prop, + JSValue val, int flags) +{ + return JS_SetPropertyInternal2(ctx, obj, prop, val, obj, flags); +} + +int JS_SetProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSValue val) +{ + return JS_SetPropertyInternal(ctx, this_obj, prop, val, JS_PROP_THROW); +} + +/* flags can be JS_PROP_THROW or JS_PROP_THROW_STRICT */ +int JS_SetPropertyValue(JSContext *ctx, JSValueConst this_obj, + JSValue prop, JSValue val, int flags) +{ + if (likely(JS_VALUE_GET_TAG(this_obj) == JS_TAG_OBJECT && + JS_VALUE_GET_TAG(prop) == JS_TAG_INT)) { + JSObject *p; + uint32_t idx; + double d; + int32_t v; + + /* fast path for array access */ + p = JS_VALUE_GET_OBJ(this_obj); + idx = JS_VALUE_GET_INT(prop); + switch(p->class_id) { + case JS_CLASS_ARRAY: + if (unlikely(idx >= (uint32_t)p->u.array.count)) { + /* fast path to add an element to the array */ + if (unlikely(idx != (uint32_t)p->u.array.count || + !p->fast_array || + !p->extensible || + p->shape->proto != JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_ARRAY]) || + !ctx->std_array_prototype)) { + goto slow_path; + } + /* add element */ + return add_fast_array_element(ctx, p, val, flags); + } + set_value(ctx, &p->u.array.u.values[idx], val); + break; + case JS_CLASS_ARGUMENTS: + if (unlikely(idx >= (uint32_t)p->u.array.count)) + goto slow_path; + set_value(ctx, &p->u.array.u.values[idx], val); + break; + case JS_CLASS_MAPPED_ARGUMENTS: + if (unlikely(idx >= (uint32_t)p->u.array.count)) + goto slow_path; + set_value(ctx, p->u.array.u.var_refs[idx]->pvalue, val); + break; + case JS_CLASS_UINT8C_ARRAY: + if (JS_ToUint8ClampFree(ctx, &v, val)) + goto ta_cvt_fail; + if (typed_array_is_immutable(p)) + goto ta_immutable; + /* Note: the conversion can detach the typed array, so the + array bound check must be done after */ + if (unlikely(idx >= (uint32_t)p->u.array.count)) + goto ta_out_of_bound; + p->u.array.u.uint8_ptr[idx] = v; + break; + case JS_CLASS_INT8_ARRAY: + case JS_CLASS_UINT8_ARRAY: + if (JS_ToInt32Free(ctx, &v, val)) + goto ta_cvt_fail; + if (typed_array_is_immutable(p)) + goto ta_immutable; + if (unlikely(idx >= (uint32_t)p->u.array.count)) + goto ta_out_of_bound; + p->u.array.u.uint8_ptr[idx] = v; + break; + case JS_CLASS_INT16_ARRAY: + case JS_CLASS_UINT16_ARRAY: + if (JS_ToInt32Free(ctx, &v, val)) + goto ta_cvt_fail; + if (typed_array_is_immutable(p)) + goto ta_immutable; + if (unlikely(idx >= (uint32_t)p->u.array.count)) + goto ta_out_of_bound; + p->u.array.u.uint16_ptr[idx] = v; + break; + case JS_CLASS_INT32_ARRAY: + case JS_CLASS_UINT32_ARRAY: + if (JS_ToInt32Free(ctx, &v, val)) + goto ta_cvt_fail; + if (typed_array_is_immutable(p)) + goto ta_immutable; + if (unlikely(idx >= (uint32_t)p->u.array.count)) + goto ta_out_of_bound; + p->u.array.u.uint32_ptr[idx] = v; + break; + case JS_CLASS_BIG_INT64_ARRAY: + case JS_CLASS_BIG_UINT64_ARRAY: + /* XXX: need specific conversion function */ + { + int64_t v; + if (JS_ToBigInt64Free(ctx, &v, val)) + goto ta_cvt_fail; + if (typed_array_is_immutable(p)) + goto ta_immutable; + if (unlikely(idx >= (uint32_t)p->u.array.count)) + goto ta_out_of_bound; + p->u.array.u.uint64_ptr[idx] = v; + } + break; + case JS_CLASS_FLOAT16_ARRAY: + if (JS_ToFloat64Free(ctx, &d, val)) + goto ta_cvt_fail; + if (typed_array_is_immutable(p)) + goto ta_immutable; + if (unlikely(idx >= (uint32_t)p->u.array.count)) + goto ta_out_of_bound; + p->u.array.u.fp16_ptr[idx] = tofp16(d); + break; + case JS_CLASS_FLOAT32_ARRAY: + if (JS_ToFloat64Free(ctx, &d, val)) + goto ta_cvt_fail; + if (typed_array_is_immutable(p)) + goto ta_immutable; + if (unlikely(idx >= (uint32_t)p->u.array.count)) + goto ta_out_of_bound; + p->u.array.u.float_ptr[idx] = d; + break; + case JS_CLASS_FLOAT64_ARRAY: + if (JS_ToFloat64Free(ctx, &d, val)) { + ta_cvt_fail: + if (flags & JS_PROP_REFLECT_DEFINE_PROPERTY) { + JS_FreeValue(ctx, JS_GetException(ctx)); + return false; + } + return -1; + } + if (typed_array_is_immutable(p)) { + ta_immutable: + return false; + } + if (unlikely(idx >= (uint32_t)p->u.array.count)) { + ta_out_of_bound: + if (typed_array_is_oob(p)) + if (flags & JS_PROP_DEFINE_PROPERTY) + return JS_ThrowTypeErrorOrFalse(ctx, flags, "out-of-bound numeric index"); + return true; // per spec: no OOB exception + } + p->u.array.u.double_ptr[idx] = d; + break; + default: + goto slow_path; + } + return true; + } else { + JSAtom atom; + int ret; + slow_path: + atom = JS_ValueToAtom(ctx, prop); + JS_FreeValue(ctx, prop); + if (unlikely(atom == JS_ATOM_NULL)) { + JS_FreeValue(ctx, val); + return -1; + } + ret = JS_SetPropertyInternal(ctx, this_obj, atom, val, flags); + JS_FreeAtom(ctx, atom); + return ret; + } +} + +int JS_SetPropertyUint32(JSContext *ctx, JSValueConst this_obj, + uint32_t idx, JSValue val) +{ + return JS_SetPropertyValue(ctx, this_obj, js_uint32(idx), val, + JS_PROP_THROW); +} + +int JS_SetPropertyInt64(JSContext *ctx, JSValueConst this_obj, + int64_t idx, JSValue val) +{ + JSAtom prop; + int res; + + if ((uint64_t)idx <= INT32_MAX) { + /* fast path for fast arrays */ + return JS_SetPropertyValue(ctx, this_obj, js_int32(idx), val, + JS_PROP_THROW); + } + prop = JS_NewAtomInt64(ctx, idx); + if (prop == JS_ATOM_NULL) { + JS_FreeValue(ctx, val); + return -1; + } + res = JS_SetProperty(ctx, this_obj, prop, val); + JS_FreeAtom(ctx, prop); + return res; +} + +/* `prop` may be pure ASCII or UTF-8 encoded */ +int JS_SetPropertyStr(JSContext *ctx, JSValueConst this_obj, + const char *prop, JSValue val) +{ + JSAtom atom; + int ret; + atom = JS_NewAtom(ctx, prop); + if (atom == JS_ATOM_NULL) { + JS_FreeValue(ctx, val); + return -1; + } + ret = JS_SetPropertyInternal(ctx, this_obj, atom, val, JS_PROP_THROW); + JS_FreeAtom(ctx, atom); + return ret; +} + +/* compute the property flags. For each flag: (JS_PROP_HAS_x forces + it, otherwise def_flags is used) + Note: makes assumption about the bit pattern of the flags +*/ +static int get_prop_flags(int flags, int def_flags) +{ + int mask; + mask = (flags >> JS_PROP_HAS_SHIFT) & JS_PROP_C_W_E; + return (flags & mask) | (def_flags & ~mask); +} + +static int JS_CreateProperty(JSContext *ctx, JSObject *p, + JSAtom prop, JSValueConst val, + JSValueConst getter, JSValueConst setter, + int flags) +{ + JSProperty *pr; + int ret, prop_flags; + + /* add a new property or modify an existing exotic one */ + if (p->is_exotic) { + if (p->class_id == JS_CLASS_ARRAY) { + uint32_t idx, len; + + if (p->fast_array) { + if (__JS_AtomIsTaggedInt(prop)) { + idx = __JS_AtomToUInt32(prop); + if (idx == p->u.array.count) { + if (!p->extensible) + goto not_extensible; + if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) + goto convert_to_array; + prop_flags = get_prop_flags(flags, 0); + if (prop_flags != JS_PROP_C_W_E) + goto convert_to_array; + return add_fast_array_element(ctx, p, + js_dup(val), flags); + } else { + goto convert_to_array; + } + } else if (JS_AtomIsArrayIndex(ctx, &idx, prop)) { + /* convert the fast array to normal array */ + convert_to_array: + if (convert_fast_array_to_array(ctx, p)) + return -1; + goto generic_array; + } + } else if (JS_AtomIsArrayIndex(ctx, &idx, prop)) { + JSProperty *plen; + JSShapeProperty *pslen; + generic_array: + /* update the length field */ + plen = &p->prop[0]; + JS_ToUint32(ctx, &len, plen->u.value); + if ((idx + 1) > len) { + pslen = get_shape_prop(p->shape); + if (unlikely(!(pslen->flags & JS_PROP_WRITABLE))) + return JS_ThrowTypeErrorReadOnly(ctx, flags, JS_ATOM_length); + /* XXX: should update the length after defining + the property */ + len = idx + 1; + set_value(ctx, &plen->u.value, js_uint32(len)); + } + } + } else if (is_typed_array(p->class_id)) { + ret = JS_AtomIsNumericIndex(ctx, prop); + if (ret != 0) { + if (ret < 0) + return -1; + return JS_ThrowTypeErrorOrFalse(ctx, flags, "cannot create numeric index in typed array"); + } + } else if (!(flags & JS_PROP_NO_EXOTIC)) { + const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; + if (em) { + if (em->define_own_property) { + return em->define_own_property(ctx, JS_MKPTR(JS_TAG_OBJECT, p), + prop, val, getter, setter, flags); + } + ret = JS_IsExtensible(ctx, JS_MKPTR(JS_TAG_OBJECT, p)); + if (ret < 0) + return -1; + if (!ret) + goto not_extensible; + } + } + } + + if (!p->extensible) { + not_extensible: + return JS_ThrowTypeErrorOrFalse(ctx, flags, "object is not extensible"); + } + + if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) { + prop_flags = (flags & (JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE)) | + JS_PROP_GETSET; + } else { + prop_flags = flags & JS_PROP_C_W_E; + } + pr = add_property(ctx, p, prop, prop_flags); + if (unlikely(!pr)) + return -1; + if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) { + pr->u.getset.getter = NULL; + if ((flags & JS_PROP_HAS_GET) && JS_IsFunction(ctx, getter)) { + pr->u.getset.getter = + JS_VALUE_GET_OBJ(js_dup(getter)); + } + pr->u.getset.setter = NULL; + if ((flags & JS_PROP_HAS_SET) && JS_IsFunction(ctx, setter)) { + pr->u.getset.setter = + JS_VALUE_GET_OBJ(js_dup(setter)); + } + } else { + if (flags & JS_PROP_HAS_VALUE) { + pr->u.value = js_dup(val); + } else { + pr->u.value = JS_UNDEFINED; + } + } + return true; +} + +/* return false if not OK */ +static bool check_define_prop_flags(int prop_flags, int flags) +{ + bool has_accessor, is_getset; + + if (!(prop_flags & JS_PROP_CONFIGURABLE)) { + if ((flags & (JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE)) == + (JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE)) { + return false; + } + if ((flags & JS_PROP_HAS_ENUMERABLE) && + (flags & JS_PROP_ENUMERABLE) != (prop_flags & JS_PROP_ENUMERABLE)) + return false; + } + if (flags & (JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE | + JS_PROP_HAS_GET | JS_PROP_HAS_SET)) { + if (!(prop_flags & JS_PROP_CONFIGURABLE)) { + has_accessor = ((flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) != 0); + is_getset = ((prop_flags & JS_PROP_TMASK) == JS_PROP_GETSET); + if (has_accessor != is_getset) + return false; + if (!has_accessor && !is_getset && !(prop_flags & JS_PROP_WRITABLE)) { + /* not writable: cannot set the writable bit */ + if ((flags & (JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE)) == + (JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE)) + return false; + } + } + } + return true; +} + +/* ensure that the shape can be safely modified */ +static int js_shape_prepare_update(JSContext *ctx, JSObject *p, + JSShapeProperty **pprs) +{ + JSShape *sh; + uint32_t idx = 0; /* prevent warning */ + + sh = p->shape; + if (sh->is_hashed) { + if (JS_REF_COUNT(sh) != 1) { + if (pprs) + idx = *pprs - get_shape_prop(sh); + /* clone the shape (the resulting one is no longer hashed) */ + sh = js_clone_shape(ctx, sh); + if (!sh) + return -1; + js_free_shape(ctx->rt, p->shape); + p->shape = sh; + if (pprs) + *pprs = &get_shape_prop(sh)[idx]; + } else { + js_shape_hash_unlink(ctx->rt, sh); + sh->is_hashed = false; + } + } + return 0; +} + +static int js_update_property_flags(JSContext *ctx, JSObject *p, + JSShapeProperty **pprs, int flags) +{ + if (flags != (*pprs)->flags) { + if (js_shape_prepare_update(ctx, p, pprs)) + return -1; + (*pprs)->flags = flags; + } + return 0; +} + +/* allowed flags: + JS_PROP_CONFIGURABLE, JS_PROP_WRITABLE, JS_PROP_ENUMERABLE + JS_PROP_HAS_GET, JS_PROP_HAS_SET, JS_PROP_HAS_VALUE, + JS_PROP_HAS_CONFIGURABLE, JS_PROP_HAS_WRITABLE, JS_PROP_HAS_ENUMERABLE, + JS_PROP_THROW, JS_PROP_NO_EXOTIC. + If JS_PROP_THROW is set, return an exception instead of false. + if JS_PROP_NO_EXOTIC is set, do not call the exotic + define_own_property callback. + return -1 (exception), false or true. +*/ +int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj, + JSAtom prop, JSValueConst val, + JSValueConst getter, JSValueConst setter, int flags) +{ + JSObject *p; + JSShapeProperty *prs; + JSProperty *pr; + int mask, res; + + if (JS_VALUE_GET_TAG(this_obj) != JS_TAG_OBJECT) { + JS_ThrowTypeErrorNotAnObject(ctx); + return -1; + } + p = JS_VALUE_GET_OBJ(this_obj); + + redo_prop_update: + prs = find_own_property(&pr, p, prop); + if (prs) { + /* the range of the Array length property is always tested before */ + if ((prs->flags & JS_PROP_LENGTH) && (flags & JS_PROP_HAS_VALUE)) { + uint32_t array_length; + if (JS_ToArrayLengthFree(ctx, &array_length, + js_dup(val), false)) { + return -1; + } + /* this code relies on the fact that Uint32 are never allocated */ + val = js_uint32(array_length); + /* prs may have been modified */ + prs = find_own_property(&pr, p, prop); + assert(prs != NULL); + } + /* property already exists */ + if (!check_define_prop_flags(prs->flags, flags)) { + not_configurable: + return JS_ThrowTypeErrorOrFalse(ctx, flags, "property is not configurable"); + } + + if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { + /* Instantiate property and retry */ + if (JS_AutoInitProperty(ctx, p, prop, pr, prs)) + return -1; + goto redo_prop_update; + } + + if (flags & (JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE | + JS_PROP_HAS_GET | JS_PROP_HAS_SET)) { + if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) { + JSObject *new_getter, *new_setter; + + if (JS_IsFunction(ctx, getter)) { + new_getter = JS_VALUE_GET_OBJ(getter); + } else { + new_getter = NULL; + } + if (JS_IsFunction(ctx, setter)) { + new_setter = JS_VALUE_GET_OBJ(setter); + } else { + new_setter = NULL; + } + + if ((prs->flags & JS_PROP_TMASK) != JS_PROP_GETSET) { + if (js_shape_prepare_update(ctx, p, &prs)) + return -1; + /* convert to getset */ + if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { + free_var_ref(ctx->rt, pr->u.var_ref); + } else { + JS_FreeValue(ctx, pr->u.value); + } + prs->flags = (prs->flags & + (JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE)) | + JS_PROP_GETSET; + pr->u.getset.getter = NULL; + pr->u.getset.setter = NULL; + } else { + if (!(prs->flags & JS_PROP_CONFIGURABLE)) { + if ((flags & JS_PROP_HAS_GET) && + new_getter != pr->u.getset.getter) { + goto not_configurable; + } + if ((flags & JS_PROP_HAS_SET) && + new_setter != pr->u.getset.setter) { + goto not_configurable; + } + } + } + if (flags & JS_PROP_HAS_GET) { + if (pr->u.getset.getter) + JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter)); + if (new_getter) + js_dup(getter); + pr->u.getset.getter = new_getter; + } + if (flags & JS_PROP_HAS_SET) { + if (pr->u.getset.setter) + JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.setter)); + if (new_setter) + js_dup(setter); + pr->u.getset.setter = new_setter; + } + } else { + if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { + /* convert to data descriptor */ + if (js_shape_prepare_update(ctx, p, &prs)) + return -1; + if (pr->u.getset.getter) + JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter)); + if (pr->u.getset.setter) + JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.setter)); + prs->flags &= ~(JS_PROP_TMASK | JS_PROP_WRITABLE); + pr->u.value = JS_UNDEFINED; + } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { + /* Note: JS_PROP_VARREF is always writable */ + } else { + if ((prs->flags & (JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE)) == 0 && + (flags & JS_PROP_HAS_VALUE)) { + if (!js_same_value(ctx, val, pr->u.value)) { + goto not_configurable; + } else { + return true; + } + } + } + if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { + if (flags & JS_PROP_HAS_VALUE) { + if (p->class_id == JS_CLASS_MODULE_NS) { + /* JS_PROP_WRITABLE is always true for variable + references, but they are write protected in module name + spaces. */ + if (!js_same_value(ctx, val, *pr->u.var_ref->pvalue)) + goto not_configurable; + } + /* update the reference */ + set_value(ctx, pr->u.var_ref->pvalue, js_dup(val)); + } + /* if writable is set to false, no longer a + reference (for mapped arguments) */ + if ((flags & (JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE)) == JS_PROP_HAS_WRITABLE) { + JSValue val1; + if (js_shape_prepare_update(ctx, p, &prs)) + return -1; + val1 = js_dup(*pr->u.var_ref->pvalue); + free_var_ref(ctx->rt, pr->u.var_ref); + pr->u.value = val1; + prs->flags &= ~(JS_PROP_TMASK | JS_PROP_WRITABLE); + } + } else if (prs->flags & JS_PROP_LENGTH) { + if (flags & JS_PROP_HAS_VALUE) { + /* Note: no JS code is executable because + 'val' is guaranted to be a Uint32 */ + res = set_array_length(ctx, p, js_dup(val), flags); + } else { + res = true; + } + /* still need to reset the writable flag if + needed. The JS_PROP_LENGTH is kept because the + Uint32 test is still done if the length + property is read-only. */ + if ((flags & (JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE)) == + JS_PROP_HAS_WRITABLE) { + prs = get_shape_prop(p->shape); + if (js_update_property_flags(ctx, p, &prs, + prs->flags & ~JS_PROP_WRITABLE)) + return -1; + } + return res; + } else { + if (flags & JS_PROP_HAS_VALUE) { + JS_FreeValue(ctx, pr->u.value); + pr->u.value = js_dup(val); + } + if (flags & JS_PROP_HAS_WRITABLE) { + if (js_update_property_flags(ctx, p, &prs, + (prs->flags & ~JS_PROP_WRITABLE) | + (flags & JS_PROP_WRITABLE))) + return -1; + } + } + } + } + mask = 0; + if (flags & JS_PROP_HAS_CONFIGURABLE) + mask |= JS_PROP_CONFIGURABLE; + if (flags & JS_PROP_HAS_ENUMERABLE) + mask |= JS_PROP_ENUMERABLE; + if (js_update_property_flags(ctx, p, &prs, + (prs->flags & ~mask) | (flags & mask))) + return -1; + return true; + } + + /* handle modification of fast array elements */ + if (p->fast_array) { + uint32_t idx; + uint32_t prop_flags; + if (p->class_id == JS_CLASS_ARRAY) { + if (__JS_AtomIsTaggedInt(prop)) { + idx = __JS_AtomToUInt32(prop); + if (idx < p->u.array.count) { + prop_flags = get_prop_flags(flags, JS_PROP_C_W_E); + if (prop_flags != JS_PROP_C_W_E) + goto convert_to_slow_array; + if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) { + convert_to_slow_array: + if (convert_fast_array_to_array(ctx, p)) + return -1; + else + goto redo_prop_update; + } + if (flags & JS_PROP_HAS_VALUE) { + set_value(ctx, &p->u.array.u.values[idx], js_dup(val)); + } + return true; + } + } + } else if (is_typed_array(p->class_id)) { + JSValue num; + int ret; + + if (!__JS_AtomIsTaggedInt(prop)) { + /* slow path with to handle all numeric indexes */ + num = JS_AtomIsNumericIndex1(ctx, prop); + if (JS_IsUndefined(num)) + goto typed_array_done; + if (JS_IsException(num)) + return -1; + ret = JS_NumberIsInteger(ctx, num); + if (ret < 0) { + JS_FreeValue(ctx, num); + return -1; + } + if (!ret) { + JS_FreeValue(ctx, num); + return JS_ThrowTypeErrorOrFalse(ctx, flags, "non integer index in typed array"); + } + ret = JS_NumberIsNegativeOrMinusZero(ctx, num); + JS_FreeValue(ctx, num); + if (ret) { + return JS_ThrowTypeErrorOrFalse(ctx, flags, "negative index in typed array"); + } + if (!__JS_AtomIsTaggedInt(prop)) + goto typed_array_oob; + } + idx = __JS_AtomToUInt32(prop); + /* if the typed array is detached, p->u.array.count = 0 */ + if (idx >= p->u.array.count) { + typed_array_oob: + return JS_ThrowTypeErrorOrFalse(ctx, flags, "out-of-bound index in typed array"); + } + prop_flags = get_prop_flags(flags, JS_PROP_ENUMERABLE | JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); + if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET) || + prop_flags != (JS_PROP_ENUMERABLE | JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE)) { + return JS_ThrowTypeErrorOrFalse(ctx, flags, "invalid descriptor flags"); + } + if (flags & JS_PROP_HAS_VALUE) { + return JS_SetPropertyValue(ctx, this_obj, js_int32(idx), js_dup(val), flags); + } + return true; + typed_array_done: ; + } + } + + return JS_CreateProperty(ctx, p, prop, val, getter, setter, flags); +} + +static int JS_DefineAutoInitProperty(JSContext *ctx, JSValueConst this_obj, + JSAtom prop, JSAutoInitIDEnum id, + void *opaque, int flags) +{ + JSObject *p; + JSProperty *pr; + + if (JS_VALUE_GET_TAG(this_obj) != JS_TAG_OBJECT) + return false; + + p = JS_VALUE_GET_OBJ(this_obj); + + if (find_own_property(&pr, p, prop)) { + /* property already exists */ + abort(); + return false; + } + + /* Specialized CreateProperty */ + pr = add_property(ctx, p, prop, (flags & JS_PROP_C_W_E) | JS_PROP_AUTOINIT); + if (unlikely(!pr)) + return -1; + pr->u.init.realm_and_id = (uintptr_t)JS_DupContext(ctx); + assert((pr->u.init.realm_and_id & 3) == 0); + assert(id <= 3); + pr->u.init.realm_and_id |= id; + pr->u.init.opaque = opaque; + return true; +} + +/* Like JS_DefinePropertyValue but borrows val (does not free it) */ +static int JS_DefinePropertyValueConst(JSContext *ctx, JSValueConst this_obj, + JSAtom prop, JSValueConst val, int flags) +{ + return JS_DefineProperty(ctx, this_obj, prop, val, JS_UNDEFINED, JS_UNDEFINED, + flags | JS_PROP_HAS_VALUE | JS_PROP_HAS_CONFIGURABLE | + JS_PROP_HAS_WRITABLE | JS_PROP_HAS_ENUMERABLE); +} + +/* shortcut to add or redefine a new property value */ +int JS_DefinePropertyValue(JSContext *ctx, JSValueConst this_obj, + JSAtom prop, JSValue val, int flags) +{ + int ret; + ret = JS_DefinePropertyValueConst(ctx, this_obj, prop, val, flags); + JS_FreeValue(ctx, val); + return ret; +} + +int JS_DefinePropertyValueValue(JSContext *ctx, JSValueConst this_obj, + JSValue prop, JSValue val, int flags) +{ + JSAtom atom; + int ret; + atom = JS_ValueToAtom(ctx, prop); + JS_FreeValue(ctx, prop); + if (unlikely(atom == JS_ATOM_NULL)) { + JS_FreeValue(ctx, val); + return -1; + } + ret = JS_DefinePropertyValue(ctx, this_obj, atom, val, flags); + JS_FreeAtom(ctx, atom); + return ret; +} + +int JS_DefinePropertyValueUint32(JSContext *ctx, JSValueConst this_obj, + uint32_t idx, JSValue val, int flags) +{ + return JS_DefinePropertyValueValue(ctx, this_obj, js_uint32(idx), + val, flags); +} + +int JS_DefinePropertyValueInt64(JSContext *ctx, JSValueConst this_obj, + int64_t idx, JSValue val, int flags) +{ + return JS_DefinePropertyValueValue(ctx, this_obj, js_int64(idx), + val, flags); +} + +/* `prop` may be pure ASCII or UTF-8 encoded */ +int JS_DefinePropertyValueStr(JSContext *ctx, JSValueConst this_obj, + const char *prop, JSValue val, int flags) +{ + JSAtom atom; + int ret; + atom = JS_NewAtom(ctx, prop); + if (atom == JS_ATOM_NULL) { + JS_FreeValue(ctx, val); + return -1; + } + ret = JS_DefinePropertyValue(ctx, this_obj, atom, val, flags); + JS_FreeAtom(ctx, atom); + return ret; +} + +/* shortcut to add getter & setter */ +int JS_DefinePropertyGetSet(JSContext *ctx, JSValueConst this_obj, + JSAtom prop, JSValue getter, JSValue setter, + int flags) +{ + int ret; + ret = JS_DefineProperty(ctx, this_obj, prop, JS_UNDEFINED, getter, setter, + flags | JS_PROP_HAS_GET | JS_PROP_HAS_SET | + JS_PROP_HAS_CONFIGURABLE | JS_PROP_HAS_ENUMERABLE); + JS_FreeValue(ctx, getter); + JS_FreeValue(ctx, setter); + return ret; +} + +static int JS_CreateDataPropertyUint32(JSContext *ctx, JSValueConst this_obj, + int64_t idx, JSValue val, int flags) +{ + return JS_DefinePropertyValueValue(ctx, this_obj, js_int64(idx), + val, flags | JS_PROP_CONFIGURABLE | + JS_PROP_ENUMERABLE | JS_PROP_WRITABLE); +} + +/* Like JS_DefinePropertyValueInt64 but borrows val (does not free it) */ +static int JS_DefinePropertyValueInt64Const(JSContext *ctx, JSValueConst this_obj, + int64_t idx, JSValueConst val, int flags) +{ + JSAtom atom; + int ret; + atom = JS_ValueToAtom(ctx, js_int64(idx)); + if (unlikely(atom == JS_ATOM_NULL)) + return -1; + ret = JS_DefinePropertyValueConst(ctx, this_obj, atom, val, flags); + JS_FreeAtom(ctx, atom); + return ret; +} + +/* Like JS_CreateDataPropertyUint32 but borrows val (does not free it) */ +static int JS_CreateDataPropertyUint32Const(JSContext *ctx, JSValueConst this_obj, + int64_t idx, JSValueConst val, int flags) +{ + return JS_DefinePropertyValueInt64Const(ctx, this_obj, idx, val, + flags | JS_PROP_CONFIGURABLE | + JS_PROP_ENUMERABLE | JS_PROP_WRITABLE); +} + + +/* return true if 'obj' has a non empty 'name' string */ +static bool js_object_has_name(JSContext *ctx, JSValue obj) +{ + JSProperty *pr; + JSShapeProperty *prs; + JSValue val; + JSString *p; + + prs = find_own_property(&pr, JS_VALUE_GET_OBJ(obj), JS_ATOM_name); + if (!prs) + return false; + if ((prs->flags & JS_PROP_TMASK) != JS_PROP_NORMAL) + return true; + val = pr->u.value; + if (JS_VALUE_GET_TAG(val) != JS_TAG_STRING) + return true; + p = JS_VALUE_GET_STRING(val); + return (p->len != 0); +} + +static int JS_DefineObjectName(JSContext *ctx, JSValue obj, + JSAtom name, int flags) +{ + if (name != JS_ATOM_NULL + && JS_IsObject(obj) + && !js_object_has_name(ctx, obj) + && JS_DefinePropertyValue(ctx, obj, JS_ATOM_name, JS_AtomToString(ctx, name), flags) < 0) { + return -1; + } + return 0; +} + +static int JS_DefineObjectNameComputed(JSContext *ctx, JSValue obj, + JSValue str, int flags) +{ + if (JS_IsObject(obj) && + !js_object_has_name(ctx, obj)) { + JSAtom prop; + JSValue name_str; + prop = JS_ValueToAtom(ctx, str); + if (prop == JS_ATOM_NULL) + return -1; + name_str = js_get_function_name(ctx, prop); + JS_FreeAtom(ctx, prop); + if (JS_IsException(name_str)) + return -1; + if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_name, name_str, flags) < 0) + return -1; + } + return 0; +} + +#define DEFINE_GLOBAL_LEX_VAR (1 << 7) +#define DEFINE_GLOBAL_FUNC_VAR (1 << 6) + +static JSValue JS_ThrowSyntaxErrorVarRedeclaration(JSContext *ctx, JSAtom prop) +{ + return JS_ThrowSyntaxErrorAtom(ctx, "redeclaration of '%s'", prop); +} + +/* flags is 0, DEFINE_GLOBAL_LEX_VAR or DEFINE_GLOBAL_FUNC_VAR */ +/* XXX: could support exotic global object. */ +static int JS_CheckDefineGlobalVar(JSContext *ctx, JSAtom prop, int flags) +{ + JSObject *p; + JSShapeProperty *prs; + + p = JS_VALUE_GET_OBJ(ctx->global_obj); + prs = find_own_property1(p, prop); + /* XXX: should handle JS_PROP_AUTOINIT */ + if (flags & DEFINE_GLOBAL_LEX_VAR) { + if (prs && !(prs->flags & JS_PROP_CONFIGURABLE)) + goto fail_redeclaration; + } else { + if (!prs && !p->extensible) + goto define_error; + if (flags & DEFINE_GLOBAL_FUNC_VAR) { + if (prs) { + if (!(prs->flags & JS_PROP_CONFIGURABLE) && + ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET || + ((prs->flags & (JS_PROP_WRITABLE | JS_PROP_ENUMERABLE)) != + (JS_PROP_WRITABLE | JS_PROP_ENUMERABLE)))) { + define_error: + JS_ThrowTypeErrorAtom(ctx, "cannot define variable '%s'", + prop); + return -1; + } + } + } + } + /* check if there already is a lexical declaration */ + p = JS_VALUE_GET_OBJ(ctx->global_var_obj); + prs = find_own_property1(p, prop); + if (prs) { + fail_redeclaration: + JS_ThrowSyntaxErrorVarRedeclaration(ctx, prop); + return -1; + } + return 0; +} + +/* def_flags is (0, DEFINE_GLOBAL_LEX_VAR) | + JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE */ +/* XXX: could support exotic global object. */ +static int JS_DefineGlobalVar(JSContext *ctx, JSAtom prop, int def_flags) +{ + JSObject *p; + JSShapeProperty *prs; + JSProperty *pr; + JSValue val; + int flags; + + if (def_flags & DEFINE_GLOBAL_LEX_VAR) { + p = JS_VALUE_GET_OBJ(ctx->global_var_obj); + flags = JS_PROP_ENUMERABLE | (def_flags & JS_PROP_WRITABLE) | + JS_PROP_CONFIGURABLE; + val = JS_UNINITIALIZED; + } else { + p = JS_VALUE_GET_OBJ(ctx->global_obj); + flags = JS_PROP_ENUMERABLE | JS_PROP_WRITABLE | + (def_flags & JS_PROP_CONFIGURABLE); + val = JS_UNDEFINED; + } + prs = find_own_property1(p, prop); + if (prs) + return 0; + if (!p->extensible) + return 0; + pr = add_property(ctx, p, prop, flags); + if (unlikely(!pr)) + return -1; + pr->u.value = val; + return 0; +} + +/* 'def_flags' is 0 or JS_PROP_CONFIGURABLE. */ +/* XXX: could support exotic global object. */ +static int JS_DefineGlobalFunction(JSContext *ctx, JSAtom prop, + JSValue func, int def_flags) +{ + + JSObject *p; + JSShapeProperty *prs; + int flags; + + p = JS_VALUE_GET_OBJ(ctx->global_obj); + prs = find_own_property1(p, prop); + flags = JS_PROP_HAS_VALUE | JS_PROP_THROW; + if (!prs || (prs->flags & JS_PROP_CONFIGURABLE)) { + flags |= JS_PROP_ENUMERABLE | JS_PROP_WRITABLE | def_flags | + JS_PROP_HAS_CONFIGURABLE | JS_PROP_HAS_WRITABLE | JS_PROP_HAS_ENUMERABLE; + } + if (JS_DefineProperty(ctx, ctx->global_obj, prop, func, + JS_UNDEFINED, JS_UNDEFINED, flags) < 0) + return -1; + return 0; +} + +static JSValue JS_GetGlobalVar(JSContext *ctx, JSAtom prop, + bool throw_ref_error) +{ + JSObject *p; + JSShapeProperty *prs; + JSProperty *pr; + + /* no exotic behavior is possible in global_var_obj */ + p = JS_VALUE_GET_OBJ(ctx->global_var_obj); + prs = find_own_property(&pr, p, prop); + if (prs) { + /* XXX: should handle JS_PROP_TMASK properties */ + if (unlikely(JS_IsUninitialized(pr->u.value))) + return JS_ThrowReferenceErrorUninitialized(ctx, prs->atom); + return js_dup(pr->u.value); + } + + /* fast path */ + p = JS_VALUE_GET_OBJ(ctx->global_obj); + prs = find_own_property(&pr, p, prop); + if (prs) { + if (likely((prs->flags & JS_PROP_TMASK) == 0)) + return js_dup(pr->u.value); + } + return JS_GetPropertyInternal(ctx, ctx->global_obj, prop, + ctx->global_obj, throw_ref_error); +} + +/* construct a reference to a global variable */ +static int JS_GetGlobalVarRef(JSContext *ctx, JSAtom prop, JSValue *sp) +{ + JSObject *p; + JSShapeProperty *prs; + JSProperty *pr; + + /* no exotic behavior is possible in global_var_obj */ + p = JS_VALUE_GET_OBJ(ctx->global_var_obj); + prs = find_own_property(&pr, p, prop); + if (prs) { + /* XXX: should handle JS_PROP_AUTOINIT properties? */ + /* XXX: conformance: do these tests in + OP_put_var_ref/OP_get_var_ref ? */ + if (unlikely(JS_IsUninitialized(pr->u.value))) { + JS_ThrowReferenceErrorUninitialized(ctx, prs->atom); + return -1; + } + if (unlikely(!(prs->flags & JS_PROP_WRITABLE))) { + return JS_ThrowTypeErrorReadOnly(ctx, JS_PROP_THROW, prop); + } + sp[0] = js_dup(ctx->global_var_obj); + } else { + int ret; + ret = JS_HasProperty(ctx, ctx->global_obj, prop); + if (ret < 0) + return -1; + if (ret) { + sp[0] = js_dup(ctx->global_obj); + } else { + sp[0] = JS_UNDEFINED; + } + } + sp[1] = JS_AtomToValue(ctx, prop); + return 0; +} + +/* flag = 0: normal variable write + flag = 1: initialize lexical variable +*/ +static inline int JS_SetGlobalVar(JSContext *ctx, JSAtom prop, JSValue val, + int flag) +{ + JSObject *p; + JSShapeProperty *prs; + JSProperty *pr; + int ret; + + /* no exotic behavior is possible in global_var_obj */ + p = JS_VALUE_GET_OBJ(ctx->global_var_obj); + prs = find_own_property(&pr, p, prop); + if (prs) { + /* XXX: should handle JS_PROP_AUTOINIT properties? */ + if (flag != 1) { + if (unlikely(JS_IsUninitialized(pr->u.value))) { + JS_FreeValue(ctx, val); + JS_ThrowReferenceErrorUninitialized(ctx, prs->atom); + return -1; + } + if (unlikely(!(prs->flags & JS_PROP_WRITABLE))) { + JS_FreeValue(ctx, val); + return JS_ThrowTypeErrorReadOnly(ctx, JS_PROP_THROW, prop); + } + } + set_value(ctx, &pr->u.value, val); + return 0; + } + + p = JS_VALUE_GET_OBJ(ctx->global_obj); + prs = find_own_property(&pr, p, prop); + if (prs) { + if (likely((prs->flags & (JS_PROP_TMASK | JS_PROP_WRITABLE | + JS_PROP_LENGTH)) == JS_PROP_WRITABLE)) { + /* fast path */ + set_value(ctx, &pr->u.value, val); + return 0; + } + } + /* slow path */ + ret = JS_HasProperty(ctx, ctx->global_obj, prop); + if (ret < 0) { + JS_FreeValue(ctx, val); + return -1; + } + if (ret == 0 && is_strict_mode(ctx)) { + JS_FreeValue(ctx, val); + JS_ThrowReferenceErrorNotDefined(ctx, prop); + return -1; + } + return JS_SetPropertyInternal(ctx, ctx->global_obj, prop, val, + JS_PROP_THROW_STRICT); +} + +/* return -1, false or true */ +static int JS_DeleteGlobalVar(JSContext *ctx, JSAtom prop) +{ + JSProperty *pr; + JSObject *p; + + /* 9.1.1.4.7 DeleteBinding ( N ) */ + p = JS_VALUE_GET_OBJ(ctx->global_var_obj); + if (find_own_property(&pr, p, prop)) + return false; /* lexical variables cannot be deleted */ + p = JS_VALUE_GET_OBJ(ctx->global_obj); + return delete_property(ctx, p, prop); +} + +/* return -1, false or true. return false if not configurable or + invalid object. return -1 in case of exception. + flags can be 0, JS_PROP_THROW or JS_PROP_THROW_STRICT */ +int JS_DeleteProperty(JSContext *ctx, JSValueConst obj, JSAtom prop, int flags) +{ + JSValue obj1; + JSObject *p; + int res; + + obj1 = JS_ToObject(ctx, obj); + if (JS_IsException(obj1)) + return -1; + p = JS_VALUE_GET_OBJ(obj1); + res = delete_property(ctx, p, prop); + JS_FreeValue(ctx, obj1); + if (res != false) + return res; + if ((flags & JS_PROP_THROW) || + ((flags & JS_PROP_THROW_STRICT) && is_strict_mode(ctx))) { + JS_ThrowTypeError(ctx, "could not delete property"); + return -1; + } + return false; +} + +int JS_DeletePropertyInt64(JSContext *ctx, JSValueConst obj, int64_t idx, int flags) +{ + JSAtom prop; + int res; + + if ((uint64_t)idx <= JS_ATOM_MAX_INT) { + /* fast path for fast arrays */ + return JS_DeleteProperty(ctx, obj, __JS_AtomFromUInt32(idx), flags); + } + prop = JS_NewAtomInt64(ctx, idx); + if (prop == JS_ATOM_NULL) + return -1; + res = JS_DeleteProperty(ctx, obj, prop, flags); + JS_FreeAtom(ctx, prop); + return res; +} + +bool JS_IsFunction(JSContext *ctx, JSValueConst val) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) + return false; + p = JS_VALUE_GET_OBJ(val); + switch(p->class_id) { + case JS_CLASS_BYTECODE_FUNCTION: + return true; + case JS_CLASS_PROXY: + return p->u.proxy_data->is_func; + default: + return (ctx->rt->class_array[p->class_id].call != NULL); + } +} + +bool JS_IsAsyncFunction(JSValueConst val) +{ + return JS_CLASS_ASYNC_FUNCTION == JS_GetClassID(val); +} + +static bool JS_IsCFunction(JSContext *ctx, JSValueConst val, JSCFunction *func, + int magic) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) + return false; + p = JS_VALUE_GET_OBJ(val); + if (p->class_id == JS_CLASS_C_FUNCTION) + return (p->u.cfunc.c_function.generic == func && p->u.cfunc.magic == magic); + else + return false; +} + +bool JS_IsConstructor(JSContext *ctx, JSValueConst val) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) + return false; + p = JS_VALUE_GET_OBJ(val); + return p->is_constructor; +} + +bool JS_SetConstructorBit(JSContext *ctx, JSValueConst func_obj, bool val) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(func_obj) != JS_TAG_OBJECT) + return false; + p = JS_VALUE_GET_OBJ(func_obj); + p->is_constructor = val; + return true; +} + +bool JS_IsRegExp(JSValueConst val) +{ + return JS_CLASS_REGEXP == JS_GetClassID(val); +} + +bool JS_IsMap(JSValueConst val) +{ + return JS_CLASS_MAP == JS_GetClassID(val); +} + +bool JS_IsSet(JSValueConst val) +{ + return JS_CLASS_SET == JS_GetClassID(val); +} + +bool JS_IsWeakRef(JSValueConst val) +{ + return JS_CLASS_WEAK_REF == JS_GetClassID(val); +} + +bool JS_IsWeakSet(JSValueConst val) +{ + return JS_CLASS_WEAKSET == JS_GetClassID(val); +} + +bool JS_IsWeakMap(JSValueConst val) +{ + return JS_CLASS_WEAKMAP == JS_GetClassID(val); +} + +bool JS_IsDataView(JSValueConst val) +{ + return JS_CLASS_DATAVIEW == JS_GetClassID(val); +} + +bool JS_IsError(JSValueConst val) +{ + return JS_CLASS_ERROR == JS_GetClassID(val); +} + +/* used to avoid catching interrupt exceptions */ +bool JS_IsUncatchableError(JSValueConst val) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) + return false; + p = JS_VALUE_GET_OBJ(val); + return p->class_id == JS_CLASS_ERROR && p->is_uncatchable_error; +} + +static void js_set_uncatchable_error(JSValueConst val, bool flag) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) + return; + p = JS_VALUE_GET_OBJ(val); + if (p->class_id == JS_CLASS_ERROR) + p->is_uncatchable_error = flag; +} + +void JS_SetUncatchableError(JSContext *ctx, JSValueConst val) +{ + js_set_uncatchable_error(val, true); +} + +void JS_ClearUncatchableError(JSContext *ctx, JSValueConst val) +{ + js_set_uncatchable_error(val, false); +} + +void JS_ResetUncatchableError(JSContext *ctx) +{ + js_set_uncatchable_error(ctx->rt->current_exception, false); +} + +int JS_SetOpaque(JSValueConst obj, void *opaque) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { + p = JS_VALUE_GET_OBJ(obj); + // User code can't set the opaque of internal objects. + if (p->class_id >= JS_CLASS_INIT_COUNT) { + p->u.opaque = opaque; + return 0; + } + } + + return -1; +} + +/* |obj| must be a JSObject of an internal class. */ +static void JS_SetOpaqueInternal(JSValueConst obj, void *opaque) +{ + JSObject *p; + assert(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT); + p = JS_VALUE_GET_OBJ(obj); + assert(p->class_id < JS_CLASS_INIT_COUNT); + p->u.opaque = opaque; +} + +/* return NULL if not an object of class class_id */ +void *JS_GetOpaque(JSValueConst obj, JSClassID class_id) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) + return NULL; + p = JS_VALUE_GET_OBJ(obj); + if (p->class_id != class_id) + return NULL; + return p->u.opaque; +} + +void *JS_GetOpaque2(JSContext *ctx, JSValueConst obj, JSClassID class_id) +{ + void *p = JS_GetOpaque(obj, class_id); + if (unlikely(!p)) { + JS_ThrowTypeErrorInvalidClass(ctx, class_id); + } + return p; +} + +void *JS_GetAnyOpaque(JSValueConst obj, JSClassID *class_id) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) { + *class_id = 0; + return NULL; + } + p = JS_VALUE_GET_OBJ(obj); + *class_id = p->class_id; + return p->u.opaque; +} + +static JSValue JS_ToPrimitiveFree(JSContext *ctx, JSValue val, int hint) +{ + int i; + bool force_ordinary; + + JSAtom method_name; + JSValue method, ret; + if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) + return val; + force_ordinary = hint & HINT_FORCE_ORDINARY; + hint &= ~HINT_FORCE_ORDINARY; + if (!force_ordinary) { + method = JS_GetProperty(ctx, val, JS_ATOM_Symbol_toPrimitive); + if (JS_IsException(method)) + goto exception; + /* ECMA says *If exoticToPrim is not undefined* but tests in + test262 use null as a non callable converter */ + if (!JS_IsUndefined(method) && !JS_IsNull(method)) { + JSAtom atom; + JSValue arg; + switch(hint) { + case HINT_STRING: + atom = JS_ATOM_string; + break; + case HINT_NUMBER: + atom = JS_ATOM_number; + break; + default: + case HINT_NONE: + atom = JS_ATOM_default; + break; + } + arg = JS_AtomToString(ctx, atom); + ret = JS_CallFree(ctx, method, val, 1, vc(&arg)); + JS_FreeValue(ctx, arg); + if (JS_IsException(ret)) + goto exception; + JS_FreeValue(ctx, val); + if (JS_VALUE_GET_TAG(ret) != JS_TAG_OBJECT) + return ret; + JS_FreeValue(ctx, ret); + return JS_ThrowTypeError(ctx, "toPrimitive"); + } + } + if (hint != HINT_STRING) + hint = HINT_NUMBER; + for(i = 0; i < 2; i++) { + if ((i ^ hint) == 0) { + method_name = JS_ATOM_toString; + } else { + method_name = JS_ATOM_valueOf; + } + method = JS_GetProperty(ctx, val, method_name); + if (JS_IsException(method)) + goto exception; + if (JS_IsFunction(ctx, method)) { + ret = JS_CallFree(ctx, method, val, 0, NULL); + if (JS_IsException(ret)) + goto exception; + if (JS_VALUE_GET_TAG(ret) != JS_TAG_OBJECT) { + JS_FreeValue(ctx, val); + return ret; + } + JS_FreeValue(ctx, ret); + } else { + JS_FreeValue(ctx, method); + } + } + JS_ThrowTypeError(ctx, "toPrimitive"); +exception: + JS_FreeValue(ctx, val); + return JS_EXCEPTION; +} + +static JSValue JS_ToPrimitive(JSContext *ctx, JSValueConst val, int hint) +{ + return JS_ToPrimitiveFree(ctx, js_dup(val), hint); +} + +void JS_SetIsHTMLDDA(JSContext *ctx, JSValueConst obj) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) + return; + p = JS_VALUE_GET_OBJ(obj); + p->is_HTMLDDA = true; +} + +static inline bool JS_IsHTMLDDA(JSContext *ctx, JSValueConst obj) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) + return false; + p = JS_VALUE_GET_OBJ(obj); + return p->is_HTMLDDA; +} + +static int JS_ToBoolFree(JSContext *ctx, JSValue val) +{ + uint32_t tag = JS_VALUE_GET_TAG(val); + switch(tag) { + case JS_TAG_INT: + return JS_VALUE_GET_INT(val) != 0; + case JS_TAG_BOOL: + case JS_TAG_NULL: + case JS_TAG_UNDEFINED: + return JS_VALUE_GET_INT(val); + case JS_TAG_EXCEPTION: + return -1; + case JS_TAG_STRING: + { + bool ret = JS_VALUE_GET_STRING(val)->len != 0; + JS_FreeValue(ctx, val); + return ret; + } + case JS_TAG_STRING_ROPE: + { + bool ret = JS_VALUE_GET_STRING_ROPE(val)->len != 0; + JS_FreeValue(ctx, val); + return ret; + } + case JS_TAG_SHORT_BIG_INT: + return JS_VALUE_GET_SHORT_BIG_INT(val) != 0; + case JS_TAG_BIG_INT: + { + JSBigInt *p = JS_VALUE_GET_PTR(val); + bool ret; + int i; + + /* fail safe: we assume it is not necessarily + normalized. Beginning from the MSB ensures that the + test is fast. */ + ret = false; + for(i = p->len - 1; i >= 0; i--) { + if (p->tab[i] != 0) { + ret = true; + break; + } + } + JS_FreeValue(ctx, val); + return ret; + } + case JS_TAG_OBJECT: + { + JSObject *p = JS_VALUE_GET_OBJ(val); + bool ret = !p->is_HTMLDDA; + JS_FreeValue(ctx, val); + return ret; + } + break; + default: + if (JS_TAG_IS_FLOAT64(tag)) { + double d = JS_VALUE_GET_FLOAT64(val); + return !isnan(d) && d != 0; + } else { + JS_FreeValue(ctx, val); + return true; + } + } +} + +int JS_ToBool(JSContext *ctx, JSValueConst val) +{ + return JS_ToBoolFree(ctx, js_dup(val)); +} + +/* pc points to pure ASCII or UTF-8, null terminated contents */ +static int skip_spaces(const char *pc) +{ + const uint8_t *p, *p_next, *p_start; + uint32_t c; + + p = p_start = (const uint8_t *)pc; + for (;;) { + c = *p++; + if (c < 0x80) { + if (!((c >= 0x09 && c <= 0x0d) || (c == 0x20))) + break; + } else { + c = utf8_decode(p - 1, &p_next); + /* no need to test for invalid UTF-8, 0xFFFD is not a space */ + if (!lre_is_space(c)) + break; + p = p_next; + } + } + return p - 1 - p_start; +} + +static inline int js_to_digit(int c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + else if (c >= 'A' && c <= 'Z') + return c - 'A' + 10; + else if (c >= 'a' && c <= 'z') + return c - 'a' + 10; + else + return 36; +} + +/* bigint support */ + +#define ADDC(res, carry_out, op1, op2, carry_in) \ +do { \ + js_limb_t __v, __a, __k, __k1; \ + __v = (op1); \ + __a = __v + (op2); \ + __k1 = __a < __v; \ + __k = (carry_in); \ + __a = __a + __k; \ + carry_out = (__a < __k) | __k1; \ + res = __a; \ +} while (0) + +/* a != 0 */ +static inline js_limb_t js_limb_clz(js_limb_t a) +{ + if (!a) + return JS_LIMB_BITS; + return clz32(a); +} + +static js_limb_t js_mp_add(js_limb_t *res, const js_limb_t *op1, const js_limb_t *op2, + js_limb_t n, js_limb_t carry) +{ + int i; + for(i = 0;i < n; i++) { + ADDC(res[i], carry, op1[i], op2[i], carry); + } + return carry; +} + +static js_limb_t js_mp_sub(js_limb_t *res, const js_limb_t *op1, const js_limb_t *op2, + int n, js_limb_t carry) +{ + int i; + js_limb_t k, a, v, k1; + + k = carry; + for(i=0;i v; + v = a - k; + k = (v > a) | k1; + res[i] = v; + } + return k; +} + +/* compute 0 - op2. carry = 0 or 1. */ +static js_limb_t js_mp_neg(js_limb_t *res, const js_limb_t *op2, int n) +{ + int i; + js_limb_t v, carry; + + carry = 1; + for(i=0;i> JS_LIMB_BITS; + } + return l; +} + +static js_limb_t js_mp_div1(js_limb_t *tabr, const js_limb_t *taba, js_limb_t n, + js_limb_t b, js_limb_t r) +{ + js_slimb_t i; + js_dlimb_t a1; + for(i = n - 1; i >= 0; i--) { + a1 = ((js_dlimb_t)r << JS_LIMB_BITS) | taba[i]; + tabr[i] = a1 / b; + r = a1 % b; + } + return r; +} + +/* tabr[] += taba[] * b, return the high word. */ +static js_limb_t js_mp_add_mul1(js_limb_t *tabr, const js_limb_t *taba, js_limb_t n, + js_limb_t b) +{ + js_limb_t i, l; + js_dlimb_t t; + + l = 0; + for(i = 0; i < n; i++) { + t = (js_dlimb_t)taba[i] * (js_dlimb_t)b + l + tabr[i]; + tabr[i] = t; + l = t >> JS_LIMB_BITS; + } + return l; +} + +/* size of the result : op1_size + op2_size. */ +static void js_mp_mul_basecase(js_limb_t *result, + const js_limb_t *op1, js_limb_t op1_size, + const js_limb_t *op2, js_limb_t op2_size) +{ + int i; + js_limb_t r; + + result[op1_size] = js_mp_mul1(result, op1, op1_size, op2[0], 0); + for(i=1;i> JS_LIMB_BITS); + } + return l; +} + +/* WARNING: d must be >= 2^(JS_LIMB_BITS-1) */ +static inline js_limb_t js_udiv1norm_init(js_limb_t d) +{ + js_limb_t a0, a1; + a1 = -d - 1; + a0 = -1; + return (((js_dlimb_t)a1 << JS_LIMB_BITS) | a0) / d; +} + +/* return the quotient and the remainder in '*pr'of 'a1*2^JS_LIMB_BITS+a0 + / d' with 0 <= a1 < d. */ +static inline js_limb_t js_udiv1norm(js_limb_t *pr, js_limb_t a1, js_limb_t a0, + js_limb_t d, js_limb_t d_inv) +{ + js_limb_t n1m, n_adj, q, r, ah; + js_dlimb_t a; + n1m = ((js_slimb_t)a0 >> (JS_LIMB_BITS - 1)); + n_adj = a0 + (n1m & d); + a = (js_dlimb_t)d_inv * (a1 - n1m) + n_adj; + q = (a >> JS_LIMB_BITS) + a1; + /* compute a - q * r and update q so that the remainder is\ + between 0 and d - 1 */ + a = ((js_dlimb_t)a1 << JS_LIMB_BITS) | a0; + a = a - (js_dlimb_t)q * d - d; + ah = a >> JS_LIMB_BITS; + q += 1 + ah; + r = (js_limb_t)a + (ah & d); + *pr = r; + return q; +} + +#define UDIV1NORM_THRESHOLD 3 + +/* b must be >= 1 << (JS_LIMB_BITS - 1) */ +static js_limb_t js_mp_div1norm(js_limb_t *tabr, const js_limb_t *taba, js_limb_t n, + js_limb_t b, js_limb_t r) +{ + js_slimb_t i; + + if (n >= UDIV1NORM_THRESHOLD) { + js_limb_t b_inv; + b_inv = js_udiv1norm_init(b); + for(i = n - 1; i >= 0; i--) { + tabr[i] = js_udiv1norm(&r, r, taba[i], b, b_inv); + } + } else { + js_dlimb_t a1; + for(i = n - 1; i >= 0; i--) { + a1 = ((js_dlimb_t)r << JS_LIMB_BITS) | taba[i]; + tabr[i] = a1 / b; + r = a1 % b; + } + } + return r; +} + +/* base case division: divides taba[0..na-1] by tabb[0..nb-1]. tabb[nb + - 1] must be >= 1 << (JS_LIMB_BITS - 1). na - nb must be >= 0. 'taba' + is modified and contains the remainder (nb limbs). tabq[0..na-nb] + contains the quotient with tabq[na - nb] <= 1. */ +static void js_mp_divnorm(js_limb_t *tabq, js_limb_t *taba, js_limb_t na, + const js_limb_t *tabb, js_limb_t nb) +{ + js_limb_t r, a, c, q, v, b1, b1_inv, n, dummy_r; + int i, j; + + b1 = tabb[nb - 1]; + if (nb == 1) { + taba[0] = js_mp_div1norm(tabq, taba, na, b1, 0); + return; + } + n = na - nb; + + if (n >= UDIV1NORM_THRESHOLD) + b1_inv = js_udiv1norm_init(b1); + else + b1_inv = 0; + + /* first iteration: the quotient is only 0 or 1 */ + q = 1; + for(j = nb - 1; j >= 0; j--) { + if (taba[n + j] != tabb[j]) { + if (taba[n + j] < tabb[j]) + q = 0; + break; + } + } + tabq[n] = q; + if (q) { + js_mp_sub(taba + n, taba + n, tabb, nb, 0); + } + + for(i = n - 1; i >= 0; i--) { + if (unlikely(taba[i + nb] >= b1)) { + q = -1; + } else if (b1_inv) { + q = js_udiv1norm(&dummy_r, taba[i + nb], taba[i + nb - 1], b1, b1_inv); + } else { + js_dlimb_t al; + al = ((js_dlimb_t)taba[i + nb] << JS_LIMB_BITS) | taba[i + nb - 1]; + q = al / b1; + r = al % b1; + } + r = js_mp_sub_mul1(taba + i, tabb, nb, q); + + v = taba[i + nb]; + a = v - r; + c = (a > v); + taba[i + nb] = a; + + if (c != 0) { + /* negative result */ + for(;;) { + q--; + c = js_mp_add(taba + i, taba + i, tabb, nb, 0); + /* propagate carry and test if positive result */ + if (c != 0) { + if (++taba[i + nb] == 0) { + break; + } + } + } + } + tabq[i] = q; + } +} + +/* 1 <= shift <= JS_LIMB_BITS - 1 */ +static js_limb_t js_mp_shl(js_limb_t *tabr, const js_limb_t *taba, int n, + int shift) +{ + int i; + js_limb_t l, v; + l = 0; + for(i = 0; i < n; i++) { + v = taba[i]; + tabr[i] = (v << shift) | l; + l = v >> (JS_LIMB_BITS - shift); + } + return l; +} + +/* r = (a + high*B^n) >> shift. Return the remainder r (0 <= r < 2^shift). + 1 <= shift <= LIMB_BITS - 1 */ +static js_limb_t js_mp_shr(js_limb_t *tab_r, const js_limb_t *tab, int n, + int shift, js_limb_t high) +{ + int i; + js_limb_t l, a; + + l = high; + for(i = n - 1; i >= 0; i--) { + a = tab[i]; + tab_r[i] = (a >> shift) | (l << (JS_LIMB_BITS - shift)); + l = a; + } + return l & (((js_limb_t)1 << shift) - 1); +} + +static JSBigInt *js_bigint_new(JSContext *ctx, int len) +{ + JSBigInt *r; + if (len > JS_BIGINT_MAX_SIZE) { + JS_ThrowRangeError(ctx, "BigInt is too large to allocate"); + return NULL; + } + r = js_malloc(ctx, sizeof(JSBigInt) + len * sizeof(js_limb_t)); + if (!r) + return NULL; + JS_REF_COUNT(r) = 1; + r->len = len; + return r; +} + +static JSBigInt *js_bigint_set_si(JSBigIntBuf *buf, js_slimb_t a) +{ + JSBigInt *r = (JSBigInt *)buf->big_int_buf; + /* r points into a stack JSBigIntBuf, not an arena block, so it has no + block-header ref_count slot; this temp is never refcounted/freed. */ + r->len = 1; + r->tab[0] = a; + return r; +} + +static JSBigInt *js_bigint_set_si64(JSBigIntBuf *buf, int64_t a) +{ + JSBigInt *r = (JSBigInt *)buf->big_int_buf; + /* stack JSBigIntBuf: no block-header ref_count slot (see js_bigint_set_si) */ + if (a >= INT32_MIN && a <= INT32_MAX) { + r->len = 1; + r->tab[0] = a; + } else { + r->len = 2; + r->tab[0] = a; + r->tab[1] = a >> JS_LIMB_BITS; + } + return r; +} + +/* val must be a short big int */ +static JSBigInt *js_bigint_set_short(JSBigIntBuf *buf, JSValueConst val) +{ + return js_bigint_set_si(buf, JS_VALUE_GET_SHORT_BIG_INT(val)); +} + +static __maybe_unused void js_bigint_dump1(JSContext *ctx, const char *str, + const js_limb_t *tab, int len) +{ + int i; + printf("%s: ", str); + for(i = len - 1; i >= 0; i--) { + printf(" %08x", tab[i]); + } + printf("\n"); +} + +static __maybe_unused void js_bigint_dump(JSContext *ctx, const char *str, + const JSBigInt *p) +{ + js_bigint_dump1(ctx, str, p->tab, p->len); +} + +static JSBigInt *js_bigint_new_si(JSContext *ctx, js_slimb_t a) +{ + JSBigInt *r; + r = js_bigint_new(ctx, 1); + if (!r) + return NULL; + r->tab[0] = a; + return r; +} + +static JSBigInt *js_bigint_new_si64(JSContext *ctx, int64_t a) +{ + if (a >= INT32_MIN && a <= INT32_MAX) { + return js_bigint_new_si(ctx, a); + } else { + JSBigInt *r; + r = js_bigint_new(ctx, 2); + if (!r) + return NULL; + r->tab[0] = a; + r->tab[1] = a >> 32; + return r; + } +} + +static JSBigInt *js_bigint_new_ui64(JSContext *ctx, uint64_t a) +{ + if (a <= INT64_MAX) { + return js_bigint_new_si64(ctx, a); + } else { + JSBigInt *r; + r = js_bigint_new(ctx, (65 + JS_LIMB_BITS - 1) / JS_LIMB_BITS); + if (!r) + return NULL; + r->tab[0] = a; + r->tab[1] = a >> 32; + r->tab[2] = 0; + return r; + } +} + +static JSBigInt *js_bigint_new_di(JSContext *ctx, js_sdlimb_t a) +{ + JSBigInt *r; + if (a == (js_slimb_t)a) { + r = js_bigint_new(ctx, 1); + if (!r) + return NULL; + r->tab[0] = a; + } else { + r = js_bigint_new(ctx, 2); + if (!r) + return NULL; + r->tab[0] = a; + r->tab[1] = a >> JS_LIMB_BITS; + } + return r; +} + +/* Remove redundant high order limbs. Warning: 'a' may be + reallocated. Can never fail. +*/ +static JSBigInt *js_bigint_normalize1(JSContext *ctx, JSBigInt *a, int l) +{ + js_limb_t v; + + assert(JS_REF_COUNT(a) == 1); + while (l > 1) { + v = a->tab[l - 1]; + if ((v != 0 && v != -1) || + (v & 1) != (a->tab[l - 2] >> (JS_LIMB_BITS - 1))) { + break; + } + l--; + } + if (l != a->len) { + JSBigInt *a1; + /* realloc to reduce the size */ + a->len = l; + a1 = js_realloc(ctx, a, sizeof(JSBigInt) + l * sizeof(js_limb_t)); + if (a1) + a = a1; + } + return a; +} + +static JSBigInt *js_bigint_normalize(JSContext *ctx, JSBigInt *a) +{ + return js_bigint_normalize1(ctx, a, a->len); +} + +/* return 0 or 1 depending on the sign */ +static inline int js_bigint_sign(const JSBigInt *a) +{ + return a->tab[a->len - 1] >> (JS_LIMB_BITS - 1); +} + +static js_slimb_t js_bigint_get_si_sat(const JSBigInt *a) +{ + if (a->len == 1) { + return a->tab[0]; + } else { + if (js_bigint_sign(a)) + return INT32_MIN; + else + return INT32_MAX; + } +} + +/* add the op1 limb */ +static JSBigInt *js_bigint_extend(JSContext *ctx, JSBigInt *r, + js_limb_t op1) +{ + int n2 = r->len; + if ((op1 != 0 && op1 != -1) || + (op1 & 1) != r->tab[n2 - 1] >> (JS_LIMB_BITS - 1)) { + JSBigInt *r1; + r1 = js_realloc(ctx, r, + sizeof(JSBigInt) + (n2 + 1) * sizeof(js_limb_t)); + if (!r1) { + js_free(ctx, r); + return NULL; + } + r = r1; + r->len = n2 + 1; + r->tab[n2] = op1; + } else { + /* otherwise still need to normalize the result */ + r = js_bigint_normalize(ctx, r); + } + return r; +} + +/* return NULL in case of error. Compute a + b (b_neg = 0) or a - b + (b_neg = 1) */ +/* XXX: optimize */ +static JSBigInt *js_bigint_add(JSContext *ctx, const JSBigInt *a, + const JSBigInt *b, int b_neg) +{ + JSBigInt *r; + int n1, n2, i; + js_limb_t carry, op1, op2, a_sign, b_sign; + + n2 = max_int(a->len, b->len); + n1 = min_int(a->len, b->len); + r = js_bigint_new(ctx, n2); + if (!r) + return NULL; + /* XXX: optimize */ + /* common part */ + carry = b_neg; + for(i = 0; i < n1; i++) { + op1 = a->tab[i]; + op2 = b->tab[i] ^ (-b_neg); + ADDC(r->tab[i], carry, op1, op2, carry); + } + a_sign = -js_bigint_sign(a); + b_sign = (-js_bigint_sign(b)) ^ (-b_neg); + /* part with sign extension of one operand */ + if (a->len > b->len) { + for(i = n1; i < n2; i++) { + op1 = a->tab[i]; + ADDC(r->tab[i], carry, op1, b_sign, carry); + } + } else if (a->len < b->len) { + for(i = n1; i < n2; i++) { + op2 = b->tab[i] ^ (-b_neg); + ADDC(r->tab[i], carry, a_sign, op2, carry); + } + } + + /* part with sign extension for both operands. Extend the result + if necessary */ + return js_bigint_extend(ctx, r, a_sign + b_sign + carry); +} + +/* XXX: optimize */ +static JSBigInt *js_bigint_neg(JSContext *ctx, const JSBigInt *a) +{ + JSBigIntBuf buf; + JSBigInt *b; + b = js_bigint_set_si(&buf, 0); + return js_bigint_add(ctx, b, a, 1); +} + +static JSBigInt *js_bigint_mul(JSContext *ctx, const JSBigInt *a, + const JSBigInt *b) +{ + JSBigInt *r; + + r = js_bigint_new(ctx, a->len + b->len); + if (!r) + return NULL; + js_mp_mul_basecase(r->tab, a->tab, a->len, b->tab, b->len); + /* correct the result if negative operands (no overflow is + possible) */ + if (js_bigint_sign(a)) + js_mp_sub(r->tab + a->len, r->tab + a->len, b->tab, b->len, 0); + if (js_bigint_sign(b)) + js_mp_sub(r->tab + b->len, r->tab + b->len, a->tab, a->len, 0); + return js_bigint_normalize(ctx, r); +} + +/* return the division or the remainder. 'b' must be != 0. return NULL + in case of exception (division by zero or memory error) */ +static JSBigInt *js_bigint_divrem(JSContext *ctx, const JSBigInt *a, + const JSBigInt *b, bool is_rem) +{ + JSBigInt *r, *q; + js_limb_t *tabb, h; + int na, nb, a_sign, b_sign, shift; + + if (b->len == 1 && b->tab[0] == 0) { + JS_ThrowRangeError(ctx, "BigInt division by zero"); + return NULL; + } + + a_sign = js_bigint_sign(a); + b_sign = js_bigint_sign(b); + na = a->len; + nb = b->len; + + r = js_bigint_new(ctx, na + 2); + if (!r) + return NULL; + if (a_sign) { + js_mp_neg(r->tab, a->tab, na); + } else { + memcpy(r->tab, a->tab, na * sizeof(a->tab[0])); + } + /* normalize */ + while (na > 1 && r->tab[na - 1] == 0) + na--; + + tabb = js_malloc(ctx, nb * sizeof(tabb[0])); + if (!tabb) { + js_free(ctx, r); + return NULL; + } + if (b_sign) { + js_mp_neg(tabb, b->tab, nb); + } else { + memcpy(tabb, b->tab, nb * sizeof(tabb[0])); + } + /* normalize */ + while (nb > 1 && tabb[nb - 1] == 0) + nb--; + + /* trivial case if 'a' is small */ + if (na < nb) { + js_free(ctx, r); + js_free(ctx, tabb); + if (is_rem) { + /* r = a */ + r = js_bigint_new(ctx, a->len); + if (!r) + return NULL; + memcpy(r->tab, a->tab, a->len * sizeof(a->tab[0])); + return r; + } else { + /* q = 0 */ + return js_bigint_new_si(ctx, 0); + } + } + + /* normalize 'b' */ + shift = js_limb_clz(tabb[nb - 1]); + if (shift != 0) { + js_mp_shl(tabb, tabb, nb, shift); + h = js_mp_shl(r->tab, r->tab, na, shift); + if (h != 0) + r->tab[na++] = h; + } + + q = js_bigint_new(ctx, na - nb + 2); /* one more limb for the sign */ + if (!q) { + js_free(ctx, r); + js_free(ctx, tabb); + return NULL; + } + + // js_bigint_dump1(ctx, "a", r->tab, na); + // js_bigint_dump1(ctx, "b", tabb, nb); + js_mp_divnorm(q->tab, r->tab, na, tabb, nb); + js_free(ctx, tabb); + + if (is_rem) { + js_free(ctx, q); + if (shift != 0) + js_mp_shr(r->tab, r->tab, nb, shift, 0); + r->tab[nb++] = 0; + if (a_sign) + js_mp_neg(r->tab, r->tab, nb); + r = js_bigint_normalize1(ctx, r, nb); + return r; + } else { + js_free(ctx, r); + q->tab[na - nb + 1] = 0; + if (a_sign ^ b_sign) { + js_mp_neg(q->tab, q->tab, q->len); + } + q = js_bigint_normalize(ctx, q); + return q; + } +} + +/* and, or, xor */ +static JSBigInt *js_bigint_logic(JSContext *ctx, const JSBigInt *a, + const JSBigInt *b, OPCodeEnum op) +{ + JSBigInt *r; + js_limb_t b_sign; + int a_len, b_len, i; + + if (a->len < b->len) { + const JSBigInt *tmp; + tmp = a; + a = b; + b = tmp; + } + /* a_len >= b_len */ + a_len = a->len; + b_len = b->len; + b_sign = -js_bigint_sign(b); + + r = js_bigint_new(ctx, a_len); + if (!r) + return NULL; + switch(op) { + case OP_or: + for(i = 0; i < b_len; i++) { + r->tab[i] = a->tab[i] | b->tab[i]; + } + for(i = b_len; i < a_len; i++) { + r->tab[i] = a->tab[i] | b_sign; + } + break; + case OP_and: + for(i = 0; i < b_len; i++) { + r->tab[i] = a->tab[i] & b->tab[i]; + } + for(i = b_len; i < a_len; i++) { + r->tab[i] = a->tab[i] & b_sign; + } + break; + case OP_xor: + for(i = 0; i < b_len; i++) { + r->tab[i] = a->tab[i] ^ b->tab[i]; + } + for(i = b_len; i < a_len; i++) { + r->tab[i] = a->tab[i] ^ b_sign; + } + break; + default: + abort(); + } + return js_bigint_normalize(ctx, r); +} + +static JSBigInt *js_bigint_not(JSContext *ctx, const JSBigInt *a) +{ + JSBigInt *r; + int i; + + r = js_bigint_new(ctx, a->len); + if (!r) + return NULL; + for(i = 0; i < a->len; i++) { + r->tab[i] = ~a->tab[i]; + } + /* no normalization is needed */ + return r; +} + +static JSBigInt *js_bigint_shl(JSContext *ctx, const JSBigInt *a, + unsigned int shift1) +{ + int d, i, shift; + JSBigInt *r; + js_limb_t l; + + if (a->len == 1 && a->tab[0] == 0) + return js_bigint_new_si(ctx, 0); /* zero case */ + d = shift1 / JS_LIMB_BITS; + shift = shift1 % JS_LIMB_BITS; + r = js_bigint_new(ctx, a->len + d); + if (!r) + return NULL; + for(i = 0; i < d; i++) + r->tab[i] = 0; + if (shift == 0) { + for(i = 0; i < a->len; i++) { + r->tab[i + d] = a->tab[i]; + } + } else { + l = js_mp_shl(r->tab + d, a->tab, a->len, shift); + if (js_bigint_sign(a)) + l |= (js_limb_t)(-1) << shift; + r = js_bigint_extend(ctx, r, l); + } + return r; +} + +static JSBigInt *js_bigint_shr(JSContext *ctx, const JSBigInt *a, + unsigned int shift1) +{ + int d, i, shift, a_sign, n1; + JSBigInt *r; + + d = shift1 / JS_LIMB_BITS; + shift = shift1 % JS_LIMB_BITS; + a_sign = js_bigint_sign(a); + if (d >= a->len) + return js_bigint_new_si(ctx, -a_sign); + n1 = a->len - d; + r = js_bigint_new(ctx, n1); + if (!r) + return NULL; + if (shift == 0) { + for(i = 0; i < n1; i++) { + r->tab[i] = a->tab[i + d]; + } + /* no normalization is needed */ + } else { + js_mp_shr(r->tab, a->tab + d, n1, shift, -a_sign); + r = js_bigint_normalize(ctx, r); + } + return r; +} + +static JSBigInt *js_bigint_pow(JSContext *ctx, const JSBigInt *a, JSBigInt *b) +{ + uint32_t e; + int n_bits, i; + JSBigInt *r, *r1; + + /* b must be >= 0 */ + if (js_bigint_sign(b)) { + JS_ThrowRangeError(ctx, "BigInt negative exponent"); + return NULL; + } + if (b->len == 1 && b->tab[0] == 0) { + /* a^0 = 1 */ + return js_bigint_new_si(ctx, 1); + } else if (a->len == 1) { + js_limb_t v; + bool is_neg; + + v = a->tab[0]; + if (v <= 1) + return js_bigint_new_si(ctx, v); + else if (v == -1) + return js_bigint_new_si(ctx, 1 - 2 * (b->tab[0] & 1)); + is_neg = (js_slimb_t)v < 0; + if (is_neg) + v = -v; + if ((v & (v - 1)) == 0) { + uint64_t e1; + int n; + /* v = 2^n */ + n = JS_LIMB_BITS - 1 - js_limb_clz(v); + if (b->len > 1) + goto overflow; + if (b->tab[0] > INT32_MAX) + goto overflow; + e = b->tab[0]; + e1 = (uint64_t)e * n; + if (e1 > JS_BIGINT_MAX_SIZE * JS_LIMB_BITS) + goto overflow; + e = e1; + if (is_neg) + is_neg = b->tab[0] & 1; + r = js_bigint_new(ctx, + (e + JS_LIMB_BITS + 1 - is_neg) / JS_LIMB_BITS); + if (!r) + return NULL; + memset(r->tab, 0, sizeof(r->tab[0]) * r->len); + r->tab[e / JS_LIMB_BITS] = + (js_limb_t)(1 - 2 * is_neg) << (e % JS_LIMB_BITS); + return r; + } + } + if (b->len > 1) + goto overflow; + if (b->tab[0] > INT32_MAX) + goto overflow; + e = b->tab[0]; + n_bits = 32 - clz32(e); + + r = js_bigint_new(ctx, a->len); + if (!r) + return NULL; + memcpy(r->tab, a->tab, a->len * sizeof(a->tab[0])); + for(i = n_bits - 2; i >= 0; i--) { + r1 = js_bigint_mul(ctx, r, r); + if (!r1) + return NULL; + js_free(ctx, r); + r = r1; + if ((e >> i) & 1) { + r1 = js_bigint_mul(ctx, r, a); + if (!r1) + return NULL; + js_free(ctx, r); + r = r1; + } + } + return r; + overflow: + JS_ThrowRangeError(ctx, "BigInt is too large"); + return NULL; +} + +/* return (mant, exp) so that abs(a) ~ mant*2^(exp - (limb_bits - + 1). a must be != 0. */ +static uint64_t js_bigint_get_mant_exp(JSContext *ctx, + int *pexp, const JSBigInt *a) +{ + js_limb_t t[4 - JS_LIMB_BITS / 32], carry, v, low_bits; + int n1, n2, sgn, shift, i, j, e; + uint64_t a1, a0; + + n2 = 4 - JS_LIMB_BITS / 32; + n1 = a->len - n2; + sgn = js_bigint_sign(a); + + /* low_bits != 0 if there are a non zero low bit in abs(a) */ + low_bits = 0; + carry = sgn; + for(i = 0; i < n1; i++) { + v = (a->tab[i] ^ (-sgn)) + carry; + carry = v < carry; + low_bits |= v; + } + /* get the n2 high limbs of abs(a) */ + for(j = 0; j < n2; j++) { + i = j + n1; + if (i < 0) { + v = 0; + } else { + v = (a->tab[i] ^ (-sgn)) + carry; + carry = v < carry; + } + t[j] = v; + } + + a1 = ((uint64_t)t[2] << 32) | t[1]; + a0 = (uint64_t)t[0] << 32; + a0 |= (low_bits != 0); + /* normalize */ + { + shift = clz64(a1); + if (shift != 0) { + a1 = (a1 << shift) | (a0 >> (64 - shift)); + a0 <<= shift; + } + } + a1 |= (a0 != 0); /* keep the bits for the final rounding */ + /* compute the exponent */ + e = a->len * JS_LIMB_BITS - shift - 1; + *pexp = e; + return a1; +} + +/* shift left with round to nearest, ties to even. n >= 1 */ +static uint64_t shr_rndn(uint64_t a, int n) +{ + uint64_t addend = ((a >> n) & 1) + ((1 << (n - 1)) - 1); + return (a + addend) >> n; +} + +/* convert to float64 with round to nearest, ties to even. Return + +/-infinity if too large. */ +static double js_bigint_to_float64(JSContext *ctx, const JSBigInt *a) +{ + int sgn, e; + uint64_t mant; + + if (a->len == 1) { + /* fast case, including zero */ + return (double)(js_slimb_t)a->tab[0]; + } + + sgn = js_bigint_sign(a); + mant = js_bigint_get_mant_exp(ctx, &e, a); + if (e > 1023) { + /* overflow: return infinity */ + mant = 0; + e = 1024; + } else { + mant = (mant >> 1) | (mant & 1); /* avoid overflow in rounding */ + mant = shr_rndn(mant, 10); + /* rounding can cause an overflow */ + if (mant >= ((uint64_t)1 << 53)) { + mant >>= 1; + e++; + } + mant &= (((uint64_t)1 << 52) - 1); + } + return uint64_as_float64(((uint64_t)sgn << 63) | + ((uint64_t)(e + 1023) << 52) | + mant); +} + +/* return (1, NULL) if not an integer, (2, NULL) if NaN or Infinity, + (0, n) if an integer, (0, NULL) in case of memory error */ +static JSBigInt *js_bigint_from_float64(JSContext *ctx, int *pres, double a1) +{ + uint64_t a = float64_as_uint64(a1); + int sgn, e, shift; + uint64_t mant; + JSBigIntBuf buf; + JSBigInt *r; + + sgn = a >> 63; + e = (a >> 52) & ((1 << 11) - 1); + mant = a & (((uint64_t)1 << 52) - 1); + if (e == 2047) { + /* NaN, Infinity */ + *pres = 2; + return NULL; + } + if (e == 0 && mant == 0) { + /* zero */ + *pres = 0; + return js_bigint_new_si(ctx, 0); + } + e -= 1023; + /* 0 < a < 1 : not an integer */ + if (e < 0) + goto not_an_integer; + mant |= (uint64_t)1 << 52; + if (e < 52) { + shift = 52 - e; + /* check that there is no fractional part */ + if (mant & (((uint64_t)1 << shift) - 1)) { + not_an_integer: + *pres = 1; + return NULL; + } + mant >>= shift; + e = 0; + } else { + e -= 52; + } + if (sgn) + mant = -mant; + /* the integer is mant*2^e */ + r = js_bigint_set_si64(&buf, (int64_t)mant); + *pres = 0; + return js_bigint_shl(ctx, r, e); +} + +/* return -1, 0, 1 or (2) (unordered) */ +static int js_bigint_float64_cmp(JSContext *ctx, const JSBigInt *a, + double b) +{ + int b_sign, a_sign, e, f; + uint64_t mant, b1, a_mant; + + b1 = float64_as_uint64(b); + b_sign = b1 >> 63; + e = (b1 >> 52) & ((1 << 11) - 1); + mant = b1 & (((uint64_t)1 << 52) - 1); + a_sign = js_bigint_sign(a); + if (e == 2047) { + if (mant != 0) { + /* NaN */ + return 2; + } else { + /* +/- infinity */ + return 2 * b_sign - 1; + } + } else if (e == 0 && mant == 0) { + /* b = +/-0 */ + if (a->len == 1 && a->tab[0] == 0) + return 0; + else + return 1 - 2 * a_sign; + } else if (a->len == 1 && a->tab[0] == 0) { + /* a = 0, b != 0 */ + return 2 * b_sign - 1; + } else if (a_sign != b_sign) { + return 1 - 2 * a_sign; + } else { + e -= 1023; + /* Note: handling denormals is not necessary because we + compare to integers hence f >= 0 */ + /* compute f so that 2^f <= abs(a) < 2^(f+1) */ + a_mant = js_bigint_get_mant_exp(ctx, &f, a); + if (f != e) { + if (f < e) + return -1; + else + return 1; + } else { + mant = (mant | ((uint64_t)1 << 52)) << 11; /* align to a_mant */ + if (a_mant < mant) + return 2 * a_sign - 1; + else if (a_mant > mant) + return 1 - 2 * a_sign; + else + return 0; + } + } +} + +/* return -1, 0 or 1 */ +static int js_bigint_cmp(JSContext *ctx, const JSBigInt *a, + const JSBigInt *b) +{ + int a_sign, b_sign, res, i; + a_sign = js_bigint_sign(a); + b_sign = js_bigint_sign(b); + if (a_sign != b_sign) { + res = 1 - 2 * a_sign; + } else { + /* we assume the numbers are normalized */ + if (a->len != b->len) { + if (a->len < b->len) + res = 2 * a_sign - 1; + else + res = 1 - 2 * a_sign; + } else { + res = 0; + for(i = a->len -1; i >= 0; i--) { + if (a->tab[i] != b->tab[i]) { + if (a->tab[i] < b->tab[i]) + res = -1; + else + res = 1; + break; + } + } + } + } + return res; +} + +/* contains 10^i */ +static const js_limb_t js_pow_dec[JS_LIMB_DIGITS + 1] = { + 1U, + 10U, + 100U, + 1000U, + 10000U, + 100000U, + 1000000U, + 10000000U, + 100000000U, + 1000000000U, +}; + +/* syntax: [-]digits in base radix. Return NULL if memory error. radix + = 10, 2, 8 or 16. */ +static JSBigInt *js_bigint_from_string(JSContext *ctx, + const char *str, int radix) +{ + const char *p = str; + size_t n_digits1; + int is_neg, n_digits, n_limbs, len, log2_radix, n_bits, i; + JSBigInt *r; + js_limb_t v, c, h; + + is_neg = 0; + if (*p == '-') { + is_neg = 1; + p++; + } + while (*p == '0') + p++; + n_digits1 = strlen(p); + /* the real check for overflox is done js_bigint_new(). Here + we just avoid integer overflow */ + if (n_digits1 > JS_BIGINT_MAX_SIZE * JS_LIMB_BITS) { + JS_ThrowRangeError(ctx, "BigInt is too large to allocate"); + return NULL; + } + n_digits = n_digits1; + log2_radix = 32 - clz32(radix - 1); /* ceil(log2(radix)) */ + /* compute the maximum number of limbs */ + if (radix == 10) { + n_bits = (n_digits * 27 + 7) / 8; /* >= ceil(n_digits * log2(10)) */ + } else { + n_bits = n_digits * log2_radix; + } + /* we add one extra bit for the sign */ + n_limbs = max_int(1, n_bits / JS_LIMB_BITS + 1); + r = js_bigint_new(ctx, n_limbs); + if (!r) + return NULL; + if (radix == 10) { + int digits_per_limb = JS_LIMB_DIGITS; + len = 1; + r->tab[0] = 0; + for(;;) { + /* XXX: slow */ + v = 0; + for(i = 0; i < digits_per_limb; i++) { + c = js_to_digit(*p); + if (c >= radix) + break; + p++; + v = v * 10 + c; + } + if (i == 0) + break; + if (len == 1 && r->tab[0] == 0) { + r->tab[0] = v; + } else { + h = js_mp_mul1(r->tab, r->tab, len, js_pow_dec[i], v); + if (h != 0) { + r->tab[len++] = h; + } + } + } + /* add one extra limb to have the correct sign*/ + if ((r->tab[len - 1] >> (JS_LIMB_BITS - 1)) != 0) + r->tab[len++] = 0; + r->len = len; + } else { + unsigned int bit_pos, shift, pos; + + /* power of two base: no multiplication is needed */ + r->len = n_limbs; + memset(r->tab, 0, sizeof(r->tab[0]) * n_limbs); + for(i = 0; i < n_digits; i++) { + c = js_to_digit(p[n_digits - 1 - i]); + assert(c < radix); + bit_pos = i * log2_radix; + shift = bit_pos & (JS_LIMB_BITS - 1); + pos = bit_pos / JS_LIMB_BITS; + r->tab[pos] |= c << shift; + /* if log2_radix does not divide JS_LIMB_BITS, needed an + additional op */ + if (shift + log2_radix > JS_LIMB_BITS) { + r->tab[pos + 1] |= c >> (JS_LIMB_BITS - shift); + } + } + } + r = js_bigint_normalize(ctx, r); + /* XXX: could do it in place */ + if (is_neg) { + JSBigInt *r1; + r1 = js_bigint_neg(ctx, r); + js_free(ctx, r); + r = r1; + } + return r; +} + +/* 2 <= base <= 36 */ +static char const digits[36] = { + '0','1','2','3','4','5','6','7','8','9', + 'a','b','c','d','e','f','g','h','i','j', + 'k','l','m','n','o','p','q','r','s','t', + 'u','v','w','x','y','z' +}; + +/* special version going backwards */ +/* XXX: use dtoa.c */ +static char *js_u64toa(char *q, int64_t n, unsigned int base) +{ + int digit; + if (base == 10) { + /* division by known base uses multiplication */ + do { + digit = (uint64_t)n % 10; + n = (uint64_t)n / 10; + *--q = '0' + digit; + } while (n != 0); + } else { + do { + digit = (uint64_t)n % base; + n = (uint64_t)n / base; + *--q = digits[digit]; + } while (n != 0); + } + return q; +} + +/* len >= 1. 2 <= radix <= 36 */ +static char *js_limb_to_a(char *q, js_limb_t n, unsigned int radix, int len) +{ + int digit, i; + + if (radix == 10) { + /* specific case with constant divisor */ + /* XXX: optimize */ + for(i = 0; i < len; i++) { + digit = (js_limb_t)n % 10; + n = (js_limb_t)n / 10; + *--q = digit + '0'; + } + } else { + for(i = 0; i < len; i++) { + digit = (js_limb_t)n % radix; + n = (js_limb_t)n / radix; + *--q = digits[digit]; + } + } + return q; +} + +#define JS_RADIX_MAX 36 + +static const uint8_t js_digits_per_limb_table[JS_RADIX_MAX - 1] = { +32,20,16,13,12,11,10,10, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +}; + +static const js_limb_t js_radix_base_table[JS_RADIX_MAX - 1] = { + 0x00000000, 0xcfd41b91, 0x00000000, 0x48c27395, + 0x81bf1000, 0x75db9c97, 0x40000000, 0xcfd41b91, + 0x3b9aca00, 0x8c8b6d2b, 0x19a10000, 0x309f1021, + 0x57f6c100, 0x98c29b81, 0x00000000, 0x18754571, + 0x247dbc80, 0x3547667b, 0x4c4b4000, 0x6b5a6e1d, + 0x94ace180, 0xcaf18367, 0x0b640000, 0x0e8d4a51, + 0x1269ae40, 0x17179149, 0x1cb91000, 0x23744899, + 0x2b73a840, 0x34e63b41, 0x40000000, 0x4cfa3cc1, + 0x5c13d840, 0x6d91b519, 0x81bf1000, +}; + +static JSValue js_bigint_to_string1(JSContext *ctx, JSValueConst val, int radix) +{ + if (JS_VALUE_GET_TAG(val) == JS_TAG_SHORT_BIG_INT) { + char buf[66]; + int len; + len = i64toa_radix(buf, JS_VALUE_GET_SHORT_BIG_INT(val), radix); + return js_new_string8_len(ctx, buf, len); + } else { + JSBigInt *r, *tmp = NULL; + char *buf, *q, *buf_end; + int is_neg, n_bits, log2_radix, n_digits; + bool is_binary_radix; + JSValue res; + + assert(JS_VALUE_GET_TAG(val) == JS_TAG_BIG_INT); + r = JS_VALUE_GET_PTR(val); + if (r->len == 1 && r->tab[0] == 0) { + /* '0' case */ + return js_new_string8_len(ctx, "0", 1); + } + is_binary_radix = ((radix & (radix - 1)) == 0); + is_neg = js_bigint_sign(r); + if (is_neg) { + tmp = js_bigint_neg(ctx, r); + if (!tmp) + return JS_EXCEPTION; + r = tmp; + } else if (!is_binary_radix) { + /* need to modify 'r' */ + tmp = js_bigint_new(ctx, r->len); + if (!tmp) + return JS_EXCEPTION; + memcpy(tmp->tab, r->tab, r->len * sizeof(r->tab[0])); + r = tmp; + } + log2_radix = 31 - clz32(radix); /* floor(log2(radix)) */ + n_bits = r->len * JS_LIMB_BITS - js_limb_clz(r->tab[r->len - 1]); + /* n_digits is exact only if radix is a power of + two. Otherwise it is >= the exact number of digits */ + n_digits = (n_bits + log2_radix - 1) / log2_radix; + /* XXX: could directly build the JSString */ + buf = js_malloc(ctx, n_digits + is_neg + 1); + if (!buf) { + js_free(ctx, tmp); + return JS_EXCEPTION; + } + q = buf + n_digits + is_neg + 1; + *--q = '\0'; + buf_end = q; + if (!is_binary_radix) { + int len; + js_limb_t radix_base, v; + radix_base = js_radix_base_table[radix - 2]; + len = r->len; + for(;;) { + /* remove leading zero limbs */ + while (len > 1 && r->tab[len - 1] == 0) + len--; + if (len == 1 && r->tab[0] < radix_base) { + v = r->tab[0]; + if (v != 0) { + q = js_u64toa(q, v, radix); + } + break; + } else { + v = js_mp_div1(r->tab, r->tab, len, radix_base, 0); + q = js_limb_to_a(q, v, radix, js_digits_per_limb_table[radix - 2]); + } + } + } else { + int i, shift; + unsigned int bit_pos, pos, c; + + /* radix is a power of two */ + for(i = 0; i < n_digits; i++) { + bit_pos = i * log2_radix; + pos = bit_pos / JS_LIMB_BITS; + shift = bit_pos % JS_LIMB_BITS; + c = r->tab[pos] >> shift; + if ((shift + log2_radix) > JS_LIMB_BITS && + (pos + 1) < r->len) { + c |= r->tab[pos + 1] << (JS_LIMB_BITS - shift); + } + c &= (radix - 1); + *--q = digits[c]; + } + } + if (is_neg) + *--q = '-'; + js_free(ctx, tmp); + res = js_new_string8_len(ctx, q, buf_end - q); + js_free(ctx, buf); + return res; + } +} + +/* if possible transform a BigInt to short big and free it, otherwise + return a normal bigint */ +static JSValue JS_CompactBigInt(JSContext *ctx, JSBigInt *p) +{ + JSValue res; + if (p->len == 1) { + res = __JS_NewShortBigInt(ctx, (js_slimb_t)p->tab[0]); + js_free(ctx, p); + return res; + } else { + return JS_MKPTR(JS_TAG_BIG_INT, p); + } +} + +#define ATOD_INT_ONLY (1 << 0) +/* accept Oo and Ob prefixes in addition to 0x prefix if radix = 0 */ +#define ATOD_ACCEPT_BIN_OCT (1 << 2) +/* accept O prefix as octal if radix == 0 and properly formed (Annex B) */ +#define ATOD_ACCEPT_LEGACY_OCTAL (1 << 4) +/* accept _ between digits as a digit separator */ +#define ATOD_ACCEPT_UNDERSCORES (1 << 5) +/* allow a suffix to override the type */ +#define ATOD_ACCEPT_SUFFIX (1 << 6) +/* default type */ +#define ATOD_TYPE_MASK (3 << 7) +#define ATOD_TYPE_FLOAT64 (0 << 7) +#define ATOD_TYPE_BIG_INT (1 << 7) +/* accept -0x1 */ +#define ATOD_ACCEPT_PREFIX_AFTER_SIGN (1 << 10) + +/* return an exception in case of memory error. Return JS_NAN if + invalid syntax */ +/* XXX: directly use js_atod() */ +static JSValue js_atof(JSContext *ctx, const char *str, const char **pp, + int radix, int flags) +{ + const char *p, *p_start; + int sep, is_neg; + bool is_float, has_legacy_octal; + int atod_type = flags & ATOD_TYPE_MASK; + char buf1[64], *buf; + int i, j, len; + bool buf_allocated = false; + JSValue val; + JSATODTempMem atod_mem; + + /* optional separator between digits */ + sep = (flags & ATOD_ACCEPT_UNDERSCORES) ? '_' : 256; + has_legacy_octal = false; + + p = str; + p_start = p; + is_neg = 0; + if (p[0] == '+') { + p++; + p_start++; + if (!(flags & ATOD_ACCEPT_PREFIX_AFTER_SIGN)) + goto no_radix_prefix; + } else if (p[0] == '-') { + p++; + p_start++; + is_neg = 1; + if (!(flags & ATOD_ACCEPT_PREFIX_AFTER_SIGN)) + goto no_radix_prefix; + } + if (p[0] == '0') { + if ((p[1] == 'x' || p[1] == 'X') && + (radix == 0 || radix == 16)) { + p += 2; + radix = 16; + } else if ((p[1] == 'o' || p[1] == 'O') && + radix == 0 && (flags & ATOD_ACCEPT_BIN_OCT)) { + p += 2; + radix = 8; + } else if ((p[1] == 'b' || p[1] == 'B') && + radix == 0 && (flags & ATOD_ACCEPT_BIN_OCT)) { + p += 2; + radix = 2; + } else if ((p[1] >= '0' && p[1] <= '9') && + radix == 0 && (flags & ATOD_ACCEPT_LEGACY_OCTAL)) { + int i; + has_legacy_octal = true; + sep = 256; + for (i = 1; (p[i] >= '0' && p[i] <= '7'); i++) + continue; + if (p[i] == '8' || p[i] == '9') + goto no_prefix; + p += 1; + radix = 8; + } else { + goto no_prefix; + } + /* there must be a digit after the prefix */ + if (js_to_digit((uint8_t)*p) >= radix) + goto fail; + no_prefix: ; + } else { + no_radix_prefix: + if (!(flags & ATOD_INT_ONLY) && + (atod_type == ATOD_TYPE_FLOAT64) && + js__strstart(p, "Infinity", &p)) { + double d = INFINITY; + if (is_neg) + d = -d; + val = js_float64(d); + goto done; + } + } + if (radix == 0) + radix = 10; + is_float = false; + p_start = p; + while (js_to_digit((uint8_t)*p) < radix + || (*p == sep && (radix != 10 || + p != p_start + 1 || p[-1] != '0') && + js_to_digit((uint8_t)p[1]) < radix)) { + p++; + } + if (!(flags & ATOD_INT_ONLY) && radix == 10) { + if (*p == '.' && (p > p_start || js_to_digit((uint8_t)p[1]) < radix)) { + is_float = true; + p++; + if (*p == sep) + goto fail; + while (js_to_digit((uint8_t)*p) < radix || + (*p == sep && js_to_digit((uint8_t)p[1]) < radix)) + p++; + } + if (p > p_start && (*p == 'e' || *p == 'E')) { + const char *p1 = p + 1; + is_float = true; + if (*p1 == '+') { + p1++; + } else if (*p1 == '-') { + p1++; + } + if (is_digit((uint8_t)*p1)) { + p = p1 + 1; + while (is_digit((uint8_t)*p) || (*p == sep && is_digit((uint8_t)p[1]))) + p++; + } + } + } + if (p == p_start) + goto fail; + + buf = buf1; + buf_allocated = false; + len = p - p_start; + if (unlikely((len + 2) > sizeof(buf1))) { + buf = js_malloc_rt(ctx->rt, len + 2); /* no exception raised */ + if (!buf) + goto mem_error; + buf_allocated = true; + } + /* remove the separators and the radix prefixes */ + j = 0; + if (is_neg) + buf[j++] = '-'; + for (i = 0; i < len; i++) { + if (p_start[i] != '_') + buf[j++] = p_start[i]; + } + buf[j] = '\0'; + + if (flags & ATOD_ACCEPT_SUFFIX) { + if (*p == 'n') { + p++; + atod_type = ATOD_TYPE_BIG_INT; + } + } + + switch(atod_type) { + case ATOD_TYPE_FLOAT64: + { + double d; + d = js_atod(buf, NULL, radix, is_float ? 0 : JS_ATOD_INT_ONLY, + &atod_mem); + /* return int or float64 */ + val = js_number(d); + } + break; + case ATOD_TYPE_BIG_INT: + { + JSBigInt *r; + if (has_legacy_octal || is_float) + goto fail; + r = js_bigint_from_string(ctx, buf, radix); + if (!r) { + val = JS_EXCEPTION; + goto done; + } + val = JS_CompactBigInt(ctx, r); + } + break; + default: + abort(); + } + +done: + if (buf_allocated) + js_free_rt(ctx->rt, buf); + if (pp) + *pp = p; + return val; + fail: + val = JS_NAN; + goto done; + mem_error: + val = JS_ThrowOutOfMemory(ctx); + goto done; +} + +typedef enum JSToNumberHintEnum { + TON_FLAG_NUMBER, + TON_FLAG_NUMERIC, +} JSToNumberHintEnum; + +static JSValue JS_ToNumberHintFree(JSContext *ctx, JSValue val, + JSToNumberHintEnum flag) +{ + uint32_t tag; + JSValue ret; + + redo: + tag = JS_VALUE_GET_NORM_TAG(val); + switch(tag) { + case JS_TAG_BIG_INT: + case JS_TAG_SHORT_BIG_INT: + if (flag != TON_FLAG_NUMERIC) { + JS_FreeValue(ctx, val); + return JS_ThrowTypeError(ctx, "cannot convert BigInt to number"); + } + ret = val; + break; + case JS_TAG_FLOAT64: + case JS_TAG_INT: + case JS_TAG_EXCEPTION: + ret = val; + break; + case JS_TAG_BOOL: + case JS_TAG_NULL: + ret = js_int32(JS_VALUE_GET_INT(val)); + break; + case JS_TAG_UNDEFINED: + ret = JS_NAN; + break; + case JS_TAG_OBJECT: + val = JS_ToPrimitiveFree(ctx, val, HINT_NUMBER); + if (JS_IsException(val)) + return JS_EXCEPTION; + goto redo; + case JS_TAG_STRING: + case JS_TAG_STRING_ROPE: + { + const char *str; + const char *p; + size_t len; + + str = JS_ToCStringLen(ctx, &len, val); + JS_FreeValue(ctx, val); + if (!str) + return JS_EXCEPTION; + p = str; + p += skip_spaces(p); + if ((p - str) == len) { + ret = JS_NewInt32(ctx, 0); + } else { + int flags = ATOD_ACCEPT_BIN_OCT; + ret = js_atof(ctx, p, &p, 0, flags); + if (!JS_IsException(ret)) { + p += skip_spaces(p); + if ((p - str) != len) { + JS_FreeValue(ctx, ret); + ret = JS_NAN; + } + } + } + JS_FreeCString(ctx, str); + } + break; + case JS_TAG_SYMBOL: + JS_FreeValue(ctx, val); + return JS_ThrowTypeError(ctx, "cannot convert symbol to number"); + default: + JS_FreeValue(ctx, val); + ret = JS_NAN; + break; + } + return ret; +} + +static JSValue JS_ToNumberFree(JSContext *ctx, JSValue val) +{ + return JS_ToNumberHintFree(ctx, val, TON_FLAG_NUMBER); +} + +static JSValue JS_ToNumericFree(JSContext *ctx, JSValue val) +{ + return JS_ToNumberHintFree(ctx, val, TON_FLAG_NUMERIC); +} + +static JSValue JS_ToNumeric(JSContext *ctx, JSValueConst val) +{ + return JS_ToNumericFree(ctx, js_dup(val)); +} + +static __exception int __JS_ToFloat64Free(JSContext *ctx, double *pres, + JSValue val) +{ + double d; + uint32_t tag; + + val = JS_ToNumberFree(ctx, val); + if (JS_IsException(val)) + goto fail; + tag = JS_VALUE_GET_NORM_TAG(val); + switch(tag) { + case JS_TAG_INT: + d = JS_VALUE_GET_INT(val); + break; + case JS_TAG_FLOAT64: + d = JS_VALUE_GET_FLOAT64(val); + break; + default: + abort(); + } + *pres = d; + return 0; +fail: + *pres = NAN; + return -1; +} + +static inline int JS_ToFloat64Free(JSContext *ctx, double *pres, JSValue val) +{ + uint32_t tag; + + tag = JS_VALUE_GET_TAG(val); + if (tag <= JS_TAG_NULL) { + *pres = JS_VALUE_GET_INT(val); + return 0; + } else if (JS_TAG_IS_FLOAT64(tag)) { + *pres = JS_VALUE_GET_FLOAT64(val); + return 0; + } else { + return __JS_ToFloat64Free(ctx, pres, val); + } +} + +int JS_ToFloat64(JSContext *ctx, double *pres, JSValueConst val) +{ + return JS_ToFloat64Free(ctx, pres, js_dup(val)); +} + +JSValue JS_ToNumber(JSContext *ctx, JSValueConst val) +{ + return JS_ToNumberFree(ctx, js_dup(val)); +} + +/* same as JS_ToNumber() but return 0 in case of NaN/Undefined */ +static __maybe_unused JSValue JS_ToIntegerFree(JSContext *ctx, JSValue val) +{ + uint32_t tag; + JSValue ret; + + redo: + tag = JS_VALUE_GET_NORM_TAG(val); + switch(tag) { + case JS_TAG_INT: + case JS_TAG_BOOL: + case JS_TAG_NULL: + case JS_TAG_UNDEFINED: + ret = js_int32(JS_VALUE_GET_INT(val)); + break; + case JS_TAG_FLOAT64: + { + double d = JS_VALUE_GET_FLOAT64(val); + if (isnan(d)) { + ret = js_int32(0); + } else { + /* convert -0 to +0 */ + d = trunc(d) + 0.0; + ret = js_number(d); + } + } + break; + default: + val = JS_ToNumberFree(ctx, val); + if (JS_IsException(val)) + return val; + goto redo; + } + return ret; +} + +/* Note: the integer value is satured to 32 bits */ +static int JS_ToInt32SatFree(JSContext *ctx, int *pres, JSValue val) +{ + uint32_t tag; + int ret; + + redo: + tag = JS_VALUE_GET_NORM_TAG(val); + switch(tag) { + case JS_TAG_INT: + case JS_TAG_BOOL: + case JS_TAG_NULL: + case JS_TAG_UNDEFINED: + ret = JS_VALUE_GET_INT(val); + break; + case JS_TAG_EXCEPTION: + *pres = 0; + return -1; + case JS_TAG_FLOAT64: + { + double d = JS_VALUE_GET_FLOAT64(val); + if (isnan(d)) { + ret = 0; + } else { + if (d < INT32_MIN) + ret = INT32_MIN; + else if (d > INT32_MAX) + ret = INT32_MAX; + else + ret = (int)d; + } + } + break; + default: + val = JS_ToNumberFree(ctx, val); + if (JS_IsException(val)) { + *pres = 0; + return -1; + } + goto redo; + } + *pres = ret; + return 0; +} + +static int JS_ToInt32Sat(JSContext *ctx, int *pres, JSValueConst val) +{ + return JS_ToInt32SatFree(ctx, pres, js_dup(val)); +} + +static int JS_ToInt32Clamp(JSContext *ctx, int *pres, JSValueConst val, + int min, int max, int min_offset) +{ + int res = JS_ToInt32SatFree(ctx, pres, js_dup(val)); + if (res == 0) { + if (*pres < min) { + *pres += min_offset; + if (*pres < min) + *pres = min; + } else { + if (*pres > max) + *pres = max; + } + } + return res; +} + +static int JS_ToInt64SatFree(JSContext *ctx, int64_t *pres, JSValue val) +{ + uint32_t tag; + + redo: + tag = JS_VALUE_GET_NORM_TAG(val); + switch(tag) { + case JS_TAG_INT: + case JS_TAG_BOOL: + case JS_TAG_NULL: + case JS_TAG_UNDEFINED: + *pres = JS_VALUE_GET_INT(val); + return 0; + case JS_TAG_EXCEPTION: + *pres = 0; + return -1; + case JS_TAG_FLOAT64: + { + double d = JS_VALUE_GET_FLOAT64(val); + if (isnan(d)) { + *pres = 0; + } else { + if (d < INT64_MIN) + *pres = INT64_MIN; + else if (d >= 0x1p63) + *pres = INT64_MAX; + else + *pres = (int64_t)d; + } + } + return 0; + default: + val = JS_ToNumberFree(ctx, val); + if (JS_IsException(val)) { + *pres = 0; + return -1; + } + goto redo; + } +} + +int JS_ToInt64Sat(JSContext *ctx, int64_t *pres, JSValueConst val) +{ + return JS_ToInt64SatFree(ctx, pres, js_dup(val)); +} + +int JS_ToInt64Clamp(JSContext *ctx, int64_t *pres, JSValueConst val, + int64_t min, int64_t max, int64_t neg_offset) +{ + int res = JS_ToInt64SatFree(ctx, pres, js_dup(val)); + if (res == 0) { + if (*pres < 0) + *pres += neg_offset; + if (*pres < min) + *pres = min; + else if (*pres > max) + *pres = max; + } + return res; +} + +/* Same as JS_ToInt32Free() but with a 64 bit result. Return (<0, 0) + in case of exception */ +static int JS_ToInt64Free(JSContext *ctx, int64_t *pres, JSValue val) +{ + uint32_t tag; + int64_t ret; + + redo: + tag = JS_VALUE_GET_NORM_TAG(val); + switch(tag) { + case JS_TAG_INT: + case JS_TAG_BOOL: + case JS_TAG_NULL: + case JS_TAG_UNDEFINED: + ret = JS_VALUE_GET_INT(val); + break; + case JS_TAG_FLOAT64: + { + JSFloat64Union u; + double d; + int e; + d = JS_VALUE_GET_FLOAT64(val); + u.d = d; + /* we avoid doing fmod(x, 2^64) */ + e = (u.u64 >> 52) & 0x7ff; + if (likely(e <= (1023 + 62))) { + /* fast case */ + ret = (int64_t)d; + } else if (e <= (1023 + 62 + 53)) { + uint64_t v; + /* remainder modulo 2^64 */ + v = (u.u64 & (((uint64_t)1 << 52) - 1)) | ((uint64_t)1 << 52); + ret = v << ((e - 1023) - 52); + /* take the sign into account */ + if (u.u64 >> 63) + if (ret != INT64_MIN) + ret = -ret; + } else { + ret = 0; /* also handles NaN and +inf */ + } + } + break; + default: + val = JS_ToNumberFree(ctx, val); + if (JS_IsException(val)) { + *pres = 0; + return -1; + } + goto redo; + } + *pres = ret; + return 0; +} + +int JS_ToInt64(JSContext *ctx, int64_t *pres, JSValueConst val) +{ + return JS_ToInt64Free(ctx, pres, js_dup(val)); +} + +int JS_ToInt64Ext(JSContext *ctx, int64_t *pres, JSValueConst val) +{ + if (JS_IsBigInt(val)) + return JS_ToBigInt64(ctx, pres, val); + else + return JS_ToInt64(ctx, pres, val); +} + +/* return (<0, 0) in case of exception */ +static int JS_ToInt32Free(JSContext *ctx, int32_t *pres, JSValue val) +{ + uint32_t tag; + int32_t ret; + + redo: + tag = JS_VALUE_GET_NORM_TAG(val); + switch(tag) { + case JS_TAG_INT: + case JS_TAG_BOOL: + case JS_TAG_NULL: + case JS_TAG_UNDEFINED: + ret = JS_VALUE_GET_INT(val); + break; + case JS_TAG_FLOAT64: + { + JSFloat64Union u; + double d; + int e; + d = JS_VALUE_GET_FLOAT64(val); + u.d = d; + /* we avoid doing fmod(x, 2^32) */ + e = (u.u64 >> 52) & 0x7ff; + if (likely(e <= (1023 + 30))) { + /* fast case */ + ret = (int32_t)d; + } else if (e <= (1023 + 30 + 53)) { + uint64_t v; + /* remainder modulo 2^32 */ + v = (u.u64 & (((uint64_t)1 << 52) - 1)) | ((uint64_t)1 << 52); + v = v << ((e - 1023) - 52 + 32); + ret = v >> 32; + /* take the sign into account */ + if (u.u64 >> 63) + if (ret != INT32_MIN) + ret = -ret; + } else { + ret = 0; /* also handles NaN and +inf */ + } + } + break; + default: + val = JS_ToNumberFree(ctx, val); + if (JS_IsException(val)) { + *pres = 0; + return -1; + } + goto redo; + } + *pres = ret; + return 0; +} + +int JS_ToInt32(JSContext *ctx, int32_t *pres, JSValueConst val) +{ + return JS_ToInt32Free(ctx, pres, js_dup(val)); +} + +static inline int JS_ToUint32Free(JSContext *ctx, uint32_t *pres, JSValue val) +{ + return JS_ToInt32Free(ctx, (int32_t *)pres, val); +} + +static int JS_ToUint8ClampFree(JSContext *ctx, int32_t *pres, JSValue val) +{ + uint32_t tag; + int res; + + redo: + tag = JS_VALUE_GET_NORM_TAG(val); + switch(tag) { + case JS_TAG_INT: + case JS_TAG_BOOL: + case JS_TAG_NULL: + case JS_TAG_UNDEFINED: + res = JS_VALUE_GET_INT(val); + res = max_int(0, min_int(255, res)); + break; + case JS_TAG_FLOAT64: + { + double d = JS_VALUE_GET_FLOAT64(val); + if (isnan(d)) { + res = 0; + } else { + if (d < 0) + res = 0; + else if (d > 255) + res = 255; + else + res = lrint(d); + } + } + break; + default: + val = JS_ToNumberFree(ctx, val); + if (JS_IsException(val)) { + *pres = 0; + return -1; + } + goto redo; + } + *pres = res; + return 0; +} + +static __exception int JS_ToArrayLengthFree(JSContext *ctx, uint32_t *plen, + JSValue val, bool is_array_ctor) +{ + uint32_t tag, len; + + tag = JS_VALUE_GET_TAG(val); + switch(tag) { + case JS_TAG_INT: + case JS_TAG_BOOL: + case JS_TAG_NULL: + { + int v; + v = JS_VALUE_GET_INT(val); + if (v < 0) + goto fail; + len = v; + } + break; + default: + if (JS_TAG_IS_FLOAT64(tag)) { + double d; + d = JS_VALUE_GET_FLOAT64(val); + if (!(d >= 0 && d <= UINT32_MAX)) + goto fail; + len = (uint32_t)d; + if (len != d) + goto fail; + } else { + uint32_t len1; + + if (is_array_ctor) { + val = JS_ToNumberFree(ctx, val); + if (JS_IsException(val)) + return -1; + /* cannot recurse because val is a number */ + if (JS_ToArrayLengthFree(ctx, &len, val, true)) + return -1; + } else { + /* legacy behavior: must do the conversion twice and compare */ + if (JS_ToUint32(ctx, &len, val)) { + JS_FreeValue(ctx, val); + return -1; + } + val = JS_ToNumberFree(ctx, val); + if (JS_IsException(val)) + return -1; + /* cannot recurse because val is a number */ + if (JS_ToArrayLengthFree(ctx, &len1, val, false)) + return -1; + if (len1 != len) { + fail: + JS_ThrowRangeError(ctx, "invalid array length"); + return -1; + } + } + } + break; + } + *plen = len; + return 0; +} + +#define MAX_SAFE_INTEGER (((int64_t)1 << 53) - 1) + +static bool is_safe_integer(double d) +{ + return isfinite(d) && floor(d) == d && + fabs(d) <= (double)MAX_SAFE_INTEGER; +} + +int JS_ToIndex(JSContext *ctx, uint64_t *plen, JSValueConst val) +{ + int64_t v; + if (JS_ToInt64Sat(ctx, &v, val)) + return -1; + if (v < 0 || v > MAX_SAFE_INTEGER) { + JS_ThrowRangeError(ctx, "invalid array index"); + *plen = 0; + return -1; + } + *plen = v; + return 0; +} + +/* convert a value to a length between 0 and MAX_SAFE_INTEGER. + return -1 for exception */ +static __exception int JS_ToLengthFree(JSContext *ctx, int64_t *plen, + JSValue val) +{ + int res = JS_ToInt64Clamp(ctx, plen, val, 0, MAX_SAFE_INTEGER, 0); + JS_FreeValue(ctx, val); + return res; +} + +/* Note: can return an exception */ +static int JS_NumberIsInteger(JSContext *ctx, JSValueConst val) +{ + double d; + if (!JS_IsNumber(val)) + return false; + if (unlikely(JS_ToFloat64(ctx, &d, val))) + return -1; + return isfinite(d) && floor(d) == d; +} + +static bool JS_NumberIsNegativeOrMinusZero(JSContext *ctx, JSValueConst val) +{ + uint32_t tag; + + tag = JS_VALUE_GET_NORM_TAG(val); + switch(tag) { + case JS_TAG_INT: + { + int v; + v = JS_VALUE_GET_INT(val); + return (v < 0); + } + case JS_TAG_FLOAT64: + { + JSFloat64Union u; + u.d = JS_VALUE_GET_FLOAT64(val); + return (u.u64 >> 63); + } + case JS_TAG_SHORT_BIG_INT: + return (JS_VALUE_GET_SHORT_BIG_INT(val) < 0); + case JS_TAG_BIG_INT: + { + JSBigInt *p = JS_VALUE_GET_PTR(val); + return js_bigint_sign(p); + } + default: + return false; + } +} + +static JSValue js_bigint_to_string(JSContext *ctx, JSValueConst val) +{ + return js_bigint_to_string1(ctx, val, 10); +} + +/*---- floating point number to string conversions ----*/ + +static JSValue js_dtoa2(JSContext *ctx, + double d, int radix, int n_digits, int flags) +{ + char static_buf[128], *buf, *tmp_buf; + int len, len_max; + JSValue res; + JSDTOATempMem dtoa_mem; + len_max = js_dtoa_max_len(d, radix, n_digits, flags); + + /* longer buffer may be used if radix != 10 */ + if (len_max > sizeof(static_buf) - 1) { + tmp_buf = js_malloc(ctx, len_max + 1); + if (!tmp_buf) + return JS_EXCEPTION; + buf = tmp_buf; + } else { + tmp_buf = NULL; + buf = static_buf; + } + len = js_dtoa(buf, d, radix, n_digits, flags, &dtoa_mem); + res = js_new_string8_len(ctx, buf, len); + js_free(ctx, tmp_buf); + return res; +} + +static JSValue JS_ToStringInternal(JSContext *ctx, JSValueConst val, + int flags) +{ + uint32_t tag; + char buf[32]; + size_t len; + + tag = JS_VALUE_GET_NORM_TAG(val); + switch(tag) { + case JS_TAG_STRING: + return js_dup(val); + case JS_TAG_STRING_ROPE: + return js_linearize_string_rope(ctx, val); + case JS_TAG_INT: + len = i32toa(buf, JS_VALUE_GET_INT(val)); + return js_new_string8_len(ctx, buf, len); + case JS_TAG_BOOL: + return JS_AtomToString(ctx, JS_VALUE_GET_BOOL(val) ? + JS_ATOM_true : JS_ATOM_false); + case JS_TAG_NULL: + return JS_AtomToString(ctx, JS_ATOM_null); + case JS_TAG_UNDEFINED: + return JS_AtomToString(ctx, JS_ATOM_undefined); + case JS_TAG_EXCEPTION: + return JS_EXCEPTION; + case JS_TAG_OBJECT: + if (flags & JS_TO_STRING_NO_SIDE_EFFECTS) { + return js_new_string8(ctx, "{}"); + } else { + JSValue val1, ret; + val1 = JS_ToPrimitive(ctx, val, HINT_STRING); + if (JS_IsException(val1)) + return val1; + ret = JS_ToStringInternal(ctx, val1, flags); + JS_FreeValue(ctx, val1); + return ret; + } + break; + case JS_TAG_FUNCTION_BYTECODE: + return js_new_string8(ctx, "[function bytecode]"); + case JS_TAG_SYMBOL: + if (flags & JS_TO_STRING_IS_PROPERTY_KEY) { + return js_dup(val); + } else { + return JS_ThrowTypeError(ctx, "cannot convert symbol to string"); + } + case JS_TAG_FLOAT64: + return js_dtoa2(ctx, JS_VALUE_GET_FLOAT64(val), 10, 0, + JS_DTOA_FORMAT_FREE); + case JS_TAG_SHORT_BIG_INT: + case JS_TAG_BIG_INT: + return js_bigint_to_string(ctx, val); + case JS_TAG_UNINITIALIZED: + return js_new_string8(ctx, "[uninitialized]"); + default: + return js_new_string8(ctx, "[unsupported type]"); + } +} + +JSValue JS_ToString(JSContext *ctx, JSValueConst val) +{ + return JS_ToStringInternal(ctx, val, /*flags*/0); +} + +static JSValue JS_ToStringFree(JSContext *ctx, JSValue val) +{ + if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING) + return val; + JSValue ret = JS_ToString(ctx, val); + JS_FreeValue(ctx, val); + return ret; +} + +static JSValue JS_ToLocaleStringFree(JSContext *ctx, JSValue val) +{ + if (JS_IsUndefined(val) || JS_IsNull(val)) + return JS_ToStringFree(ctx, val); + return JS_InvokeFree(ctx, val, JS_ATOM_toLocaleString, 0, NULL); +} + +static JSValue JS_ToPropertyKeyInternal(JSContext *ctx, JSValueConst val, + int flags) +{ + return JS_ToStringInternal(ctx, val, flags | JS_TO_STRING_IS_PROPERTY_KEY); +} + +JSValue JS_ToPropertyKey(JSContext *ctx, JSValueConst val) +{ + return JS_ToPropertyKeyInternal(ctx, val, /*flags*/0); +} + +static JSValue JS_ToStringCheckObject(JSContext *ctx, JSValueConst val) +{ + uint32_t tag = JS_VALUE_GET_TAG(val); + if (tag == JS_TAG_NULL || tag == JS_TAG_UNDEFINED) + return JS_ThrowTypeError(ctx, "null or undefined are forbidden"); + return JS_ToString(ctx, val); +} + +static JSValue JS_ToQuotedString(JSContext *ctx, JSValueConst val1) +{ + JSValue val; + JSString *p; + int i; + uint32_t c; + StringBuffer b_s, *b = &b_s; + char buf[16]; + + val = JS_ToStringCheckObject(ctx, val1); + if (JS_IsException(val)) + return val; + p = JS_VALUE_GET_STRING(val); + + if (string_buffer_init(ctx, b, p->len + 2)) + goto fail; + + if (string_buffer_putc8(b, '\"')) + goto fail; + for(i = 0; i < p->len; ) { + c = string_getc(p, &i); + switch(c) { + case '\t': + c = 't'; + goto quote; + case '\r': + c = 'r'; + goto quote; + case '\n': + c = 'n'; + goto quote; + case '\b': + c = 'b'; + goto quote; + case '\f': + c = 'f'; + goto quote; + case '\"': + case '\\': + quote: + if (string_buffer_putc8(b, '\\')) + goto fail; + if (string_buffer_putc8(b, c)) + goto fail; + break; + default: + if (c < 32 || is_surrogate(c)) { + snprintf(buf, sizeof(buf), "\\u%04x", c); + if (string_buffer_write8(b, (uint8_t*)buf, 6)) + goto fail; + } else { + if (string_buffer_putc(b, c)) + goto fail; + } + break; + } + } + if (string_buffer_putc8(b, '\"')) + goto fail; + JS_FreeValue(ctx, val); + return string_buffer_end(b); + fail: + JS_FreeValue(ctx, val); + string_buffer_free(b); + return JS_EXCEPTION; +} + +static __maybe_unused void JS_DumpObjectHeader(JSRuntime *rt) +{ + printf("%14s %4s %4s %14s %10s %s\n", + "ADDRESS", "REFS", "SHRF", "PROTO", "CLASS", "PROPS"); +} + +/* for debug only: dump an object without side effect */ +static __maybe_unused void JS_DumpObject(JSRuntime *rt, JSObject *p) +{ + uint32_t i; + char atom_buf[ATOM_GET_STR_BUF_SIZE]; + JSShape *sh; + JSShapeProperty *prs; + JSProperty *pr; + bool is_first = true; + + /* XXX: should encode atoms with special characters */ + sh = p->shape; /* the shape can be NULL while freeing an object */ + printf("%14p %4d ", + (void *)p, + JS_REF_COUNT(p)); + if (sh) { + printf("%3d%c %14p ", + JS_REF_COUNT(sh), + " *"[sh->is_hashed], + (void *)sh->proto); + } else { + printf("%3s %14s ", "-", "-"); + } + printf("%10s ", + JS_AtomGetStrRT(rt, atom_buf, sizeof(atom_buf), rt->class_array[p->class_id].class_name)); + if (p->is_exotic && p->fast_array) { + printf("[ "); + for(i = 0; i < p->u.array.count; i++) { + if (i != 0) + printf(", "); + switch (p->class_id) { + case JS_CLASS_ARRAY: + case JS_CLASS_ARGUMENTS: + JS_DumpValue(rt, p->u.array.u.values[i]); + break; + case JS_CLASS_UINT8C_ARRAY: + case JS_CLASS_INT8_ARRAY: + case JS_CLASS_UINT8_ARRAY: + case JS_CLASS_INT16_ARRAY: + case JS_CLASS_UINT16_ARRAY: + case JS_CLASS_INT32_ARRAY: + case JS_CLASS_UINT32_ARRAY: + case JS_CLASS_BIG_INT64_ARRAY: + case JS_CLASS_BIG_UINT64_ARRAY: + case JS_CLASS_FLOAT16_ARRAY: + case JS_CLASS_FLOAT32_ARRAY: + case JS_CLASS_FLOAT64_ARRAY: + { + int size = 1 << typed_array_size_log2(p->class_id); + const uint8_t *b = p->u.array.u.uint8_ptr + i * size; + while (size-- > 0) + printf("%02X", *b++); + } + break; + } + } + printf(" ] "); + } + + if (sh) { + printf("{ "); + for(i = 0, prs = get_shape_prop(sh); i < sh->prop_count; i++, prs++) { + if (prs->atom != JS_ATOM_NULL) { + pr = &p->prop[i]; + if (!is_first) + printf(", "); + printf("%s: ", + JS_AtomGetStrRT(rt, atom_buf, sizeof(atom_buf), prs->atom)); + if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { + printf("[getset %p %p]", (void *)pr->u.getset.getter, + (void *)pr->u.getset.setter); + } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { + printf("[varref %p]", (void *)pr->u.var_ref); + } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { + printf("[autoinit %p %d %p]", + (void *)js_autoinit_get_realm(pr), + js_autoinit_get_id(pr), + (void *)pr->u.init.opaque); + } else { + JS_DumpValue(rt, pr->u.value); + } + is_first = false; + } + } + printf(" }"); + } + + if (js_class_has_bytecode(p->class_id)) { + JSFunctionBytecode *b = p->u.func.function_bytecode; + JSVarRef **var_refs; + if (b->closure_var_count) { + var_refs = p->u.func.var_refs; + printf(" Closure:"); + for(i = 0; i < b->closure_var_count; i++) { + printf(" "); + JS_DumpValue(rt, var_refs[i]->value); + } + if (p->u.func.home_object) { + printf(" HomeObject: "); + JS_DumpValue(rt, JS_MKPTR(JS_TAG_OBJECT, p->u.func.home_object)); + } + } + } + printf("\n"); +} + +static __maybe_unused void JS_DumpGCObject(JSRuntime *rt, JSGCObjectHeader *p) +{ + if (JS_GC_TYPE(p) == JS_GC_OBJ_TYPE_JS_OBJECT) { + JS_DumpObject(rt, (JSObject *)p); + } else { + printf("%14p %4d ", + (void *)p, + JS_REF_COUNT(p)); + switch(JS_GC_TYPE(p)) { + case JS_GC_OBJ_TYPE_FUNCTION_BYTECODE: + printf("[function bytecode]"); + break; + case JS_GC_OBJ_TYPE_SHAPE: + printf("[shape]"); + break; + case JS_GC_OBJ_TYPE_VAR_REF: + printf("[var_ref]"); + break; + case JS_GC_OBJ_TYPE_ASYNC_FUNCTION: + printf("[async_function]"); + break; + case JS_GC_OBJ_TYPE_JS_CONTEXT: + printf("[js_context]"); + break; + default: + printf("[unknown %d]", JS_GC_TYPE(p)); + break; + } + printf("\n"); + } +} + +static __maybe_unused void JS_DumpValue(JSRuntime *rt, JSValueConst val) +{ + uint32_t tag = JS_VALUE_GET_NORM_TAG(val); + const char *str; + + switch(tag) { + case JS_TAG_INT: + printf("%d", JS_VALUE_GET_INT(val)); + break; + case JS_TAG_BOOL: + if (JS_VALUE_GET_BOOL(val)) + str = "true"; + else + str = "false"; + goto print_str; + case JS_TAG_NULL: + str = "null"; + goto print_str; + case JS_TAG_EXCEPTION: + str = "exception"; + goto print_str; + case JS_TAG_UNINITIALIZED: + str = "uninitialized"; + goto print_str; + case JS_TAG_UNDEFINED: + str = "undefined"; + print_str: + printf("%s", str); + break; + case JS_TAG_FLOAT64: + printf("%.14g", JS_VALUE_GET_FLOAT64(val)); + break; + case JS_TAG_SHORT_BIG_INT: + printf("%" PRId64 "n", (int64_t)JS_VALUE_GET_SHORT_BIG_INT(val)); + break; + case JS_TAG_BIG_INT: + { + JSBigInt *p = JS_VALUE_GET_PTR(val); + int sgn, i; + /* In order to avoid allocations we just dump the limbs */ + sgn = js_bigint_sign(p); + if (sgn) + printf("BigInt.asIntN(%d,", p->len * JS_LIMB_BITS); + printf("0x"); + for(i = p->len - 1; i >= 0; i--) { + if (i != p->len - 1) + printf("_"); + printf("%08x", p->tab[i]); + } + printf("n"); + if (sgn) + printf(")"); + } + break; + case JS_TAG_STRING: + { + JSString *p; + p = JS_VALUE_GET_STRING(val); + JS_DumpString(rt, p); + } + break; + case JS_TAG_STRING_ROPE: + { + JSStringRope *r = JS_VALUE_GET_STRING_ROPE(val); + printf("[rope len=%d depth=%d]", r->len, r->depth); + } + break; + case JS_TAG_FUNCTION_BYTECODE: + { + JSFunctionBytecode *b = JS_VALUE_GET_PTR(val); + char buf[ATOM_GET_STR_BUF_SIZE]; + if (b->func_name) { + printf("[bytecode %s]", JS_AtomGetStrRT(rt, buf, sizeof(buf), b->func_name)); + } else { + printf("[bytecode (anonymous)]"); + } + } + break; + case JS_TAG_OBJECT: + { + JSObject *p = JS_VALUE_GET_OBJ(val); + JSAtom atom = rt->class_array[p->class_id].class_name; + char atom_buf[ATOM_GET_STR_BUF_SIZE]; + printf("[%s %p]", + JS_AtomGetStrRT(rt, atom_buf, sizeof(atom_buf), atom), (void *)p); + } + break; + case JS_TAG_SYMBOL: + { + JSAtomStruct *p = JS_VALUE_GET_PTR(val); + char atom_buf[ATOM_GET_STR_BUF_SIZE]; + printf("Symbol(%s)", + JS_AtomGetStrRT(rt, atom_buf, sizeof(atom_buf), js_get_atom_index(rt, p))); + } + break; + case JS_TAG_MODULE: + printf("[module]"); + break; + default: + printf("[unknown tag %d]", tag); + break; + } +} + +bool JS_IsArray(JSValueConst val) +{ + if (JS_VALUE_GET_TAG(val) == JS_TAG_OBJECT) { + JSObject *p = JS_VALUE_GET_OBJ(val); + return p->class_id == JS_CLASS_ARRAY; + } + return false; +} + +/* return -1 if exception (proxy case) or true/false */ +static int js_is_array(JSContext *ctx, JSValueConst val) +{ + JSObject *p; + if (JS_VALUE_GET_TAG(val) == JS_TAG_OBJECT) { + p = JS_VALUE_GET_OBJ(val); + if (unlikely(p->class_id == JS_CLASS_PROXY)) + return js_proxy_isArray(ctx, val); + else + return p->class_id == JS_CLASS_ARRAY; + } else { + return false; + } +} + +static double js_math_pow(double a, double b) +{ + double d; + + if (unlikely(!isfinite(b)) && fabs(a) == 1) { + /* not compatible with IEEE 754 */ + d = NAN; + } else { + JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + d = pow(a, b); + JS_X87_FPCW_RESTORE(fpcw); + } + return d; +} + +JSValue JS_NewBigInt64(JSContext *ctx, int64_t v) +{ + if (v >= JS_SHORT_BIG_INT_MIN && v <= JS_SHORT_BIG_INT_MAX) { + return __JS_NewShortBigInt(ctx, v); + } else { + JSBigInt *p; + p = js_bigint_new_si64(ctx, v); + if (!p) + return JS_EXCEPTION; + return JS_MKPTR(JS_TAG_BIG_INT, p); + } +} + +JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v) +{ + if (v <= JS_SHORT_BIG_INT_MAX) { + return __JS_NewShortBigInt(ctx, v); + } else { + JSBigInt *p; + p = js_bigint_new_ui64(ctx, v); + if (!p) + return JS_EXCEPTION; + return JS_MKPTR(JS_TAG_BIG_INT, p); + } +} + +/* return NaN if bad bigint literal */ +static JSValue JS_StringToBigInt(JSContext *ctx, JSValue val) +{ + const char *str, *p; + size_t len; + int flags; + + str = JS_ToCStringLen(ctx, &len, val); + JS_FreeValue(ctx, val); + if (!str) + return JS_EXCEPTION; + p = str; + p += skip_spaces(p); + if ((p - str) == len) { + val = JS_NewBigInt64(ctx, 0); + } else { + flags = ATOD_INT_ONLY | ATOD_ACCEPT_BIN_OCT | ATOD_TYPE_BIG_INT; + val = js_atof(ctx, p, &p, 0, flags); + p += skip_spaces(p); + if (!JS_IsException(val)) { + if ((p - str) != len) { + JS_FreeValue(ctx, val); + val = JS_NAN; + } + } + } + JS_FreeCString(ctx, str); + return val; +} + +static JSValue JS_StringToBigIntErr(JSContext *ctx, JSValue val) +{ + val = JS_StringToBigInt(ctx, val); + if (JS_VALUE_IS_NAN(val)) + return JS_ThrowSyntaxError(ctx, "invalid BigInt literal"); + return val; +} + +/* JS Numbers are not allowed */ +static JSValue JS_ToBigIntFree(JSContext *ctx, JSValue val) +{ + uint32_t tag; + + redo: + tag = JS_VALUE_GET_NORM_TAG(val); + switch(tag) { + case JS_TAG_SHORT_BIG_INT: + case JS_TAG_BIG_INT: + break; + case JS_TAG_INT: + case JS_TAG_NULL: + case JS_TAG_UNDEFINED: + case JS_TAG_FLOAT64: + goto fail; + case JS_TAG_BOOL: + val = __JS_NewShortBigInt(ctx, JS_VALUE_GET_INT(val)); + break; + case JS_TAG_STRING: + case JS_TAG_STRING_ROPE: + val = JS_StringToBigIntErr(ctx, val); + if (JS_IsException(val)) + return val; + goto redo; + case JS_TAG_OBJECT: + val = JS_ToPrimitiveFree(ctx, val, HINT_NUMBER); + if (JS_IsException(val)) + return val; + goto redo; + default: + fail: + JS_FreeValue(ctx, val); + return JS_ThrowTypeError(ctx, "cannot convert to bigint"); + } + return val; +} + +static JSValue JS_ToBigInt(JSContext *ctx, JSValueConst val) +{ + return JS_ToBigIntFree(ctx, js_dup(val)); +} + +/* XXX: merge with JS_ToInt64Free with a specific flag */ +static int JS_ToBigInt64Free(JSContext *ctx, int64_t *pres, JSValue val) +{ + uint64_t res; + + val = JS_ToBigIntFree(ctx, val); + if (JS_IsException(val)) { + *pres = 0; + return -1; + } + if (JS_VALUE_GET_TAG(val) == JS_TAG_SHORT_BIG_INT) { + res = JS_VALUE_GET_SHORT_BIG_INT(val); + } else { + JSBigInt *p = JS_VALUE_GET_PTR(val); + /* return the value mod 2^64 */ + res = p->tab[0]; + if (p->len >= 2) + res |= (uint64_t)p->tab[1] << 32; + JS_FreeValue(ctx, val); + } + *pres = res; + return 0; +} + +int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValueConst val) +{ + return JS_ToBigInt64Free(ctx, pres, js_dup(val)); +} + +int JS_ToBigUint64(JSContext *ctx, uint64_t *pres, JSValueConst val) +{ + return JS_ToBigInt64Free(ctx, (int64_t *)pres, js_dup(val)); +} + +static no_inline __exception int js_unary_arith_slow(JSContext *ctx, + JSValue *sp, + OPCodeEnum op) +{ + JSValue op1; + int v; + uint32_t tag; + JSBigIntBuf buf1; + JSBigInt *p1; + + op1 = sp[-1]; + /* fast path for float64 */ + if (JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(op1))) + goto handle_float64; + op1 = JS_ToNumericFree(ctx, op1); + if (JS_IsException(op1)) + goto exception; + tag = JS_VALUE_GET_TAG(op1); + switch(tag) { + case JS_TAG_INT: + { + int64_t v64; + v64 = JS_VALUE_GET_INT(op1); + switch(op) { + case OP_inc: + case OP_dec: + v = 2 * (op - OP_dec) - 1; + v64 += v; + break; + case OP_plus: + break; + case OP_neg: + if (v64 == 0) { + sp[-1] = js_float64(-0.0); + return 0; + } else { + v64 = -v64; + } + break; + default: + abort(); + } + sp[-1] = js_int64(v64); + } + break; + case JS_TAG_SHORT_BIG_INT: + { + int64_t v; + v = JS_VALUE_GET_SHORT_BIG_INT(op1); + switch(op) { + case OP_plus: + JS_ThrowTypeError(ctx, "bigint argument with unary +"); + goto exception; + case OP_inc: + if (v == JS_SHORT_BIG_INT_MAX) + goto bigint_slow_case; + sp[-1] = __JS_NewShortBigInt(ctx, v + 1); + break; + case OP_dec: + if (v == JS_SHORT_BIG_INT_MIN) + goto bigint_slow_case; + sp[-1] = __JS_NewShortBigInt(ctx, v - 1); + break; + case OP_neg: + v = JS_VALUE_GET_SHORT_BIG_INT(op1); + if (v == JS_SHORT_BIG_INT_MIN) { + bigint_slow_case: + p1 = js_bigint_set_short(&buf1, op1); + goto bigint_slow_case1; + } + sp[-1] = __JS_NewShortBigInt(ctx, -v); + break; + default: + abort(); + } + } + break; + case JS_TAG_BIG_INT: + { + JSBigInt *r; + p1 = JS_VALUE_GET_PTR(op1); + bigint_slow_case1: + switch(op) { + case OP_plus: + JS_ThrowTypeError(ctx, "bigint argument with unary +"); + JS_FreeValue(ctx, op1); + goto exception; + case OP_inc: + case OP_dec: + { + JSBigIntBuf buf2; + JSBigInt *p2; + p2 = js_bigint_set_si(&buf2, 2 * (op - OP_dec) - 1); + r = js_bigint_add(ctx, p1, p2, 0); + } + break; + case OP_neg: + r = js_bigint_neg(ctx, p1); + break; + case OP_not: + r = js_bigint_not(ctx, p1); + break; + default: + abort(); + } + JS_FreeValue(ctx, op1); + if (!r) + goto exception; + sp[-1] = JS_CompactBigInt(ctx, r); + } + break; + default: + handle_float64: + { + double d; + d = JS_VALUE_GET_FLOAT64(op1); + switch(op) { + case OP_inc: + case OP_dec: + v = 2 * (op - OP_dec) - 1; + d += v; + break; + case OP_plus: + break; + case OP_neg: + d = -d; + break; + default: + abort(); + } + sp[-1] = js_float64(d); + } + break; + } + return 0; + exception: + sp[-1] = JS_UNDEFINED; + return -1; +} + +static __exception int js_post_inc_slow(JSContext *ctx, + JSValue *sp, OPCodeEnum op) +{ + JSValue op1; + + /* XXX: allow custom operators */ + op1 = sp[-1]; + op1 = JS_ToNumericFree(ctx, op1); + if (JS_IsException(op1)) { + sp[-1] = JS_UNDEFINED; + return -1; + } + sp[-1] = op1; + sp[0] = js_dup(op1); + return js_unary_arith_slow(ctx, sp + 1, op - OP_post_dec + OP_dec); +} + +static no_inline int js_not_slow(JSContext *ctx, JSValue *sp) +{ + JSValue op1; + + op1 = sp[-1]; + op1 = JS_ToNumericFree(ctx, op1); + if (JS_IsException(op1)) + goto exception; + if (JS_VALUE_GET_TAG(op1) == JS_TAG_SHORT_BIG_INT) { + sp[-1] = __JS_NewShortBigInt(ctx, ~JS_VALUE_GET_SHORT_BIG_INT(op1)); + } else if (JS_VALUE_GET_TAG(op1) == JS_TAG_BIG_INT) { + JSBigInt *r; + r = js_bigint_not(ctx, JS_VALUE_GET_PTR(op1)); + JS_FreeValue(ctx, op1); + if (!r) + goto exception; + sp[-1] = JS_CompactBigInt(ctx, r); + } else { + int32_t v1; + if (unlikely(JS_ToInt32Free(ctx, &v1, op1))) + goto exception; + sp[-1] = js_int32(~v1); + } + return 0; + exception: + sp[-1] = JS_UNDEFINED; + return -1; +} + +static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *sp, + OPCodeEnum op) +{ + JSValue op1, op2; + uint32_t tag1, tag2; + double d1, d2; + + op1 = sp[-2]; + op2 = sp[-1]; + tag1 = JS_VALUE_GET_NORM_TAG(op1); + tag2 = JS_VALUE_GET_NORM_TAG(op2); + /* fast path for float operations */ + if (tag1 == JS_TAG_FLOAT64 && tag2 == JS_TAG_FLOAT64) { + d1 = JS_VALUE_GET_FLOAT64(op1); + d2 = JS_VALUE_GET_FLOAT64(op2); + goto handle_float64; + } + /* fast path for short big int operations */ + if (tag1 == JS_TAG_SHORT_BIG_INT && tag2 == JS_TAG_SHORT_BIG_INT) { + js_slimb_t v1, v2; + js_sdlimb_t v; + v1 = JS_VALUE_GET_SHORT_BIG_INT(op1); + v2 = JS_VALUE_GET_SHORT_BIG_INT(op2); + switch(op) { + case OP_sub: + v = (js_sdlimb_t)v1 - (js_sdlimb_t)v2; + break; + case OP_mul: + v = (js_sdlimb_t)v1 * (js_sdlimb_t)v2; + break; + case OP_div: + if (v2 == 0 || + ((js_limb_t)v1 == (js_limb_t)1 << (JS_LIMB_BITS - 1) && + v2 == -1)) { + goto slow_big_int; + } + sp[-2] = __JS_NewShortBigInt(ctx, v1 / v2); + return 0; + case OP_mod: + if (v2 == 0 || + ((js_limb_t)v1 == (js_limb_t)1 << (JS_LIMB_BITS - 1) && + v2 == -1)) { + goto slow_big_int; + } + sp[-2] = __JS_NewShortBigInt(ctx, v1 % v2); + return 0; + case OP_pow: + goto slow_big_int; + default: + abort(); + } + if (likely(v >= JS_SHORT_BIG_INT_MIN && v <= JS_SHORT_BIG_INT_MAX)) { + sp[-2] = __JS_NewShortBigInt(ctx, v); + } else { + JSBigInt *r = js_bigint_new_di(ctx, v); + if (!r) + goto exception; + sp[-2] = JS_MKPTR(JS_TAG_BIG_INT, r); + } + return 0; + } + op1 = JS_ToNumericFree(ctx, op1); + if (JS_IsException(op1)) { + JS_FreeValue(ctx, op2); + goto exception; + } + op2 = JS_ToNumericFree(ctx, op2); + if (JS_IsException(op2)) { + JS_FreeValue(ctx, op1); + goto exception; + } + tag1 = JS_VALUE_GET_NORM_TAG(op1); + tag2 = JS_VALUE_GET_NORM_TAG(op2); + + if (tag1 == JS_TAG_INT && tag2 == JS_TAG_INT) { + int32_t v1, v2; + int64_t v; + v1 = JS_VALUE_GET_INT(op1); + v2 = JS_VALUE_GET_INT(op2); + switch(op) { + case OP_sub: + v = (int64_t)v1 - (int64_t)v2; + break; + case OP_mul: + v = (int64_t)v1 * (int64_t)v2; + if (v == 0 && (v1 | v2) < 0) { + sp[-2] = js_float64(-0.0); + return 0; + } + break; + case OP_div: + { + JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + sp[-2] = js_number((double)v1 / (double)v2); + JS_X87_FPCW_RESTORE(fpcw); + } + return 0; + case OP_mod: + if (v1 < 0 || v2 <= 0) { + JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + sp[-2] = js_number(fmod(v1, v2)); + JS_X87_FPCW_RESTORE(fpcw); + return 0; + } else { + v = (int64_t)v1 % (int64_t)v2; + } + break; + case OP_pow: + sp[-2] = js_number(js_math_pow(v1, v2)); + return 0; + default: + abort(); + } + sp[-2] = js_int64(v); + } else if ((tag1 == JS_TAG_SHORT_BIG_INT || tag1 == JS_TAG_BIG_INT) && + (tag2 == JS_TAG_SHORT_BIG_INT || tag2 == JS_TAG_BIG_INT)) { + JSBigInt *p1, *p2, *r; + JSBigIntBuf buf1, buf2; + slow_big_int: + /* bigint result */ + if (JS_VALUE_GET_TAG(op1) == JS_TAG_SHORT_BIG_INT) + p1 = js_bigint_set_short(&buf1, op1); + else + p1 = JS_VALUE_GET_PTR(op1); + if (JS_VALUE_GET_TAG(op2) == JS_TAG_SHORT_BIG_INT) + p2 = js_bigint_set_short(&buf2, op2); + else + p2 = JS_VALUE_GET_PTR(op2); + switch(op) { + case OP_add: + r = js_bigint_add(ctx, p1, p2, 0); + break; + case OP_sub: + r = js_bigint_add(ctx, p1, p2, 1); + break; + case OP_mul: + r = js_bigint_mul(ctx, p1, p2); + break; + case OP_div: + r = js_bigint_divrem(ctx, p1, p2, false); + break; + case OP_mod: + r = js_bigint_divrem(ctx, p1, p2, true); + break; + case OP_pow: + r = js_bigint_pow(ctx, p1, p2); + break; + default: + abort(); + } + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + if (!r) + goto exception; + sp[-2] = JS_CompactBigInt(ctx, r); + } else { + double dr; + /* float64 result */ + if (JS_ToFloat64Free(ctx, &d1, op1)) { + JS_FreeValue(ctx, op2); + goto exception; + } + if (JS_ToFloat64Free(ctx, &d2, op2)) + goto exception; + handle_float64: + JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + switch(op) { + case OP_sub: + dr = d1 - d2; + break; + case OP_mul: + dr = d1 * d2; + break; + case OP_div: + dr = d1 / d2; + break; + case OP_mod: + dr = fmod(d1, d2); + break; + case OP_pow: + dr = js_math_pow(d1, d2); + break; + default: + abort(); + } + JS_X87_FPCW_RESTORE(fpcw); + sp[-2] = js_float64(dr); + } + return 0; + exception: + sp[-2] = JS_UNDEFINED; + sp[-1] = JS_UNDEFINED; + return -1; +} + +static no_inline __exception int js_add_slow(JSContext *ctx, JSValue *sp) +{ + JSValue op1, op2; + uint32_t tag1, tag2; + + op1 = sp[-2]; + op2 = sp[-1]; + + tag1 = JS_VALUE_GET_NORM_TAG(op1); + tag2 = JS_VALUE_GET_NORM_TAG(op2); + /* fast path for float64 */ + if (tag1 == JS_TAG_FLOAT64 && tag2 == JS_TAG_FLOAT64) { + double d1, d2; + d1 = JS_VALUE_GET_FLOAT64(op1); + d2 = JS_VALUE_GET_FLOAT64(op2); + sp[-2] = js_float64(d1 + d2); + return 0; + } + /* fast path for short bigint */ + if (tag1 == JS_TAG_SHORT_BIG_INT && tag2 == JS_TAG_SHORT_BIG_INT) { + js_slimb_t v1, v2; + js_sdlimb_t v; + v1 = JS_VALUE_GET_SHORT_BIG_INT(op1); + v2 = JS_VALUE_GET_SHORT_BIG_INT(op2); + v = (js_sdlimb_t)v1 + (js_sdlimb_t)v2; + if (likely(v >= JS_SHORT_BIG_INT_MIN && v <= JS_SHORT_BIG_INT_MAX)) { + sp[-2] = __JS_NewShortBigInt(ctx, v); + } else { + JSBigInt *r = js_bigint_new_di(ctx, v); + if (!r) + goto exception; + sp[-2] = JS_MKPTR(JS_TAG_BIG_INT, r); + } + return 0; + } + + if (tag1 == JS_TAG_OBJECT || tag2 == JS_TAG_OBJECT) { + op1 = JS_ToPrimitiveFree(ctx, op1, HINT_NONE); + if (JS_IsException(op1)) { + JS_FreeValue(ctx, op2); + goto exception; + } + + op2 = JS_ToPrimitiveFree(ctx, op2, HINT_NONE); + if (JS_IsException(op2)) { + JS_FreeValue(ctx, op1); + goto exception; + } + tag1 = JS_VALUE_GET_NORM_TAG(op1); + tag2 = JS_VALUE_GET_NORM_TAG(op2); + } + + if (tag_is_string(tag1) || tag_is_string(tag2)) { + sp[-2] = JS_ConcatString(ctx, op1, op2); + if (JS_IsException(sp[-2])) + goto exception; + return 0; + } + + op1 = JS_ToNumericFree(ctx, op1); + if (JS_IsException(op1)) { + JS_FreeValue(ctx, op2); + goto exception; + } + op2 = JS_ToNumericFree(ctx, op2); + if (JS_IsException(op2)) { + JS_FreeValue(ctx, op1); + goto exception; + } + tag1 = JS_VALUE_GET_NORM_TAG(op1); + tag2 = JS_VALUE_GET_NORM_TAG(op2); + + if (tag1 == JS_TAG_INT && tag2 == JS_TAG_INT) { + int32_t v1, v2; + int64_t v; + v1 = JS_VALUE_GET_INT(op1); + v2 = JS_VALUE_GET_INT(op2); + v = (int64_t)v1 + (int64_t)v2; + sp[-2] = js_int64(v); + } else if ((tag1 == JS_TAG_BIG_INT || tag1 == JS_TAG_SHORT_BIG_INT) && + (tag2 == JS_TAG_BIG_INT || tag2 == JS_TAG_SHORT_BIG_INT)) { + JSBigInt *p1, *p2, *r; + JSBigIntBuf buf1, buf2; + /* bigint result */ + if (JS_VALUE_GET_TAG(op1) == JS_TAG_SHORT_BIG_INT) + p1 = js_bigint_set_short(&buf1, op1); + else + p1 = JS_VALUE_GET_PTR(op1); + if (JS_VALUE_GET_TAG(op2) == JS_TAG_SHORT_BIG_INT) + p2 = js_bigint_set_short(&buf2, op2); + else + p2 = JS_VALUE_GET_PTR(op2); + r = js_bigint_add(ctx, p1, p2, 0); + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + if (!r) + goto exception; + sp[-2] = JS_CompactBigInt(ctx, r); + } else { + double d1, d2; + /* float64 result */ + if (JS_ToFloat64Free(ctx, &d1, op1)) { + JS_FreeValue(ctx, op2); + goto exception; + } + if (JS_ToFloat64Free(ctx, &d2, op2)) + goto exception; + JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + sp[-2] = js_float64(d1 + d2); + JS_X87_FPCW_RESTORE(fpcw); + } + return 0; + exception: + sp[-2] = JS_UNDEFINED; + sp[-1] = JS_UNDEFINED; + return -1; +} + +static no_inline __exception int js_binary_logic_slow(JSContext *ctx, + JSValue *sp, + OPCodeEnum op) +{ + JSValue op1, op2; + uint32_t tag1, tag2; + uint32_t v1, v2, r; + + op1 = sp[-2]; + op2 = sp[-1]; + tag1 = JS_VALUE_GET_NORM_TAG(op1); + tag2 = JS_VALUE_GET_NORM_TAG(op2); + + if (tag1 == JS_TAG_SHORT_BIG_INT && tag2 == JS_TAG_SHORT_BIG_INT) { + js_slimb_t v1, v2, v; + js_sdlimb_t vd; + v1 = JS_VALUE_GET_SHORT_BIG_INT(op1); + v2 = JS_VALUE_GET_SHORT_BIG_INT(op2); + /* bigint fast path */ + switch(op) { + case OP_and: + v = v1 & v2; + break; + case OP_or: + v = v1 | v2; + break; + case OP_xor: + v = v1 ^ v2; + break; + case OP_sar: + if (v2 > (JS_LIMB_BITS - 1)) { + goto slow_big_int; + } else if (v2 < 0) { + if (v2 < -(JS_LIMB_BITS - 1)) + goto slow_big_int; + v2 = -v2; + goto bigint_shl; + } + bigint_sar: + v = v1 >> v2; + break; + case OP_shl: + if (v2 > (JS_LIMB_BITS - 1)) { + goto slow_big_int; + } else if (v2 < 0) { + if (v2 < -(JS_LIMB_BITS - 1)) + goto slow_big_int; + v2 = -v2; + goto bigint_sar; + } + bigint_shl: + vd = (js_dlimb_t)v1 << v2; + if (likely(vd >= JS_SHORT_BIG_INT_MIN && + vd <= JS_SHORT_BIG_INT_MAX)) { + v = vd; + } else { + JSBigInt *r = js_bigint_new_di(ctx, vd); + if (!r) + goto exception; + sp[-2] = JS_MKPTR(JS_TAG_BIG_INT, r); + return 0; + } + break; + default: + abort(); + } + sp[-2] = __JS_NewShortBigInt(ctx, v); + return 0; + } + op1 = JS_ToNumericFree(ctx, op1); + if (JS_IsException(op1)) { + JS_FreeValue(ctx, op2); + goto exception; + } + op2 = JS_ToNumericFree(ctx, op2); + if (JS_IsException(op2)) { + JS_FreeValue(ctx, op1); + goto exception; + } + + tag1 = JS_VALUE_GET_TAG(op1); + tag2 = JS_VALUE_GET_TAG(op2); + if ((tag1 == JS_TAG_BIG_INT || tag1 == JS_TAG_SHORT_BIG_INT) && + (tag2 == JS_TAG_BIG_INT || tag2 == JS_TAG_SHORT_BIG_INT)) { + JSBigInt *p1, *p2, *r; + JSBigIntBuf buf1, buf2; + slow_big_int: + /* buf2 is zero-initialized here (after the label, so it also runs on + the goto slow_big_int paths) to silence a -Wmaybe-uninitialized + false positive: GCC cannot prove buf2 is initialized through the + inlined js_bigint_get_si_sat() -> js_bigint_sign() read below. */ + memset(&buf2, 0, sizeof(buf2)); + if (JS_VALUE_GET_TAG(op1) == JS_TAG_SHORT_BIG_INT) + p1 = js_bigint_set_short(&buf1, op1); + else + p1 = JS_VALUE_GET_PTR(op1); + if (JS_VALUE_GET_TAG(op2) == JS_TAG_SHORT_BIG_INT) + p2 = js_bigint_set_short(&buf2, op2); + else + p2 = JS_VALUE_GET_PTR(op2); + switch(op) { + case OP_and: + case OP_or: + case OP_xor: + r = js_bigint_logic(ctx, p1, p2, op); + break; + case OP_shl: + case OP_sar: + { + js_slimb_t shift; + shift = js_bigint_get_si_sat(p2); + if (shift > INT32_MAX) + shift = INT32_MAX; + else if (shift < -INT32_MAX) + shift = -INT32_MAX; + if (op == OP_sar) + shift = -shift; + if (shift >= 0) + r = js_bigint_shl(ctx, p1, shift); + else + r = js_bigint_shr(ctx, p1, -shift); + } + break; + default: + abort(); + } + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + if (!r) + goto exception; + sp[-2] = JS_CompactBigInt(ctx, r); + } else { + if (unlikely(JS_ToInt32Free(ctx, (int32_t *)&v1, op1))) { + JS_FreeValue(ctx, op2); + goto exception; + } + if (unlikely(JS_ToInt32Free(ctx, (int32_t *)&v2, op2))) + goto exception; + switch(op) { + case OP_shl: + r = v1 << (v2 & 0x1f); + break; + case OP_sar: + r = (int)v1 >> (v2 & 0x1f); + break; + case OP_and: + r = v1 & v2; + break; + case OP_or: + r = v1 | v2; + break; + case OP_xor: + r = v1 ^ v2; + break; + default: + abort(); + } + sp[-2] = js_int32(r); + } + return 0; + exception: + sp[-2] = JS_UNDEFINED; + sp[-1] = JS_UNDEFINED; + return -1; +} + +/* op1 must be a bigint or int. */ +static JSBigInt *JS_ToBigIntBuf(JSContext *ctx, JSBigIntBuf *buf1, + JSValue op1) +{ + JSBigInt *p1; + + switch(JS_VALUE_GET_TAG(op1)) { + case JS_TAG_INT: + p1 = js_bigint_set_si(buf1, JS_VALUE_GET_INT(op1)); + break; + case JS_TAG_SHORT_BIG_INT: + p1 = js_bigint_set_short(buf1, op1); + break; + case JS_TAG_BIG_INT: + p1 = JS_VALUE_GET_PTR(op1); + break; + default: + abort(); + } + return p1; +} + +/* op1 and op2 must be numeric types and at least one must be a + bigint. No exception is generated. */ +static int js_compare_bigint(JSContext *ctx, OPCodeEnum op, + JSValue op1, JSValue op2) +{ + int res, val, tag1, tag2; + JSBigIntBuf buf1, buf2; + JSBigInt *p1, *p2; + + tag1 = JS_VALUE_GET_NORM_TAG(op1); + tag2 = JS_VALUE_GET_NORM_TAG(op2); + if ((tag1 == JS_TAG_SHORT_BIG_INT || tag1 == JS_TAG_INT) && + (tag2 == JS_TAG_SHORT_BIG_INT || tag2 == JS_TAG_INT)) { + /* fast path */ + js_slimb_t v1, v2; + if (tag1 == JS_TAG_INT) + v1 = JS_VALUE_GET_INT(op1); + else + v1 = JS_VALUE_GET_SHORT_BIG_INT(op1); + if (tag2 == JS_TAG_INT) + v2 = JS_VALUE_GET_INT(op2); + else + v2 = JS_VALUE_GET_SHORT_BIG_INT(op2); + val = (v1 > v2) - (v1 < v2); + } else { + if (tag1 == JS_TAG_FLOAT64) { + p2 = JS_ToBigIntBuf(ctx, &buf2, op2); + val = js_bigint_float64_cmp(ctx, p2, JS_VALUE_GET_FLOAT64(op1)); + if (val == 2) + goto unordered; + val = -val; + } else if (tag2 == JS_TAG_FLOAT64) { + p1 = JS_ToBigIntBuf(ctx, &buf1, op1); + val = js_bigint_float64_cmp(ctx, p1, JS_VALUE_GET_FLOAT64(op2)); + if (val == 2) { + unordered: + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + return false; + } + } else { + p1 = JS_ToBigIntBuf(ctx, &buf1, op1); + p2 = JS_ToBigIntBuf(ctx, &buf2, op2); + val = js_bigint_cmp(ctx, p1, p2); + } + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + } + + switch(op) { + case OP_lt: + res = val < 0; + break; + case OP_lte: + res = val <= 0; + break; + case OP_gt: + res = val > 0; + break; + case OP_gte: + res = val >= 0; + break; + case OP_eq: + res = val == 0; + break; + default: + abort(); + } + return res; +} + +static no_inline int js_relational_slow(JSContext *ctx, JSValue *sp, + OPCodeEnum op) +{ + JSValue op1, op2; + int res; + uint32_t tag1, tag2; + + op1 = sp[-2]; + op2 = sp[-1]; + tag1 = JS_VALUE_GET_NORM_TAG(op1); + tag2 = JS_VALUE_GET_NORM_TAG(op2); + + op1 = JS_ToPrimitiveFree(ctx, op1, HINT_NUMBER); + if (JS_IsException(op1)) { + JS_FreeValue(ctx, op2); + goto exception; + } + op2 = JS_ToPrimitiveFree(ctx, op2, HINT_NUMBER); + if (JS_IsException(op2)) { + JS_FreeValue(ctx, op1); + goto exception; + } + tag1 = JS_VALUE_GET_NORM_TAG(op1); + tag2 = JS_VALUE_GET_NORM_TAG(op2); + + if (tag_is_string(tag1) && tag_is_string(tag2)) { + if (tag1 == JS_TAG_STRING && tag2 == JS_TAG_STRING) { + res = js_string_compare(JS_VALUE_GET_STRING(op1), + JS_VALUE_GET_STRING(op2)); + } else { + res = js_string_rope_compare(op1, op2, false); + } + switch(op) { + case OP_lt: + res = (res < 0); + break; + case OP_lte: + res = (res <= 0); + break; + case OP_gt: + res = (res > 0); + break; + default: + case OP_gte: + res = (res >= 0); + break; + } + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + } else if ((tag1 <= JS_TAG_NULL || tag1 == JS_TAG_FLOAT64) && + (tag2 <= JS_TAG_NULL || tag2 == JS_TAG_FLOAT64)) { + /* fast path for float64/int */ + goto float64_compare; + } else { + if ((((tag1 == JS_TAG_BIG_INT || tag1 == JS_TAG_SHORT_BIG_INT) && + tag2 == JS_TAG_STRING) || + ((tag2 == JS_TAG_BIG_INT || tag2 == JS_TAG_SHORT_BIG_INT) && + tag1 == JS_TAG_STRING))) { + if (tag1 == JS_TAG_STRING) { + op1 = JS_StringToBigInt(ctx, op1); + if (JS_VALUE_GET_TAG(op1) != JS_TAG_BIG_INT && + JS_VALUE_GET_TAG(op1) != JS_TAG_SHORT_BIG_INT) + goto invalid_bigint_string; + } + if (tag2 == JS_TAG_STRING) { + op2 = JS_StringToBigInt(ctx, op2); + if (JS_VALUE_GET_TAG(op2) != JS_TAG_BIG_INT && + JS_VALUE_GET_TAG(op2) != JS_TAG_SHORT_BIG_INT) { + invalid_bigint_string: + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + res = false; + goto done; + } + } + } else { + op1 = JS_ToNumericFree(ctx, op1); + if (JS_IsException(op1)) { + JS_FreeValue(ctx, op2); + goto exception; + } + op2 = JS_ToNumericFree(ctx, op2); + if (JS_IsException(op2)) { + JS_FreeValue(ctx, op1); + goto exception; + } + } + + tag1 = JS_VALUE_GET_NORM_TAG(op1); + tag2 = JS_VALUE_GET_NORM_TAG(op2); + + if (tag1 == JS_TAG_BIG_INT || tag1 == JS_TAG_SHORT_BIG_INT || + tag2 == JS_TAG_BIG_INT || tag2 == JS_TAG_SHORT_BIG_INT) { + res = js_compare_bigint(ctx, op, op1, op2); + } else { + double d1, d2; + + float64_compare: + /* can use floating point comparison */ + if (tag1 == JS_TAG_FLOAT64) { + d1 = JS_VALUE_GET_FLOAT64(op1); + } else { + d1 = JS_VALUE_GET_INT(op1); + } + if (tag2 == JS_TAG_FLOAT64) { + d2 = JS_VALUE_GET_FLOAT64(op2); + } else { + d2 = JS_VALUE_GET_INT(op2); + } + switch(op) { + case OP_lt: + res = (d1 < d2); /* if NaN return false */ + break; + case OP_lte: + res = (d1 <= d2); /* if NaN return false */ + break; + case OP_gt: + res = (d1 > d2); /* if NaN return false */ + break; + default: + case OP_gte: + res = (d1 >= d2); /* if NaN return false */ + break; + } + } + } + done: + sp[-2] = js_bool(res); + return 0; + exception: + sp[-2] = JS_UNDEFINED; + sp[-1] = JS_UNDEFINED; + return -1; +} + +static bool tag_is_number(uint32_t tag) +{ + return (tag == JS_TAG_INT || + tag == JS_TAG_FLOAT64 || + tag == JS_TAG_BIG_INT || tag == JS_TAG_SHORT_BIG_INT); +} + +static no_inline __exception int js_eq_slow(JSContext *ctx, JSValue *sp, + bool is_neq) +{ + JSValue op1, op2; + int res; + uint32_t tag1, tag2; + + op1 = sp[-2]; + op2 = sp[-1]; + redo: + tag1 = JS_VALUE_GET_NORM_TAG(op1); + tag2 = JS_VALUE_GET_NORM_TAG(op2); + if (tag_is_number(tag1) && tag_is_number(tag2)) { + if (tag1 == JS_TAG_INT && tag2 == JS_TAG_INT) { + res = JS_VALUE_GET_INT(op1) == JS_VALUE_GET_INT(op2); + } else if ((tag1 == JS_TAG_FLOAT64 && + (tag2 == JS_TAG_INT || tag2 == JS_TAG_FLOAT64)) || + (tag2 == JS_TAG_FLOAT64 && + (tag1 == JS_TAG_INT || tag1 == JS_TAG_FLOAT64))) { + double d1, d2; + if (tag1 == JS_TAG_FLOAT64) { + d1 = JS_VALUE_GET_FLOAT64(op1); + } else { + d1 = JS_VALUE_GET_INT(op1); + } + if (tag2 == JS_TAG_FLOAT64) { + d2 = JS_VALUE_GET_FLOAT64(op2); + } else { + d2 = JS_VALUE_GET_INT(op2); + } + res = (d1 == d2); + } else { + res = js_compare_bigint(ctx, OP_eq, op1, op2); + if (res < 0) + goto exception; + } + } else if (tag1 == tag2) { + res = js_strict_eq2(ctx, op1, op2, JS_EQ_STRICT); + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + } else if ((tag1 == JS_TAG_NULL && tag2 == JS_TAG_UNDEFINED) || + (tag2 == JS_TAG_NULL && tag1 == JS_TAG_UNDEFINED)) { + res = true; + } else if ((tag_is_string(tag1) && tag_is_number(tag2)) || + (tag_is_string(tag2) && tag_is_number(tag1))) { + + if (tag1 == JS_TAG_BIG_INT || tag1 == JS_TAG_SHORT_BIG_INT || + tag2 == JS_TAG_BIG_INT || tag2 == JS_TAG_SHORT_BIG_INT) { + if (tag_is_string(tag1)) { + op1 = JS_StringToBigInt(ctx, op1); + if (JS_VALUE_GET_TAG(op1) != JS_TAG_BIG_INT && + JS_VALUE_GET_TAG(op1) != JS_TAG_SHORT_BIG_INT) + goto invalid_bigint_string; + } + if (tag_is_string(tag2)) { + op2 = JS_StringToBigInt(ctx, op2); + if (JS_VALUE_GET_TAG(op2) != JS_TAG_BIG_INT && + JS_VALUE_GET_TAG(op2) != JS_TAG_SHORT_BIG_INT ) { + invalid_bigint_string: + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + res = false; + goto done; + } + } + } else { + op1 = JS_ToNumericFree(ctx, op1); + if (JS_IsException(op1)) { + JS_FreeValue(ctx, op2); + goto exception; + } + op2 = JS_ToNumericFree(ctx, op2); + if (JS_IsException(op2)) { + JS_FreeValue(ctx, op1); + goto exception; + } + } + res = js_strict_eq(ctx, op1, op2); + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + } else if (tag1 == JS_TAG_BOOL) { + op1 = js_int32(JS_VALUE_GET_INT(op1)); + goto redo; + } else if (tag2 == JS_TAG_BOOL) { + op2 = js_int32(JS_VALUE_GET_INT(op2)); + goto redo; + } else if ((tag1 == JS_TAG_OBJECT && + (tag_is_number(tag2) || tag_is_string(tag2) || tag2 == JS_TAG_SYMBOL)) || + (tag2 == JS_TAG_OBJECT && + (tag_is_number(tag1) || tag_is_string(tag1) || tag1 == JS_TAG_SYMBOL))) { + op1 = JS_ToPrimitiveFree(ctx, op1, HINT_NONE); + if (JS_IsException(op1)) { + JS_FreeValue(ctx, op2); + goto exception; + } + op2 = JS_ToPrimitiveFree(ctx, op2, HINT_NONE); + if (JS_IsException(op2)) { + JS_FreeValue(ctx, op1); + goto exception; + } + goto redo; + } else { + /* IsHTMLDDA object is equivalent to undefined for '==' and '!=' */ + if ((JS_IsHTMLDDA(ctx, op1) && + (tag2 == JS_TAG_NULL || tag2 == JS_TAG_UNDEFINED)) || + (JS_IsHTMLDDA(ctx, op2) && + (tag1 == JS_TAG_NULL || tag1 == JS_TAG_UNDEFINED))) { + res = true; + } else { + res = false; + } + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + } + done: + sp[-2] = js_bool(res ^ is_neq); + return 0; + exception: + sp[-2] = JS_UNDEFINED; + sp[-1] = JS_UNDEFINED; + return -1; +} + +static no_inline int js_shr_slow(JSContext *ctx, JSValue *sp) +{ + JSValue op1, op2; + uint32_t v1, v2, r; + + op1 = sp[-2]; + op2 = sp[-1]; + op1 = JS_ToNumericFree(ctx, op1); + if (JS_IsException(op1)) { + JS_FreeValue(ctx, op2); + goto exception; + } + op2 = JS_ToNumericFree(ctx, op2); + if (JS_IsException(op2)) { + JS_FreeValue(ctx, op1); + goto exception; + } + + if (JS_VALUE_GET_TAG(op1) == JS_TAG_BIG_INT || + JS_VALUE_GET_TAG(op1) == JS_TAG_SHORT_BIG_INT || + JS_VALUE_GET_TAG(op2) == JS_TAG_BIG_INT || + JS_VALUE_GET_TAG(op2) == JS_TAG_SHORT_BIG_INT) { + JS_ThrowTypeError(ctx, "BigInt operands are forbidden for >>>"); + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + goto exception; + } + /* cannot give an exception */ + JS_ToUint32Free(ctx, &v1, op1); + JS_ToUint32Free(ctx, &v2, op2); + r = v1 >> (v2 & 0x1f); + sp[-2] = js_uint32(r); + return 0; + exception: + sp[-2] = JS_UNDEFINED; + sp[-1] = JS_UNDEFINED; + return -1; +} + +static bool js_strict_eq2(JSContext *ctx, JSValueConst op1, JSValueConst op2, + JSStrictEqModeEnum eq_mode) +{ + bool res; + int tag1, tag2; + double d1, d2; + + tag1 = JS_VALUE_GET_NORM_TAG(op1); + tag2 = JS_VALUE_GET_NORM_TAG(op2); + switch(tag1) { + case JS_TAG_BOOL: + if (tag1 != tag2) { + res = false; + } else { + res = JS_VALUE_GET_INT(op1) == JS_VALUE_GET_INT(op2); + } + break; + case JS_TAG_NULL: + case JS_TAG_UNDEFINED: + res = (tag1 == tag2); + break; + case JS_TAG_STRING: + case JS_TAG_STRING_ROPE: + { + if (!tag_is_string(tag2)) { + res = false; + } else if (tag1 == JS_TAG_STRING && tag2 == JS_TAG_STRING) { + res = js_string_eq(JS_VALUE_GET_STRING(op1), + JS_VALUE_GET_STRING(op2)); + } else { + res = (js_string_rope_compare(op1, op2, true) == 0); + } + } + break; + case JS_TAG_SYMBOL: + { + JSAtomStruct *p1, *p2; + if (tag1 != tag2) { + res = false; + } else { + p1 = JS_VALUE_GET_PTR(op1); + p2 = JS_VALUE_GET_PTR(op2); + res = (p1 == p2); + } + } + break; + case JS_TAG_OBJECT: + if (tag1 != tag2) + res = false; + else + res = JS_VALUE_GET_OBJ(op1) == JS_VALUE_GET_OBJ(op2); + break; + case JS_TAG_INT: + d1 = JS_VALUE_GET_INT(op1); + if (tag2 == JS_TAG_INT) { + d2 = JS_VALUE_GET_INT(op2); + goto number_test; + } else if (tag2 == JS_TAG_FLOAT64) { + d2 = JS_VALUE_GET_FLOAT64(op2); + goto number_test; + } else { + res = false; + } + break; + case JS_TAG_FLOAT64: + d1 = JS_VALUE_GET_FLOAT64(op1); + if (tag2 == JS_TAG_FLOAT64) { + d2 = JS_VALUE_GET_FLOAT64(op2); + } else if (tag2 == JS_TAG_INT) { + d2 = JS_VALUE_GET_INT(op2); + } else { + res = false; + break; + } + number_test: + if (unlikely(eq_mode >= JS_EQ_SAME_VALUE)) { + JSFloat64Union u1, u2; + /* NaN is not always normalized, so this test is necessary */ + if (isnan(d1) || isnan(d2)) { + res = isnan(d1) == isnan(d2); + } else if (eq_mode == JS_EQ_SAME_VALUE_ZERO) { + res = (d1 == d2); /* +0 == -0 */ + } else { + u1.d = d1; + u2.d = d2; + res = (u1.u64 == u2.u64); /* +0 != -0 */ + } + } else { + res = (d1 == d2); /* if NaN return false and +0 == -0 */ + } + break; + case JS_TAG_SHORT_BIG_INT: + case JS_TAG_BIG_INT: + { + JSBigIntBuf buf1, buf2; + JSBigInt *p1, *p2; + + if (tag2 != JS_TAG_SHORT_BIG_INT && + tag2 != JS_TAG_BIG_INT) { + res = false; + break; + } + + if (JS_VALUE_GET_TAG(op1) == JS_TAG_SHORT_BIG_INT) + p1 = js_bigint_set_short(&buf1, op1); + else + p1 = JS_VALUE_GET_PTR(op1); + if (JS_VALUE_GET_TAG(op2) == JS_TAG_SHORT_BIG_INT) + p2 = js_bigint_set_short(&buf2, op2); + else + p2 = JS_VALUE_GET_PTR(op2); + res = (js_bigint_cmp(ctx, p1, p2) == 0); + } + break; + default: + res = false; + break; + } + return res; +} + +static bool js_strict_eq(JSContext *ctx, JSValueConst op1, JSValueConst op2) +{ + return js_strict_eq2(ctx, op1, op2, JS_EQ_STRICT); +} + +static bool js_same_value(JSContext *ctx, JSValueConst op1, JSValueConst op2) +{ + return js_strict_eq2(ctx, op1, op2, JS_EQ_SAME_VALUE); +} + +static bool js_same_value_zero(JSContext *ctx, JSValueConst op1, JSValueConst op2) +{ + return js_strict_eq2(ctx, op1, op2, JS_EQ_SAME_VALUE_ZERO); +} + +static no_inline int js_strict_eq_slow(JSContext *ctx, JSValue *sp, + bool is_neq) +{ + bool res; + res = js_strict_eq(ctx, sp[-2], sp[-1]); + JS_FreeValue(ctx, sp[-2]); + JS_FreeValue(ctx, sp[-1]); + sp[-2] = js_bool(res ^ is_neq); + return 0; +} + +static __exception int js_operator_in(JSContext *ctx, JSValue *sp) +{ + JSValue op1, op2; + JSAtom atom; + int ret; + + op1 = sp[-2]; + op2 = sp[-1]; + + if (JS_VALUE_GET_TAG(op2) != JS_TAG_OBJECT) { + JS_ThrowTypeError(ctx, "invalid 'in' operand"); + return -1; + } + atom = JS_ValueToAtom(ctx, op1); + if (unlikely(atom == JS_ATOM_NULL)) + return -1; + ret = JS_HasProperty(ctx, op2, atom); + JS_FreeAtom(ctx, atom); + if (ret < 0) + return -1; + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + sp[-2] = js_bool(ret); + return 0; +} + +static __exception int js_operator_private_in(JSContext *ctx, JSValue *sp) +{ + JSValue op1, op2; + int ret; + op1 = sp[-2]; /* object */ + op2 = sp[-1]; /* field name or method function */ + if (JS_VALUE_GET_TAG(op1) != JS_TAG_OBJECT) { + JS_ThrowTypeError(ctx, "invalid 'in' operand"); + return -1; + } + if (JS_IsObject(op2)) { + /* method: use the brand */ + ret = JS_CheckBrand(ctx, op1, op2); + if (ret < 0) + return -1; + } else { + JSAtom atom; + JSObject *p; + JSShapeProperty *prs; + JSProperty *pr; + /* field */ + atom = JS_ValueToAtom(ctx, op2); + if (unlikely(atom == JS_ATOM_NULL)) + return -1; + p = JS_VALUE_GET_OBJ(op1); + prs = find_own_property(&pr, p, atom); + JS_FreeAtom(ctx, atom); + ret = (prs != NULL); + } + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + sp[-2] = js_bool(ret); + return 0; +} + +static __exception int js_has_unscopable(JSContext *ctx, JSValue obj, + JSAtom atom) +{ + JSValue arr, val; + int ret; + + arr = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_unscopables); + if (JS_IsException(arr)) + return -1; + ret = 0; + if (JS_IsObject(arr)) { + val = JS_GetProperty(ctx, arr, atom); + ret = JS_ToBoolFree(ctx, val); + } + JS_FreeValue(ctx, arr); + return ret; +} + +static __exception int js_operator_instanceof(JSContext *ctx, JSValue *sp) +{ + JSValue op1, op2; + int ret; + + op1 = sp[-2]; + op2 = sp[-1]; + ret = JS_IsInstanceOf(ctx, op1, op2); + if (ret < 0) + return ret; + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + sp[-2] = js_bool(ret); + return 0; +} + +static __exception int js_operator_typeof(JSContext *ctx, JSValue op1) +{ + JSAtom atom; + uint32_t tag; + + tag = JS_VALUE_GET_NORM_TAG(op1); + switch(tag) { + case JS_TAG_SHORT_BIG_INT: + case JS_TAG_BIG_INT: + atom = JS_ATOM_bigint; + break; + case JS_TAG_INT: + case JS_TAG_FLOAT64: + atom = JS_ATOM_number; + break; + case JS_TAG_UNDEFINED: + atom = JS_ATOM_undefined; + break; + case JS_TAG_BOOL: + atom = JS_ATOM_boolean; + break; + case JS_TAG_STRING: + case JS_TAG_STRING_ROPE: + atom = JS_ATOM_string; + break; + case JS_TAG_OBJECT: + { + JSObject *p; + p = JS_VALUE_GET_OBJ(op1); + if (unlikely(p->is_HTMLDDA)) + atom = JS_ATOM_undefined; + else if (JS_IsFunction(ctx, op1)) + atom = JS_ATOM_function; + else + goto obj_type; + } + break; + case JS_TAG_NULL: + obj_type: + atom = JS_ATOM_object; + break; + case JS_TAG_SYMBOL: + atom = JS_ATOM_symbol; + break; + default: + atom = JS_ATOM_unknown; + break; + } + return atom; +} + +static __exception int js_operator_delete(JSContext *ctx, JSValue *sp) +{ + JSValue op1, op2; + JSAtom atom; + int ret; + + op1 = sp[-2]; + op2 = sp[-1]; + atom = JS_ValueToAtom(ctx, op2); + if (unlikely(atom == JS_ATOM_NULL)) + return -1; + ret = JS_DeleteProperty(ctx, op1, atom, JS_PROP_THROW_STRICT); + JS_FreeAtom(ctx, atom); + if (unlikely(ret < 0)) + return -1; + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + sp[-2] = js_bool(ret); + return 0; +} + +static JSValue js_throw_type_error(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSFunctionBytecode *b = JS_GetFunctionBytecode(this_val); + if (!b || b->is_strict_mode || !b->has_prototype) { + return JS_ThrowTypeError(ctx, "invalid property access"); + } + return JS_UNDEFINED; +} + +static JSValue js_function_proto_fileName(JSContext *ctx, + JSValueConst this_val) +{ + JSFunctionBytecode *b = JS_GetFunctionBytecode(this_val); + if (b) { + return JS_AtomToString(ctx, b->filename); + } + return JS_UNDEFINED; +} + +static JSValue js_function_proto_int32(JSContext *ctx, + JSValueConst this_val, + int magic) +{ + JSFunctionBytecode *b = JS_GetFunctionBytecode(this_val); + if (b) { + int *field = (int *) ((char *)b + magic); + return js_int32(*field); + } + return JS_UNDEFINED; +} + +static int js_arguments_define_own_property(JSContext *ctx, + JSValueConst this_obj, + JSAtom prop, JSValueConst val, + JSValueConst getter, + JSValueConst setter, int flags) +{ + JSObject *p; + uint32_t idx; + p = JS_VALUE_GET_OBJ(this_obj); + /* convert to normal array when redefining an existing numeric field */ + if (p->fast_array && JS_AtomIsArrayIndex(ctx, &idx, prop) && + idx < p->u.array.count) { + if (convert_fast_array_to_array(ctx, p)) + return -1; + } + /* run the default define own property */ + return JS_DefineProperty(ctx, this_obj, prop, val, getter, setter, + flags | JS_PROP_NO_EXOTIC); +} + +static const JSClassExoticMethods js_arguments_exotic_methods = { + .define_own_property = js_arguments_define_own_property, +}; + +static JSValue js_build_arguments(JSContext *ctx, int argc, JSValueConst *argv) +{ + JSValue val, *tab; + JSProperty props[3]; + JSObject *p; + int i; + + props[0].u.value = js_int32(argc); /* length */ + props[1].u.value = js_dup(ctx->array_proto_values); /* Symbol.iterator */ + props[2].u.getset.getter = JS_VALUE_GET_OBJ(js_dup(ctx->throw_type_error)); /* callee */ + props[2].u.getset.setter = JS_VALUE_GET_OBJ(js_dup(ctx->throw_type_error)); /* callee */ + + val = JS_NewObjectFromShape(ctx, js_dup_shape(ctx->arguments_shape), + JS_CLASS_ARGUMENTS, props); + if (JS_IsException(val)) + return val; + p = JS_VALUE_GET_OBJ(val); + + /* initialize the fast array part */ + tab = NULL; + if (argc > 0) { + tab = js_malloc(ctx, sizeof(tab[0]) * argc); + if (!tab) + goto fail; + for(i = 0; i < argc; i++) { + tab[i] = js_dup(argv[i]); + } + } + p->u.array.u.values = tab; + p->u.array.count = argc; + + return val; + fail: + JS_FreeValue(ctx, val); + return JS_EXCEPTION; +} + +#define GLOBAL_VAR_OFFSET 0x40000000 +#define ARGUMENT_VAR_OFFSET 0x20000000 + +static void js_mapped_arguments_finalizer(JSRuntime *rt, JSValueConst val) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + if (p->fast_array) { + JSVarRef **var_refs = p->u.array.u.var_refs; + int i; + if (var_refs) { + for(i = 0; i < p->u.array.count; i++) { + if (var_refs[i]) + free_var_ref(rt, var_refs[i]); + } + js_free_rt(rt, var_refs); + } + } +} + +static void js_mapped_arguments_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + if (p->fast_array) { + JSVarRef **var_refs = p->u.array.u.var_refs; + int i; + if (var_refs) { + for(i = 0; i < p->u.array.count; i++) { + /* mapped arguments hold a counted ref to each var_ref; the + ones that are GC objects (detached, or open capturing a + coroutine local) must be marked, like the other holders */ + JSVarRef *vr = var_refs[i]; + if (vr && (vr->is_detached || vr->is_coro)) + mark_func(rt, &vr->header); + } + } + } +} + +/* legacy arguments object: add references to the function arguments */ +static JSValue js_build_mapped_arguments(JSContext *ctx, int argc, + JSValueConst *argv, + JSStackFrame *sf, int arg_count) +{ + JSValue val; + JSProperty props[3]; + JSVarRef **tab, *var_ref; + JSObject *p; + int i, j; + + props[0].u.value = js_int32(argc); /* length */ + props[1].u.value = js_dup(ctx->array_proto_values); /* Symbol.iterator */ + props[2].u.value = js_dup(ctx->rt->current_stack_frame->cur_func); /* callee */ + + val = JS_NewObjectFromShape(ctx, js_dup_shape(ctx->mapped_arguments_shape), + JS_CLASS_MAPPED_ARGUMENTS, props); + if (JS_IsException(val)) + return val; + p = JS_VALUE_GET_OBJ(val); + + /* initialize the fast array part */ + tab = NULL; + if (argc > 0) { + tab = js_malloc(ctx, sizeof(tab[0]) * argc); + if (!tab) + goto fail; + for(i = 0; i < arg_count; i++) { + var_ref = get_var_ref(ctx, sf, i, true); + if (!var_ref) + goto fail1; + tab[i] = var_ref; + } + for(i = arg_count; i < argc; i++) { + var_ref = js_create_var_ref(ctx, true); + if (!var_ref) { + fail1: + for(j = 0; j < i; j++) + free_var_ref(ctx->rt, tab[j]); + js_free(ctx, tab); + goto fail; + } + var_ref->value = js_dup(argv[i]); + tab[i] = var_ref; + } + } + p->u.array.u.var_refs = tab; + p->u.array.count = argc; + return val; + fail: + JS_FreeValue(ctx, val); + return JS_EXCEPTION; +} + +static JSValue build_for_in_iterator(JSContext *ctx, JSValue obj) +{ + JSObject *p; + JSPropertyEnum *tab_atom; + int i; + JSValue enum_obj, obj1; + JSForInIterator *it; + uint32_t tag, tab_atom_count; + + tag = JS_VALUE_GET_TAG(obj); + if (tag != JS_TAG_OBJECT && tag != JS_TAG_NULL && tag != JS_TAG_UNDEFINED) { + obj = JS_ToObjectFree(ctx, obj); + } + + it = js_malloc(ctx, sizeof(*it)); + if (!it) { + JS_FreeValue(ctx, obj); + return JS_EXCEPTION; + } + enum_obj = JS_NewObjectProtoClass(ctx, JS_NULL, JS_CLASS_FOR_IN_ITERATOR); + if (JS_IsException(enum_obj)) { + js_free(ctx, it); + JS_FreeValue(ctx, obj); + return JS_EXCEPTION; + } + it->is_array = false; + it->obj = obj; + it->idx = 0; + p = JS_VALUE_GET_OBJ(enum_obj); + p->u.for_in_iterator = it; + + if (tag == JS_TAG_NULL || tag == JS_TAG_UNDEFINED) + return enum_obj; + + /* fast path: assume no enumerable properties in the prototype chain */ + obj1 = js_dup(obj); + for(;;) { + obj1 = JS_GetPrototypeFree(ctx, obj1); + if (JS_IsNull(obj1)) + break; + if (JS_IsException(obj1)) + goto fail; + if (JS_GetOwnPropertyNamesInternal(ctx, &tab_atom, &tab_atom_count, + JS_VALUE_GET_OBJ(obj1), + JS_GPN_STRING_MASK | JS_GPN_ENUM_ONLY)) { + JS_FreeValue(ctx, obj1); + goto fail; + } + js_free_prop_enum(ctx, tab_atom, tab_atom_count); + if (tab_atom_count != 0) { + JS_FreeValue(ctx, obj1); + goto slow_path; + } + /* must check for timeout to avoid infinite loop */ + if (js_poll_interrupts(ctx)) { + JS_FreeValue(ctx, obj1); + goto fail; + } + } + + p = JS_VALUE_GET_OBJ(obj); + + if (p->fast_array) { + JSShape *sh; + JSShapeProperty *prs; + /* check that there are no enumerable normal fields */ + sh = p->shape; + for(i = 0, prs = get_shape_prop(sh); i < sh->prop_count; i++, prs++) { + if (prs->flags & JS_PROP_ENUMERABLE) + goto normal_case; + } + /* for fast arrays, we only store the number of elements */ + it->is_array = true; + it->array_length = p->u.array.count; + } else { + normal_case: + if (JS_GetOwnPropertyNamesInternal(ctx, &tab_atom, &tab_atom_count, p, + JS_GPN_STRING_MASK | JS_GPN_ENUM_ONLY)) + goto fail; + for(i = 0; i < tab_atom_count; i++) { + JS_SetPropertyInternal(ctx, enum_obj, tab_atom[i].atom, JS_NULL, 0); + } + js_free_prop_enum(ctx, tab_atom, tab_atom_count); + } + return enum_obj; + + slow_path: + /* non enumerable properties hide the enumerables ones in the + prototype chain */ + obj1 = js_dup(obj); + for(;;) { + if (JS_GetOwnPropertyNamesInternal(ctx, &tab_atom, &tab_atom_count, + JS_VALUE_GET_OBJ(obj1), + JS_GPN_STRING_MASK | JS_GPN_SET_ENUM)) { + JS_FreeValue(ctx, obj1); + goto fail; + } + for(i = 0; i < tab_atom_count; i++) { + JS_DefinePropertyValue(ctx, enum_obj, tab_atom[i].atom, JS_NULL, + (tab_atom[i].is_enumerable ? + JS_PROP_ENUMERABLE : 0)); + } + js_free_prop_enum(ctx, tab_atom, tab_atom_count); + obj1 = JS_GetPrototypeFree(ctx, obj1); + if (JS_IsNull(obj1)) + break; + if (JS_IsException(obj1)) + goto fail; + /* must check for timeout to avoid infinite loop */ + if (js_poll_interrupts(ctx)) { + JS_FreeValue(ctx, obj1); + goto fail; + } + } + return enum_obj; + + fail: + JS_FreeValue(ctx, enum_obj); + return JS_EXCEPTION; +} + +/* obj -> enum_obj */ +static __exception int js_for_in_start(JSContext *ctx, JSValue *sp) +{ + sp[-1] = build_for_in_iterator(ctx, sp[-1]); + if (JS_IsException(sp[-1])) + return -1; + return 0; +} + +/* enum_obj -> enum_obj value done */ +static __exception int js_for_in_next(JSContext *ctx, JSValue *sp) +{ + JSValue enum_obj; + JSObject *p; + JSAtom prop; + JSForInIterator *it; + int ret; + + enum_obj = sp[-1]; + /* fail safe */ + if (JS_VALUE_GET_TAG(enum_obj) != JS_TAG_OBJECT) + goto done; + p = JS_VALUE_GET_OBJ(enum_obj); + if (p->class_id != JS_CLASS_FOR_IN_ITERATOR) + goto done; + it = p->u.for_in_iterator; + + for(;;) { + if (it->is_array) { + if (it->idx >= it->array_length) + goto done; + prop = __JS_AtomFromUInt32(it->idx); + it->idx++; + } else { + JSShape *sh = p->shape; + JSShapeProperty *prs; + if (it->idx >= sh->prop_count) + goto done; + prs = &get_shape_prop(sh)[it->idx]; + prop = prs->atom; + it->idx++; + if (prop == JS_ATOM_NULL || !(prs->flags & JS_PROP_ENUMERABLE)) + continue; + } + // check if the property was deleted unless we're dealing with a proxy + JSValue obj = it->obj; + if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { + JSObject *p = JS_VALUE_GET_OBJ(obj); + if (p->class_id == JS_CLASS_PROXY) + break; + } + ret = JS_HasProperty(ctx, obj, prop); + if (ret < 0) + return ret; + if (ret) + break; + } + /* return the property */ + sp[0] = JS_AtomToValue(ctx, prop); + sp[1] = JS_FALSE; + return 0; + done: + /* return the end */ + sp[0] = JS_UNDEFINED; + sp[1] = JS_TRUE; + return 0; +} + +static JSValue JS_GetIterator2(JSContext *ctx, JSValueConst obj, + JSValueConst method) +{ + JSValue enum_obj; + + enum_obj = JS_Call(ctx, method, obj, 0, NULL); + if (JS_IsException(enum_obj)) + return enum_obj; + if (!JS_IsObject(enum_obj)) { + JS_FreeValue(ctx, enum_obj); + return JS_ThrowTypeErrorNotAnObject(ctx); + } + return enum_obj; +} + +static JSValue JS_GetIterator(JSContext *ctx, JSValueConst obj, bool is_async) +{ + JSValue method, ret, sync_iter; + + if (is_async) { + method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_asyncIterator); + if (JS_IsException(method)) + return method; + if (JS_IsUndefined(method) || JS_IsNull(method)) { + method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_iterator); + if (JS_IsException(method)) + return method; + sync_iter = JS_GetIterator2(ctx, obj, method); + JS_FreeValue(ctx, method); + if (JS_IsException(sync_iter)) + return sync_iter; + ret = JS_CreateAsyncFromSyncIterator(ctx, sync_iter); + JS_FreeValue(ctx, sync_iter); + return ret; + } + } else { + method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_iterator); + if (JS_IsException(method)) + return method; + } + if (!JS_IsFunction(ctx, method)) { + JS_FreeValue(ctx, method); + return JS_ThrowTypeError(ctx, "value is not iterable"); + } + ret = JS_GetIterator2(ctx, obj, method); + JS_FreeValue(ctx, method); + return ret; +} + +/* return *pdone = 2 if the iterator object is not parsed */ +static JSValue JS_IteratorNext2(JSContext *ctx, JSValueConst enum_obj, + JSValueConst method, + int argc, JSValueConst *argv, int *pdone) +{ + JSValue obj; + + /* fast path for the built-in iterators (avoid creating the + intermediate result object) */ + if (JS_IsObject(method)) { + JSObject *p = JS_VALUE_GET_OBJ(method); + if (p->class_id == JS_CLASS_C_FUNCTION && + p->u.cfunc.cproto == JS_CFUNC_iterator_next) { + JSCFunctionType func; + JSValueConst args[1]; + + /* in case the function expects one argument */ + if (argc == 0) { + args[0] = JS_UNDEFINED; + argv = args; + } + func = p->u.cfunc.c_function; + return func.iterator_next(ctx, enum_obj, argc, argv, + pdone, p->u.cfunc.magic); + } + } + obj = JS_Call(ctx, method, enum_obj, argc, argv); + if (JS_IsException(obj)) + goto fail; + if (!JS_IsObject(obj)) { + JS_FreeValue(ctx, obj); + JS_ThrowTypeError(ctx, "iterator must return an object"); + goto fail; + } + *pdone = 2; + return obj; + fail: + *pdone = false; + return JS_EXCEPTION; +} + +static JSValue JS_IteratorNext(JSContext *ctx, JSValueConst enum_obj, + JSValueConst method, + int argc, JSValueConst *argv, int *pdone) +{ + JSValue obj, value, done_val; + int done; + + obj = JS_IteratorNext2(ctx, enum_obj, method, argc, argv, &done); + if (JS_IsException(obj)) + goto fail; + if (likely(done == 0)) { + *pdone = false; + return obj; + } else if (done != 2) { + JS_FreeValue(ctx, obj); + *pdone = true; + return JS_UNDEFINED; + } else { + done_val = JS_GetProperty(ctx, obj, JS_ATOM_done); + if (JS_IsException(done_val)) + goto fail; + *pdone = JS_ToBoolFree(ctx, done_val); + value = JS_UNDEFINED; + if (!*pdone) { + value = JS_GetProperty(ctx, obj, JS_ATOM_value); + } + JS_FreeValue(ctx, obj); + return value; + } + fail: + JS_FreeValue(ctx, obj); + *pdone = false; + return JS_EXCEPTION; +} + +/* return < 0 in case of exception */ +static int JS_IteratorClose(JSContext *ctx, JSValueConst enum_obj, + bool is_exception_pending) +{ + JSValue method, ret, ex_obj; + int res; + + if (is_exception_pending) { + ex_obj = ctx->rt->current_exception; + ctx->rt->current_exception = JS_UNINITIALIZED; + res = -1; + } else { + ex_obj = JS_UNDEFINED; + res = 0; + } + method = JS_GetProperty(ctx, enum_obj, JS_ATOM_return); + if (JS_IsException(method)) { + res = -1; + goto done; + } + if (JS_IsUndefined(method) || JS_IsNull(method)) { + goto done; + } + ret = JS_CallFree(ctx, method, enum_obj, 0, NULL); + if (!is_exception_pending) { + if (JS_IsException(ret)) { + res = -1; + } else if (!JS_IsObject(ret)) { + JS_ThrowTypeErrorNotAnObject(ctx); + res = -1; + } + } + JS_FreeValue(ctx, ret); + done: + if (is_exception_pending) { + JS_Throw(ctx, ex_obj); + } + return res; +} + +/* obj -> enum_rec (3 slots) */ +static __exception int js_for_of_start(JSContext *ctx, JSValue *sp, + bool is_async) +{ + JSValue op1, obj, method; + op1 = sp[-1]; + obj = JS_GetIterator(ctx, op1, is_async); + if (JS_IsException(obj)) + return -1; + JS_FreeValue(ctx, op1); + sp[-1] = obj; + method = JS_GetProperty(ctx, obj, JS_ATOM_next); + if (JS_IsException(method)) + return -1; + sp[0] = method; + return 0; +} + +/* enum_rec [objs] -> enum_rec [objs] value done. There are 'offset' + objs. If 'done' is true or in case of exception, 'enum_rec' is set + to undefined. If 'done' is true, 'value' is always set to + undefined. */ +static __exception int js_for_of_next(JSContext *ctx, JSValue *sp, int offset) +{ + JSValue value = JS_UNDEFINED; + int done = 1; + + if (likely(!JS_IsUndefined(sp[offset]))) { + value = JS_IteratorNext(ctx, sp[offset], sp[offset + 1], 0, NULL, &done); + if (JS_IsException(value)) + done = -1; + if (done) { + /* value is JS_UNDEFINED or JS_EXCEPTION */ + /* replace the iteration object with undefined */ + JS_FreeValue(ctx, sp[offset]); + sp[offset] = JS_UNDEFINED; + if (done < 0) { + return -1; + } else { + JS_FreeValue(ctx, value); + value = JS_UNDEFINED; + } + } + } + sp[0] = value; + sp[1] = js_bool(done); + return 0; +} + +static JSValue JS_IteratorGetCompleteValue(JSContext *ctx, JSValue obj, + int *pdone) +{ + JSValue done_val, value; + int done; + done_val = JS_GetProperty(ctx, obj, JS_ATOM_done); + if (JS_IsException(done_val)) + goto fail; + done = JS_ToBoolFree(ctx, done_val); + value = JS_GetProperty(ctx, obj, JS_ATOM_value); + if (JS_IsException(value)) + goto fail; + *pdone = done; + return value; + fail: + *pdone = false; + return JS_EXCEPTION; +} + +static JSValue js_sync_dispose_wrapper(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, + int magic, JSValueConst *func_data); + +static __exception int js_op_using_check(JSContext *ctx, JSValueConst val, + int hint, JSValue *pmethod) +{ + JSValue method; + bool is_sync_fallback = false; + + *pmethod = JS_UNDEFINED; + if (JS_IsNull(val) || JS_IsUndefined(val)) + return 0; + if (!JS_IsObject(val)) { + JS_ThrowTypeErrorNotAnObject(ctx); + return -1; + } + if (hint == 1) { + method = JS_GetProperty(ctx, val, JS_ATOM_Symbol_asyncDispose); + if (JS_IsException(method)) + return -1; + if (JS_IsUndefined(method) || JS_IsNull(method)) { + JS_FreeValue(ctx, method); + method = JS_GetProperty(ctx, val, JS_ATOM_Symbol_dispose); + if (JS_IsException(method)) + return -1; + is_sync_fallback = true; + } + } else { + method = JS_GetProperty(ctx, val, JS_ATOM_Symbol_dispose); + if (JS_IsException(method)) + return -1; + } + if (JS_IsUndefined(method) || JS_IsNull(method)) { + JS_ThrowTypeError(ctx, "value is not disposable"); + return -1; + } + if (!JS_IsFunction(ctx, method)) { + JS_FreeValue(ctx, method); + JS_ThrowTypeError(ctx, "dispose method is not a function"); + return -1; + } + if (is_sync_fallback) { + JSValueConst data[1]; + JSValue wrapped; + data[0] = method; + wrapped = JS_NewCFunctionData(ctx, js_sync_dispose_wrapper, 0, 0, + 1, data); + JS_FreeValue(ctx, method); + if (JS_IsException(wrapped)) + return -1; + method = wrapped; + } + *pmethod = method; + return 0; +} + +static __exception int js_iterator_get_value_done(JSContext *ctx, JSValue *sp) +{ + JSValue obj, value; + int done; + obj = sp[-1]; + if (!JS_IsObject(obj)) { + JS_ThrowTypeError(ctx, "iterator must return an object"); + return -1; + } + value = JS_IteratorGetCompleteValue(ctx, obj, &done); + if (JS_IsException(value)) + return -1; + JS_FreeValue(ctx, obj); + sp[-1] = value; + sp[0] = js_bool(done); + if (done) { + /* Iterator exhausted via {done:true}: drop the iterator object (stack + layout at the for-await `next` call is iter_obj,next,catch_offset,result + so iter_obj is sp[-4]) so the trailing OP_iterator_close skips calling + return(). Mirrors js_for_of_next, which nulls the iterator on done. + Per spec AsyncIteratorClose must NOT run on normal completion. This op + is emitted only by the for-await-of loop, so the layout is fixed. */ + JS_FreeValue(ctx, sp[-4]); + sp[-4] = JS_UNDEFINED; + } + return 0; +} + +static JSValue js_create_iterator_result(JSContext *ctx, + JSValue val, + bool done) +{ + JSValue obj; + obj = JS_NewObject(ctx); + if (JS_IsException(obj)) { + JS_FreeValue(ctx, val); + return obj; + } + if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_value, + val, JS_PROP_C_W_E) < 0) { + goto fail; + } + if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_done, + js_bool(done), JS_PROP_C_W_E) < 0) { + fail: + JS_FreeValue(ctx, obj); + return JS_EXCEPTION; + } + return obj; +} + +static JSValue js_array_iterator_next(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, + int *pdone, int magic); + +static JSValue js_create_array_iterator(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int magic); + +static bool js_is_fast_array(JSContext *ctx, JSValue obj) +{ + /* Try and handle fast arrays explicitly */ + if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { + JSObject *p = JS_VALUE_GET_OBJ(obj); + if (p->class_id == JS_CLASS_ARRAY && p->fast_array) { + return true; + } + } + return false; +} + +/* Access an Array's internal JSValue array if available */ +static bool js_get_fast_array(JSContext *ctx, JSValue obj, + JSValue **arrpp, uint32_t *countp) +{ + /* Try and handle fast arrays explicitly */ + if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { + JSObject *p = JS_VALUE_GET_OBJ(obj); + if (p->class_id == JS_CLASS_ARRAY && p->fast_array) { + *countp = p->u.array.count; + *arrpp = p->u.array.u.values; + return true; + } + } + return false; +} + +static __exception int js_append_enumerate(JSContext *ctx, JSValue *sp) +{ + JSValue iterator, enumobj, method, value; + int is_array_iterator; + JSValue *arrp; + uint32_t i, count32, pos; + + if (JS_VALUE_GET_TAG(sp[-2]) != JS_TAG_INT) { + JS_ThrowInternalError(ctx, "invalid index for append"); + return -1; + } + + pos = JS_VALUE_GET_INT(sp[-2]); + + /* XXX: further optimisations: + - use ctx->array_proto_values? + - check if array_iterator_prototype next method is built-in and + avoid constructing actual iterator object? + - build this into js_for_of_start and use in all `for (x of o)` loops + */ + iterator = JS_GetProperty(ctx, sp[-1], JS_ATOM_Symbol_iterator); + if (JS_IsException(iterator)) + return -1; + /* Used to squelch a -Wcast-function-type warning. */ + JSCFunctionType ft = { .generic_magic = js_create_array_iterator }; + is_array_iterator = JS_IsCFunction(ctx, iterator, + ft.generic, + JS_ITERATOR_KIND_VALUE); + JS_FreeValue(ctx, iterator); + + enumobj = JS_GetIterator(ctx, sp[-1], false); + if (JS_IsException(enumobj)) + return -1; + method = JS_GetProperty(ctx, enumobj, JS_ATOM_next); + if (JS_IsException(method)) { + JS_FreeValue(ctx, enumobj); + return -1; + } + /* Used to squelch a -Wcast-function-type warning. */ + JSCFunctionType ft2 = { .iterator_next = js_array_iterator_next }; + if (is_array_iterator + && JS_IsCFunction(ctx, method, ft2.generic, 0) + && js_get_fast_array(ctx, sp[-1], &arrp, &count32)) { + uint32_t len; + if (js_get_length32(ctx, &len, sp[-1])) + goto exception; + /* if len > count32, the elements >= count32 might be read in + the prototypes and might have side effects */ + if (len != count32) + goto general_case; + /* Handle fast arrays explicitly */ + for (i = 0; i < count32; i++) { + if (JS_DefinePropertyValueUint32(ctx, sp[-3], pos++, + js_dup(arrp[i]), JS_PROP_C_W_E) < 0) + goto exception; + } + } else { + general_case: + for (;;) { + int done; + value = JS_IteratorNext(ctx, enumobj, method, 0, NULL, &done); + if (JS_IsException(value)) + goto exception; + if (done) { + /* value is JS_UNDEFINED */ + break; + } + if (JS_DefinePropertyValueUint32(ctx, sp[-3], pos++, value, JS_PROP_C_W_E) < 0) + goto exception; + } + } + /* Note: could raise an error if too many elements */ + sp[-2] = js_int32(pos); + JS_FreeValue(ctx, enumobj); + JS_FreeValue(ctx, method); + return 0; + +exception: + JS_IteratorClose(ctx, enumobj, true); + JS_FreeValue(ctx, enumobj); + JS_FreeValue(ctx, method); + return -1; +} + +static __exception int JS_CopyDataProperties(JSContext *ctx, + JSValue target, + JSValue source, + JSValue excluded, + bool setprop) +{ + JSPropertyEnum *tab_atom; + JSValue val; + uint32_t i, tab_atom_count; + JSObject *p; + JSObject *pexcl = NULL; + int ret, gpn_flags; + int desc_flags; + bool is_enumerable; + + if (JS_VALUE_GET_TAG(source) != JS_TAG_OBJECT) + return 0; + + if (JS_VALUE_GET_TAG(excluded) == JS_TAG_OBJECT) + pexcl = JS_VALUE_GET_OBJ(excluded); + + p = JS_VALUE_GET_OBJ(source); + + gpn_flags = JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK | JS_GPN_ENUM_ONLY; + if (p->is_exotic) { + const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; + /* cannot use JS_GPN_ENUM_ONLY with e.g. proxies because it + introduces a visible change */ + if (em && em->get_own_property_names) { + gpn_flags &= ~JS_GPN_ENUM_ONLY; + } + } + if (JS_GetOwnPropertyNamesInternal(ctx, &tab_atom, &tab_atom_count, p, + gpn_flags)) + return -1; + + for (i = 0; i < tab_atom_count; i++) { + if (pexcl) { + ret = JS_GetOwnPropertyInternal(ctx, NULL, pexcl, tab_atom[i].atom); + if (ret) { + if (ret < 0) + goto exception; + continue; + } + } + if (!(gpn_flags & JS_GPN_ENUM_ONLY)) { + /* test if the property is enumerable */ + ret = JS_GetOwnPropertyFlagsInternal(ctx, &desc_flags, p, tab_atom[i].atom); + if (ret < 0) + goto exception; + if (!ret) + continue; + is_enumerable = (desc_flags & JS_PROP_ENUMERABLE) != 0; + if (!is_enumerable) + continue; + } + val = JS_GetProperty(ctx, source, tab_atom[i].atom); + if (JS_IsException(val)) + goto exception; + if (setprop) + ret = JS_SetProperty(ctx, target, tab_atom[i].atom, val); + else + ret = JS_DefinePropertyValue(ctx, target, tab_atom[i].atom, val, + JS_PROP_C_W_E); + if (ret < 0) + goto exception; + } + js_free_prop_enum(ctx, tab_atom, tab_atom_count); + return 0; + exception: + js_free_prop_enum(ctx, tab_atom, tab_atom_count); + return -1; +} + +/* only valid inside C functions */ +static JSValueConst JS_GetActiveFunction(JSContext *ctx) +{ + return ctx->rt->current_stack_frame->cur_func; +} + +/* create a detached var ref */ +static JSVarRef *js_create_var_ref(JSContext *ctx, bool is_gc_object) +{ + JSVarRef *var_ref; + var_ref = js_malloc(ctx, sizeof(JSVarRef)); + if (!var_ref) + return NULL; + JS_REF_COUNT(var_ref) = 1; + var_ref->is_detached = true; + var_ref->is_coro = false; + var_ref->value = JS_UNDEFINED; + var_ref->pvalue = &var_ref->value; + if (is_gc_object) + add_gc_object(ctx->rt, &var_ref->header, JS_GC_OBJ_TYPE_VAR_REF); + return var_ref; +} + +static JSVarRef *get_var_ref(JSContext *ctx, JSStackFrame *sf, int var_idx, + bool is_arg) +{ + JSObject *p; + JSFunctionBytecode *b; + JSVarRef *var_ref; + JSValue *pvalue; + int var_ref_idx; + JSVarDef *vd; + + p = JS_VALUE_GET_OBJ(sf->cur_func); + b = p->u.func.function_bytecode; + + if (is_arg) { + vd = &b->vardefs[var_idx]; + pvalue = &sf->arg_buf[var_idx]; + } else { + vd = &b->vardefs[b->arg_count + var_idx]; + pvalue = &sf->var_buf[var_idx]; + } + + /* If the variable is captured, use the pre-computed index for O(1) lookup */ + if (vd->is_captured) { + var_ref_idx = vd->var_ref_idx; + var_ref = sf->var_refs[var_ref_idx]; + if (var_ref) { + /* reference to the already created local variable */ + JS_REF_COUNT(var_ref)++; + return var_ref; + } + + /* create a new one */ + var_ref = js_malloc(ctx, sizeof(JSVarRef)); + if (!var_ref) + return NULL; + JS_REF_COUNT(var_ref) = 1; + var_ref->is_detached = false; + var_ref->is_lexical = false; + var_ref->is_const = false; + var_ref->var_ref_idx = var_ref_idx; + var_ref->stack_frame = sf; + sf->var_refs[var_ref_idx] = var_ref; + var_ref->pvalue = pvalue; + /* If this local belongs to a coroutine (async function, generator or + async generator), keep the coroutine reachable for as long as a + closure references the variable: make the open var_ref a GC object + holding a counted reference to the coroutine (sf->cur_gc_obj). + Otherwise (ordinary C-stack frame, cur_gc_obj == NULL) the running + function is a GC root and no extra bookkeeping is needed. Snapshot + the decision in is_coro now (cur_gc_obj may become non-NULL later); + the coroutine itself is recovered via stack_frame->cur_gc_obj. */ + var_ref->is_coro = (sf->cur_gc_obj != NULL); + if (sf->cur_gc_obj) { + JS_REF_COUNT(sf->cur_gc_obj)++; + add_gc_object(ctx->rt, &var_ref->header, JS_GC_OBJ_TYPE_VAR_REF); + } + return var_ref; + } else { + /* Variable is not captured (e.g., from eval closures on uncaptured vars). + Create a detached var_ref that holds a copy of the value. */ + var_ref = js_malloc(ctx, sizeof(JSVarRef)); + if (!var_ref) + return NULL; + JS_REF_COUNT(var_ref) = 1; + var_ref->is_detached = true; + var_ref->is_coro = false; + var_ref->value = js_dup(*pvalue); + var_ref->pvalue = &var_ref->value; + add_gc_object(ctx->rt, &var_ref->header, JS_GC_OBJ_TYPE_VAR_REF); + return var_ref; + } +} + +static JSValue js_closure2(JSContext *ctx, JSValue func_obj, + JSFunctionBytecode *b, + JSVarRef **cur_var_refs, + JSStackFrame *sf) +{ + JSObject *p; + JSVarRef **var_refs; + int i; + + p = JS_VALUE_GET_OBJ(func_obj); + p->u.func.function_bytecode = b; + p->u.func.home_object = NULL; + p->u.func.var_refs = NULL; + if (b->closure_var_count) { + var_refs = js_mallocz(ctx, sizeof(var_refs[0]) * b->closure_var_count); + if (!var_refs) + goto fail; + p->u.func.var_refs = var_refs; + for(i = 0; i < b->closure_var_count; i++) { + JSClosureVar *cv = &b->closure_var[i]; + JSVarRef *var_ref; + switch(cv->closure_type) { + case JS_CLOSURE_LOCAL: + /* reuse the existing variable reference if it already exists */ + var_ref = get_var_ref(ctx, sf, cv->var_idx, false); + break; + case JS_CLOSURE_ARG: + /* reuse the existing variable reference if it already exists */ + var_ref = get_var_ref(ctx, sf, cv->var_idx, true); + break; + case JS_CLOSURE_REF: + case JS_CLOSURE_GLOBAL_REF: + var_ref = cur_var_refs[cv->var_idx]; + JS_REF_COUNT(var_ref)++; + break; + default: + abort(); + } + if (!var_ref) + goto fail; + var_refs[i] = var_ref; + } + } + return func_obj; + fail: + /* bfunc is freed when func_obj is freed */ + JS_FreeValue(ctx, func_obj); + return JS_EXCEPTION; +} + +static JSValue js_instantiate_prototype(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque) +{ + JSValue obj, this_val; + int ret; + + this_val = JS_MKPTR(JS_TAG_OBJECT, p); + obj = JS_NewObject(ctx); + if (JS_IsException(obj)) + return JS_EXCEPTION; + ret = JS_DefinePropertyValue(ctx, obj, JS_ATOM_constructor, + js_dup(this_val), + JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); + if (ret < 0) { + JS_FreeValue(ctx, obj); + return JS_EXCEPTION; + } + return obj; +} + +static const uint16_t func_kind_to_class_id[] = { + [JS_FUNC_NORMAL] = JS_CLASS_BYTECODE_FUNCTION, + [JS_FUNC_GENERATOR] = JS_CLASS_GENERATOR_FUNCTION, + [JS_FUNC_ASYNC] = JS_CLASS_ASYNC_FUNCTION, + [JS_FUNC_ASYNC_GENERATOR] = JS_CLASS_ASYNC_GENERATOR_FUNCTION, +}; + +static JSValue js_closure(JSContext *ctx, JSValue bfunc, + JSVarRef **cur_var_refs, + JSStackFrame *sf) +{ + JSFunctionBytecode *b; + JSValue func_obj; + JSAtom name_atom; + + b = JS_VALUE_GET_PTR(bfunc); + func_obj = JS_NewObjectClass(ctx, func_kind_to_class_id[b->func_kind]); + if (JS_IsException(func_obj)) { + JS_FreeValue(ctx, bfunc); + return JS_EXCEPTION; + } + func_obj = js_closure2(ctx, func_obj, b, cur_var_refs, sf); + if (JS_IsException(func_obj)) { + /* bfunc has been freed */ + goto fail; + } + name_atom = b->func_name; + if (name_atom == JS_ATOM_NULL) + name_atom = JS_ATOM_empty_string; + js_function_set_properties(ctx, func_obj, name_atom, + b->defined_arg_count); + + if (b->func_kind & JS_FUNC_GENERATOR) { + JSValue proto; + int proto_class_id; + /* generators have a prototype field which is used as + prototype for the generator object */ + if (b->func_kind == JS_FUNC_ASYNC_GENERATOR) + proto_class_id = JS_CLASS_ASYNC_GENERATOR; + else + proto_class_id = JS_CLASS_GENERATOR; + proto = JS_NewObjectProto(ctx, ctx->class_proto[proto_class_id]); + if (JS_IsException(proto)) + goto fail; + JS_DefinePropertyValue(ctx, func_obj, JS_ATOM_prototype, proto, + JS_PROP_WRITABLE); + } else if (b->has_prototype) { + /* add the 'prototype' property: delay instantiation to avoid + creating cycles for every javascript function. The prototype + object is created on the fly when first accessed */ + JS_SetConstructorBit(ctx, func_obj, true); + JS_DefineAutoInitProperty(ctx, func_obj, JS_ATOM_prototype, + JS_AUTOINIT_ID_PROTOTYPE, NULL, + JS_PROP_WRITABLE); + } + return func_obj; + fail: + /* bfunc is freed when func_obj is freed */ + JS_FreeValue(ctx, func_obj); + return JS_EXCEPTION; +} + +#define JS_DEFINE_CLASS_HAS_HERITAGE (1 << 0) + +static int js_op_define_class(JSContext *ctx, JSValue *sp, + JSAtom class_name, int class_flags, + JSVarRef **cur_var_refs, + JSStackFrame *sf, bool is_computed_name) +{ + JSValue bfunc, parent_class, proto = JS_UNDEFINED; + JSValue ctor = JS_UNDEFINED, parent_proto = JS_UNDEFINED; + JSFunctionBytecode *b; + + parent_class = sp[-2]; + bfunc = sp[-1]; + + if (class_flags & JS_DEFINE_CLASS_HAS_HERITAGE) { + if (JS_IsNull(parent_class)) { + parent_proto = JS_NULL; + parent_class = js_dup(ctx->function_proto); + } else { + if (!JS_IsConstructor(ctx, parent_class)) { + JS_ThrowTypeError(ctx, "parent class must be constructor"); + goto fail; + } + parent_proto = JS_GetProperty(ctx, parent_class, JS_ATOM_prototype); + if (JS_IsException(parent_proto)) + goto fail; + if (!JS_IsNull(parent_proto) && !JS_IsObject(parent_proto)) { + JS_ThrowTypeError(ctx, "parent prototype must be an object or null"); + goto fail; + } + } + } else { + /* parent_class is JS_UNDEFINED in this case */ + parent_proto = js_dup(ctx->class_proto[JS_CLASS_OBJECT]); + parent_class = js_dup(ctx->function_proto); + } + proto = JS_NewObjectProto(ctx, parent_proto); + if (JS_IsException(proto)) + goto fail; + + b = JS_VALUE_GET_PTR(bfunc); + assert(b->func_kind == JS_FUNC_NORMAL); + ctor = JS_NewObjectProtoClass(ctx, parent_class, + JS_CLASS_BYTECODE_FUNCTION); + if (JS_IsException(ctor)) + goto fail; + ctor = js_closure2(ctx, ctor, b, cur_var_refs, sf); + bfunc = JS_UNDEFINED; + if (JS_IsException(ctor)) + goto fail; + js_method_set_home_object(ctx, ctor, proto); + JS_SetConstructorBit(ctx, ctor, true); + + JS_DefinePropertyValue(ctx, ctor, JS_ATOM_length, + js_int32(b->defined_arg_count), + JS_PROP_CONFIGURABLE); + + if (is_computed_name) { + if (JS_DefineObjectNameComputed(ctx, ctor, sp[-3], + JS_PROP_CONFIGURABLE) < 0) + goto fail; + } else { + if (JS_DefineObjectName(ctx, ctor, class_name, JS_PROP_CONFIGURABLE) < 0) + goto fail; + } + + /* the constructor property must be first. It can be overriden by + computed property names */ + if (JS_DefinePropertyValue(ctx, proto, JS_ATOM_constructor, + js_dup(ctor), + JS_PROP_CONFIGURABLE | + JS_PROP_WRITABLE | JS_PROP_THROW) < 0) + goto fail; + /* set the prototype property */ + if (JS_DefinePropertyValue(ctx, ctor, JS_ATOM_prototype, + js_dup(proto), JS_PROP_THROW) < 0) + goto fail; + + JS_FreeValue(ctx, parent_proto); + JS_FreeValue(ctx, parent_class); + + sp[-2] = ctor; + sp[-1] = proto; + return 0; + fail: + JS_FreeValue(ctx, parent_class); + JS_FreeValue(ctx, parent_proto); + JS_FreeValue(ctx, bfunc); + JS_FreeValue(ctx, proto); + JS_FreeValue(ctx, ctor); + sp[-2] = JS_UNDEFINED; + sp[-1] = JS_UNDEFINED; + return -1; +} + +static void close_var_ref(JSRuntime *rt, JSVarRef *var_ref) +{ + JSGCObjectHeader *coro; + /* Already closed. This can happen during reentrant coroutine teardown: + closing one var_ref can drop the coroutine's refcount to zero and + re-enter close_var_refs on the same frame. Once detached, the union + holds 'value' rather than stack_frame, so we must not touch it. */ + if (var_ref->is_detached) + return; + /* Read the coroutine (if any) before js_dup() overwrites the union + member that aliases stack_frame with 'value'. */ + coro = var_ref->is_coro ? var_ref->stack_frame->cur_gc_obj : NULL; + var_ref->value = js_dup(*var_ref->pvalue); + var_ref->pvalue = &var_ref->value; + /* the reference is no longer to a local variable */ + var_ref->is_detached = true; + var_ref->is_coro = false; + /* an open coroutine var_ref is already a GC object and holds a + reference to its coroutine; drop it now that it is detached. */ + if (coro) + js_release_coro(rt, coro); + else + add_gc_object(rt, &var_ref->header, JS_GC_OBJ_TYPE_VAR_REF); +} + +static void close_var_refs(JSRuntime *rt, JSStackFrame *sf) +{ + JSVarRef *var_ref; + int i; + + for (i = 0; i < sf->var_ref_count; i++) { + var_ref = sf->var_refs[i]; + if (var_ref) + close_var_ref(rt, var_ref); + } +} + +static void close_lexical_var(JSContext *ctx, JSFunctionBytecode *b, + JSStackFrame *sf, int var_idx) +{ + JSVarRef *var_ref; + int var_ref_idx; + + var_ref_idx = b->vardefs[b->arg_count + var_idx].var_ref_idx; + var_ref = sf->var_refs[var_ref_idx]; + if (var_ref) { + close_var_ref(ctx->rt, var_ref); + sf->var_refs[var_ref_idx] = NULL; + } +} + +#define JS_CALL_FLAG_COPY_ARGV (1 << 1) +#define JS_CALL_FLAG_GENERATOR (1 << 2) + +static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj, + JSValueConst this_obj, + int argc, JSValueConst *argv, int flags) +{ + JSRuntime *rt = ctx->rt; + JSCFunctionType func; + JSObject *p; + JSStackFrame sf_s, *sf = &sf_s, *prev_sf; + JSValue ret_val; + JSValueConst *arg_buf; + int arg_count, i; + JSCFunctionEnum cproto; + + p = JS_VALUE_GET_OBJ(func_obj); + cproto = p->u.cfunc.cproto; + arg_count = p->u.cfunc.length; + + /* better to always check stack overflow */ + if (js_check_stack_overflow(rt, sizeof(arg_buf[0]) * arg_count)) + return JS_ThrowStackOverflow(ctx); + + prev_sf = rt->current_stack_frame; + sf->prev_frame = prev_sf; + rt->current_stack_frame = sf; + ctx = p->u.cfunc.realm; /* change the current realm */ + + sf->is_strict_mode = false; + sf->is_constructor = (flags & JS_CALL_FLAG_CONSTRUCTOR) != 0; + sf->cur_func = unsafe_unconst(func_obj); + sf->arg_count = argc; + arg_buf = argv; + + if (unlikely(argc < arg_count)) { + /* ensure that at least argc_count arguments are readable */ + arg_buf = alloca(sizeof(arg_buf[0]) * arg_count); + for(i = 0; i < argc; i++) + arg_buf[i] = argv[i]; + for(i = argc; i < arg_count; i++) + arg_buf[i] = JS_UNDEFINED; + sf->arg_count = arg_count; + } + sf->arg_buf = (JSValue *)arg_buf; + + func = p->u.cfunc.c_function; + switch(cproto) { + case JS_CFUNC_constructor: + case JS_CFUNC_constructor_or_func: + if (!(flags & JS_CALL_FLAG_CONSTRUCTOR)) { + if (cproto == JS_CFUNC_constructor) { + not_a_constructor: + ret_val = JS_ThrowTypeError(ctx, "must be called with new"); + break; + } else { + this_obj = JS_UNDEFINED; + } + } + /* here this_obj is new_target */ + /* fall thru */ + case JS_CFUNC_generic: + ret_val = func.generic(ctx, this_obj, argc, arg_buf); + break; + case JS_CFUNC_constructor_magic: + case JS_CFUNC_constructor_or_func_magic: + if (!(flags & JS_CALL_FLAG_CONSTRUCTOR)) { + if (cproto == JS_CFUNC_constructor_magic) { + goto not_a_constructor; + } else { + this_obj = JS_UNDEFINED; + } + } + /* fall thru */ + case JS_CFUNC_generic_magic: + ret_val = func.generic_magic(ctx, this_obj, argc, arg_buf, + p->u.cfunc.magic); + break; + case JS_CFUNC_getter: + ret_val = func.getter(ctx, this_obj); + break; + case JS_CFUNC_setter: + ret_val = func.setter(ctx, this_obj, arg_buf[0]); + break; + case JS_CFUNC_getter_magic: + ret_val = func.getter_magic(ctx, this_obj, p->u.cfunc.magic); + break; + case JS_CFUNC_setter_magic: + ret_val = func.setter_magic(ctx, this_obj, arg_buf[0], p->u.cfunc.magic); + break; + case JS_CFUNC_f_f: + { + double d1; + + if (unlikely(JS_ToFloat64(ctx, &d1, arg_buf[0]))) { + ret_val = JS_EXCEPTION; + break; + } + ret_val = js_number(func.f_f(d1)); + } + break; + case JS_CFUNC_f_f_f: + { + double d1, d2; + + if (unlikely(JS_ToFloat64(ctx, &d1, arg_buf[0]))) { + ret_val = JS_EXCEPTION; + break; + } + if (unlikely(JS_ToFloat64(ctx, &d2, arg_buf[1]))) { + ret_val = JS_EXCEPTION; + break; + } + ret_val = js_number(func.f_f_f(d1, d2)); + } + break; + case JS_CFUNC_iterator_next: + { + int done; + ret_val = func.iterator_next(ctx, this_obj, argc, arg_buf, + &done, p->u.cfunc.magic); + if (!JS_IsException(ret_val) && done != 2) { + ret_val = js_create_iterator_result(ctx, ret_val, done); + } + } + break; + default: + abort(); + } + + rt->current_stack_frame = sf->prev_frame; + return ret_val; +} + +static JSValue js_call_bound_function(JSContext *ctx, JSValueConst func_obj, + JSValueConst this_obj, + int argc, JSValueConst *argv, int flags) +{ + JSObject *p; + JSBoundFunction *bf; + JSValueConst *arg_buf, new_target; + int arg_count, i; + + p = JS_VALUE_GET_OBJ(func_obj); + bf = p->u.bound_function; + arg_count = bf->argc + argc; + if (js_check_stack_overflow(ctx->rt, sizeof(JSValue) * arg_count)) + return JS_ThrowStackOverflow(ctx); + arg_buf = alloca(sizeof(JSValue) * arg_count); + for(i = 0; i < bf->argc; i++) { + arg_buf[i] = bf->argv[i]; + } + for(i = 0; i < argc; i++) { + arg_buf[bf->argc + i] = argv[i]; + } + if (flags & JS_CALL_FLAG_CONSTRUCTOR) { + new_target = this_obj; + if (js_same_value(ctx, func_obj, new_target)) + new_target = bf->func_obj; + return JS_CallConstructor2(ctx, bf->func_obj, new_target, + arg_count, arg_buf); + } else { + return JS_Call(ctx, bf->func_obj, bf->this_val, + arg_count, arg_buf); + } +} + +/* argument of OP_special_object */ +typedef enum { + OP_SPECIAL_OBJECT_ARGUMENTS, + OP_SPECIAL_OBJECT_MAPPED_ARGUMENTS, + OP_SPECIAL_OBJECT_THIS_FUNC, + OP_SPECIAL_OBJECT_NEW_TARGET, + OP_SPECIAL_OBJECT_HOME_OBJECT, + OP_SPECIAL_OBJECT_VAR_OBJECT, + OP_SPECIAL_OBJECT_IMPORT_META, + OP_SPECIAL_OBJECT_NULL_PROTO, +} OPSpecialObjectEnum; + +#define FUNC_RET_AWAIT 0 +#define FUNC_RET_YIELD 1 +#define FUNC_RET_YIELD_STAR 2 + +#ifdef ENABLE_DUMPS // JS_DUMP_BYTECODE_* +static void dump_single_byte_code(JSContext *ctx, const uint8_t *pc, + JSFunctionBytecode *b, int start_pos); +static void print_func_name(JSFunctionBytecode *b); +#endif + +static bool needs_backtrace(JSValue exc) +{ + return can_store_error_stack(exc) || can_add_backtrace(exc); +} + +/* argv[] is modified if (flags & JS_CALL_FLAG_COPY_ARGV) = 0. */ +static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, + JSValueConst this_obj, JSValueConst new_target, + int argc, JSValueConst *argv, int flags) +{ + JSRuntime *rt = caller_ctx->rt; + JSContext *ctx; + JSObject *p; + JSFunctionBytecode *b; + JSStackFrame sf_s, *sf = &sf_s; + uint8_t *pc; + int opcode, arg_allocated_size, i; + JSValue *local_buf, *stack_buf, *var_buf, *arg_buf, *sp, ret_val, *pval; + JSVarRef **var_refs; + size_t alloca_size; + +#ifdef ENABLE_DUMPS // JS_DUMP_BYTECODE_STEP +#define DUMP_BYTECODE_OR_DONT(pc) \ + if (check_dump_flag(ctx->rt, JS_DUMP_BYTECODE_STEP)) dump_single_byte_code(ctx, pc, b, 0); +#else +#define DUMP_BYTECODE_OR_DONT(pc) +#endif + +#if !DIRECT_DISPATCH +#define SWITCH(pc) DUMP_BYTECODE_OR_DONT(pc) switch (opcode = *pc++) +#define CASE(op) case op +#define DEFAULT default +#define BREAK break +#else + __extension__ static const void * const dispatch_table[256] = { +#define DEF(id, size, n_pop, n_push, f) && case_OP_ ## id, +#define def(id, size, n_pop, n_push, f) +#include "quickjs-opcode.h" + [ OP_COUNT ... 255 ] = &&case_default + }; +#define SWITCH(pc) DUMP_BYTECODE_OR_DONT(pc) __extension__ ({ goto *dispatch_table[opcode = *pc++]; }); +#define CASE(op) case_ ## op +#define DEFAULT case_default +#define BREAK SWITCH(pc) +#endif + + if (js_poll_interrupts(caller_ctx)) + return JS_EXCEPTION; + if (unlikely(JS_VALUE_GET_TAG(func_obj) != JS_TAG_OBJECT)) { + if (flags & JS_CALL_FLAG_GENERATOR) { + JSAsyncFunctionState *s = JS_VALUE_GET_PTR(func_obj); + /* func_obj get contains a pointer to JSFuncAsyncState */ + /* the stack frame is already allocated */ + sf = &s->frame; + p = JS_VALUE_GET_OBJ(sf->cur_func); + b = p->u.func.function_bytecode; + ctx = b->realm; + var_refs = p->u.func.var_refs; + local_buf = arg_buf = sf->arg_buf; + var_buf = sf->var_buf; + stack_buf = sf->var_buf + b->var_count; + sp = sf->cur_sp; + sf->cur_sp = NULL; /* cur_sp is NULL if the function is running */ + pc = sf->cur_pc; + sf->prev_frame = rt->current_stack_frame; + rt->current_stack_frame = sf; + if (s->throw_flag) + goto exception; + else + goto restart; + } else { + goto not_a_function; + } + } + p = JS_VALUE_GET_OBJ(func_obj); + if (unlikely(p->class_id != JS_CLASS_BYTECODE_FUNCTION)) { + JSClassCall *call_func; + call_func = rt->class_array[p->class_id].call; + if (!call_func) { + not_a_function: + return JS_ThrowTypeErrorNotAFunction(caller_ctx); + } + return call_func(caller_ctx, func_obj, this_obj, argc, + argv, flags); + } + b = p->u.func.function_bytecode; + + if (unlikely(argc < b->arg_count || (flags & JS_CALL_FLAG_COPY_ARGV))) { + arg_allocated_size = b->arg_count; + } else { + arg_allocated_size = 0; + } + + alloca_size = sizeof(JSValue) * (arg_allocated_size + b->var_count + + b->stack_size) + + sizeof(JSVarRef *) * b->var_ref_count; + if (js_check_stack_overflow(rt, alloca_size)) + return JS_ThrowStackOverflow(caller_ctx); + + sf->is_strict_mode = b->is_strict_mode; + sf->is_constructor = (flags & JS_CALL_FLAG_CONSTRUCTOR) != 0; + arg_buf = (JSValue *)argv; + sf->arg_count = argc; + sf->cur_func = unsafe_unconst(func_obj); + var_refs = p->u.func.var_refs; + + local_buf = alloca(alloca_size); + if (unlikely(arg_allocated_size)) { + int n = min_int(argc, b->arg_count); + arg_buf = local_buf; + for(i = 0; i < n; i++) + arg_buf[i] = js_dup(argv[i]); + for(; i < b->arg_count; i++) + arg_buf[i] = JS_UNDEFINED; + sf->arg_count = b->arg_count; + } + var_buf = local_buf + arg_allocated_size; + sf->var_buf = var_buf; + sf->arg_buf = arg_buf; + + for(i = 0; i < b->var_count; i++) + var_buf[i] = JS_UNDEFINED; + + stack_buf = var_buf + b->var_count; + sf->var_refs = (JSVarRef **)(stack_buf + b->stack_size); + sf->var_ref_count = b->var_ref_count; + for(i = 0; i < b->var_ref_count; i++) + sf->var_refs[i] = NULL; + /* ordinary C-stack frame: not owned by a coroutine GC object */ + sf->cur_gc_obj = NULL; + sp = stack_buf; + pc = b->byte_code_buf; + /* sf->cur_pc must we set to pc before any recursive calls to JS_CallInternal. */ + sf->cur_pc = NULL; + sf->prev_frame = rt->current_stack_frame; + rt->current_stack_frame = sf; + ctx = b->realm; /* set the current realm */ + +#ifdef ENABLE_DUMPS // JS_DUMP_BYTECODE_STEP + if (check_dump_flag(ctx->rt, JS_DUMP_BYTECODE_STEP)) + print_func_name(b); +#endif + + restart: + for(;;) { + int call_argc; + JSValue *call_argv; + + SWITCH(pc) { + CASE(OP_push_i32): + *sp++ = js_int32(get_u32(pc)); + pc += 4; + BREAK; + CASE(OP_push_bigint_i32): + *sp++ = __JS_NewShortBigInt(ctx, (int)get_u32(pc)); + pc += 4; + BREAK; + CASE(OP_push_const): + *sp++ = js_dup(b->cpool[get_u32(pc)]); + pc += 4; + BREAK; + CASE(OP_push_minus1): + CASE(OP_push_0): + CASE(OP_push_1): + CASE(OP_push_2): + CASE(OP_push_3): + CASE(OP_push_4): + CASE(OP_push_5): + CASE(OP_push_6): + CASE(OP_push_7): + *sp++ = js_int32(opcode - OP_push_0); + BREAK; + CASE(OP_push_i8): + *sp++ = js_int32(get_i8(pc)); + pc += 1; + BREAK; + CASE(OP_push_i16): + *sp++ = js_int32(get_i16(pc)); + pc += 2; + BREAK; + CASE(OP_push_const8): + *sp++ = js_dup(b->cpool[*pc++]); + BREAK; + CASE(OP_fclosure8): + *sp++ = js_closure(ctx, js_dup(b->cpool[*pc++]), var_refs, sf); + if (unlikely(JS_IsException(sp[-1]))) + goto exception; + BREAK; + CASE(OP_push_empty_string): + *sp++ = js_empty_string(rt); + BREAK; + CASE(OP_get_length): + { + JSValue val, obj; + JSAtom atom; + JSObject *p; + JSProperty *pr; + JSShapeProperty *prs; + + atom = JS_ATOM_length; + + obj = sp[-1]; + if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT)) { + p = JS_VALUE_GET_OBJ(obj); + for(;;) { + prs = find_own_property(&pr, p, atom); + if (prs) { + /* found */ + if (unlikely(prs->flags & JS_PROP_TMASK)) + goto get_length_slow_path; + val = js_dup(pr->u.value); + break; + } + if (unlikely(p->is_exotic)) { + obj = JS_MKPTR(JS_TAG_OBJECT, p); + goto get_length_slow_path; + } + p = p->shape->proto; + if (!p) { + val = JS_UNDEFINED; + break; + } + } + } else { + get_length_slow_path: + sf->cur_pc = pc; + val = JS_GetPropertyInternal(ctx, obj, atom, sp[-1], false); + if (unlikely(JS_IsException(val))) + goto exception; + } + JS_FreeValue(ctx, sp[-1]); + sp[-1] = val; + } + BREAK; + CASE(OP_push_atom_value): + *sp++ = JS_AtomToValue(ctx, get_u32(pc)); + pc += 4; + BREAK; + CASE(OP_undefined): + *sp++ = JS_UNDEFINED; + BREAK; + CASE(OP_null): + *sp++ = JS_NULL; + BREAK; + CASE(OP_push_this): + /* OP_push_this is only called at the start of a function */ + { + JSValue val; + if (!b->is_strict_mode) { + uint32_t tag = JS_VALUE_GET_TAG(this_obj); + if (likely(tag == JS_TAG_OBJECT)) + goto normal_this; + if (tag == JS_TAG_NULL || tag == JS_TAG_UNDEFINED) { + val = js_dup(ctx->global_obj); + } else { + val = JS_ToObject(ctx, this_obj); + if (JS_IsException(val)) + goto exception; + } + } else { + normal_this: + val = js_dup(this_obj); + } + *sp++ = val; + } + BREAK; + CASE(OP_push_false): + *sp++ = JS_FALSE; + BREAK; + CASE(OP_push_true): + *sp++ = JS_TRUE; + BREAK; + CASE(OP_object): + *sp++ = JS_NewObject(ctx); + if (unlikely(JS_IsException(sp[-1]))) + goto exception; + BREAK; + CASE(OP_special_object): + { + int arg = *pc++; + switch(arg) { + case OP_SPECIAL_OBJECT_ARGUMENTS: + *sp++ = js_build_arguments(ctx, argc, argv); + if (unlikely(JS_IsException(sp[-1]))) + goto exception; + break; + case OP_SPECIAL_OBJECT_MAPPED_ARGUMENTS: + *sp++ = js_build_mapped_arguments(ctx, argc, argv, + sf, min_int(argc, b->arg_count)); + if (unlikely(JS_IsException(sp[-1]))) + goto exception; + break; + case OP_SPECIAL_OBJECT_THIS_FUNC: + *sp++ = js_dup(sf->cur_func); + break; + case OP_SPECIAL_OBJECT_NEW_TARGET: + *sp++ = js_dup(new_target); + break; + case OP_SPECIAL_OBJECT_HOME_OBJECT: + { + JSObject *p1; + p1 = p->u.func.home_object; + if (unlikely(!p1)) + *sp++ = JS_UNDEFINED; + else + *sp++ = js_dup(JS_MKPTR(JS_TAG_OBJECT, p1)); + } + break; + case OP_SPECIAL_OBJECT_VAR_OBJECT: + *sp++ = JS_NewObjectProto(ctx, JS_NULL); + if (unlikely(JS_IsException(sp[-1]))) + goto exception; + break; + case OP_SPECIAL_OBJECT_IMPORT_META: + *sp++ = js_import_meta(ctx); + if (unlikely(JS_IsException(sp[-1]))) + goto exception; + break; + case OP_SPECIAL_OBJECT_NULL_PROTO: + *sp++ = JS_NewObjectProtoClass(ctx, JS_NULL, JS_CLASS_OBJECT); + if (unlikely(JS_IsException(sp[-1]))) + goto exception; + break; + default: + abort(); + } + } + BREAK; + CASE(OP_rest): + { + int i, n, first = get_u16(pc); + pc += 2; + i = min_int(first, argc); + n = argc - i; + *sp++ = js_create_array(ctx, n, n ? &argv[i] : NULL); + if (unlikely(JS_IsException(sp[-1]))) + goto exception; + } + BREAK; + + CASE(OP_drop): + JS_FreeValue(ctx, sp[-1]); + sp--; + BREAK; + CASE(OP_nip): + JS_FreeValue(ctx, sp[-2]); + sp[-2] = sp[-1]; + sp--; + BREAK; + CASE(OP_nip1): /* a b c -> b c */ + JS_FreeValue(ctx, sp[-3]); + sp[-3] = sp[-2]; + sp[-2] = sp[-1]; + sp--; + BREAK; + CASE(OP_dup): + sp[0] = js_dup(sp[-1]); + sp++; + BREAK; + CASE(OP_dup2): /* a b -> a b a b */ + sp[0] = js_dup(sp[-2]); + sp[1] = js_dup(sp[-1]); + sp += 2; + BREAK; + CASE(OP_dup3): /* a b c -> a b c a b c */ + sp[0] = js_dup(sp[-3]); + sp[1] = js_dup(sp[-2]); + sp[2] = js_dup(sp[-1]); + sp += 3; + BREAK; + CASE(OP_dup1): /* a b -> a a b */ + sp[0] = sp[-1]; + sp[-1] = js_dup(sp[-2]); + sp++; + BREAK; + CASE(OP_insert2): /* obj a -> a obj a (dup_x1) */ + sp[0] = sp[-1]; + sp[-1] = sp[-2]; + sp[-2] = js_dup(sp[0]); + sp++; + BREAK; + CASE(OP_insert3): /* obj prop a -> a obj prop a (dup_x2) */ + sp[0] = sp[-1]; + sp[-1] = sp[-2]; + sp[-2] = sp[-3]; + sp[-3] = js_dup(sp[0]); + sp++; + BREAK; + CASE(OP_insert4): /* this obj prop a -> a this obj prop a */ + sp[0] = sp[-1]; + sp[-1] = sp[-2]; + sp[-2] = sp[-3]; + sp[-3] = sp[-4]; + sp[-4] = js_dup(sp[0]); + sp++; + BREAK; + CASE(OP_perm3): /* obj a b -> a obj b (213) */ + { + JSValue tmp; + tmp = sp[-2]; + sp[-2] = sp[-3]; + sp[-3] = tmp; + } + BREAK; + CASE(OP_rot3l): /* x a b -> a b x (231) */ + { + JSValue tmp; + tmp = sp[-3]; + sp[-3] = sp[-2]; + sp[-2] = sp[-1]; + sp[-1] = tmp; + } + BREAK; + CASE(OP_rot4l): /* x a b c -> a b c x */ + { + JSValue tmp; + tmp = sp[-4]; + sp[-4] = sp[-3]; + sp[-3] = sp[-2]; + sp[-2] = sp[-1]; + sp[-1] = tmp; + } + BREAK; + CASE(OP_rot5l): /* x a b c d -> a b c d x */ + { + JSValue tmp; + tmp = sp[-5]; + sp[-5] = sp[-4]; + sp[-4] = sp[-3]; + sp[-3] = sp[-2]; + sp[-2] = sp[-1]; + sp[-1] = tmp; + } + BREAK; + CASE(OP_rot3r): /* a b x -> x a b (312) */ + { + JSValue tmp; + tmp = sp[-1]; + sp[-1] = sp[-2]; + sp[-2] = sp[-3]; + sp[-3] = tmp; + } + BREAK; + CASE(OP_perm4): /* obj prop a b -> a obj prop b */ + { + JSValue tmp; + tmp = sp[-2]; + sp[-2] = sp[-3]; + sp[-3] = sp[-4]; + sp[-4] = tmp; + } + BREAK; + CASE(OP_perm5): /* this obj prop a b -> a this obj prop b */ + { + JSValue tmp; + tmp = sp[-2]; + sp[-2] = sp[-3]; + sp[-3] = sp[-4]; + sp[-4] = sp[-5]; + sp[-5] = tmp; + } + BREAK; + CASE(OP_swap): /* a b -> b a */ + { + JSValue tmp; + tmp = sp[-2]; + sp[-2] = sp[-1]; + sp[-1] = tmp; + } + BREAK; + CASE(OP_swap2): /* a b c d -> c d a b */ + { + JSValue tmp1, tmp2; + tmp1 = sp[-4]; + tmp2 = sp[-3]; + sp[-4] = sp[-2]; + sp[-3] = sp[-1]; + sp[-2] = tmp1; + sp[-1] = tmp2; + } + BREAK; + + CASE(OP_fclosure): + { + JSValue bfunc = js_dup(b->cpool[get_u32(pc)]); + pc += 4; + *sp++ = js_closure(ctx, bfunc, var_refs, sf); + if (unlikely(JS_IsException(sp[-1]))) + goto exception; + } + BREAK; + CASE(OP_call0): + CASE(OP_call1): + CASE(OP_call2): + CASE(OP_call3): + call_argc = opcode - OP_call0; + goto has_call_argc; + CASE(OP_call): + CASE(OP_tail_call): + { + call_argc = get_u16(pc); + pc += 2; + goto has_call_argc; + has_call_argc: + call_argv = sp - call_argc; + sf->cur_pc = pc; + ret_val = JS_CallInternal(ctx, call_argv[-1], JS_UNDEFINED, + JS_UNDEFINED, call_argc, + vc(call_argv), 0); + if (unlikely(JS_IsException(ret_val))) + goto exception; + if (opcode == OP_tail_call) + goto done; + for(i = -1; i < call_argc; i++) + JS_FreeValue(ctx, call_argv[i]); + sp -= call_argc + 1; + *sp++ = ret_val; + } + BREAK; + CASE(OP_call_constructor): + { + call_argc = get_u16(pc); + pc += 2; + call_argv = sp - call_argc; + sf->cur_pc = pc; + ret_val = JS_CallConstructorInternal(ctx, call_argv[-2], + call_argv[-1], call_argc, + vc(call_argv), 0); + if (unlikely(JS_IsException(ret_val))) + goto exception; + for(i = -2; i < call_argc; i++) + JS_FreeValue(ctx, call_argv[i]); + sp -= call_argc + 2; + *sp++ = ret_val; + } + BREAK; + CASE(OP_call_method): + CASE(OP_tail_call_method): + { + call_argc = get_u16(pc); + pc += 2; + call_argv = sp - call_argc; + sf->cur_pc = pc; + ret_val = JS_CallInternal(ctx, call_argv[-1], call_argv[-2], + JS_UNDEFINED, call_argc, + vc(call_argv), 0); + if (unlikely(JS_IsException(ret_val))) + goto exception; + if (opcode == OP_tail_call_method) + goto done; + for(i = -2; i < call_argc; i++) + JS_FreeValue(ctx, call_argv[i]); + sp -= call_argc + 2; + *sp++ = ret_val; + } + BREAK; + CASE(OP_array_from): + { + call_argc = get_u16(pc); + pc += 2; + call_argv = sp - call_argc; + ret_val = JS_NewArrayFrom(ctx, call_argc, call_argv); + sp -= call_argc; + if (unlikely(JS_IsException(ret_val))) + goto exception; + *sp++ = ret_val; + } + BREAK; + + CASE(OP_apply): + { + int magic; + magic = get_u16(pc); + pc += 2; + sf->cur_pc = pc; + + ret_val = js_function_apply(ctx, sp[-3], 2, vc(&sp[-2]), magic); + if (unlikely(JS_IsException(ret_val))) + goto exception; + JS_FreeValue(ctx, sp[-3]); + JS_FreeValue(ctx, sp[-2]); + JS_FreeValue(ctx, sp[-1]); + sp -= 3; + *sp++ = ret_val; + } + BREAK; + CASE(OP_return): + ret_val = *--sp; + goto done; + CASE(OP_return_undef): + ret_val = JS_UNDEFINED; + goto done; + + CASE(OP_check_ctor_return): + /* return true if 'this' should be returned */ + if (!JS_IsObject(sp[-1])) { + if (!JS_IsUndefined(sp[-1])) { + JS_ThrowTypeError(caller_ctx, "derived class constructor must return an object or undefined"); + goto exception; + } + sp[0] = JS_TRUE; + } else { + sp[0] = JS_FALSE; + } + sp++; + BREAK; + CASE(OP_check_ctor): + if (JS_IsUndefined(new_target)) { + non_ctor_call: + JS_ThrowTypeError(ctx, "class constructors must be invoked with 'new'"); + goto exception; + } + BREAK; + CASE(OP_init_ctor): + { + JSValue super, ret; + sf->cur_pc = pc; + if (JS_IsUndefined(new_target)) + goto non_ctor_call; + super = JS_GetPrototype(ctx, func_obj); + if (JS_IsException(super)) + goto exception; + ret = JS_CallConstructor2(ctx, super, new_target, argc, argv); + JS_FreeValue(ctx, super); + if (JS_IsException(ret)) + goto exception; + *sp++ = ret; + } + BREAK; + CASE(OP_check_brand): + { + int ret = JS_CheckBrand(ctx, sp[-2], sp[-1]); + if (ret < 0) + goto exception; + if (!ret) { + JS_ThrowTypeError(ctx, "invalid brand on object"); + goto exception; + } + } + BREAK; + CASE(OP_add_brand): + if (JS_AddBrand(ctx, sp[-2], sp[-1]) < 0) + goto exception; + JS_FreeValue(ctx, sp[-2]); + JS_FreeValue(ctx, sp[-1]); + sp -= 2; + BREAK; + + CASE(OP_throw): + JS_Throw(ctx, *--sp); + goto exception; + + CASE(OP_throw_error): +#define JS_THROW_VAR_RO 0 +#define JS_THROW_VAR_REDECL 1 +#define JS_THROW_VAR_UNINITIALIZED 2 +#define JS_THROW_ERROR_DELETE_SUPER 3 +#define JS_THROW_ERROR_ITERATOR_THROW 4 + { + JSAtom atom; + int type; + atom = get_u32(pc); + type = pc[4]; + pc += 5; + if (type == JS_THROW_VAR_RO) + JS_ThrowTypeErrorReadOnly(ctx, JS_PROP_THROW, atom); + else + if (type == JS_THROW_VAR_REDECL) + JS_ThrowSyntaxErrorVarRedeclaration(ctx, atom); + else + if (type == JS_THROW_VAR_UNINITIALIZED) + JS_ThrowReferenceErrorUninitialized(ctx, atom); + else + if (type == JS_THROW_ERROR_DELETE_SUPER) + JS_ThrowReferenceError(ctx, "unsupported reference to 'super'"); + else + if (type == JS_THROW_ERROR_ITERATOR_THROW) + JS_ThrowTypeError(ctx, "iterator does not have a throw method"); + else + JS_ThrowInternalError(ctx, "invalid throw var type %d", type); + } + goto exception; + + CASE(OP_eval): + { + JSValue obj; + int scope_idx; + call_argc = get_u16(pc); + scope_idx = get_u16(pc + 2) - 1; + pc += 4; + call_argv = sp - call_argc; + sf->cur_pc = pc; + if (js_same_value(ctx, call_argv[-1], ctx->eval_obj)) { + if (call_argc >= 1) + obj = call_argv[0]; + else + obj = JS_UNDEFINED; + ret_val = JS_EvalObject(ctx, JS_UNDEFINED, obj, + JS_EVAL_TYPE_DIRECT, scope_idx); + } else { + ret_val = JS_CallInternal(ctx, call_argv[-1], JS_UNDEFINED, + JS_UNDEFINED, call_argc, + vc(call_argv), 0); + } + if (unlikely(JS_IsException(ret_val))) + goto exception; + for(i = -1; i < call_argc; i++) + JS_FreeValue(ctx, call_argv[i]); + sp -= call_argc + 1; + *sp++ = ret_val; + } + BREAK; + /* could merge with OP_apply */ + CASE(OP_apply_eval): + { + int scope_idx; + uint32_t len; + JSValue *tab; + JSValue obj; + + scope_idx = get_u16(pc) - 1; + pc += 2; + sf->cur_pc = pc; + tab = build_arg_list(ctx, &len, sp[-1]); + if (!tab) + goto exception; + if (js_same_value(ctx, sp[-2], ctx->eval_obj)) { + if (len >= 1) + obj = tab[0]; + else + obj = JS_UNDEFINED; + ret_val = JS_EvalObject(ctx, JS_UNDEFINED, obj, + JS_EVAL_TYPE_DIRECT, scope_idx); + } else { + ret_val = JS_Call(ctx, sp[-2], JS_UNDEFINED, len, vc(tab)); + } + free_arg_list(ctx, tab, len); + if (unlikely(JS_IsException(ret_val))) + goto exception; + JS_FreeValue(ctx, sp[-2]); + JS_FreeValue(ctx, sp[-1]); + sp -= 2; + *sp++ = ret_val; + } + BREAK; + + CASE(OP_regexp): + { + sp[-2] = js_regexp_constructor_internal(ctx, JS_UNDEFINED, + sp[-2], sp[-1]); + sp--; + if (JS_IsException(sp[-1])) + goto exception; + } + BREAK; + + CASE(OP_get_super): + { + JSValue proto; + proto = JS_GetPrototype(ctx, sp[-1]); + if (JS_IsException(proto)) + goto exception; + JS_FreeValue(ctx, sp[-1]); + sp[-1] = proto; + } + BREAK; + + CASE(OP_import): + { + JSValue val; + sf->cur_pc = pc; + val = js_dynamic_import(ctx, sp[-2], sp[-1]); + if (JS_IsException(val)) + goto exception; + JS_FreeValue(ctx, sp[-2]); + JS_FreeValue(ctx, sp[-1]); + sp--; + sp[-1] = val; + } + BREAK; + + CASE(OP_get_var_undef): + CASE(OP_get_var): + { + JSValue val; + JSAtom atom; + atom = get_u32(pc); + pc += 4; + sf->cur_pc = pc; + + val = JS_GetGlobalVar(ctx, atom, opcode - OP_get_var_undef); + if (unlikely(JS_IsException(val))) + goto exception; + *sp++ = val; + } + BREAK; + + CASE(OP_put_var): + CASE(OP_put_var_init): + { + int ret; + JSAtom atom; + atom = get_u32(pc); + pc += 4; + sf->cur_pc = pc; + + ret = JS_SetGlobalVar(ctx, atom, sp[-1], opcode - OP_put_var); + sp--; + if (unlikely(ret < 0)) + goto exception; + } + BREAK; + + CASE(OP_check_define_var): + { + JSAtom atom; + int flags; + atom = get_u32(pc); + flags = pc[4]; + pc += 5; + if (JS_CheckDefineGlobalVar(ctx, atom, flags)) + goto exception; + } + BREAK; + CASE(OP_define_var): + { + JSAtom atom; + int flags; + atom = get_u32(pc); + flags = pc[4]; + pc += 5; + if (JS_DefineGlobalVar(ctx, atom, flags)) + goto exception; + } + BREAK; + CASE(OP_define_func): + { + JSAtom atom; + int flags; + atom = get_u32(pc); + flags = pc[4]; + pc += 5; + if (JS_DefineGlobalFunction(ctx, atom, sp[-1], flags)) + goto exception; + JS_FreeValue(ctx, sp[-1]); + sp--; + } + BREAK; + + CASE(OP_get_loc): + { + int idx; + idx = get_u16(pc); + pc += 2; + sp[0] = js_dup(var_buf[idx]); + sp++; + } + BREAK; + CASE(OP_put_loc): + { + int idx; + idx = get_u16(pc); + pc += 2; + set_value(ctx, &var_buf[idx], sp[-1]); + sp--; + } + BREAK; + CASE(OP_set_loc): + { + int idx; + idx = get_u16(pc); + pc += 2; + set_value(ctx, &var_buf[idx], js_dup(sp[-1])); + } + BREAK; + CASE(OP_get_arg): + { + int idx; + idx = get_u16(pc); + pc += 2; + sp[0] = js_dup(arg_buf[idx]); + sp++; + } + BREAK; + CASE(OP_put_arg): + { + int idx; + idx = get_u16(pc); + pc += 2; + set_value(ctx, &arg_buf[idx], sp[-1]); + sp--; + } + BREAK; + CASE(OP_set_arg): + { + int idx; + idx = get_u16(pc); + pc += 2; + set_value(ctx, &arg_buf[idx], js_dup(sp[-1])); + } + BREAK; + + CASE(OP_get_loc8): *sp++ = js_dup(var_buf[*pc++]); BREAK; + CASE(OP_put_loc8): set_value(ctx, &var_buf[*pc++], *--sp); BREAK; + CASE(OP_set_loc8): set_value(ctx, &var_buf[*pc++], js_dup(sp[-1])); BREAK; + + // Observation: get_loc0 and get_loc1 are individually very + // frequent opcodes _and_ they are very often paired together, + // making them ideal candidates for opcode fusion. + CASE(OP_get_loc0_loc1): + *sp++ = js_dup(var_buf[0]); + *sp++ = js_dup(var_buf[1]); + BREAK; + + CASE(OP_get_loc0): *sp++ = js_dup(var_buf[0]); BREAK; + CASE(OP_get_loc1): *sp++ = js_dup(var_buf[1]); BREAK; + CASE(OP_get_loc2): *sp++ = js_dup(var_buf[2]); BREAK; + CASE(OP_get_loc3): *sp++ = js_dup(var_buf[3]); BREAK; + CASE(OP_put_loc0): set_value(ctx, &var_buf[0], *--sp); BREAK; + CASE(OP_put_loc1): set_value(ctx, &var_buf[1], *--sp); BREAK; + CASE(OP_put_loc2): set_value(ctx, &var_buf[2], *--sp); BREAK; + CASE(OP_put_loc3): set_value(ctx, &var_buf[3], *--sp); BREAK; + CASE(OP_set_loc0): set_value(ctx, &var_buf[0], js_dup(sp[-1])); BREAK; + CASE(OP_set_loc1): set_value(ctx, &var_buf[1], js_dup(sp[-1])); BREAK; + CASE(OP_set_loc2): set_value(ctx, &var_buf[2], js_dup(sp[-1])); BREAK; + CASE(OP_set_loc3): set_value(ctx, &var_buf[3], js_dup(sp[-1])); BREAK; + CASE(OP_get_arg0): *sp++ = js_dup(arg_buf[0]); BREAK; + CASE(OP_get_arg1): *sp++ = js_dup(arg_buf[1]); BREAK; + CASE(OP_get_arg2): *sp++ = js_dup(arg_buf[2]); BREAK; + CASE(OP_get_arg3): *sp++ = js_dup(arg_buf[3]); BREAK; + CASE(OP_put_arg0): set_value(ctx, &arg_buf[0], *--sp); BREAK; + CASE(OP_put_arg1): set_value(ctx, &arg_buf[1], *--sp); BREAK; + CASE(OP_put_arg2): set_value(ctx, &arg_buf[2], *--sp); BREAK; + CASE(OP_put_arg3): set_value(ctx, &arg_buf[3], *--sp); BREAK; + CASE(OP_set_arg0): set_value(ctx, &arg_buf[0], js_dup(sp[-1])); BREAK; + CASE(OP_set_arg1): set_value(ctx, &arg_buf[1], js_dup(sp[-1])); BREAK; + CASE(OP_set_arg2): set_value(ctx, &arg_buf[2], js_dup(sp[-1])); BREAK; + CASE(OP_set_arg3): set_value(ctx, &arg_buf[3], js_dup(sp[-1])); BREAK; + CASE(OP_get_var_ref0): *sp++ = js_dup(*var_refs[0]->pvalue); BREAK; + CASE(OP_get_var_ref1): *sp++ = js_dup(*var_refs[1]->pvalue); BREAK; + CASE(OP_get_var_ref2): *sp++ = js_dup(*var_refs[2]->pvalue); BREAK; + CASE(OP_get_var_ref3): *sp++ = js_dup(*var_refs[3]->pvalue); BREAK; + CASE(OP_put_var_ref0): set_value(ctx, var_refs[0]->pvalue, *--sp); BREAK; + CASE(OP_put_var_ref1): set_value(ctx, var_refs[1]->pvalue, *--sp); BREAK; + CASE(OP_put_var_ref2): set_value(ctx, var_refs[2]->pvalue, *--sp); BREAK; + CASE(OP_put_var_ref3): set_value(ctx, var_refs[3]->pvalue, *--sp); BREAK; + CASE(OP_set_var_ref0): set_value(ctx, var_refs[0]->pvalue, js_dup(sp[-1])); BREAK; + CASE(OP_set_var_ref1): set_value(ctx, var_refs[1]->pvalue, js_dup(sp[-1])); BREAK; + CASE(OP_set_var_ref2): set_value(ctx, var_refs[2]->pvalue, js_dup(sp[-1])); BREAK; + CASE(OP_set_var_ref3): set_value(ctx, var_refs[3]->pvalue, js_dup(sp[-1])); BREAK; + + CASE(OP_get_var_ref): + { + int idx; + JSValue val; + idx = get_u16(pc); + pc += 2; + val = *var_refs[idx]->pvalue; + sp[0] = js_dup(val); + sp++; + } + BREAK; + CASE(OP_put_var_ref): + { + int idx; + idx = get_u16(pc); + pc += 2; + set_value(ctx, var_refs[idx]->pvalue, sp[-1]); + sp--; + } + BREAK; + CASE(OP_set_var_ref): + { + int idx; + idx = get_u16(pc); + pc += 2; + set_value(ctx, var_refs[idx]->pvalue, js_dup(sp[-1])); + } + BREAK; + CASE(OP_get_var_ref_check): + { + int idx; + JSValue val; + idx = get_u16(pc); + pc += 2; + val = *var_refs[idx]->pvalue; + if (unlikely(JS_IsUninitialized(val))) { + JS_ThrowReferenceErrorUninitialized2(ctx, b, idx, true); + goto exception; + } + sp[0] = js_dup(val); + sp++; + } + BREAK; + CASE(OP_put_var_ref_check): + { + int idx; + idx = get_u16(pc); + pc += 2; + if (unlikely(JS_IsUninitialized(*var_refs[idx]->pvalue))) { + JS_ThrowReferenceErrorUninitialized2(ctx, b, idx, true); + goto exception; + } + set_value(ctx, var_refs[idx]->pvalue, sp[-1]); + sp--; + } + BREAK; + CASE(OP_put_var_ref_check_init): + { + int idx; + idx = get_u16(pc); + pc += 2; + if (unlikely(!JS_IsUninitialized(*var_refs[idx]->pvalue))) { + JS_ThrowReferenceErrorUninitialized2(ctx, b, idx, true); + goto exception; + } + set_value(ctx, var_refs[idx]->pvalue, sp[-1]); + sp--; + } + BREAK; + CASE(OP_set_loc_uninitialized): + { + int idx; + idx = get_u16(pc); + pc += 2; + set_value(ctx, &var_buf[idx], JS_UNINITIALIZED); + } + BREAK; + CASE(OP_get_loc_check): + { + int idx; + idx = get_u16(pc); + pc += 2; + if (unlikely(JS_IsUninitialized(var_buf[idx]))) { + JS_ThrowReferenceErrorUninitialized2(caller_ctx, b, idx, + false); + goto exception; + } + sp[0] = js_dup(var_buf[idx]); + sp++; + } + BREAK; + CASE(OP_put_loc_check): + { + int idx; + idx = get_u16(pc); + pc += 2; + if (unlikely(JS_IsUninitialized(var_buf[idx]))) { + JS_ThrowReferenceErrorUninitialized2(caller_ctx, b, idx, + false); + goto exception; + } + set_value(ctx, &var_buf[idx], sp[-1]); + sp--; + } + BREAK; + CASE(OP_put_loc_check_init): + { + int idx; + idx = get_u16(pc); + pc += 2; + if (unlikely(!JS_IsUninitialized(var_buf[idx]))) { + JS_ThrowReferenceError(caller_ctx, + "'this' can be initialized only once"); + goto exception; + } + set_value(ctx, &var_buf[idx], sp[-1]); + sp--; + } + BREAK; + CASE(OP_close_loc): + { + int idx; + idx = get_u16(pc); + pc += 2; + close_lexical_var(ctx, b, sf, idx); + } + BREAK; + + CASE(OP_make_loc_ref): + CASE(OP_make_arg_ref): + CASE(OP_make_var_ref_ref): + { + JSVarRef *var_ref; + JSProperty *pr; + JSAtom atom; + int idx; + atom = get_u32(pc); + idx = get_u16(pc + 4); + pc += 6; + *sp++ = JS_NewObjectProto(ctx, JS_NULL); + if (unlikely(JS_IsException(sp[-1]))) + goto exception; + if (opcode == OP_make_var_ref_ref) { + var_ref = var_refs[idx]; + JS_REF_COUNT(var_ref)++; + } else { + var_ref = get_var_ref(ctx, sf, idx, opcode == OP_make_arg_ref); + if (!var_ref) + goto exception; + } + pr = add_property(ctx, JS_VALUE_GET_OBJ(sp[-1]), atom, + JS_PROP_WRITABLE | JS_PROP_VARREF); + if (!pr) { + free_var_ref(rt, var_ref); + goto exception; + } + pr->u.var_ref = var_ref; + *sp++ = JS_AtomToValue(ctx, atom); + } + BREAK; + CASE(OP_make_var_ref): + { + JSAtom atom; + atom = get_u32(pc); + pc += 4; + + if (JS_GetGlobalVarRef(ctx, atom, sp)) + goto exception; + sp += 2; + } + BREAK; + + CASE(OP_goto): + pc += (int32_t)get_u32(pc); + if (unlikely(js_poll_interrupts(ctx))) + goto exception; + BREAK; + CASE(OP_goto16): + pc += (int16_t)get_u16(pc); + if (unlikely(js_poll_interrupts(ctx))) + goto exception; + BREAK; + CASE(OP_goto8): + pc += (int8_t)pc[0]; + if (unlikely(js_poll_interrupts(ctx))) + goto exception; + BREAK; + CASE(OP_if_true): + { + int res; + JSValue op1; + + op1 = sp[-1]; + pc += 4; + if ((uint32_t)JS_VALUE_GET_TAG(op1) <= JS_TAG_UNDEFINED) { + res = JS_VALUE_GET_INT(op1); + } else { + res = JS_ToBoolFree(ctx, op1); + } + sp--; + if (res) { + pc += (int32_t)get_u32(pc - 4) - 4; + } + if (unlikely(js_poll_interrupts(ctx))) + goto exception; + } + BREAK; + CASE(OP_if_false): + { + int res; + JSValue op1; + + op1 = sp[-1]; + pc += 4; + if ((uint32_t)JS_VALUE_GET_TAG(op1) <= JS_TAG_UNDEFINED) { + res = JS_VALUE_GET_INT(op1); + } else { + res = JS_ToBoolFree(ctx, op1); + } + sp--; + if (!res) { + pc += (int32_t)get_u32(pc - 4) - 4; + } + if (unlikely(js_poll_interrupts(ctx))) + goto exception; + } + BREAK; + CASE(OP_if_true8): + { + int res; + JSValue op1; + + op1 = sp[-1]; + pc += 1; + if ((uint32_t)JS_VALUE_GET_TAG(op1) <= JS_TAG_UNDEFINED) { + res = JS_VALUE_GET_INT(op1); + } else { + res = JS_ToBoolFree(ctx, op1); + } + sp--; + if (res) { + pc += (int8_t)pc[-1] - 1; + } + if (unlikely(js_poll_interrupts(ctx))) + goto exception; + } + BREAK; + CASE(OP_if_false8): + { + int res; + JSValue op1; + + op1 = sp[-1]; + pc += 1; + if ((uint32_t)JS_VALUE_GET_TAG(op1) <= JS_TAG_UNDEFINED) { + res = JS_VALUE_GET_INT(op1); + } else { + res = JS_ToBoolFree(ctx, op1); + } + sp--; + if (!res) { + pc += (int8_t)pc[-1] - 1; + } + if (unlikely(js_poll_interrupts(ctx))) + goto exception; + } + BREAK; + CASE(OP_catch): + { + int32_t diff; + diff = get_u32(pc); + sp[0] = JS_NewCatchOffset(ctx, pc + diff - b->byte_code_buf); + sp++; + pc += 4; + } + BREAK; + CASE(OP_gosub): + { + int32_t diff; + diff = get_u32(pc); + /* XXX: should have a different tag to avoid security flaw */ + sp[0] = js_int32(pc + 4 - b->byte_code_buf); + sp++; + pc += diff; + } + BREAK; + CASE(OP_ret): + { + JSValue op1; + uint32_t pos; + op1 = sp[-1]; + if (unlikely(JS_VALUE_GET_TAG(op1) != JS_TAG_INT)) + goto ret_fail; + pos = JS_VALUE_GET_INT(op1); + if (unlikely(pos >= b->byte_code_len)) { + ret_fail: + JS_ThrowInternalError(ctx, "invalid ret value"); + goto exception; + } + sp--; + pc = b->byte_code_buf + pos; + } + BREAK; + + CASE(OP_for_in_start): + sf->cur_pc = pc; + if (js_for_in_start(ctx, sp)) + goto exception; + BREAK; + CASE(OP_for_in_next): + sf->cur_pc = pc; + if (js_for_in_next(ctx, sp)) + goto exception; + sp += 2; + BREAK; + CASE(OP_for_of_start): + sf->cur_pc = pc; + if (js_for_of_start(ctx, sp, false)) + goto exception; + sp += 1; + *sp++ = JS_NewCatchOffset(ctx, 0); + BREAK; + CASE(OP_for_of_next): + { + int offset = -3 - pc[0]; + pc += 1; + sf->cur_pc = pc; + if (js_for_of_next(ctx, sp, offset)) + goto exception; + sp += 2; + } + BREAK; + CASE(OP_for_await_of_start): + sf->cur_pc = pc; + if (js_for_of_start(ctx, sp, true)) + goto exception; + sp += 1; + *sp++ = JS_NewCatchOffset(ctx, 0); + BREAK; + CASE(OP_iterator_get_value_done): + sf->cur_pc = pc; + if (js_iterator_get_value_done(ctx, sp)) + goto exception; + sp += 1; + BREAK; + CASE(OP_check_object): + if (unlikely(!JS_IsObject(sp[-1]))) { + JS_ThrowTypeErrorNotAnObject(ctx); + goto exception; + } + BREAK; + + CASE(OP_iterator_close): + /* iter_obj next catch_offset -> */ + sp--; /* drop the catch offset to avoid getting caught by exception */ + JS_FreeValue(ctx, sp[-1]); /* drop the next method */ + sp--; + if (!JS_IsUndefined(sp[-1])) { + sf->cur_pc = pc; + if (JS_IteratorClose(ctx, sp[-1], false)) + goto exception; + JS_FreeValue(ctx, sp[-1]); + } + sp--; + BREAK; + CASE(OP_nip_catch): + { + JSValue ret_val; + /* catch_offset ... ret_val -> ret_eval */ + ret_val = *--sp; + while (sp > stack_buf && + JS_VALUE_GET_TAG(sp[-1]) != JS_TAG_CATCH_OFFSET) { + JS_FreeValue(ctx, *--sp); + } + if (unlikely(sp == stack_buf)) { + JS_ThrowInternalError(ctx, "nip_catch"); + JS_FreeValue(ctx, ret_val); + goto exception; + } + sp[-1] = ret_val; + } + BREAK; + + CASE(OP_using_dispose_init): + sp[0] = JS_UNINITIALIZED; + sp++; + BREAK; + + CASE(OP_using_dispose): + { + int idx; + JSValueConst val, method; + JSValue ret, error_state; + + idx = get_u16(pc); + pc += 2; + val = var_buf[idx]; + method = var_buf[idx + 1]; + error_state = sp[-1]; + + if (JS_IsNull(val) || JS_IsUndefined(val) || + JS_IsUninitialized(val)) { + /* null/undefined (spec-permitted) or uninitialized + (declaration threw before assignment). */ + BREAK; + } + sf->cur_pc = pc; + ret = JS_Call(ctx, method, val, 0, NULL); + if (JS_IsException(ret)) { + JSValue new_error = JS_GetException(ctx); + if (!JS_IsUninitialized(error_state)) { + JSValue se; + se = js_new_suppressed_error(ctx, new_error, + error_state); + JS_FreeValue(ctx, new_error); + JS_FreeValue(ctx, error_state); + if (JS_IsException(se)) { + sp[-1] = JS_GetException(ctx); + } else { + sp[-1] = se; + } + } else { + sp[-1] = new_error; + } + } else { + JS_FreeValue(ctx, ret); + } + } + BREAK; + + CASE(OP_using_dispose_async): + { + int idx; + JSValueConst val, method; + JSValue ret; + + idx = get_u16(pc); + pc += 2; + val = var_buf[idx]; + method = var_buf[idx + 1]; + + if (JS_IsNull(val) || JS_IsUndefined(val) || + JS_IsUninitialized(val)) { + sp[0] = JS_UNDEFINED; + sp++; + BREAK; + } + sf->cur_pc = pc; + ret = JS_Call(ctx, method, val, 0, NULL); + if (JS_IsException(ret)) + goto exception; + sp[0] = ret; + sp++; + } + BREAK; + + CASE(OP_using_dispose_merge): + { + JSValue new_error = sp[-1]; + JSValue error_state = sp[-2]; + sp--; + if (!JS_IsUninitialized(error_state)) { + JSValue se = js_new_suppressed_error(ctx, new_error, + error_state); + JS_FreeValue(ctx, new_error); + JS_FreeValue(ctx, error_state); + if (JS_IsException(se)) { + sp[-1] = JS_GetException(ctx); + } else { + sp[-1] = se; + } + } else { + sp[-1] = new_error; + } + } + BREAK; + + CASE(OP_using_dispose_end): + { + JSValue error_state = sp[-1]; + sp--; + if (!JS_IsUninitialized(error_state)) { + JS_Throw(ctx, error_state); + goto exception; + } + } + BREAK; + + CASE(OP_using_check): + { + int hint = pc[0]; + JSValue method; + pc += 1; + sf->cur_pc = pc; + if (js_op_using_check(ctx, sp[-1], hint, &method)) + goto exception; + sp[0] = method; + sp++; + } + BREAK; + + CASE(OP_iterator_next): + /* stack: iter_obj next catch_offset val */ + { + JSValue ret; + sf->cur_pc = pc; + ret = JS_Call(ctx, sp[-3], sp[-4], 1, vc(sp - 1)); + if (JS_IsException(ret)) + goto exception; + JS_FreeValue(ctx, sp[-1]); + sp[-1] = ret; + } + BREAK; + + CASE(OP_iterator_call): + /* stack: iter_obj next catch_offset val */ + { + JSValue method, ret; + bool ret_flag; + int flags; + flags = *pc++; + sf->cur_pc = pc; + method = JS_GetProperty(ctx, sp[-4], (flags & 1) ? + JS_ATOM_throw : JS_ATOM_return); + if (JS_IsException(method)) + goto exception; + if (JS_IsUndefined(method) || JS_IsNull(method)) { + ret_flag = true; + } else { + if (flags & 2) { + /* no argument */ + ret = JS_CallFree(ctx, method, sp[-4], + 0, NULL); + } else { + ret = JS_CallFree(ctx, method, sp[-4], + 1, vc(sp - 1)); + } + if (JS_IsException(ret)) + goto exception; + JS_FreeValue(ctx, sp[-1]); + sp[-1] = ret; + ret_flag = false; + } + sp[0] = js_bool(ret_flag); + sp += 1; + } + BREAK; + + CASE(OP_lnot): + { + int res; + JSValue op1; + + op1 = sp[-1]; + if ((uint32_t)JS_VALUE_GET_TAG(op1) <= JS_TAG_UNDEFINED) { + res = JS_VALUE_GET_INT(op1) != 0; + } else { + res = JS_ToBoolFree(ctx, op1); + } + sp[-1] = js_bool(!res); + } + BREAK; + + CASE(OP_get_field): + { + JSValue val, obj; + JSAtom atom; + JSObject *p; + JSProperty *pr; + JSShapeProperty *prs; + + atom = get_u32(pc); + pc += 4; + + obj = sp[-1]; + if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT)) { + p = JS_VALUE_GET_OBJ(obj); + for(;;) { + prs = find_own_property(&pr, p, atom); + if (prs) { + /* found */ + if (unlikely(prs->flags & JS_PROP_TMASK)) + goto get_field_slow_path; + val = js_dup(pr->u.value); + break; + } + if (unlikely(p->is_exotic)) { + /* XXX: should avoid the slow path for arrays + and typed arrays by ensuring that 'prop' is + not numeric */ + obj = JS_MKPTR(JS_TAG_OBJECT, p); + goto get_field_slow_path; + } + p = p->shape->proto; + if (!p) { + val = JS_UNDEFINED; + break; + } + } + } else { + get_field_slow_path: + sf->cur_pc = pc; + val = JS_GetPropertyInternal(ctx, obj, atom, sp[-1], false); + if (unlikely(JS_IsException(val))) + goto exception; + } + JS_FreeValue(ctx, sp[-1]); + sp[-1] = val; + } + BREAK; + + CASE(OP_get_field2): + { + JSValue val, obj; + JSAtom atom; + JSObject *p; + JSProperty *pr; + JSShapeProperty *prs; + + atom = get_u32(pc); + pc += 4; + + obj = sp[-1]; + if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT)) { + p = JS_VALUE_GET_OBJ(obj); + for(;;) { + prs = find_own_property(&pr, p, atom); + if (prs) { + /* found */ + if (unlikely(prs->flags & JS_PROP_TMASK)) + goto get_field2_slow_path; + val = js_dup(pr->u.value); + break; + } + if (unlikely(p->is_exotic)) { + /* XXX: should avoid the slow path for arrays + and typed arrays by ensuring that 'prop' is + not numeric */ + obj = JS_MKPTR(JS_TAG_OBJECT, p); + goto get_field2_slow_path; + } + p = p->shape->proto; + if (!p) { + val = JS_UNDEFINED; + break; + } + } + } else { + get_field2_slow_path: + sf->cur_pc = pc; + val = JS_GetPropertyInternal(ctx, obj, atom, sp[-1], false); + if (unlikely(JS_IsException(val))) + goto exception; + } + *sp++ = val; + } + BREAK; + + CASE(OP_put_field): + { + int ret; + JSValue obj; + JSAtom atom; + JSObject *p; + JSProperty *pr; + JSShapeProperty *prs; + + atom = get_u32(pc); + pc += 4; + + obj = sp[-2]; + if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT)) { + p = JS_VALUE_GET_OBJ(obj); + prs = find_own_property(&pr, p, atom); + if (!prs) + goto put_field_slow_path; + if (likely((prs->flags & (JS_PROP_TMASK | JS_PROP_WRITABLE | + JS_PROP_LENGTH)) == JS_PROP_WRITABLE)) { + /* fast path */ + set_value(ctx, &pr->u.value, sp[-1]); + } else { + goto put_field_slow_path; + } + JS_FreeValue(ctx, obj); + sp -= 2; + } else { + put_field_slow_path: + sf->cur_pc = pc; + ret = JS_SetPropertyInternal2(ctx, obj, atom, sp[-1], obj, + JS_PROP_THROW_STRICT); + JS_FreeValue(ctx, obj); + sp -= 2; + if (unlikely(ret < 0)) + goto exception; + } + } + BREAK; + + CASE(OP_private_symbol): + { + JSAtom atom; + JSValue val; + + atom = get_u32(pc); + pc += 4; + val = JS_NewSymbolFromAtom(ctx, atom, JS_ATOM_TYPE_PRIVATE); + if (JS_IsException(val)) + goto exception; + *sp++ = val; + } + BREAK; + + CASE(OP_get_private_field): + { + JSValue val; + sf->cur_pc = pc; + val = JS_GetPrivateField(ctx, sp[-2], sp[-1]); + JS_FreeValue(ctx, sp[-1]); + JS_FreeValue(ctx, sp[-2]); + sp[-2] = val; + sp--; + if (unlikely(JS_IsException(val))) + goto exception; + } + BREAK; + + CASE(OP_put_private_field): + { + int ret; + sf->cur_pc = pc; + ret = JS_SetPrivateField(ctx, sp[-3], sp[-1], sp[-2]); + JS_FreeValue(ctx, sp[-3]); + JS_FreeValue(ctx, sp[-1]); + sp -= 3; + if (unlikely(ret < 0)) + goto exception; + } + BREAK; + + CASE(OP_define_private_field): + { + int ret; + ret = JS_DefinePrivateField(ctx, sp[-3], sp[-2], sp[-1]); + JS_FreeValue(ctx, sp[-2]); + sp -= 2; + if (unlikely(ret < 0)) + goto exception; + } + BREAK; + + CASE(OP_define_field): + { + int ret; + JSAtom atom; + atom = get_u32(pc); + pc += 4; + + ret = JS_DefinePropertyValue(ctx, sp[-2], atom, sp[-1], + JS_PROP_C_W_E | JS_PROP_THROW); + sp--; + if (unlikely(ret < 0)) + goto exception; + } + BREAK; + + CASE(OP_set_name): + { + int ret; + JSAtom atom; + atom = get_u32(pc); + pc += 4; + + ret = JS_DefineObjectName(ctx, sp[-1], atom, JS_PROP_CONFIGURABLE); + if (unlikely(ret < 0)) + goto exception; + } + BREAK; + CASE(OP_set_name_computed): + { + int ret; + ret = JS_DefineObjectNameComputed(ctx, sp[-1], sp[-2], JS_PROP_CONFIGURABLE); + if (unlikely(ret < 0)) + goto exception; + } + BREAK; + CASE(OP_set_proto): + { + JSValue proto; + proto = sp[-1]; + if (JS_IsObject(proto) || JS_IsNull(proto)) { + if (JS_SetPrototypeInternal(ctx, sp[-2], proto, true) < 0) + goto exception; + } + JS_FreeValue(ctx, proto); + sp--; + } + BREAK; + CASE(OP_set_home_object): + js_method_set_home_object(ctx, sp[-1], sp[-2]); + BREAK; + CASE(OP_define_method): + CASE(OP_define_method_computed): + { + JSValue getter, setter, value; + JSValue obj; + JSAtom atom; + int flags, ret, op_flags; + bool is_computed; +#define OP_DEFINE_METHOD_METHOD 0 +#define OP_DEFINE_METHOD_GETTER 1 +#define OP_DEFINE_METHOD_SETTER 2 +#define OP_DEFINE_METHOD_ENUMERABLE 4 + + is_computed = (opcode == OP_define_method_computed); + if (is_computed) { + atom = JS_ValueToAtom(ctx, sp[-2]); + if (unlikely(atom == JS_ATOM_NULL)) + goto exception; + opcode += OP_define_method - OP_define_method_computed; + } else { + atom = get_u32(pc); + pc += 4; + } + op_flags = *pc++; + + obj = sp[-2 - is_computed]; + flags = JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE | + JS_PROP_HAS_ENUMERABLE | JS_PROP_THROW; + if (op_flags & OP_DEFINE_METHOD_ENUMERABLE) + flags |= JS_PROP_ENUMERABLE; + op_flags &= 3; + value = JS_UNDEFINED; + getter = JS_UNDEFINED; + setter = JS_UNDEFINED; + if (op_flags == OP_DEFINE_METHOD_METHOD) { + value = sp[-1]; + flags |= JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE; + } else if (op_flags == OP_DEFINE_METHOD_GETTER) { + getter = sp[-1]; + flags |= JS_PROP_HAS_GET; + } else { + setter = sp[-1]; + flags |= JS_PROP_HAS_SET; + } + ret = js_method_set_properties(ctx, sp[-1], atom, flags, obj); + if (ret >= 0) { + ret = JS_DefineProperty(ctx, obj, atom, value, + getter, setter, flags); + } + JS_FreeValue(ctx, sp[-1]); + if (is_computed) { + JS_FreeAtom(ctx, atom); + JS_FreeValue(ctx, sp[-2]); + } + sp -= 1 + is_computed; + if (unlikely(ret < 0)) + goto exception; + } + BREAK; + + CASE(OP_define_class): + CASE(OP_define_class_computed): + { + int class_flags; + JSAtom atom; + + atom = get_u32(pc); + class_flags = pc[4]; + pc += 5; + if (js_op_define_class(ctx, sp, atom, class_flags, + var_refs, sf, + (opcode == OP_define_class_computed)) < 0) + goto exception; + } + BREAK; + + CASE(OP_get_array_el): + { + JSValue val; + + /* fast path: regular/typed array element by int index */ + if (likely(JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_OBJECT && + JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_INT)) { + JSObject *p = JS_VALUE_GET_OBJ(sp[-2]); + uint32_t idx = JS_VALUE_GET_INT(sp[-1]); + if (likely(p->class_id == JS_CLASS_ARRAY && + idx < p->u.array.count)) { + val = js_dup(p->u.array.u.values[idx]); + JS_FreeValue(ctx, sp[-2]); + sp[-2] = val; + sp--; + BREAK; + } + if (js_get_fast_array_element(ctx, p, idx, &val)) { + JS_FreeValue(ctx, sp[-2]); + sp[-2] = val; + sp--; + BREAK; + } + } + sf->cur_pc = pc; + val = JS_GetPropertyValue(ctx, sp[-2], sp[-1]); + JS_FreeValue(ctx, sp[-2]); + sp[-2] = val; + sp--; + if (unlikely(JS_IsException(val))) + goto exception; + } + BREAK; + + CASE(OP_get_array_el2): + { + JSValue val; + + /* fast path: regular/typed array element by int index */ + if (likely(JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_OBJECT && + JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_INT)) { + JSObject *p = JS_VALUE_GET_OBJ(sp[-2]); + uint32_t idx = JS_VALUE_GET_INT(sp[-1]); + if (likely(p->class_id == JS_CLASS_ARRAY && + idx < p->u.array.count)) { + sp[-1] = js_dup(p->u.array.u.values[idx]); + BREAK; + } + if (js_get_fast_array_element(ctx, p, idx, &val)) { + sp[-1] = val; + BREAK; + } + } + sf->cur_pc = pc; + val = JS_GetPropertyValue(ctx, sp[-2], sp[-1]); + sp[-1] = val; + if (unlikely(JS_IsException(val))) + goto exception; + } + BREAK; + + CASE(OP_get_ref_value): + { + JSValue val; + sf->cur_pc = pc; + if (unlikely(JS_IsUndefined(sp[-2]))) { + JSAtom atom = JS_ValueToAtom(ctx, sp[-1]); + if (atom != JS_ATOM_NULL) { + JS_ThrowReferenceErrorNotDefined(ctx, atom); + JS_FreeAtom(ctx, atom); + } + goto exception; + } + val = JS_GetPropertyValue(ctx, sp[-2], + js_dup(sp[-1])); + if (unlikely(JS_IsException(val))) + goto exception; + sp[0] = val; + sp++; + } + BREAK; + + CASE(OP_get_super_value): + { + JSValue val; + JSAtom atom; + sf->cur_pc = pc; + atom = JS_ValueToAtom(ctx, sp[-1]); + if (unlikely(atom == JS_ATOM_NULL)) + goto exception; + val = JS_GetPropertyInternal(ctx, sp[-2], atom, sp[-3], false); + JS_FreeAtom(ctx, atom); + if (unlikely(JS_IsException(val))) + goto exception; + JS_FreeValue(ctx, sp[-1]); + JS_FreeValue(ctx, sp[-2]); + JS_FreeValue(ctx, sp[-3]); + sp[-3] = val; + sp -= 2; + } + BREAK; + + CASE(OP_put_array_el): + { + int ret; + JSValue val; + uint32_t idx; + JSObject *p; + + val = sp[-1]; + if (likely(JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_INT)) { + idx = JS_VALUE_GET_INT(sp[-2]); + if (likely(JS_VALUE_GET_TAG(sp[-3]) == JS_TAG_OBJECT)) { + p = JS_VALUE_GET_OBJ(sp[-3]); + if (likely(p->class_id == JS_CLASS_ARRAY && + idx < (uint32_t)p->u.array.count)) { + set_value(ctx, &p->u.array.u.values[idx], val); + JS_FreeValue(ctx, sp[-3]); + sp -= 3; + BREAK; + } + if (likely(p->class_id == JS_CLASS_ARRAY && + idx == (uint32_t)p->u.array.count && + p->fast_array && + p->extensible && + p->shape->proto == JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_ARRAY]) && + ctx->std_array_prototype)) { + /* fast path to add an element */ + uint32_t array_len; + if (likely(JS_VALUE_GET_TAG(p->prop[0].u.value) == JS_TAG_INT)) { + uint32_t new_len = idx + 1; + array_len = JS_VALUE_GET_INT(p->prop[0].u.value); + if (likely(new_len <= p->u.array.u1.size)) { + p->u.array.u.values[idx] = val; + p->u.array.count = new_len; + if (new_len > array_len) + p->prop[0].u.value = js_int32(new_len); + JS_FreeValue(ctx, sp[-3]); + sp -= 3; + BREAK; + } + } + } + } + } + sf->cur_pc = pc; + ret = JS_SetPropertyValue(ctx, sp[-3], sp[-2], sp[-1], JS_PROP_THROW_STRICT); + JS_FreeValue(ctx, sp[-3]); + sp -= 3; + if (unlikely(ret < 0)) + goto exception; + } + BREAK; + + CASE(OP_put_ref_value): + { + int ret, flags; + sf->cur_pc = pc; + flags = JS_PROP_THROW_STRICT; + if (unlikely(JS_IsUndefined(sp[-3]))) { + if (is_strict_mode(ctx)) { + JSAtom atom = JS_ValueToAtom(ctx, sp[-2]); + if (atom != JS_ATOM_NULL) { + JS_ThrowReferenceErrorNotDefined(ctx, atom); + JS_FreeAtom(ctx, atom); + } + goto exception; + } else { + sp[-3] = js_dup(ctx->global_obj); + } + } else { + if (is_strict_mode(ctx)) + flags |= JS_PROP_NO_ADD; + } + ret = JS_SetPropertyValue(ctx, sp[-3], sp[-2], sp[-1], flags); + JS_FreeValue(ctx, sp[-3]); + sp -= 3; + if (unlikely(ret < 0)) + goto exception; + } + BREAK; + + CASE(OP_put_super_value): + { + int ret; + JSAtom atom; + sf->cur_pc = pc; + if (JS_VALUE_GET_TAG(sp[-3]) != JS_TAG_OBJECT) { + JS_ThrowTypeErrorNotAnObject(ctx); + goto exception; + } + atom = JS_ValueToAtom(ctx, sp[-2]); + if (unlikely(atom == JS_ATOM_NULL)) + goto exception; + ret = JS_SetPropertyInternal2(ctx, + sp[-3], atom, + sp[-1], sp[-4], + JS_PROP_THROW_STRICT); + JS_FreeAtom(ctx, atom); + JS_FreeValue(ctx, sp[-4]); + JS_FreeValue(ctx, sp[-3]); + JS_FreeValue(ctx, sp[-2]); + sp -= 4; + if (ret < 0) + goto exception; + } + BREAK; + + CASE(OP_define_array_el): + { + int ret; + ret = JS_DefinePropertyValueValue(ctx, sp[-3], js_dup(sp[-2]), sp[-1], + JS_PROP_C_W_E | JS_PROP_THROW); + sp -= 1; + if (unlikely(ret < 0)) + goto exception; + } + BREAK; + + CASE(OP_append): /* array pos enumobj -- array pos */ + { + sf->cur_pc = pc; + if (js_append_enumerate(ctx, sp)) + goto exception; + JS_FreeValue(ctx, *--sp); + } + BREAK; + + CASE(OP_copy_data_properties): /* target source excludeList */ + { + /* stack offsets (-1 based): + 2 bits for target, + 3 bits for source, + 2 bits for exclusionList */ + int mask; + + mask = *pc++; + sf->cur_pc = pc; + if (JS_CopyDataProperties(ctx, sp[-1 - (mask & 3)], + sp[-1 - ((mask >> 2) & 7)], + sp[-1 - ((mask >> 5) & 7)], 0)) + goto exception; + } + BREAK; + + CASE(OP_add): + { + JSValue op1, op2; + op1 = sp[-2]; + op2 = sp[-1]; + if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { + int64_t r; + r = (int64_t)JS_VALUE_GET_INT(op1) + JS_VALUE_GET_INT(op2); + if (unlikely(r < INT32_MIN || r > INT32_MAX)) + sp[-2] = js_float64(r); + else + sp[-2] = js_int32(r); + sp--; + } else if (JS_VALUE_IS_BOTH_FLOAT(op1, op2)) { + JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + sp[-2] = js_float64(JS_VALUE_GET_FLOAT64(op1) + + JS_VALUE_GET_FLOAT64(op2)); + JS_X87_FPCW_RESTORE(fpcw); + sp--; + } else if (JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(op1)) || + JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(op2))) { + /* mixed int/float; the BOTH_FLOAT fast path above is unchanged */ + double d1, d2; + if (!js_arith_to_float64(op1, &d1) || + !js_arith_to_float64(op2, &d2)) + goto add_slow_case; + JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + sp[-2] = js_float64(d1 + d2); + JS_X87_FPCW_RESTORE(fpcw); + sp--; + } else { + add_slow_case: + sf->cur_pc = pc; + if (js_add_slow(ctx, sp)) + goto exception; + sp--; + } + } + BREAK; + CASE(OP_add_loc): + { + JSValue *pv; + int idx; + idx = *pc; + pc += 1; + + pv = &var_buf[idx]; + if (likely(JS_VALUE_IS_BOTH_INT(*pv, sp[-1]))) { + int64_t r; + r = (int64_t)JS_VALUE_GET_INT(*pv) + + JS_VALUE_GET_INT(sp[-1]); + if (unlikely((int)r != r)) + *pv = __JS_NewFloat64((double)r); + else + *pv = js_int32(r); + sp--; + } else if (JS_VALUE_GET_TAG(*pv) == JS_TAG_STRING) { + JSValue op1; + op1 = sp[-1]; + sp--; + sf->cur_pc = pc; + op1 = JS_ToPrimitiveFree(ctx, op1, HINT_NONE); + if (JS_IsException(op1)) + goto exception; + op1 = JS_ConcatString(ctx, js_dup(*pv), op1); + if (JS_IsException(op1)) + goto exception; + set_value(ctx, pv, op1); + } else { + JSValue ops[2]; + /* In case of exception, js_add_slow frees ops[0] + and ops[1], so we must duplicate *pv */ + sf->cur_pc = pc; + ops[0] = js_dup(*pv); + ops[1] = sp[-1]; + sp--; + if (js_add_slow(ctx, ops + 2)) + goto exception; + set_value(ctx, pv, ops[0]); + } + } + BREAK; + CASE(OP_sub): + { + JSValue op1, op2; + op1 = sp[-2]; + op2 = sp[-1]; + if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { + int64_t r; + r = (int64_t)JS_VALUE_GET_INT(op1) - JS_VALUE_GET_INT(op2); + if (unlikely((int)r != r)) + sp[-2] = __JS_NewFloat64((double)r); + else + sp[-2] = js_int32(r); + sp--; + } else if (JS_VALUE_IS_BOTH_FLOAT(op1, op2)) { + JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + sp[-2] = js_float64(JS_VALUE_GET_FLOAT64(op1) - + JS_VALUE_GET_FLOAT64(op2)); + JS_X87_FPCW_RESTORE(fpcw); + sp--; + } else if (JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(op1)) || + JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(op2))) { + /* mixed int/float; the BOTH_FLOAT fast path above is unchanged */ + double d1, d2; + if (!js_arith_to_float64(op1, &d1) || + !js_arith_to_float64(op2, &d2)) + goto binary_arith_slow; + JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + sp[-2] = js_float64(d1 - d2); + JS_X87_FPCW_RESTORE(fpcw); + sp--; + } else { + goto binary_arith_slow; + } + } + BREAK; + CASE(OP_mul): + { + JSValue op1, op2; + double d; + op1 = sp[-2]; + op2 = sp[-1]; + if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { + int32_t v1, v2; + int64_t r; + v1 = JS_VALUE_GET_INT(op1); + v2 = JS_VALUE_GET_INT(op2); + r = (int64_t)v1 * v2; + if (unlikely((int)r != r)) { + d = (double)r; + goto mul_fp_res; + } + /* need to test zero case for -0 result */ + if (unlikely(r == 0 && (v1 | v2) < 0)) { + d = -0.0; + goto mul_fp_res; + } + sp[-2] = js_int32(r); + sp--; + } else if (JS_VALUE_IS_BOTH_FLOAT(op1, op2)) { + JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + d = JS_VALUE_GET_FLOAT64(op1) * JS_VALUE_GET_FLOAT64(op2); + JS_X87_FPCW_RESTORE(fpcw); + mul_fp_res: + sp[-2] = js_float64(d); + sp--; + } else if (JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(op1)) || + JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(op2))) { + /* mixed int/float; the BOTH_FLOAT fast path above is unchanged */ + double d1, d2; + if (!js_arith_to_float64(op1, &d1) || + !js_arith_to_float64(op2, &d2)) + goto binary_arith_slow; + JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + d = d1 * d2; + JS_X87_FPCW_RESTORE(fpcw); + goto mul_fp_res; + } else { + goto binary_arith_slow; + } + } + BREAK; + CASE(OP_div): + { + JSValue op1, op2; + op1 = sp[-2]; + op2 = sp[-1]; + if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { + int v1, v2; + v1 = JS_VALUE_GET_INT(op1); + v2 = JS_VALUE_GET_INT(op2); + sp[-2] = js_number((double)v1 / (double)v2); + sp--; + } else if (JS_VALUE_IS_BOTH_FLOAT(op1, op2)) { + JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + sp[-2] = js_number(JS_VALUE_GET_FLOAT64(op1) / + JS_VALUE_GET_FLOAT64(op2)); + JS_X87_FPCW_RESTORE(fpcw); + sp--; + } else if (JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(op1)) || + JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(op2))) { + /* mixed int/float; the BOTH_FLOAT fast path above is unchanged */ + double d1, d2; + if (!js_arith_to_float64(op1, &d1) || + !js_arith_to_float64(op2, &d2)) + goto binary_arith_slow; + JS_X87_FPCW_SAVE_AND_ADJUST(fpcw); + sp[-2] = js_number(d1 / d2); + JS_X87_FPCW_RESTORE(fpcw); + sp--; + } else { + goto binary_arith_slow; + } + } + BREAK; + CASE(OP_mod): + { + JSValue op1, op2; + op1 = sp[-2]; + op2 = sp[-1]; + if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { + int v1, v2, r; + v1 = JS_VALUE_GET_INT(op1); + v2 = JS_VALUE_GET_INT(op2); + /* We must avoid v2 = 0, v1 = INT32_MIN and v2 = + -1 and the cases where the result is -0. */ + if (unlikely(v1 < 0 || v2 <= 0)) + goto binary_arith_slow; + r = v1 % v2; + sp[-2] = js_int32(r); + sp--; + } else { + goto binary_arith_slow; + } + } + BREAK; + CASE(OP_pow): + binary_arith_slow: + sf->cur_pc = pc; + if (js_binary_arith_slow(ctx, sp, opcode)) + goto exception; + sp--; + BREAK; + + CASE(OP_plus): + { + JSValue op1; + uint32_t tag; + op1 = sp[-1]; + tag = JS_VALUE_GET_TAG(op1); + if (tag == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag)) { + } else { + sf->cur_pc = pc; + if (js_unary_arith_slow(ctx, sp, opcode)) + goto exception; + } + } + BREAK; + CASE(OP_neg): + { + JSValue op1; + uint32_t tag; + int val; + double d; + op1 = sp[-1]; + tag = JS_VALUE_GET_TAG(op1); + if (tag == JS_TAG_INT) { + val = JS_VALUE_GET_INT(op1); + /* Note: -0 cannot be expressed as integer */ + if (unlikely(val == 0)) { + d = -0.0; + goto neg_fp_res; + } + if (unlikely(val == INT32_MIN)) { + d = -(double)val; + goto neg_fp_res; + } + sp[-1] = js_int32(-val); + } else if (JS_TAG_IS_FLOAT64(tag)) { + d = -JS_VALUE_GET_FLOAT64(op1); + neg_fp_res: + sp[-1] = js_float64(d); + } else { + sf->cur_pc = pc; + if (js_unary_arith_slow(ctx, sp, opcode)) + goto exception; + } + } + BREAK; + CASE(OP_inc): + { + JSValue op1; + int val; + op1 = sp[-1]; + if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { + val = JS_VALUE_GET_INT(op1); + if (unlikely(val == INT32_MAX)) + goto inc_slow; + sp[-1] = js_int32(val + 1); + } else { + inc_slow: + sf->cur_pc = pc; + if (js_unary_arith_slow(ctx, sp, opcode)) + goto exception; + } + } + BREAK; + CASE(OP_dec): + { + JSValue op1; + int val; + op1 = sp[-1]; + if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { + val = JS_VALUE_GET_INT(op1); + if (unlikely(val == INT32_MIN)) + goto dec_slow; + sp[-1] = js_int32(val - 1); + } else { + dec_slow: + sf->cur_pc = pc; + if (js_unary_arith_slow(ctx, sp, opcode)) + goto exception; + } + } + BREAK; + CASE(OP_post_inc): + { + JSValue op1; + int val; + op1 = sp[-1]; + if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { + val = JS_VALUE_GET_INT(op1); + if (unlikely(val == INT32_MAX)) + goto post_inc_slow; + sp[0] = js_int32(val + 1); + } else { + post_inc_slow: + sf->cur_pc = pc; + if (js_post_inc_slow(ctx, sp, opcode)) + goto exception; + } + sp++; + } + BREAK; + CASE(OP_post_dec): + { + JSValue op1; + int val; + op1 = sp[-1]; + if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { + val = JS_VALUE_GET_INT(op1); + if (unlikely(val == INT32_MIN)) + goto post_dec_slow; + sp[0] = js_int32(val - 1); + } else { + post_dec_slow: + sf->cur_pc = pc; + if (js_post_inc_slow(ctx, sp, opcode)) + goto exception; + } + sp++; + } + BREAK; + CASE(OP_inc_loc): + { + JSValue op1; + int val; + int idx; + idx = *pc; + pc += 1; + + op1 = var_buf[idx]; + if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { + val = JS_VALUE_GET_INT(op1); + if (unlikely(val == INT32_MAX)) + goto inc_loc_slow; + var_buf[idx] = js_int32(val + 1); + } else { + inc_loc_slow: + sf->cur_pc = pc; + /* must duplicate otherwise the variable value may + be destroyed before JS code accesses it */ + op1 = js_dup(op1); + if (js_unary_arith_slow(ctx, &op1 + 1, OP_inc)) + goto exception; + set_value(ctx, &var_buf[idx], op1); + } + } + BREAK; + CASE(OP_dec_loc): + { + JSValue op1; + int val; + int idx; + idx = *pc; + pc += 1; + + op1 = var_buf[idx]; + if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { + val = JS_VALUE_GET_INT(op1); + if (unlikely(val == INT32_MIN)) + goto dec_loc_slow; + var_buf[idx] = js_int32(val - 1); + } else { + dec_loc_slow: + sf->cur_pc = pc; + /* must duplicate otherwise the variable value may + be destroyed before JS code accesses it */ + op1 = js_dup(op1); + if (js_unary_arith_slow(ctx, &op1 + 1, OP_dec)) + goto exception; + set_value(ctx, &var_buf[idx], op1); + } + } + BREAK; + CASE(OP_not): + { + JSValue op1; + op1 = sp[-1]; + if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { + sp[-1] = js_int32(~JS_VALUE_GET_INT(op1)); + } else { + sf->cur_pc = pc; + if (js_not_slow(ctx, sp)) + goto exception; + } + } + BREAK; + + CASE(OP_shl): + { + JSValue op1, op2; + op1 = sp[-2]; + op2 = sp[-1]; + if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { + uint32_t v1, v2; + v1 = JS_VALUE_GET_INT(op1); + v2 = JS_VALUE_GET_INT(op2) & 0x1f; + sp[-2] = js_int32(v1 << v2); + sp--; + } else { + sf->cur_pc = pc; + if (js_binary_logic_slow(ctx, sp, opcode)) + goto exception; + sp--; + } + } + BREAK; + CASE(OP_shr): + { + JSValue op1, op2; + op1 = sp[-2]; + op2 = sp[-1]; + if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { + uint32_t v2; + v2 = JS_VALUE_GET_INT(op2); + v2 &= 0x1f; + sp[-2] = js_uint32((uint32_t)JS_VALUE_GET_INT(op1) >> v2); + sp--; + } else { + sf->cur_pc = pc; + if (js_shr_slow(ctx, sp)) + goto exception; + sp--; + } + } + BREAK; + CASE(OP_sar): + { + JSValue op1, op2; + op1 = sp[-2]; + op2 = sp[-1]; + if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { + uint32_t v2; + v2 = JS_VALUE_GET_INT(op2); + if (unlikely(v2 > 0x1f)) { + v2 &= 0x1f; + } + sp[-2] = js_int32((int)JS_VALUE_GET_INT(op1) >> v2); + sp--; + } else { + sf->cur_pc = pc; + if (js_binary_logic_slow(ctx, sp, opcode)) + goto exception; + sp--; + } + } + BREAK; + CASE(OP_and): + { + JSValue op1, op2; + op1 = sp[-2]; + op2 = sp[-1]; + if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { + sp[-2] = js_int32(JS_VALUE_GET_INT(op1) & JS_VALUE_GET_INT(op2)); + sp--; + } else { + sf->cur_pc = pc; + if (js_binary_logic_slow(ctx, sp, opcode)) + goto exception; + sp--; + } + } + BREAK; + CASE(OP_or): + { + JSValue op1, op2; + op1 = sp[-2]; + op2 = sp[-1]; + if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { + sp[-2] = js_int32(JS_VALUE_GET_INT(op1) | JS_VALUE_GET_INT(op2)); + sp--; + } else { + sf->cur_pc = pc; + if (js_binary_logic_slow(ctx, sp, opcode)) + goto exception; + sp--; + } + } + BREAK; + CASE(OP_xor): + { + JSValue op1, op2; + op1 = sp[-2]; + op2 = sp[-1]; + if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { + sp[-2] = js_int32(JS_VALUE_GET_INT(op1) ^ JS_VALUE_GET_INT(op2)); + sp--; + } else { + sf->cur_pc = pc; + if (js_binary_logic_slow(ctx, sp, opcode)) + goto exception; + sp--; + } + } + BREAK; + + +#define OP_CMP(opcode, binary_op, slow_call) \ + CASE(opcode): \ + { \ + JSValue op1, op2; \ + op1 = sp[-2]; \ + op2 = sp[-1]; \ + if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { \ + sp[-2] = js_bool(JS_VALUE_GET_INT(op1) binary_op JS_VALUE_GET_INT(op2)); \ + sp--; \ + } else { \ + sf->cur_pc = pc; \ + if (slow_call) \ + goto exception; \ + sp--; \ + } \ + } \ + BREAK + + OP_CMP(OP_lt, <, js_relational_slow(ctx, sp, opcode)); + OP_CMP(OP_lte, <=, js_relational_slow(ctx, sp, opcode)); + OP_CMP(OP_gt, >, js_relational_slow(ctx, sp, opcode)); + OP_CMP(OP_gte, >=, js_relational_slow(ctx, sp, opcode)); + OP_CMP(OP_eq, ==, js_eq_slow(ctx, sp, 0)); + OP_CMP(OP_neq, !=, js_eq_slow(ctx, sp, 1)); + OP_CMP(OP_strict_eq, ==, js_strict_eq_slow(ctx, sp, 0)); + OP_CMP(OP_strict_neq, !=, js_strict_eq_slow(ctx, sp, 1)); + + CASE(OP_in): + sf->cur_pc = pc; + if (js_operator_in(ctx, sp)) + goto exception; + sp--; + BREAK; + CASE(OP_private_in): + if (js_operator_private_in(ctx, sp)) + goto exception; + sp--; + BREAK; + CASE(OP_instanceof): + sf->cur_pc = pc; + if (js_operator_instanceof(ctx, sp)) + goto exception; + sp--; + BREAK; + CASE(OP_typeof): + { + JSValue op1; + JSAtom atom; + + op1 = sp[-1]; + atom = js_operator_typeof(ctx, op1); + JS_FreeValue(ctx, op1); + sp[-1] = JS_AtomToString(ctx, atom); + } + BREAK; + CASE(OP_delete): + sf->cur_pc = pc; + if (js_operator_delete(ctx, sp)) + goto exception; + sp--; + BREAK; + CASE(OP_delete_var): + { + JSAtom atom; + int ret; + + atom = get_u32(pc); + pc += 4; + + sf->cur_pc = pc; + ret = JS_DeleteGlobalVar(ctx, atom); + if (unlikely(ret < 0)) + goto exception; + *sp++ = js_bool(ret); + } + BREAK; + + CASE(OP_to_object): + if (JS_VALUE_GET_TAG(sp[-1]) != JS_TAG_OBJECT) { + sf->cur_pc = pc; + ret_val = JS_ToObject(ctx, sp[-1]); + if (JS_IsException(ret_val)) + goto exception; + JS_FreeValue(ctx, sp[-1]); + sp[-1] = ret_val; + } + BREAK; + + CASE(OP_to_propkey): + switch (JS_VALUE_GET_TAG(sp[-1])) { + case JS_TAG_INT: + case JS_TAG_STRING: + case JS_TAG_SYMBOL: + break; + default: + sf->cur_pc = pc; + ret_val = JS_ToPropertyKey(ctx, sp[-1]); + if (JS_IsException(ret_val)) + goto exception; + JS_FreeValue(ctx, sp[-1]); + sp[-1] = ret_val; + break; + } + BREAK; + + CASE(OP_to_propkey2): + /* must be tested first */ + if (unlikely(JS_IsUndefined(sp[-2]) || JS_IsNull(sp[-2]))) { + JS_ThrowTypeError(ctx, "value has no property"); + goto exception; + } + switch (JS_VALUE_GET_TAG(sp[-1])) { + case JS_TAG_INT: + case JS_TAG_STRING: + case JS_TAG_SYMBOL: + break; + default: + sf->cur_pc = pc; + ret_val = JS_ToPropertyKey(ctx, sp[-1]); + if (JS_IsException(ret_val)) + goto exception; + JS_FreeValue(ctx, sp[-1]); + sp[-1] = ret_val; + break; + } + BREAK; + CASE(OP_with_get_var): + CASE(OP_with_put_var): + CASE(OP_with_delete_var): + CASE(OP_with_make_ref): + CASE(OP_with_get_ref): + CASE(OP_with_get_ref_undef): + { + JSAtom atom; + int32_t diff; + JSValue obj, val; + int ret, is_with; + atom = get_u32(pc); + diff = get_u32(pc + 4); + is_with = pc[8]; + pc += 9; + sf->cur_pc = pc; + + obj = sp[-1]; + ret = JS_HasProperty(ctx, obj, atom); + if (unlikely(ret < 0)) + goto exception; + if (ret) { + if (is_with) { + ret = js_has_unscopable(ctx, obj, atom); + if (unlikely(ret < 0)) + goto exception; + if (ret) + goto no_with; + } + switch (opcode) { + case OP_with_get_var: + ret = JS_HasProperty(ctx, obj, atom); + if (unlikely(ret < 0)) + goto exception; + + if (ret == 0) { + if (is_strict_mode(ctx)) { + JS_ThrowReferenceErrorNotDefined(ctx, atom); + goto exception; + } + val = JS_UNDEFINED; + } else { + val = JS_GetProperty(ctx, obj, atom); + if (unlikely(JS_IsException(val))) + goto exception; + } + set_value(ctx, &sp[-1], val); + break; + case OP_with_put_var: + /* XXX: check if strict mode */ + ret = JS_SetPropertyInternal(ctx, obj, atom, sp[-2], + JS_PROP_THROW_STRICT); + JS_FreeValue(ctx, sp[-1]); + sp -= 2; + if (unlikely(ret < 0)) + goto exception; + break; + case OP_with_delete_var: + ret = JS_DeleteProperty(ctx, obj, atom, 0); + if (unlikely(ret < 0)) + goto exception; + JS_FreeValue(ctx, sp[-1]); + sp[-1] = js_bool(ret); + break; + case OP_with_make_ref: + /* produce a pair object/propname on the stack */ + *sp++ = JS_AtomToValue(ctx, atom); + break; + case OP_with_get_ref: + /* produce a pair object/method on the stack */ + ret = JS_HasProperty(ctx, obj, atom); + if (unlikely(ret < 0)) + goto exception; + if (ret == 0) { + if (is_strict_mode(ctx)) { + JS_ThrowReferenceErrorNotDefined(ctx, atom); + goto exception; + } + val = JS_UNDEFINED; + } else { + val = JS_GetProperty(ctx, obj, atom); + if (unlikely(JS_IsException(val))) + goto exception; + } + *sp++ = val; + break; + case OP_with_get_ref_undef: + /* produce a pair undefined/function on the stack */ + val = JS_GetProperty(ctx, obj, atom); + if (unlikely(JS_IsException(val))) + goto exception; + JS_FreeValue(ctx, sp[-1]); + sp[-1] = JS_UNDEFINED; + *sp++ = val; + break; + } + pc += diff - 5; + } else { + no_with: + /* if not jumping, drop the object argument */ + JS_FreeValue(ctx, sp[-1]); + sp--; + } + } + BREAK; + + CASE(OP_await): + ret_val = js_int32(FUNC_RET_AWAIT); + goto done_generator; + CASE(OP_yield): + ret_val = js_int32(FUNC_RET_YIELD); + goto done_generator; + CASE(OP_yield_star): + CASE(OP_async_yield_star): + ret_val = js_int32(FUNC_RET_YIELD_STAR); + goto done_generator; + CASE(OP_return_async): + CASE(OP_initial_yield): + ret_val = JS_UNDEFINED; + goto done_generator; + + CASE(OP_nop): + BREAK; + CASE(OP_is_undefined_or_null): + if (JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_UNDEFINED || + JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_NULL) { + goto set_true; + } else { + goto free_and_set_false; + } + CASE(OP_is_undefined): + if (JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_UNDEFINED) { + goto set_true; + } else { + goto free_and_set_false; + } + CASE(OP_is_null): + if (JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_NULL) { + goto set_true; + } else { + goto free_and_set_false; + } + /* XXX: could merge to a single opcode */ + CASE(OP_typeof_is_undefined): + /* different from OP_is_undefined because of isHTMLDDA */ + if (js_operator_typeof(ctx, sp[-1]) == JS_ATOM_undefined) { + goto free_and_set_true; + } else { + goto free_and_set_false; + } + CASE(OP_typeof_is_function): + if (js_operator_typeof(ctx, sp[-1]) == JS_ATOM_function) { + goto free_and_set_true; + } else { + goto free_and_set_false; + } + free_and_set_true: + JS_FreeValue(ctx, sp[-1]); + set_true: + sp[-1] = JS_TRUE; + BREAK; + free_and_set_false: + JS_FreeValue(ctx, sp[-1]); + sp[-1] = JS_FALSE; + BREAK; + CASE(OP_invalid): + DEFAULT: + JS_ThrowInternalError(ctx, "invalid opcode: pc=%u opcode=0x%02x", + (int)(pc - b->byte_code_buf - 1), opcode); + goto exception; + } + } + exception: + if (needs_backtrace(rt->current_exception) + || JS_IsUndefined(ctx->error_back_trace)) { + sf->cur_pc = pc; + build_backtrace(ctx, rt->current_exception, JS_UNDEFINED, + NULL, 0, 0, 0); + } + if (!JS_IsUncatchableError(rt->current_exception)) { + while (sp > stack_buf) { + JSValue val = *--sp; + JS_FreeValue(ctx, val); + if (JS_VALUE_GET_TAG(val) == JS_TAG_CATCH_OFFSET) { + int pos = JS_VALUE_GET_INT(val); + if (pos == 0) { + /* enumerator: close it with a throw */ + JS_FreeValue(ctx, sp[-1]); /* drop the next method */ + sp--; + JS_IteratorClose(ctx, sp[-1], true); + } else { + *sp++ = rt->current_exception; + rt->current_exception = JS_UNINITIALIZED; + JS_FreeValueRT(rt, ctx->error_back_trace); + ctx->error_back_trace = JS_UNDEFINED; + pc = b->byte_code_buf + pos; + goto restart; + } + } + } + } + ret_val = JS_EXCEPTION; + /* the local variables are freed by the caller in the generator + case. Hence the label 'done' should never be reached in a + generator function. */ + if (b->func_kind != JS_FUNC_NORMAL) { + done_generator: + sf->cur_pc = pc; + sf->cur_sp = sp; + } else { + done: + if (unlikely(sf->var_ref_count != 0)) { + /* variable references reference the stack: must close them */ + close_var_refs(rt, sf); + } + /* free the local variables and stack */ + for(pval = local_buf; pval < sp; pval++) { + JS_FreeValue(ctx, *pval); + } + } + rt->current_stack_frame = sf->prev_frame; + return ret_val; +} + +JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, + int argc, JSValueConst *argv) +{ + return JS_CallInternal(ctx, func_obj, this_obj, JS_UNDEFINED, + argc, argv, JS_CALL_FLAG_COPY_ARGV); +} + +static JSValue JS_CallFree(JSContext *ctx, JSValue func_obj, JSValueConst this_obj, + int argc, JSValueConst *argv) +{ + JSValue res = JS_CallInternal(ctx, func_obj, this_obj, JS_UNDEFINED, + argc, argv, JS_CALL_FLAG_COPY_ARGV); + JS_FreeValue(ctx, func_obj); + return res; +} + +/* warning: the refcount of the context is not incremented. Return + NULL in case of exception (case of revoked proxy only) */ +static JSContext *JS_GetFunctionRealm(JSContext *ctx, JSValueConst func_obj) +{ + JSObject *p; + JSContext *realm; + + if (JS_VALUE_GET_TAG(func_obj) != JS_TAG_OBJECT) + return ctx; + p = JS_VALUE_GET_OBJ(func_obj); + switch(p->class_id) { + case JS_CLASS_C_FUNCTION: + realm = p->u.cfunc.realm; + break; + case JS_CLASS_BYTECODE_FUNCTION: + case JS_CLASS_GENERATOR_FUNCTION: + case JS_CLASS_ASYNC_FUNCTION: + case JS_CLASS_ASYNC_GENERATOR_FUNCTION: + { + JSFunctionBytecode *b; + b = p->u.func.function_bytecode; + realm = b->realm; + } + break; + case JS_CLASS_PROXY: + { + JSProxyData *s = p->u.opaque; + if (!s) + return ctx; + if (s->is_revoked) { + JS_ThrowTypeErrorRevokedProxy(ctx); + return NULL; + } else { + realm = JS_GetFunctionRealm(ctx, s->target); + } + } + break; + case JS_CLASS_BOUND_FUNCTION: + { + JSBoundFunction *bf = p->u.bound_function; + realm = JS_GetFunctionRealm(ctx, bf->func_obj); + } + break; + default: + realm = ctx; + break; + } + return realm; +} + +static JSValue js_create_from_ctor(JSContext *ctx, JSValueConst ctor, + int class_id) +{ + JSValue proto, obj; + JSContext *realm; + + if (JS_IsUndefined(ctor)) { + proto = js_dup(ctx->class_proto[class_id]); + } else { + proto = JS_GetProperty(ctx, ctor, JS_ATOM_prototype); + if (JS_IsException(proto)) + return proto; + if (!JS_IsObject(proto)) { + JS_FreeValue(ctx, proto); + realm = JS_GetFunctionRealm(ctx, ctor); + if (!realm) + return JS_EXCEPTION; + proto = js_dup(realm->class_proto[class_id]); + } + } + obj = JS_NewObjectProtoClass(ctx, proto, class_id); + JS_FreeValue(ctx, proto); + return obj; +} + +/* argv[] is modified if (flags & JS_CALL_FLAG_COPY_ARGV) = 0. */ +static JSValue JS_CallConstructorInternal(JSContext *ctx, + JSValueConst func_obj, + JSValueConst new_target, + int argc, JSValueConst *argv, + int flags) +{ + JSObject *p; + JSFunctionBytecode *b; + + if (js_poll_interrupts(ctx)) + return JS_EXCEPTION; + flags |= JS_CALL_FLAG_CONSTRUCTOR; + if (unlikely(JS_VALUE_GET_TAG(func_obj) != JS_TAG_OBJECT)) + goto not_a_function; + p = JS_VALUE_GET_OBJ(func_obj); + if (unlikely(!p->is_constructor)) + return JS_ThrowTypeErrorNotAConstructor(ctx, func_obj); + if (unlikely(p->class_id != JS_CLASS_BYTECODE_FUNCTION)) { + JSClassCall *call_func; + call_func = ctx->rt->class_array[p->class_id].call; + if (!call_func) { + not_a_function: + return JS_ThrowTypeErrorNotAFunction(ctx); + } + return call_func(ctx, func_obj, new_target, argc, + argv, flags); + } + + b = p->u.func.function_bytecode; + if (b->is_derived_class_constructor) { + return JS_CallInternal(ctx, func_obj, JS_UNDEFINED, new_target, argc, argv, flags); + } else { + JSValue obj, ret; + /* legacy constructor behavior */ + obj = js_create_from_ctor(ctx, new_target, JS_CLASS_OBJECT); + if (JS_IsException(obj)) + return JS_EXCEPTION; + ret = JS_CallInternal(ctx, func_obj, obj, new_target, argc, argv, flags); + if (JS_VALUE_GET_TAG(ret) == JS_TAG_OBJECT || + JS_IsException(ret)) { + JS_FreeValue(ctx, obj); + return ret; + } else { + JS_FreeValue(ctx, ret); + return obj; + } + } +} + +JSValue JS_CallConstructor2(JSContext *ctx, JSValueConst func_obj, + JSValueConst new_target, + int argc, JSValueConst *argv) +{ + return JS_CallConstructorInternal(ctx, func_obj, new_target, + argc, argv, + JS_CALL_FLAG_COPY_ARGV); +} + +JSValue JS_CallConstructor(JSContext *ctx, JSValueConst func_obj, + int argc, JSValueConst *argv) +{ + return JS_CallConstructorInternal(ctx, func_obj, func_obj, + argc, argv, + JS_CALL_FLAG_COPY_ARGV); +} + +JSValue JS_Invoke(JSContext *ctx, JSValueConst this_val, JSAtom atom, + int argc, JSValueConst *argv) +{ + JSValue func_obj; + func_obj = JS_GetProperty(ctx, this_val, atom); + if (JS_IsException(func_obj)) + return func_obj; + return JS_CallFree(ctx, func_obj, this_val, argc, argv); +} + +static JSValue JS_InvokeFree(JSContext *ctx, JSValue this_val, JSAtom atom, + int argc, JSValueConst *argv) +{ + JSValue res = JS_Invoke(ctx, this_val, atom, argc, argv); + JS_FreeValue(ctx, this_val); + return res; +} + +/* JSAsyncFunctionState (used by generator and async functions) */ +static __exception int async_func_init(JSContext *ctx, JSAsyncFunctionState *s, + JSValueConst func_obj, + JSValueConst this_obj, + int argc, JSValueConst *argv) +{ + JSObject *p; + JSFunctionBytecode *b; + JSStackFrame *sf; + int local_count, i, arg_buf_len, n; + size_t alloc_size; + + sf = &s->frame; + p = JS_VALUE_GET_OBJ(func_obj); + b = p->u.func.function_bytecode; + sf->is_strict_mode = b->is_strict_mode; + sf->is_constructor = false; + sf->cur_pc = b->byte_code_buf; + arg_buf_len = max_int(b->arg_count, argc); + local_count = arg_buf_len + b->var_count + b->stack_size; + alloc_size = sizeof(JSValue) * max_int(local_count, 1) + + sizeof(JSVarRef *) * b->var_ref_count; + sf->arg_buf = js_malloc(ctx, alloc_size); + if (!sf->arg_buf) + return -1; + sf->cur_func = js_dup(func_obj); + s->this_val = js_dup(this_obj); + s->argc = argc; + sf->arg_count = arg_buf_len; + sf->var_buf = sf->arg_buf + arg_buf_len; + sf->cur_sp = sf->var_buf + b->var_count; + /* set by the caller once the owning coroutine GC object exists */ + sf->cur_gc_obj = NULL; + sf->var_refs = (JSVarRef **)(sf->cur_sp + b->stack_size); + sf->var_ref_count = b->var_ref_count; + for(i = 0; i < b->var_ref_count; i++) + sf->var_refs[i] = NULL; + for(i = 0; i < argc; i++) + sf->arg_buf[i] = js_dup(argv[i]); + n = arg_buf_len + b->var_count; + for(i = argc; i < n; i++) + sf->arg_buf[i] = JS_UNDEFINED; + return 0; +} + +static void async_func_mark(JSRuntime *rt, JSAsyncFunctionState *s, + JS_MarkFunc *mark_func) +{ + JSStackFrame *sf; + JSValue *sp; + + sf = &s->frame; + JS_MarkValue(rt, sf->cur_func, mark_func); + JS_MarkValue(rt, s->this_val, mark_func); + if (sf->cur_sp) { + /* if the function is running, cur_sp is not known so we + cannot mark the stack. Marking the variables is not needed + because a running function cannot be part of a removable + cycle */ + for(sp = sf->arg_buf; sp < sf->cur_sp; sp++) + JS_MarkValue(rt, *sp, mark_func); + } +} + +static void async_func_free(JSRuntime *rt, JSAsyncFunctionState *s) +{ + JSStackFrame *sf; + JSValue *sp; + + sf = &s->frame; + + if (sf->arg_buf) { + /* close the closure variables. */ + if (sf->var_ref_count != 0) + close_var_refs(rt, sf); + + /* cannot free the function if it is running */ + assert(sf->cur_sp != NULL); + for(sp = sf->arg_buf; sp < sf->cur_sp; sp++) { + JS_FreeValueRT(rt, *sp); + } + js_free_rt(rt, sf->arg_buf); + } + JS_FreeValueRT(rt, sf->cur_func); + JS_FreeValueRT(rt, s->this_val); +} + +static JSValue async_func_resume(JSContext *ctx, JSAsyncFunctionState *s) +{ + JSValue func_obj; + + if (js_check_stack_overflow(ctx->rt, 0)) + return JS_ThrowStackOverflow(ctx); + + /* the tag does not matter provided it is not an object */ + func_obj = JS_MKPTR(JS_TAG_INT, s); + return JS_CallInternal(ctx, func_obj, s->this_val, JS_UNDEFINED, + s->argc, vc(s->frame.arg_buf), + JS_CALL_FLAG_GENERATOR); +} + + +/* Generators */ + +typedef enum JSGeneratorStateEnum { + JS_GENERATOR_STATE_SUSPENDED_START, + JS_GENERATOR_STATE_SUSPENDED_YIELD, + JS_GENERATOR_STATE_SUSPENDED_YIELD_STAR, + JS_GENERATOR_STATE_EXECUTING, + JS_GENERATOR_STATE_COMPLETED, +} JSGeneratorStateEnum; + +typedef struct JSGeneratorData { + JSGeneratorStateEnum state; + JSAsyncFunctionState func_state; +} JSGeneratorData; + +static void free_generator_stack_rt(JSRuntime *rt, JSGeneratorData *s) +{ + if (s->state == JS_GENERATOR_STATE_COMPLETED) + return; + async_func_free(rt, &s->func_state); + s->state = JS_GENERATOR_STATE_COMPLETED; +} + +static void js_generator_finalizer(JSRuntime *rt, JSValueConst obj) +{ + JSGeneratorData *s = JS_GetOpaque(obj, JS_CLASS_GENERATOR); + + if (s) { + free_generator_stack_rt(rt, s); + js_free_rt(rt, s); + } +} + +static void free_generator_stack(JSContext *ctx, JSGeneratorData *s) +{ + free_generator_stack_rt(ctx->rt, s); +} + +static void js_generator_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + JSGeneratorData *s = p->u.generator_data; + + if (!s || s->state == JS_GENERATOR_STATE_COMPLETED) + return; + async_func_mark(rt, &s->func_state, mark_func); +} + +/* XXX: use enum */ +#define GEN_MAGIC_NEXT 0 +#define GEN_MAGIC_RETURN 1 +#define GEN_MAGIC_THROW 2 + +static JSValue js_generator_next(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, + int *pdone, int magic) +{ + JSGeneratorData *s = JS_GetOpaque(this_val, JS_CLASS_GENERATOR); + JSStackFrame *sf; + JSValue ret, func_ret; + + *pdone = true; + if (!s) + return JS_ThrowTypeError(ctx, "not a generator"); + sf = &s->func_state.frame; + switch(s->state) { + default: + case JS_GENERATOR_STATE_SUSPENDED_START: + if (magic == GEN_MAGIC_NEXT) { + goto exec_no_arg; + } else { + free_generator_stack(ctx, s); + goto done; + } + break; + case JS_GENERATOR_STATE_SUSPENDED_YIELD_STAR: + case JS_GENERATOR_STATE_SUSPENDED_YIELD: + /* cur_sp[-1] was set to JS_UNDEFINED in the previous call */ + ret = js_dup(argv[0]); + if (magic == GEN_MAGIC_THROW && + s->state == JS_GENERATOR_STATE_SUSPENDED_YIELD) { + JS_Throw(ctx, ret); + s->func_state.throw_flag = true; + } else { + sf->cur_sp[-1] = ret; + sf->cur_sp[0] = js_int32(magic); + sf->cur_sp++; + exec_no_arg: + s->func_state.throw_flag = false; + } + s->state = JS_GENERATOR_STATE_EXECUTING; + func_ret = async_func_resume(ctx, &s->func_state); + s->state = JS_GENERATOR_STATE_SUSPENDED_YIELD; + if (JS_IsException(func_ret)) { + /* finalize the execution in case of exception */ + free_generator_stack(ctx, s); + return func_ret; + } + if (JS_VALUE_GET_TAG(func_ret) == JS_TAG_INT) { + /* get the returned yield value at the top of the stack */ + ret = sf->cur_sp[-1]; + sf->cur_sp[-1] = JS_UNDEFINED; + if (JS_VALUE_GET_INT(func_ret) == FUNC_RET_YIELD_STAR) { + s->state = JS_GENERATOR_STATE_SUSPENDED_YIELD_STAR; + /* return (value, done) object */ + *pdone = 2; + } else { + *pdone = false; + } + } else { + /* end of iterator */ + ret = sf->cur_sp[-1]; + sf->cur_sp[-1] = JS_UNDEFINED; + JS_FreeValue(ctx, func_ret); + free_generator_stack(ctx, s); + } + break; + case JS_GENERATOR_STATE_COMPLETED: + done: + /* execution is finished */ + switch(magic) { + default: + case GEN_MAGIC_NEXT: + ret = JS_UNDEFINED; + break; + case GEN_MAGIC_RETURN: + ret = js_dup(argv[0]); + break; + case GEN_MAGIC_THROW: + ret = JS_Throw(ctx, js_dup(argv[0])); + break; + } + break; + case JS_GENERATOR_STATE_EXECUTING: + ret = JS_ThrowTypeError(ctx, "cannot invoke a running generator"); + break; + } + return ret; +} + +static JSValue js_call_generator_function(JSContext *ctx, JSValueConst func_obj, + JSValueConst this_obj, + int argc, JSValueConst *argv, + int flags) +{ + JSValue obj, func_ret; + JSGeneratorData *s; + + s = js_mallocz(ctx, sizeof(*s)); + if (!s) + return JS_EXCEPTION; + s->state = JS_GENERATOR_STATE_SUSPENDED_START; + if (async_func_init(ctx, &s->func_state, func_obj, this_obj, argc, argv)) { + s->state = JS_GENERATOR_STATE_COMPLETED; + goto fail; + } + + /* execute the function up to 'OP_initial_yield' */ + func_ret = async_func_resume(ctx, &s->func_state); + if (JS_IsException(func_ret)) + goto fail; + JS_FreeValue(ctx, func_ret); + + obj = js_create_from_ctor(ctx, func_obj, JS_CLASS_GENERATOR); + if (JS_IsException(obj)) + goto fail; + JS_SetOpaqueInternal(obj, s); + /* the body only starts running on the first next(); root captured + locals against the generator object from now on (the initial resume + above only reaches OP_initial_yield, before any user code) */ + s->func_state.frame.cur_gc_obj = &JS_VALUE_GET_OBJ(obj)->header; + return obj; + fail: + free_generator_stack_rt(ctx->rt, s); + js_free(ctx, s); + return JS_EXCEPTION; +} + +/* AsyncFunction */ + +static void js_async_function_terminate(JSRuntime *rt, JSAsyncFunctionData *s) +{ + if (s->is_active) { + async_func_free(rt, &s->func_state); + s->is_active = false; + } +} + +static void js_async_function_free0(JSRuntime *rt, JSAsyncFunctionData *s) +{ + js_async_function_terminate(rt, s); + JS_FreeValueRT(rt, s->resolving_funcs[0]); + JS_FreeValueRT(rt, s->resolving_funcs[1]); + remove_gc_object(&s->header); + js_free_rt(rt, s); +} + +static void js_async_function_free(JSRuntime *rt, JSAsyncFunctionData *s) +{ + if (--JS_REF_COUNT(s) == 0) { + js_async_function_free0(rt, s); + } +} + +static void js_async_function_resolve_finalizer(JSRuntime *rt, + JSValueConst val) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + JSAsyncFunctionData *s = p->u.async_function_data; + if (s) { + js_async_function_free(rt, s); + } +} + +static void js_async_function_resolve_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func) +{ + JSObject *p = JS_VALUE_GET_OBJ(val); + JSAsyncFunctionData *s = p->u.async_function_data; + if (s) { + mark_func(rt, &s->header); + } +} + +static int js_async_function_resolve_create(JSContext *ctx, + JSAsyncFunctionData *s, + JSValue *resolving_funcs) +{ + int i; + JSObject *p; + + for(i = 0; i < 2; i++) { + resolving_funcs[i] = + JS_NewObjectProtoClass(ctx, ctx->function_proto, + JS_CLASS_ASYNC_FUNCTION_RESOLVE + i); + if (JS_IsException(resolving_funcs[i])) { + if (i == 1) + JS_FreeValue(ctx, resolving_funcs[0]); + resolving_funcs[0] = JS_UNDEFINED; + resolving_funcs[1] = JS_UNDEFINED; + return -1; + } + p = JS_VALUE_GET_OBJ(resolving_funcs[i]); + JS_REF_COUNT(s)++; + p->u.async_function_data = s; + } + return 0; +} + +static bool js_async_function_resume(JSContext *ctx, JSAsyncFunctionData *s) +{ + bool is_success = true; + JSValue func_ret, ret2; + + func_ret = async_func_resume(ctx, &s->func_state); + if (JS_IsException(func_ret)) { + fail: + if (unlikely(JS_IsUncatchableError(ctx->rt->current_exception))) { + is_success = false; + } else { + JSValue error = JS_GetException(ctx); + ret2 = JS_Call(ctx, s->resolving_funcs[1], JS_UNDEFINED, + 1, vc(&error)); + JS_FreeValue(ctx, error); + resolved: + if (unlikely(JS_IsException(ret2))) { + if (JS_IsUncatchableError(ctx->rt->current_exception)) { + is_success = false; + } else { + abort(); /* BUG */ + } + } + JS_FreeValue(ctx, ret2); + } + js_async_function_terminate(ctx->rt, s); + } else { + JSValue value; + value = s->func_state.frame.cur_sp[-1]; + s->func_state.frame.cur_sp[-1] = JS_UNDEFINED; + if (JS_IsUndefined(func_ret)) { + /* function returned */ + ret2 = JS_Call(ctx, s->resolving_funcs[0], JS_UNDEFINED, + 1, vc(&value)); + JS_FreeValue(ctx, value); + goto resolved; + } else { + JSValue promise, resolving_funcs[2], resolving_funcs1[2]; + int i, res; + + /* await */ + JS_FreeValue(ctx, func_ret); /* not used */ + promise = js_promise_resolve(ctx, ctx->promise_ctor, + 1, vc(&value), 0); + JS_FreeValue(ctx, value); + if (JS_IsException(promise)) + goto fail; + if (js_async_function_resolve_create(ctx, s, resolving_funcs)) { + JS_FreeValue(ctx, promise); + goto fail; + } + + /* Note: no need to create 'thrownawayCapability' as in + the spec */ + for(i = 0; i < 2; i++) + resolving_funcs1[i] = JS_UNDEFINED; + res = perform_promise_then(ctx, promise, + vc(resolving_funcs), + vc(resolving_funcs1)); + JS_FreeValue(ctx, promise); + for(i = 0; i < 2; i++) + JS_FreeValue(ctx, resolving_funcs[i]); + if (res) + goto fail; + } + } + return is_success; +} + +static JSValue js_async_function_resolve_call(JSContext *ctx, + JSValueConst func_obj, + JSValueConst this_obj, + int argc, JSValueConst *argv, + int flags) +{ + JSObject *p = JS_VALUE_GET_OBJ(func_obj); + JSAsyncFunctionData *s = p->u.async_function_data; + bool is_reject = p->class_id - JS_CLASS_ASYNC_FUNCTION_RESOLVE; + JSValueConst arg; + + if (argc > 0) + arg = argv[0]; + else + arg = JS_UNDEFINED; + s->func_state.throw_flag = is_reject; + if (is_reject) { + JS_Throw(ctx, js_dup(arg)); + } else { + /* return value of await */ + s->func_state.frame.cur_sp[-1] = js_dup(arg); + } + if (!js_async_function_resume(ctx, s)) + return JS_EXCEPTION; + return JS_UNDEFINED; +} + +static JSValue js_async_function_call(JSContext *ctx, JSValueConst func_obj, + JSValueConst this_obj, + int argc, JSValueConst *argv, int flags) +{ + JSValue promise; + JSAsyncFunctionData *s; + + s = js_mallocz(ctx, sizeof(*s)); + if (!s) + return JS_EXCEPTION; + JS_REF_COUNT(s) = 1; + add_gc_object(ctx->rt, &s->header, JS_GC_OBJ_TYPE_ASYNC_FUNCTION); + s->is_active = false; + s->resolving_funcs[0] = JS_UNDEFINED; + s->resolving_funcs[1] = JS_UNDEFINED; + + promise = JS_NewPromiseCapability(ctx, s->resolving_funcs); + if (JS_IsException(promise)) + goto fail; + + if (async_func_init(ctx, &s->func_state, func_obj, this_obj, argc, argv)) { + fail: + JS_FreeValue(ctx, promise); + js_async_function_free(ctx->rt, s); + return JS_EXCEPTION; + } + s->is_active = true; + /* the body runs immediately (up to the first await), so the frame must + already know its owning coroutine to root captured locals */ + s->func_state.frame.cur_gc_obj = &s->header; + + if (!js_async_function_resume(ctx, s)) + goto fail; + + js_async_function_free(ctx->rt, s); + + return promise; +} + +/* AsyncGenerator */ + +typedef enum JSAsyncGeneratorStateEnum { + JS_ASYNC_GENERATOR_STATE_SUSPENDED_START, + JS_ASYNC_GENERATOR_STATE_SUSPENDED_YIELD, + JS_ASYNC_GENERATOR_STATE_SUSPENDED_YIELD_STAR, + JS_ASYNC_GENERATOR_STATE_EXECUTING, + JS_ASYNC_GENERATOR_STATE_AWAITING_RETURN, + JS_ASYNC_GENERATOR_STATE_COMPLETED, +} JSAsyncGeneratorStateEnum; + +typedef struct JSAsyncGeneratorRequest { + struct list_head link; + /* completion */ + int completion_type; /* GEN_MAGIC_x */ + JSValue result; + /* promise capability */ + JSValue promise; + JSValue resolving_funcs[2]; +} JSAsyncGeneratorRequest; + +typedef struct JSAsyncGeneratorData { + JSObject *generator; /* back pointer to the object (const) */ + JSAsyncGeneratorStateEnum state; + JSAsyncFunctionState func_state; + struct list_head queue; /* list of JSAsyncGeneratorRequest.link */ +} JSAsyncGeneratorData; + +static void js_async_generator_free(JSRuntime *rt, + JSAsyncGeneratorData *s) +{ + struct list_head *el, *el1; + JSAsyncGeneratorRequest *req; + + list_for_each_safe(el, el1, &s->queue) { + req = list_entry(el, JSAsyncGeneratorRequest, link); + JS_FreeValueRT(rt, req->result); + JS_FreeValueRT(rt, req->promise); + JS_FreeValueRT(rt, req->resolving_funcs[0]); + JS_FreeValueRT(rt, req->resolving_funcs[1]); + js_free_rt(rt, req); + } + if (s->state != JS_ASYNC_GENERATOR_STATE_COMPLETED && + s->state != JS_ASYNC_GENERATOR_STATE_AWAITING_RETURN) { + async_func_free(rt, &s->func_state); + } + js_free_rt(rt, s); +} + +static void js_async_generator_finalizer(JSRuntime *rt, JSValueConst obj) +{ + JSAsyncGeneratorData *s = JS_GetOpaque(obj, JS_CLASS_ASYNC_GENERATOR); + + if (s) { + js_async_generator_free(rt, s); + } +} + +static void js_async_generator_mark(JSRuntime *rt, JSValueConst val, + JS_MarkFunc *mark_func) +{ + JSAsyncGeneratorData *s = JS_GetOpaque(val, JS_CLASS_ASYNC_GENERATOR); + struct list_head *el; + JSAsyncGeneratorRequest *req; + if (s) { + list_for_each(el, &s->queue) { + req = list_entry(el, JSAsyncGeneratorRequest, link); + JS_MarkValue(rt, req->result, mark_func); + JS_MarkValue(rt, req->promise, mark_func); + JS_MarkValue(rt, req->resolving_funcs[0], mark_func); + JS_MarkValue(rt, req->resolving_funcs[1], mark_func); + } + if (s->state != JS_ASYNC_GENERATOR_STATE_COMPLETED && + s->state != JS_ASYNC_GENERATOR_STATE_AWAITING_RETURN) { + async_func_mark(rt, &s->func_state, mark_func); + } + } +} + +static JSValue js_async_generator_resolve_function(JSContext *ctx, + JSValueConst this_obj, + int argc, JSValueConst *argv, + int magic, JSValueConst *func_data); + +static int js_async_generator_resolve_function_create(JSContext *ctx, + JSValue generator, + JSValue *resolving_funcs, + bool is_resume_next) +{ + int i; + JSValue func; + + for(i = 0; i < 2; i++) { + func = JS_NewCFunctionData(ctx, js_async_generator_resolve_function, 1, + i + is_resume_next * 2, 1, vc(&generator)); + if (JS_IsException(func)) { + if (i == 1) + JS_FreeValue(ctx, resolving_funcs[0]); + resolving_funcs[0] = JS_UNDEFINED; + resolving_funcs[1] = JS_UNDEFINED; + return -1; + } + resolving_funcs[i] = func; + } + return 0; +} + +static int js_async_generator_await(JSContext *ctx, + JSAsyncGeneratorData *s, + JSValue value) +{ + JSValue promise, resolving_funcs[2], resolving_funcs1[2]; + int i, res; + + promise = js_promise_resolve(ctx, ctx->promise_ctor, + 1, vc(&value), 0); + if (JS_IsException(promise)) + goto fail; + + if (js_async_generator_resolve_function_create(ctx, JS_MKPTR(JS_TAG_OBJECT, s->generator), + resolving_funcs, false)) { + JS_FreeValue(ctx, promise); + goto fail; + } + + /* Note: no need to create 'thrownawayCapability' as in + the spec */ + for(i = 0; i < 2; i++) + resolving_funcs1[i] = JS_UNDEFINED; + res = perform_promise_then(ctx, promise, + vc(resolving_funcs), + vc(resolving_funcs1)); + JS_FreeValue(ctx, promise); + for(i = 0; i < 2; i++) + JS_FreeValue(ctx, resolving_funcs[i]); + if (res) + goto fail; + return 0; + fail: + return -1; +} + +static void js_async_generator_resolve_or_reject(JSContext *ctx, + JSAsyncGeneratorData *s, + JSValueConst result, + int is_reject) +{ + JSAsyncGeneratorRequest *next; + JSValue ret; + + next = list_entry(s->queue.next, JSAsyncGeneratorRequest, link); + list_del(&next->link); + ret = JS_Call(ctx, next->resolving_funcs[is_reject], JS_UNDEFINED, 1, + &result); + JS_FreeValue(ctx, ret); + JS_FreeValue(ctx, next->result); + JS_FreeValue(ctx, next->promise); + JS_FreeValue(ctx, next->resolving_funcs[0]); + JS_FreeValue(ctx, next->resolving_funcs[1]); + js_free(ctx, next); +} + +static void js_async_generator_resolve(JSContext *ctx, + JSAsyncGeneratorData *s, + JSValueConst value, + bool done) +{ + JSValue result; + result = js_create_iterator_result(ctx, js_dup(value), done); + /* XXX: better exception handling ? */ + js_async_generator_resolve_or_reject(ctx, s, result, 0); + JS_FreeValue(ctx, result); + } + +static void js_async_generator_reject(JSContext *ctx, + JSAsyncGeneratorData *s, + JSValueConst exception) +{ + js_async_generator_resolve_or_reject(ctx, s, exception, 1); +} + +static void js_async_generator_complete(JSContext *ctx, + JSAsyncGeneratorData *s) +{ + if (s->state != JS_ASYNC_GENERATOR_STATE_COMPLETED) { + s->state = JS_ASYNC_GENERATOR_STATE_COMPLETED; + async_func_free(ctx->rt, &s->func_state); + } +} + +static int js_async_generator_completed_return(JSContext *ctx, + JSAsyncGeneratorData *s, + JSValue value) +{ + JSValue promise, resolving_funcs[2], resolving_funcs1[2]; + int res; + + // Can fail looking up JS_ATOM_constructor when is_reject==0. + promise = js_promise_resolve(ctx, ctx->promise_ctor, 1, vc(&value), + /*is_reject*/0); + // A poisoned .constructor property is observable and the resulting + // exception should be delivered to the catch handler. + if (JS_IsException(promise)) { + JSValue err = JS_GetException(ctx); + promise = js_promise_resolve(ctx, ctx->promise_ctor, 1, vc(&err), + /*is_reject*/1); + JS_FreeValue(ctx, err); + if (JS_IsException(promise)) + return -1; + } + if (js_async_generator_resolve_function_create(ctx, + JS_MKPTR(JS_TAG_OBJECT, s->generator), + resolving_funcs1, + true)) { + JS_FreeValue(ctx, promise); + return -1; + } + resolving_funcs[0] = JS_UNDEFINED; + resolving_funcs[1] = JS_UNDEFINED; + res = perform_promise_then(ctx, promise, + vc(resolving_funcs1), + vc(resolving_funcs)); + JS_FreeValue(ctx, resolving_funcs1[0]); + JS_FreeValue(ctx, resolving_funcs1[1]); + JS_FreeValue(ctx, promise); + return res; +} + +static void js_async_generator_resume_next(JSContext *ctx, + JSAsyncGeneratorData *s) +{ + JSAsyncGeneratorRequest *next; + JSValue func_ret, value; + + for(;;) { + if (list_empty(&s->queue)) + break; + next = list_entry(s->queue.next, JSAsyncGeneratorRequest, link); + switch(s->state) { + case JS_ASYNC_GENERATOR_STATE_EXECUTING: + /* only happens when restarting execution after await() */ + goto resume_exec; + case JS_ASYNC_GENERATOR_STATE_AWAITING_RETURN: + goto done; + case JS_ASYNC_GENERATOR_STATE_SUSPENDED_START: + if (next->completion_type == GEN_MAGIC_NEXT) { + goto exec_no_arg; + } else { + js_async_generator_complete(ctx, s); + } + break; + case JS_ASYNC_GENERATOR_STATE_COMPLETED: + if (next->completion_type == GEN_MAGIC_NEXT) { + js_async_generator_resolve(ctx, s, JS_UNDEFINED, true); + } else if (next->completion_type == GEN_MAGIC_RETURN) { + s->state = JS_ASYNC_GENERATOR_STATE_AWAITING_RETURN; + js_async_generator_completed_return(ctx, s, next->result); + } else { + js_async_generator_reject(ctx, s, next->result); + } + goto done; + case JS_ASYNC_GENERATOR_STATE_SUSPENDED_YIELD: + case JS_ASYNC_GENERATOR_STATE_SUSPENDED_YIELD_STAR: + value = js_dup(next->result); + if (next->completion_type == GEN_MAGIC_THROW && + s->state == JS_ASYNC_GENERATOR_STATE_SUSPENDED_YIELD) { + JS_Throw(ctx, value); + s->func_state.throw_flag = true; + } else { + /* 'yield' returns a value. 'yield *' also returns a value + in case the 'throw' method is called */ + s->func_state.frame.cur_sp[-1] = value; + s->func_state.frame.cur_sp[0] = + js_int32(next->completion_type); + s->func_state.frame.cur_sp++; + exec_no_arg: + s->func_state.throw_flag = false; + } + s->state = JS_ASYNC_GENERATOR_STATE_EXECUTING; + resume_exec: + func_ret = async_func_resume(ctx, &s->func_state); + if (JS_IsException(func_ret)) { + value = JS_GetException(ctx); + js_async_generator_complete(ctx, s); + js_async_generator_reject(ctx, s, value); + JS_FreeValue(ctx, value); + } else if (JS_VALUE_GET_TAG(func_ret) == JS_TAG_INT) { + int func_ret_code, ret; + value = s->func_state.frame.cur_sp[-1]; + s->func_state.frame.cur_sp[-1] = JS_UNDEFINED; + func_ret_code = JS_VALUE_GET_INT(func_ret); + switch(func_ret_code) { + case FUNC_RET_YIELD: + case FUNC_RET_YIELD_STAR: + if (func_ret_code == FUNC_RET_YIELD_STAR) + s->state = JS_ASYNC_GENERATOR_STATE_SUSPENDED_YIELD_STAR; + else + s->state = JS_ASYNC_GENERATOR_STATE_SUSPENDED_YIELD; + js_async_generator_resolve(ctx, s, value, false); + JS_FreeValue(ctx, value); + break; + case FUNC_RET_AWAIT: + ret = js_async_generator_await(ctx, s, value); + JS_FreeValue(ctx, value); + if (ret < 0) { + /* exception: throw it */ + s->func_state.throw_flag = true; + goto resume_exec; + } + goto done; + default: + abort(); + } + } else { + assert(JS_IsUndefined(func_ret)); + /* end of function */ + value = s->func_state.frame.cur_sp[-1]; + s->func_state.frame.cur_sp[-1] = JS_UNDEFINED; + js_async_generator_complete(ctx, s); + js_async_generator_resolve(ctx, s, value, true); + JS_FreeValue(ctx, value); + } + break; + default: + abort(); + } + } + done: ; +} + +static JSValue js_async_generator_resolve_function(JSContext *ctx, + JSValueConst this_obj, + int argc, JSValueConst *argv, + int magic, JSValueConst *func_data) +{ + bool is_reject = magic & 1; + JSAsyncGeneratorData *s = JS_GetOpaque(func_data[0], JS_CLASS_ASYNC_GENERATOR); + JSValueConst arg = argv[0]; + + /* XXX: what if s == NULL */ + + if (magic >= 2) { + /* resume next case in AWAITING_RETURN state */ + assert(s->state == JS_ASYNC_GENERATOR_STATE_AWAITING_RETURN || + s->state == JS_ASYNC_GENERATOR_STATE_COMPLETED); + s->state = JS_ASYNC_GENERATOR_STATE_COMPLETED; + if (is_reject) { + js_async_generator_reject(ctx, s, arg); + } else { + js_async_generator_resolve(ctx, s, arg, true); + } + } else if (s->state == JS_ASYNC_GENERATOR_STATE_EXECUTING) { + /* restart function execution after await() */ + s->func_state.throw_flag = is_reject; + if (is_reject) { + JS_Throw(ctx, js_dup(arg)); + } else { + /* return value of await */ + s->func_state.frame.cur_sp[-1] = js_dup(arg); + } + js_async_generator_resume_next(ctx, s); + } + return JS_UNDEFINED; +} + +/* magic = GEN_MAGIC_x */ +static JSValue js_async_generator_next(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, + int magic) +{ + JSAsyncGeneratorData *s = JS_GetOpaque(this_val, JS_CLASS_ASYNC_GENERATOR); + JSValue promise, resolving_funcs[2]; + JSAsyncGeneratorRequest *req; + + promise = JS_NewPromiseCapability(ctx, resolving_funcs); + if (JS_IsException(promise)) + return JS_EXCEPTION; + if (!s) { + JSValue err, res2; + JS_ThrowTypeError(ctx, "not an AsyncGenerator object"); + err = JS_GetException(ctx); + res2 = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, + 1, vc(&err)); + JS_FreeValue(ctx, err); + JS_FreeValue(ctx, res2); + JS_FreeValue(ctx, resolving_funcs[0]); + JS_FreeValue(ctx, resolving_funcs[1]); + return promise; + } + req = js_mallocz(ctx, sizeof(*req)); + if (!req) + goto fail; + req->completion_type = magic; + req->result = js_dup(argv[0]); + req->promise = js_dup(promise); + req->resolving_funcs[0] = resolving_funcs[0]; + req->resolving_funcs[1] = resolving_funcs[1]; + list_add_tail(&req->link, &s->queue); + if (s->state != JS_ASYNC_GENERATOR_STATE_EXECUTING) { + js_async_generator_resume_next(ctx, s); + } + return promise; + fail: + JS_FreeValue(ctx, resolving_funcs[0]); + JS_FreeValue(ctx, resolving_funcs[1]); + JS_FreeValue(ctx, promise); + return JS_EXCEPTION; +} + +static JSValue js_async_generator_function_call(JSContext *ctx, + JSValueConst func_obj, + JSValueConst this_obj, + int argc, JSValueConst *argv, + int flags) +{ + JSValue obj, func_ret; + JSAsyncGeneratorData *s; + + s = js_mallocz(ctx, sizeof(*s)); + if (!s) + return JS_EXCEPTION; + s->state = JS_ASYNC_GENERATOR_STATE_SUSPENDED_START; + init_list_head(&s->queue); + if (async_func_init(ctx, &s->func_state, func_obj, this_obj, argc, argv)) { + s->state = JS_ASYNC_GENERATOR_STATE_COMPLETED; + goto fail; + } + + /* execute the function up to 'OP_initial_yield' (no yield nor + await are possible) */ + func_ret = async_func_resume(ctx, &s->func_state); + if (JS_IsException(func_ret)) + goto fail; + JS_FreeValue(ctx, func_ret); + + obj = js_create_from_ctor(ctx, func_obj, JS_CLASS_ASYNC_GENERATOR); + if (JS_IsException(obj)) + goto fail; + s->generator = JS_VALUE_GET_OBJ(obj); + /* root captured locals against the async generator object (the initial + resume above only reaches OP_initial_yield, before any user code) */ + s->func_state.frame.cur_gc_obj = &s->generator->header; + JS_SetOpaqueInternal(obj, s); + return obj; + fail: + js_async_generator_free(ctx->rt, s); + return JS_EXCEPTION; +} + +/* JS parser */ + +enum { + TOK_NUMBER = -128, + TOK_STRING, + TOK_TEMPLATE, + TOK_IDENT, + TOK_REGEXP, + /* warning: order matters (see js_parse_assign_expr) */ + TOK_MUL_ASSIGN, + TOK_DIV_ASSIGN, + TOK_MOD_ASSIGN, + TOK_PLUS_ASSIGN, + TOK_MINUS_ASSIGN, + TOK_SHL_ASSIGN, + TOK_SAR_ASSIGN, + TOK_SHR_ASSIGN, + TOK_AND_ASSIGN, + TOK_XOR_ASSIGN, + TOK_OR_ASSIGN, + TOK_POW_ASSIGN, + TOK_LAND_ASSIGN, + TOK_LOR_ASSIGN, + TOK_DOUBLE_QUESTION_MARK_ASSIGN, + TOK_DEC, + TOK_INC, + TOK_SHL, + TOK_SAR, + TOK_SHR, + TOK_LT, + TOK_LTE, + TOK_GT, + TOK_GTE, + TOK_EQ, + TOK_STRICT_EQ, + TOK_NEQ, + TOK_STRICT_NEQ, + TOK_LAND, + TOK_LOR, + TOK_POW, + TOK_ARROW, + TOK_ELLIPSIS, + TOK_DOUBLE_QUESTION_MARK, + TOK_QUESTION_MARK_DOT, + TOK_ERROR, + TOK_PRIVATE_NAME, + TOK_EOF, + /* keywords: WARNING: same order as atoms */ + TOK_NULL, /* must be first */ + TOK_FALSE, + TOK_TRUE, + TOK_IF, + TOK_ELSE, + TOK_RETURN, + TOK_VAR, + TOK_THIS, + TOK_DELETE, + TOK_VOID, + TOK_TYPEOF, + TOK_NEW, + TOK_IN, + TOK_INSTANCEOF, + TOK_DO, + TOK_WHILE, + TOK_FOR, + TOK_BREAK, + TOK_CONTINUE, + TOK_SWITCH, + TOK_CASE, + TOK_DEFAULT, + TOK_THROW, + TOK_TRY, + TOK_CATCH, + TOK_FINALLY, + TOK_FUNCTION, + TOK_DEBUGGER, + TOK_WITH, + /* FutureReservedWord */ + TOK_CLASS, + TOK_CONST, + TOK_ENUM, + TOK_EXPORT, + TOK_EXTENDS, + TOK_IMPORT, + TOK_SUPER, + TOK_USING, + /* FutureReservedWords when parsing strict mode code */ + TOK_IMPLEMENTS, + TOK_INTERFACE, + TOK_LET, + TOK_PACKAGE, + TOK_PRIVATE, + TOK_PROTECTED, + TOK_PUBLIC, + TOK_STATIC, + TOK_YIELD, + TOK_AWAIT, /* must be last */ + TOK_OF, /* only used for js_parse_skip_parens_token() */ +}; + +#define TOK_FIRST_KEYWORD TOK_NULL +#define TOK_LAST_KEYWORD TOK_AWAIT + +/* unicode code points */ +#define CP_NBSP 0x00a0 +#define CP_BOM 0xfeff + +#define CP_LS 0x2028 +#define CP_PS 0x2029 + +typedef struct BlockEnv { + struct BlockEnv *prev; + JSAtom label_name; /* JS_ATOM_NULL if none */ + int label_break; /* -1 if none */ + int label_cont; /* -1 if none */ + int drop_count; /* number of stack elements to drop */ + int label_finally; /* -1 if none */ + int scope_level; + uint8_t has_iterator : 1; + uint8_t is_async_iterator : 1; + uint8_t is_regular_stmt : 1; // i.e. not a loop statement + uint8_t has_using : 1; /* scope has using declarations needing disposal */ + int using_scope_level; /* scope level for OP_dispose_scope (-1 if none) */ +} BlockEnv; + +typedef struct JSGlobalVar { + int cpool_idx; /* if >= 0, index in the constant pool for hoisted + function defintion*/ + uint8_t force_init : 1; /* force initialization to undefined */ + uint8_t is_lexical : 1; /* global let/const definition */ + uint8_t is_const : 1; /* const definition */ + int scope_level; /* scope of definition */ + JSAtom var_name; /* variable name */ +} JSGlobalVar; + +typedef struct RelocEntry { + struct RelocEntry *next; + uint32_t addr; /* address to patch */ + int size; /* address size: 1, 2 or 4 bytes */ +} RelocEntry; + +typedef struct JumpSlot { + int op; + int size; + int pos; + int label; +} JumpSlot; + +typedef struct LabelSlot { + int ref_count; + int pos; /* phase 1 address, -1 means not resolved yet */ + int pos2; /* phase 2 address, -1 means not resolved yet */ + int addr; /* phase 3 address, -1 means not resolved yet */ + RelocEntry *first_reloc; +} LabelSlot; + +typedef struct SourceLocSlot { + uint32_t pc; + int line_num; + int col_num; +} SourceLocSlot; + +typedef enum JSParseFunctionEnum { + JS_PARSE_FUNC_STATEMENT, + JS_PARSE_FUNC_VAR, + JS_PARSE_FUNC_EXPR, + JS_PARSE_FUNC_ARROW, + JS_PARSE_FUNC_GETTER, + JS_PARSE_FUNC_SETTER, + JS_PARSE_FUNC_METHOD, + JS_PARSE_FUNC_CLASS_STATIC_INIT, + JS_PARSE_FUNC_CLASS_CONSTRUCTOR, + JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR, +} JSParseFunctionEnum; + +typedef enum JSParseExportEnum { + JS_PARSE_EXPORT_NONE, + JS_PARSE_EXPORT_NAMED, + JS_PARSE_EXPORT_DEFAULT, +} JSParseExportEnum; + +typedef struct JSFunctionDef { + JSContext *ctx; + struct JSFunctionDef *parent; + int parent_cpool_idx; /* index in the constant pool of the parent + or -1 if none */ + int parent_scope_level; /* scope level in parent at point of definition */ + struct list_head child_list; /* list of JSFunctionDef.link */ + struct list_head link; + + int eval_type; /* only valid if is_eval = true */ + + /* Pack all boolean flags together as 1-bit fields to reduce struct size + while avoiding padding and compiler deoptimization. */ + bool is_eval : 1; /* true if eval code */ + bool is_global_var : 1; /* true if variables are not defined locally: + eval global, eval module or non strict eval */ + bool is_func_expr : 1; /* true if function expression */ + bool has_home_object : 1; /* true if the home object is available */ + bool has_prototype : 1; /* true if a prototype field is necessary */ + bool has_simple_parameter_list : 1; + bool has_parameter_expressions : 1; /* if true, an argument scope is created */ + bool has_use_strict : 1; /* to reject directive in special cases */ + bool has_eval_call : 1; /* true if the function contains a call to eval() */ + bool has_arguments_binding : 1; /* true if the 'arguments' binding is + available in the function */ + bool has_this_binding : 1; /* true if the 'this' and new.target binding are + available in the function */ + bool new_target_allowed : 1; /* true if the 'new.target' does not + throw a syntax error */ + bool super_call_allowed : 1; /* true if super() is allowed */ + bool super_allowed : 1; /* true if super. or super[] is allowed */ + bool arguments_allowed : 1; /* true if the 'arguments' identifier is allowed */ + bool is_derived_class_constructor : 1; + bool in_function_body : 1; + bool backtrace_barrier : 1; + bool need_home_object : 1; + bool use_short_opcodes : 1; /* true if short opcodes are used in byte_code */ + bool has_await : 1; /* true if await is used (used in module eval) */ + + JSFunctionKindEnum func_kind : 8; + JSParseFunctionEnum func_type : 7; + uint8_t is_strict_mode : 1; + JSAtom func_name; /* JS_ATOM_NULL if no name */ + + JSVarDef *vars; + uint32_t *vars_htab; // indexes into vars[] + int var_size; /* allocated size for vars[] */ + int var_count; + JSVarDef *args; + int arg_size; /* allocated size for args[] */ + int arg_count; /* number of arguments */ + int defined_arg_count; + int var_ref_count; /* number of local/arg variable references */ + int var_object_idx; /* -1 if none */ + int arg_var_object_idx; /* -1 if none (var object for the argument scope) */ + int arguments_var_idx; /* -1 if none */ + int arguments_arg_idx; /* argument variable definition in argument scope, + -1 if none */ + int func_var_idx; /* variable containing the current function (-1 + if none, only used if is_func_expr is true) */ + int eval_ret_idx; /* variable containing the return value of the eval, -1 if none */ + int this_var_idx; /* variable containg the 'this' value, -1 if none */ + int new_target_var_idx; /* variable containg the 'new.target' value, -1 if none */ + int this_active_func_var_idx; /* variable containg the 'this.active_func' value, -1 if none */ + int home_object_var_idx; + + int scope_level; /* index into fd->scopes if the current lexical scope */ + int scope_first; /* index into vd->vars of first lexically scoped variable */ + int scope_size; /* allocated size of fd->scopes array */ + int scope_count; /* number of entries used in the fd->scopes array */ + JSVarScope *scopes; + JSVarScope def_scope_array[4]; + int body_scope; /* scope of the body of the function or eval */ + + int global_var_count; + int global_var_size; + JSGlobalVar *global_vars; + + DynBuf byte_code; + int last_opcode_pos; /* -1 if no last opcode */ + + LabelSlot *label_slots; + int label_size; /* allocated size for label_slots[] */ + int label_count; + BlockEnv *top_break; /* break/continue label stack */ + + /* constant pool (strings, functions, numbers) */ + JSValue *cpool; + int cpool_count; + int cpool_size; + + /* list of variables in the closure */ + int closure_var_count; + int closure_var_size; + JSClosureVar *closure_var; + + JumpSlot *jump_slots; + int jump_size; + int jump_count; + + SourceLocSlot *source_loc_slots; + int source_loc_size; + int source_loc_count; + int line_number_last; + int line_number_last_pc; + int col_number_last; + + /* pc2line table */ + JSAtom filename; + int line_num; + int col_num; + DynBuf pc2line; + + char *source; /* raw source, utf-8 encoded */ + int source_len; + + JSModuleDef *module; /* != NULL when parsing a module */ +} JSFunctionDef; + +typedef struct JSToken { + int val; + int line_num; /* line number of token start */ + int col_num; /* column number of token start */ + const uint8_t *ptr; + const uint8_t *line_start; /* first character of the line of token start */ + union { + struct { + JSValue str; + int sep; + } str; + struct { + JSValue val; + } num; + struct { + JSAtom atom; + bool has_escape; + bool is_reserved; + } ident; + struct { + JSValue body; + JSValue flags; + } regexp; + } u; +} JSToken; + +typedef struct JSParseState { + JSContext *ctx; + int last_line_num; /* line number of last token */ + int last_col_num; /* column number of last token */ + int line_num; /* line number of current offset */ + int col_num; /* column number of current offset */ + const char *filename; + JSToken token; + bool got_lf; /* true if got line feed before the current token */ + const uint8_t *last_ptr; + const uint8_t *buf_start; + const uint8_t *buf_ptr; + const uint8_t *buf_end; + const uint8_t *line_start; /* first character of the current line */ + const uint8_t *eol; // most recently seen end-of-line character + const uint8_t *mark; // first token character, invariant: eol < mark + + /* current function code */ + JSFunctionDef *cur_func; + bool is_module; /* parsing a module */ + bool allow_html_comments; +} JSParseState; + +typedef struct JSOpCode { +#ifdef ENABLE_DUMPS // JS_DUMP_BYTECODE_* + const char *name; +#endif + uint8_t size; /* in bytes */ + /* the opcodes remove n_pop items from the top of the stack, then + pushes n_push items */ + uint8_t n_pop; + uint8_t n_push; + uint8_t fmt; +} JSOpCode; + +static const JSOpCode opcode_info[OP_COUNT + (OP_TEMP_END - OP_TEMP_START)] = { +#define FMT(f) +#ifdef ENABLE_DUMPS // JS_DUMP_BYTECODE_* +#define DEF(id, size, n_pop, n_push, f) { #id, size, n_pop, n_push, OP_FMT_ ## f }, +#else +#define DEF(id, size, n_pop, n_push, f) { size, n_pop, n_push, OP_FMT_ ## f }, +#endif +#include "quickjs-opcode.h" +#undef DEF +#undef FMT +}; + +/* After the final compilation pass, short opcodes are used. Their + opcodes overlap with the temporary opcodes which cannot appear in + the final bytecode. Their description is after the temporary + opcodes in opcode_info[]. */ +#define short_opcode_info(op) \ + opcode_info[(op) >= OP_TEMP_START ? \ + (op) + (OP_TEMP_END - OP_TEMP_START) : (op)] + +static void json_free_token(JSParseState *s, JSToken *token) { + // Only free actual allocated values + switch(token->val) { + case TOK_NUMBER: + JS_FreeValue(s->ctx, token->u.num.val); + break; + case TOK_STRING: + JS_FreeValue(s->ctx, token->u.str.str); + break; + case TOK_IDENT: + JS_FreeAtom(s->ctx, token->u.ident.atom); + break; + } +} + +static void free_token(JSParseState *s, JSToken *token) +{ + switch(token->val) { + case TOK_NUMBER: + JS_FreeValue(s->ctx, token->u.num.val); + break; + case TOK_STRING: + case TOK_TEMPLATE: + JS_FreeValue(s->ctx, token->u.str.str); + break; + case TOK_REGEXP: + JS_FreeValue(s->ctx, token->u.regexp.body); + JS_FreeValue(s->ctx, token->u.regexp.flags); + break; + case TOK_IDENT: + case TOK_PRIVATE_NAME: + JS_FreeAtom(s->ctx, token->u.ident.atom); + break; + default: + if (token->val >= TOK_FIRST_KEYWORD && + token->val <= TOK_LAST_KEYWORD) { + JS_FreeAtom(s->ctx, token->u.ident.atom); + } + break; + } +} + +static void __attribute((unused)) dump_token(JSParseState *s, + const JSToken *token) +{ + printf("%d:%d ", token->line_num, token->col_num); + switch(token->val) { + case TOK_NUMBER: + { + double d; + JS_ToFloat64(s->ctx, &d, token->u.num.val); /* no exception possible */ + printf("number: %.14g\n", d); + } + break; + case TOK_IDENT: + dump_atom: + { + char buf[ATOM_GET_STR_BUF_SIZE]; + printf("ident: '%s'\n", + JS_AtomGetStr(s->ctx, buf, sizeof(buf), token->u.ident.atom)); + } + break; + case TOK_STRING: + { + const char *str; + /* XXX: quote the string */ + str = JS_ToCString(s->ctx, token->u.str.str); + printf("string: '%s'\n", str); + JS_FreeCString(s->ctx, str); + } + break; + case TOK_TEMPLATE: + { + const char *str; + str = JS_ToCString(s->ctx, token->u.str.str); + printf("template: `%s`\n", str); + JS_FreeCString(s->ctx, str); + } + break; + case TOK_REGEXP: + { + const char *str, *str2; + str = JS_ToCString(s->ctx, token->u.regexp.body); + str2 = JS_ToCString(s->ctx, token->u.regexp.flags); + printf("regexp: '%s' '%s'\n", str, str2); + JS_FreeCString(s->ctx, str); + JS_FreeCString(s->ctx, str2); + } + break; + case TOK_EOF: + printf("eof\n"); + break; + default: + if (s->token.val >= TOK_NULL && s->token.val <= TOK_LAST_KEYWORD) { + goto dump_atom; + } else if (s->token.val >= 256) { + printf("token: %d\n", token->val); + } else { + printf("token: '%c'\n", token->val); + } + break; + } +} + +int JS_PRINTF_FORMAT_ATTR(2, 3) js_parse_error(JSParseState *s, JS_PRINTF_FORMAT const char *fmt, ...) +{ + JSContext *ctx = s->ctx; + va_list ap; + int backtrace_flags; + + va_start(ap, fmt); + JS_ThrowError2(ctx, JS_SYNTAX_ERROR, false, fmt, ap); + va_end(ap); + backtrace_flags = 0; + if (s->cur_func && s->cur_func->backtrace_barrier) + backtrace_flags = JS_BACKTRACE_FLAG_SINGLE_LEVEL; + /* s->col_num is not advanced during token scanning, so derive the column + as the 1-based offset of the token from the start of its line. */ + int err_col_num = s->token.col_num; + if (s->token.ptr && s->token.ptr >= s->token.line_start) + err_col_num = (int)(s->token.ptr - s->token.line_start) + 1; + build_backtrace(ctx, ctx->rt->current_exception, JS_UNDEFINED, s->filename, + s->token.line_num, err_col_num, backtrace_flags); + return -1; +} + +#ifndef QJS_DISABLE_PARSER + +static __exception int next_token(JSParseState *s); + +static int js_parse_expect(JSParseState *s, int tok) +{ + char buf[ATOM_GET_STR_BUF_SIZE]; + + if (s->token.val == tok) + return next_token(s); + + switch(s->token.val) { + case TOK_EOF: + return js_parse_error(s, "Unexpected end of input"); + case TOK_NUMBER: + return js_parse_error(s, "Unexpected number"); + case TOK_STRING: + return js_parse_error(s, "Unexpected string"); + case TOK_TEMPLATE: + return js_parse_error(s, "Unexpected string template"); + case TOK_REGEXP: + return js_parse_error(s, "Unexpected regexp"); + case TOK_IDENT: + return js_parse_error(s, "Unexpected identifier '%s'", + JS_AtomGetStr(s->ctx, buf, sizeof(buf), + s->token.u.ident.atom)); + case TOK_ERROR: + return js_parse_error(s, "Invalid or unexpected token"); + default: + return js_parse_error(s, "Unexpected token '%.*s'", + (int)(s->buf_ptr - s->token.ptr), + (const char *)s->token.ptr); + } +} + +static int js_parse_expect_semi(JSParseState *s) +{ + if (s->token.val != ';') { + /* automatic insertion of ';' */ + if (s->token.val == TOK_EOF || s->token.val == '}' || s->got_lf) { + return 0; + } + return js_parse_error(s, "expecting '%c'", ';'); + } + return next_token(s); +} + +static int js_parse_error_reserved_identifier(JSParseState *s) +{ + char buf1[ATOM_GET_STR_BUF_SIZE]; + return js_parse_error(s, "'%s' is a reserved identifier", + JS_AtomGetStr(s->ctx, buf1, sizeof(buf1), + s->token.u.ident.atom)); +} + +static __exception int js_parse_template_part(JSParseState *s, + const uint8_t *p) +{ + const uint8_t *p_next; + uint32_t c; + StringBuffer b_s, *b = &b_s; + JSValue str; + + /* p points to the first byte of the template part */ + if (string_buffer_init(s->ctx, b, 32)) + goto fail; + for(;;) { + if (p >= s->buf_end) + goto unexpected_eof; + c = *p++; + if (c == '`') { + /* template end part */ + break; + } + if (c == '$' && *p == '{') { + /* template start or middle part */ + p++; + break; + } + if (c == '\\') { + if (string_buffer_putc8(b, c)) + goto fail; + if (p >= s->buf_end) + goto unexpected_eof; + c = *p++; + } + /* newline sequences are normalized as single '\n' bytes */ + if (c == '\r') { + if (*p == '\n') + p++; + c = '\n'; + } + if (c == '\n') { + s->line_num++; + s->line_start = p; + s->eol = &p[-1]; + s->mark = p; + } else if (c >= 0x80) { + c = utf8_decode(p - 1, &p_next); + if (p_next == p) { + js_parse_error(s, "invalid UTF-8 sequence"); + goto fail; + } + p = p_next; + } + if (string_buffer_putc(b, c)) + goto fail; + } + str = string_buffer_end(b); + if (JS_IsException(str)) + return -1; + s->token.val = TOK_TEMPLATE; + s->token.u.str.sep = c; + s->token.u.str.str = str; + s->buf_ptr = p; + return 0; + + unexpected_eof: + js_parse_error(s, "unexpected end of string"); + fail: + string_buffer_free(b); + return -1; +} + +static __exception int js_parse_string(JSParseState *s, int sep, + bool do_throw, const uint8_t *p, + JSToken *token, const uint8_t **pp) +{ + const uint8_t *p_next; + int ret; + uint32_t c; + StringBuffer b_s, *b = &b_s; + JSValue str; + + /* string */ + if (string_buffer_init(s->ctx, b, 32)) + goto fail; + for(;;) { + if (p >= s->buf_end) + goto invalid_char; + c = *p; + if (c < 0x20) { + if (sep == '`') { + if (c == '\r') { + if (p[1] == '\n') + p++; + c = '\n'; + } + /* do not update s->line_num */ + } else if (c == '\n' || c == '\r') + goto invalid_char; + } + p++; + if (c == sep) + break; + if (c == '$' && *p == '{' && sep == '`') { + /* template start or middle part */ + p++; + break; + } + if (c == '\\') { + c = *p; + switch(c) { + case '\0': + if (p >= s->buf_end) { + if (sep != '`') + goto invalid_char; + if (do_throw) + js_parse_error(s, "Unexpected end of input"); + goto fail; + } + p++; + break; + case '\'': + case '\"': + case '\\': + p++; + break; + case '\r': /* accept DOS and MAC newline sequences */ + if (p[1] == '\n') { + p++; + } + /* fall thru */ + case '\n': + /* ignore escaped newline sequence */ + p++; + if (sep != '`') { + s->line_num++; + s->line_start = p; + s->eol = &p[-1]; + s->mark = p; + } + continue; + default: + if (c == '0' && !(p[1] >= '0' && p[1] <= '9')) { + /* accept isolated \0 */ + p++; + c = '\0'; + } else + if ((c >= '0' && c <= '9') + && (s->cur_func->is_strict_mode || sep == '`')) { + if (do_throw) { + js_parse_error(s, "%s are not allowed in %s", + (c >= '8') ? "\\8 and \\9" : "Octal escape sequences", + (sep == '`') ? "template strings" : "strict mode"); + } + goto fail; + } else if (c >= 0x80) { + c = utf8_decode(p, &p_next); + if (p_next == p + 1) { + goto invalid_utf8; + } + p = p_next; + /* LS or PS are skipped */ + if (c == CP_LS || c == CP_PS) + continue; + } else { + ret = lre_parse_escape(&p, true); + if (ret == -1) { + if (do_throw) { + js_parse_error(s, "Invalid %s escape sequence", + c == 'u' ? "Unicode" : "hexadecimal"); + } + goto fail; + } else if (ret < 0) { + /* ignore the '\' (could output a warning) */ + p++; + } else { + c = ret; + } + } + break; + } + } else if (c >= 0x80) { + c = utf8_decode(p - 1, &p_next); + if (p_next == p) + goto invalid_utf8; + p = p_next; + } + if (string_buffer_putc(b, c)) + goto fail; + } + str = string_buffer_end(b); + if (JS_IsException(str)) + return -1; + token->val = TOK_STRING; + token->u.str.sep = c; + token->u.str.str = str; + *pp = p; + return 0; + + invalid_utf8: + if (do_throw) + js_parse_error(s, "invalid UTF-8 sequence"); + goto fail; + invalid_char: + if (do_throw) + js_parse_error(s, "unexpected end of string"); + fail: + string_buffer_free(b); + return -1; +} + +static inline bool token_is_pseudo_keyword(JSParseState *s, JSAtom atom) { + return s->token.val == TOK_IDENT && s->token.u.ident.atom == atom && + !s->token.u.ident.has_escape; +} + +static __exception int js_parse_regexp(JSParseState *s) +{ + const uint8_t *p, *p_next; + bool in_class; + StringBuffer b_s, *b = &b_s; + StringBuffer b2_s, *b2 = &b2_s; + uint32_t c; + JSValue body_str, flags_str; + + p = s->buf_ptr; + p++; + in_class = false; + if (string_buffer_init(s->ctx, b, 32)) + return -1; + if (string_buffer_init(s->ctx, b2, 1)) + goto fail; + for(;;) { + if (p >= s->buf_end) { + eof_error: + js_parse_error(s, "unexpected end of regexp"); + goto fail; + } + c = *p++; + if (c == '\n' || c == '\r') { + goto eol_error; + } else if (c == '/') { + if (!in_class) + break; + } else if (c == '[') { + in_class = true; + } else if (c == ']') { + /* XXX: incorrect as the first character in a class */ + in_class = false; + } else if (c == '\\') { + if (string_buffer_putc8(b, c)) + goto fail; + c = *p++; + if (c == '\n' || c == '\r') + goto eol_error; + else if (c == '\0' && p >= s->buf_end) + goto eof_error; + else if (c >= 0x80) { + c = utf8_decode(p - 1, &p_next); + if (p_next == p) { + goto invalid_utf8; + } + p = p_next; + if (c == CP_LS || c == CP_PS) + goto eol_error; + } + } else if (c >= 0x80) { + c = utf8_decode(p - 1, &p_next); + if (p_next == p) { + invalid_utf8: + js_parse_error(s, "invalid UTF-8 sequence"); + goto fail; + } + p = p_next; + /* LS or PS are considered as line terminator */ + if (c == CP_LS || c == CP_PS) { + eol_error: + js_parse_error(s, "unexpected line terminator in regexp"); + goto fail; + } + } + if (string_buffer_putc(b, c)) + goto fail; + } + + /* flags */ + for(;;) { + c = utf8_decode(p, &p_next); + /* no need to test for invalid UTF-8, 0xFFFD is not ident_next */ + if (!lre_js_is_ident_next(c)) + break; + if (string_buffer_putc(b2, c)) + goto fail; + p = p_next; + } + + body_str = string_buffer_end(b); + flags_str = string_buffer_end(b2); + if (JS_IsException(body_str) || + JS_IsException(flags_str)) { + JS_FreeValue(s->ctx, body_str); + JS_FreeValue(s->ctx, flags_str); + return -1; + } + s->token.val = TOK_REGEXP; + s->token.u.regexp.body = body_str; + s->token.u.regexp.flags = flags_str; + s->buf_ptr = p; + return 0; + fail: + string_buffer_free(b); + string_buffer_free(b2); + return -1; +} + +#endif // QJS_DISABLE_PARSER + +static __exception int ident_realloc(JSContext *ctx, char **pbuf, size_t *psize, + char *static_buf) +{ + char *buf, *new_buf; + size_t size, new_size; + + buf = *pbuf; + size = *psize; + if (size >= (SIZE_MAX / 3) * 2) + new_size = SIZE_MAX; + else + new_size = size + (size >> 1); + if (buf == static_buf) { + new_buf = js_malloc(ctx, new_size); + if (!new_buf) + return -1; + memcpy(new_buf, buf, size); + } else { + new_buf = js_realloc(ctx, buf, new_size); + if (!new_buf) + return -1; + } + *pbuf = new_buf; + *psize = new_size; + return 0; +} + +#ifndef QJS_DISABLE_PARSER + +/* convert a TOK_IDENT to a keyword when needed */ +static void update_token_ident(JSParseState *s) +{ + /* `using` is contextually reserved, not a true keyword. Leave it as + TOK_IDENT so it can be used as a regular identifier in expressions. + Using declarations are detected explicitly at statement and + for-loop head parsing via token_is_pseudo_keyword. */ + if (s->token.u.ident.atom == JS_ATOM_using) + return; + if (s->token.u.ident.atom <= JS_ATOM_LAST_KEYWORD || + (s->token.u.ident.atom <= JS_ATOM_LAST_STRICT_KEYWORD && + s->cur_func->is_strict_mode) || + (s->token.u.ident.atom == JS_ATOM_yield && + ((s->cur_func->func_kind & JS_FUNC_GENERATOR) || + (s->cur_func->func_type == JS_PARSE_FUNC_ARROW && + !s->cur_func->in_function_body && s->cur_func->parent && + (s->cur_func->parent->func_kind & JS_FUNC_GENERATOR)))) || + (s->token.u.ident.atom == JS_ATOM_await && + (s->is_module || + (s->cur_func->func_kind & JS_FUNC_ASYNC) || + s->cur_func->func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT || + (s->cur_func->func_type == JS_PARSE_FUNC_ARROW && + !s->cur_func->in_function_body && s->cur_func->parent && + ((s->cur_func->parent->func_kind & JS_FUNC_ASYNC) || + s->cur_func->parent->func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT))))) { + if (s->token.u.ident.has_escape) { + s->token.u.ident.is_reserved = true; + s->token.val = TOK_IDENT; + } else { + /* The keywords atoms are pre allocated */ + s->token.val = s->token.u.ident.atom - 1 + TOK_FIRST_KEYWORD; + } + } +} + +/* if the current token is an identifier or keyword, reparse it + according to the current function type */ +static void reparse_ident_token(JSParseState *s) +{ + if (s->token.val == TOK_IDENT || + (s->token.val >= TOK_FIRST_KEYWORD && + s->token.val <= TOK_LAST_KEYWORD)) { + s->token.val = TOK_IDENT; + s->token.u.ident.is_reserved = false; + update_token_ident(s); + } +} + +/* 'c' is the first character. Return JS_ATOM_NULL in case of error */ +static JSAtom parse_ident(JSParseState *s, const uint8_t **pp, + bool *pident_has_escape, int c, bool is_private) +{ + const uint8_t *p, *p_next; + char ident_buf[128], *buf; + size_t ident_size, ident_pos; + JSAtom atom = JS_ATOM_NULL; + + p = *pp; + buf = ident_buf; + ident_size = sizeof(ident_buf); + ident_pos = 0; + if (is_private) + buf[ident_pos++] = '#'; + for(;;) { + if (c < 0x80) { + buf[ident_pos++] = c; + } else { + ident_pos += utf8_encode((uint8_t*)buf + ident_pos, c); + } + c = *p; + p_next = p + 1; + if (c == '\\' && *p_next == 'u') { + c = lre_parse_escape(&p_next, true); + *pident_has_escape = true; + } else if (c >= 0x80) { + c = utf8_decode(p, &p_next); + /* no need to test for invalid UTF-8, 0xFFFD is not ident_next */ + } + if (!lre_js_is_ident_next(c)) + break; + p = p_next; + if (unlikely(ident_pos >= ident_size - UTF8_CHAR_LEN_MAX)) { + if (ident_realloc(s->ctx, &buf, &ident_size, ident_buf)) + goto done; + } + } + /* buf is pure ASCII or UTF-8 encoded */ + atom = JS_NewAtomLen(s->ctx, buf, ident_pos); + done: + if (unlikely(buf != ident_buf)) + js_free(s->ctx, buf); + *pp = p; + return atom; +} + + +static __exception int next_token(JSParseState *s) +{ + const uint8_t *p, *p_next; + int c; + bool ident_has_escape; + JSAtom atom; + + if (js_check_stack_overflow(s->ctx->rt, 1000)) { + JS_ThrowStackOverflow(s->ctx); + return -1; + } + + free_token(s, &s->token); + + p = s->last_ptr = s->buf_ptr; + s->got_lf = false; + s->last_line_num = s->token.line_num; + s->last_col_num = s->token.col_num; + redo: + s->token.line_num = s->line_num; + s->token.col_num = s->col_num; + s->token.ptr = p; + s->token.line_start = s->line_start; + c = *p; + switch(c) { + case 0: + if (p >= s->buf_end) { + s->token.val = TOK_EOF; + } else { + goto def_token; + } + break; + case '`': + if (js_parse_template_part(s, p + 1)) + goto fail; + p = s->buf_ptr; + break; + case '\'': + case '\"': + if (js_parse_string(s, c, true, p + 1, &s->token, &p)) + goto fail; + break; + case '\r': /* accept DOS and MAC newline sequences */ + if (p[1] == '\n') { + p++; + } + /* fall thru */ + case '\n': + p++; + line_terminator: + s->line_start = p; + s->eol = &p[-1]; + s->mark = p; + s->got_lf = true; + s->line_num++; + goto redo; + case '\f': + case '\v': + case ' ': + case '\t': + s->mark = ++p; + goto redo; + case '/': + if (p[1] == '*') { + /* comment */ + p += 2; + for(;;) { + if (*p == '\0' && p >= s->buf_end) { + js_parse_error(s, "unexpected end of comment"); + goto fail; + } + if (p[0] == '*' && p[1] == '/') { + p += 2; + break; + } + if (*p == '\n') { + s->line_num++; + s->got_lf = true; /* considered as LF for ASI */ + s->eol = p++; + s->line_start = p; + s->mark = p; + } else if (*p == '\r') { + s->got_lf = true; /* considered as LF for ASI */ + p++; + s->line_start = p; + } else if (*p >= 0x80) { + c = utf8_decode(p, &p); + /* ignore invalid UTF-8 in comments */ + if (c == CP_LS || c == CP_PS) { + s->got_lf = true; /* considered as LF for ASI */ + } + } else { + p++; + } + } + s->mark = p; + goto redo; + } else if (p[1] == '/') { + /* line comment */ + p += 2; + skip_line_comment: + for(;;) { + if (*p == '\0' && p >= s->buf_end) + break; + if (*p == '\r' || *p == '\n') + break; + if (*p >= 0x80) { + c = utf8_decode(p, &p); + /* ignore invalid UTF-8 in comments */ + /* LS or PS are considered as line terminator */ + if (c == CP_LS || c == CP_PS) { + break; + } + } else { + p++; + } + } + s->mark = p; + goto redo; + } else if (p[1] == '=') { + p += 2; + s->token.val = TOK_DIV_ASSIGN; + } else { + p++; + s->token.val = c; + } + break; + case '\\': + if (p[1] == 'u') { + const uint8_t *p1 = p + 1; + int c1 = lre_parse_escape(&p1, true); + if (c1 >= 0 && lre_js_is_ident_first(c1)) { + c = c1; + p = p1; + ident_has_escape = true; + goto has_ident; + } else { + /* XXX: syntax error? */ + } + } + goto def_token; + case 'a': case 'b': case 'c': case 'd': + case 'e': case 'f': case 'g': case 'h': + case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': + case 'q': case 'r': case 's': case 't': + case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + case 'A': case 'B': case 'C': case 'D': + case 'E': case 'F': case 'G': case 'H': + case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': + case 'Q': case 'R': case 'S': case 'T': + case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case '_': + case '$': + /* identifier */ + s->mark = p; + p++; + ident_has_escape = false; + has_ident: + atom = parse_ident(s, &p, &ident_has_escape, c, false); + if (atom == JS_ATOM_NULL) + goto fail; + s->token.u.ident.atom = atom; + s->token.u.ident.has_escape = ident_has_escape; + s->token.u.ident.is_reserved = false; + s->token.val = TOK_IDENT; + update_token_ident(s); + break; + case '#': + /* private name */ + { + p++; + c = *p; + p_next = p + 1; + if (c == '\\' && *p_next == 'u') { + c = lre_parse_escape(&p_next, true); + } else if (c >= 0x80) { + c = utf8_decode(p, &p_next); + if (p_next == p + 1) + goto invalid_utf8; + } + if (!lre_js_is_ident_first(c)) { + js_parse_error(s, "invalid first character of private name"); + goto fail; + } + p = p_next; + ident_has_escape = false; /* not used */ + atom = parse_ident(s, &p, &ident_has_escape, c, true); + if (atom == JS_ATOM_NULL) + goto fail; + s->token.u.ident.atom = atom; + s->token.val = TOK_PRIVATE_NAME; + } + break; + case '.': + if (p[1] == '.' && p[2] == '.') { + p += 3; + s->token.val = TOK_ELLIPSIS; + break; + } + if (p[1] >= '0' && p[1] <= '9') { + goto parse_number; + } else { + goto def_token; + } + break; + case '0': + /* in strict mode, octal literals are not accepted */ + if (is_digit(p[1]) && (s->cur_func->is_strict_mode)) { + js_parse_error(s, "Octal literals are not allowed in strict mode"); + goto fail; + } + goto parse_number; + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': + case '9': + /* number */ + parse_number: + { + JSValue ret; + const uint8_t *p1; + int flags; + flags = ATOD_ACCEPT_BIN_OCT | ATOD_ACCEPT_LEGACY_OCTAL | + ATOD_ACCEPT_UNDERSCORES | ATOD_ACCEPT_SUFFIX; + ret = js_atof(s->ctx, (const char *)p, (const char **)&p, 0, + flags); + if (JS_IsException(ret)) + goto fail; + /* reject `10instanceof Number` */ + if (JS_VALUE_IS_NAN(ret) || + lre_js_is_ident_next(utf8_decode(p, &p1))) { + JS_FreeValue(s->ctx, ret); + s->col_num = max_int(1, s->mark - s->eol); + js_parse_error(s, "invalid number literal"); + goto fail; + } + s->token.val = TOK_NUMBER; + s->token.u.num.val = ret; + } + break; + case '*': + if (p[1] == '=') { + p += 2; + s->token.val = TOK_MUL_ASSIGN; + } else if (p[1] == '*') { + if (p[2] == '=') { + p += 3; + s->token.val = TOK_POW_ASSIGN; + } else { + p += 2; + s->token.val = TOK_POW; + } + } else { + goto def_token; + } + break; + case '%': + if (p[1] == '=') { + p += 2; + s->token.val = TOK_MOD_ASSIGN; + } else { + goto def_token; + } + break; + case '+': + if (p[1] == '=') { + p += 2; + s->token.val = TOK_PLUS_ASSIGN; + } else if (p[1] == '+') { + p += 2; + s->token.val = TOK_INC; + } else { + goto def_token; + } + break; + case '-': + if (p[1] == '=') { + p += 2; + s->token.val = TOK_MINUS_ASSIGN; + } else if (p[1] == '-') { + if (s->allow_html_comments && p[2] == '>' && + (s->got_lf || s->last_ptr == s->buf_start)) { + /* Annex B: `-->` at beginning of line is an html comment end. + It extends to the end of the line. + */ + goto skip_line_comment; + } + p += 2; + s->token.val = TOK_DEC; + } else { + goto def_token; + } + break; + case '<': + if (p[1] == '=') { + p += 2; + s->token.val = TOK_LTE; + } else if (p[1] == '<') { + if (p[2] == '=') { + p += 3; + s->token.val = TOK_SHL_ASSIGN; + } else { + p += 2; + s->token.val = TOK_SHL; + } + } else if (s->allow_html_comments && + p[1] == '!' && p[2] == '-' && p[3] == '-') { + /* Annex B: handle `