From 046d8967ae755c633080a1aaca24e78883675bba Mon Sep 17 00:00:00 2001 From: Watson Date: Tue, 5 May 2026 20:05:43 -0400 Subject: [PATCH 1/3] Added a login_page.py in the pages folder and added some API additions --- API/api.py | 7 + README.md | 5 + node_modules/.bin/acorn | 1 + node_modules/.bin/mcr | 1 + node_modules/.bin/node-which | 1 + node_modules/.bin/semver | 1 + node_modules/.package-lock.json | 282 + node_modules/acorn-loose/CHANGELOG.md | 165 + node_modules/acorn-loose/LICENSE | 21 + node_modules/acorn-loose/README.md | 64 + .../acorn-loose/dist/acorn-loose.d.mts | 10 + .../acorn-loose/dist/acorn-loose.d.ts | 10 + node_modules/acorn-loose/dist/acorn-loose.js | 1638 +++++ node_modules/acorn-loose/dist/acorn-loose.mjs | 1630 +++++ node_modules/acorn-loose/package.json | 50 + node_modules/acorn-walk/CHANGELOG.md | 209 + node_modules/acorn-walk/LICENSE | 21 + node_modules/acorn-walk/README.md | 124 + node_modules/acorn-walk/dist/walk.d.mts | 152 + node_modules/acorn-walk/dist/walk.d.ts | 152 + node_modules/acorn-walk/dist/walk.js | 485 ++ node_modules/acorn-walk/dist/walk.mjs | 467 ++ node_modules/acorn-walk/package.json | 50 + node_modules/acorn/CHANGELOG.md | 972 +++ node_modules/acorn/LICENSE | 21 + node_modules/acorn/README.md | 301 + node_modules/acorn/bin/acorn | 4 + node_modules/acorn/dist/acorn.d.mts | 883 +++ node_modules/acorn/dist/acorn.d.ts | 883 +++ node_modules/acorn/dist/acorn.js | 6295 +++++++++++++++++ node_modules/acorn/dist/acorn.mjs | 6266 ++++++++++++++++ node_modules/acorn/dist/bin.js | 90 + node_modules/acorn/package.json | 50 + node_modules/commander/LICENSE | 22 + node_modules/commander/Readme.md | 1176 +++ node_modules/commander/esm.mjs | 16 + node_modules/commander/index.js | 24 + node_modules/commander/lib/argument.js | 150 + node_modules/commander/lib/command.js | 2777 ++++++++ node_modules/commander/lib/error.js | 39 + node_modules/commander/lib/help.js | 747 ++ node_modules/commander/lib/option.js | 380 + node_modules/commander/lib/suggestSimilar.js | 101 + node_modules/commander/package-support.json | 19 + node_modules/commander/package.json | 82 + node_modules/commander/typings/esm.d.mts | 3 + node_modules/commander/typings/index.d.ts | 1113 +++ node_modules/console-grid/LICENSE | 21 + node_modules/console-grid/README.md | 482 ++ node_modules/console-grid/lib/comparers.js | 140 + .../console-grid/lib/get-char-length.js | 60 + node_modules/console-grid/lib/index.d.ts | 77 + node_modules/console-grid/lib/index.js | 692 ++ node_modules/console-grid/lib/index.mjs | 3 + node_modules/console-grid/package.json | 40 + node_modules/cross-spawn/LICENSE | 21 + node_modules/cross-spawn/README.md | 89 + node_modules/cross-spawn/index.js | 39 + node_modules/cross-spawn/lib/enoent.js | 59 + node_modules/cross-spawn/lib/parse.js | 91 + node_modules/cross-spawn/lib/util/escape.js | 47 + .../cross-spawn/lib/util/readShebang.js | 23 + .../cross-spawn/lib/util/resolveCommand.js | 52 + node_modules/cross-spawn/package.json | 73 + node_modules/eight-colors/LICENSE | 21 + node_modules/eight-colors/README.md | 194 + .../eight-colors/dist/eight-colors.js | 1 + node_modules/eight-colors/lib/index.d.ts | 58 + node_modules/eight-colors/lib/index.js | 125 + node_modules/eight-colors/lib/index.mjs | 2 + node_modules/eight-colors/package.json | 38 + node_modules/foreground-child/LICENSE | 15 + node_modules/foreground-child/README.md | 128 + .../dist/commonjs/all-signals.d.ts | 2 + .../dist/commonjs/all-signals.d.ts.map | 1 + .../dist/commonjs/all-signals.js | 58 + .../dist/commonjs/all-signals.js.map | 1 + .../foreground-child/dist/commonjs/index.d.ts | 58 + .../dist/commonjs/index.d.ts.map | 1 + .../foreground-child/dist/commonjs/index.js | 123 + .../dist/commonjs/index.js.map | 1 + .../dist/commonjs/package.json | 3 + .../dist/commonjs/proxy-signals.d.ts | 6 + .../dist/commonjs/proxy-signals.d.ts.map | 1 + .../dist/commonjs/proxy-signals.js | 38 + .../dist/commonjs/proxy-signals.js.map | 1 + .../dist/commonjs/watchdog.d.ts | 10 + .../dist/commonjs/watchdog.d.ts.map | 1 + .../dist/commonjs/watchdog.js | 50 + .../dist/commonjs/watchdog.js.map | 1 + .../dist/esm/all-signals.d.ts | 2 + .../dist/esm/all-signals.d.ts.map | 1 + .../foreground-child/dist/esm/all-signals.js | 52 + .../dist/esm/all-signals.js.map | 1 + .../foreground-child/dist/esm/index.d.ts | 58 + .../foreground-child/dist/esm/index.d.ts.map | 1 + .../foreground-child/dist/esm/index.js | 115 + .../foreground-child/dist/esm/index.js.map | 1 + .../foreground-child/dist/esm/package.json | 3 + .../dist/esm/proxy-signals.d.ts | 6 + .../dist/esm/proxy-signals.d.ts.map | 1 + .../dist/esm/proxy-signals.js | 34 + .../dist/esm/proxy-signals.js.map | 1 + .../foreground-child/dist/esm/watchdog.d.ts | 10 + .../dist/esm/watchdog.d.ts.map | 1 + .../foreground-child/dist/esm/watchdog.js | 46 + .../foreground-child/dist/esm/watchdog.js.map | 1 + node_modules/foreground-child/package.json | 106 + node_modules/has-flag/index.d.ts | 39 + node_modules/has-flag/index.js | 8 + node_modules/has-flag/license | 9 + node_modules/has-flag/package.json | 46 + node_modules/has-flag/readme.md | 89 + node_modules/html-escaper/LICENSE.txt | 19 + node_modules/html-escaper/README.md | 97 + node_modules/html-escaper/cjs/index.js | 65 + node_modules/html-escaper/cjs/package.json | 1 + node_modules/html-escaper/esm/index.js | 62 + node_modules/html-escaper/index.js | 70 + node_modules/html-escaper/min.js | 1 + node_modules/html-escaper/package.json | 42 + node_modules/html-escaper/test/index.js | 23 + node_modules/html-escaper/test/package.json | 1 + node_modules/isexe/.npmignore | 2 + node_modules/isexe/LICENSE | 15 + node_modules/isexe/README.md | 51 + node_modules/isexe/index.js | 57 + node_modules/isexe/mode.js | 41 + node_modules/isexe/package.json | 31 + node_modules/isexe/test/basic.js | 221 + node_modules/isexe/windows.js | 42 + .../istanbul-lib-coverage/CHANGELOG.md | 209 + node_modules/istanbul-lib-coverage/LICENSE | 24 + node_modules/istanbul-lib-coverage/README.md | 29 + node_modules/istanbul-lib-coverage/index.js | 64 + .../istanbul-lib-coverage/lib/coverage-map.js | 134 + .../lib/coverage-summary.js | 112 + .../lib/data-properties.js | 12 + .../lib/file-coverage.js | 444 ++ .../istanbul-lib-coverage/lib/percent.js | 15 + .../istanbul-lib-coverage/package.json | 47 + node_modules/istanbul-lib-report/CHANGELOG.md | 192 + node_modules/istanbul-lib-report/LICENSE | 24 + node_modules/istanbul-lib-report/README.md | 43 + node_modules/istanbul-lib-report/index.js | 40 + .../istanbul-lib-report/lib/context.js | 132 + .../istanbul-lib-report/lib/file-writer.js | 189 + node_modules/istanbul-lib-report/lib/path.js | 169 + .../istanbul-lib-report/lib/report-base.js | 16 + .../lib/summarizer-factory.js | 284 + node_modules/istanbul-lib-report/lib/tree.js | 137 + .../istanbul-lib-report/lib/watermarks.js | 15 + .../istanbul-lib-report/lib/xml-writer.js | 90 + node_modules/istanbul-lib-report/package.json | 44 + node_modules/istanbul-reports/CHANGELOG.md | 476 ++ node_modules/istanbul-reports/LICENSE | 24 + node_modules/istanbul-reports/README.md | 12 + node_modules/istanbul-reports/index.js | 24 + .../istanbul-reports/lib/clover/index.js | 163 + .../istanbul-reports/lib/cobertura/index.js | 151 + .../istanbul-reports/lib/html-spa/.babelrc | 3 + .../lib/html-spa/assets/bundle.js | 30 + .../lib/html-spa/assets/sort-arrow-sprite.png | Bin 0 -> 138 bytes .../lib/html-spa/assets/spa.css | 298 + .../istanbul-reports/lib/html-spa/index.js | 176 + .../lib/html-spa/src/fileBreadcrumbs.js | 31 + .../lib/html-spa/src/filterToggle.js | 50 + .../lib/html-spa/src/flattenToggle.js | 25 + .../lib/html-spa/src/getChildData.js | 155 + .../lib/html-spa/src/index.js | 160 + .../lib/html-spa/src/routing.js | 52 + .../lib/html-spa/src/summaryHeader.js | 63 + .../lib/html-spa/src/summaryTableHeader.js | 130 + .../lib/html-spa/src/summaryTableLine.js | 159 + .../lib/html-spa/webpack.config.js | 22 + .../istanbul-reports/lib/html/annotator.js | 305 + .../istanbul-reports/lib/html/assets/base.css | 224 + .../lib/html/assets/block-navigation.js | 86 + .../lib/html/assets/favicon.png | Bin 0 -> 445 bytes .../lib/html/assets/sort-arrow-sprite.png | Bin 0 -> 138 bytes .../lib/html/assets/sorter.js | 209 + .../lib/html/assets/vendor/prettify.css | 1 + .../lib/html/assets/vendor/prettify.js | 1 + .../istanbul-reports/lib/html/index.js | 421 ++ .../lib/html/insertion-text.js | 114 + .../lib/json-summary/index.js | 56 + .../istanbul-reports/lib/json/index.js | 44 + .../istanbul-reports/lib/lcov/index.js | 33 + .../istanbul-reports/lib/lcovonly/index.js | 77 + .../istanbul-reports/lib/none/index.js | 10 + .../istanbul-reports/lib/teamcity/index.js | 67 + .../istanbul-reports/lib/text-lcov/index.js | 17 + .../lib/text-summary/index.js | 62 + .../istanbul-reports/lib/text/index.js | 298 + node_modules/istanbul-reports/package.json | 60 + node_modules/lz-utils/LICENSE | 21 + node_modules/lz-utils/README.md | 82 + node_modules/lz-utils/dist/browser.js | 2 + node_modules/lz-utils/dist/compress.js | 1 + .../lz-utils/dist/create-script-loader.js | 1 + node_modules/lz-utils/dist/decompress.js | 1 + node_modules/lz-utils/dist/deflate-sync.js | 1 + node_modules/lz-utils/dist/deflate.js | 1 + node_modules/lz-utils/dist/index.js | 9 + node_modules/lz-utils/dist/index.mjs | 19 + node_modules/lz-utils/dist/inflate-sync.js | 1 + .../lz-utils/dist/inflate-worker-data.js | 1 + node_modules/lz-utils/dist/inflate-worker.js | 1 + node_modules/lz-utils/dist/inflate.js | 2 + .../lz-utils/dist/script-loader-data.js | 1 + node_modules/lz-utils/dist/script-loader.js | 2 + node_modules/lz-utils/lib/browser.js | 7 + node_modules/lz-utils/lib/compress.js | 244 + .../lz-utils/lib/create-script-loader.js | 5 + node_modules/lz-utils/lib/decompress.js | 201 + node_modules/lz-utils/lib/deflate-sync.js | 9 + node_modules/lz-utils/lib/deflate.js | 16 + node_modules/lz-utils/lib/index.d.ts | 14 + node_modules/lz-utils/lib/index.js | 9 + node_modules/lz-utils/lib/index.mjs | 19 + node_modules/lz-utils/lib/inflate-sync.js | 18 + node_modules/lz-utils/lib/inflate-worker.js | 5 + node_modules/lz-utils/lib/inflate.js | 22 + node_modules/lz-utils/lib/script-loader.js | 6 + node_modules/lz-utils/package.json | 51 + node_modules/make-dir/index.d.ts | 66 + node_modules/make-dir/index.js | 155 + node_modules/make-dir/license | 9 + node_modules/make-dir/package.json | 63 + node_modules/make-dir/readme.md | 125 + .../monocart-coverage-reports/LICENSE | 21 + .../monocart-coverage-reports/README.md | 1186 ++++ .../README.zh-Hans.md | 1191 ++++ .../monocart-coverage-reports/lib/assets.js | 98 + .../monocart-coverage-reports/lib/cli.js | 251 + .../lib/client/cdp-client.js | 143 + .../lib/client/coverage-client.js | 322 + .../lib/client/ws-session.js | 63 + .../lib/converter/ast-visitor.js | 809 +++ .../lib/converter/ast.js | 364 + .../lib/converter/collect-source-maps.js | 287 + .../lib/converter/converter.js | 1823 +++++ .../lib/converter/find-original-range.js | 980 +++ .../lib/converter/flatten-source-maps.js | 186 + .../lib/converter/ignore.js | 225 + .../lib/converter/info-branch.js | 93 + .../lib/converter/info-function.js | 66 + .../lib/converter/info-statement.js | 43 + .../lib/converter/untested.js | 315 + .../lib/default/options.js | 107 + .../monocart-coverage-reports/lib/generate.js | 494 ++ .../monocart-coverage-reports/lib/index.d.ts | 606 ++ .../monocart-coverage-reports/lib/index.js | 280 + .../monocart-coverage-reports/lib/index.mjs | 9 + .../lib/istanbul/istanbul-summary.js | 73 + .../lib/istanbul/istanbul.js | 170 + .../lib/packages/monocart-coverage-assets.js | 4 + .../lib/packages/monocart-coverage-vendor.js | 35 + .../lib/platform/concurrency.js | 74 + .../lib/platform/share.js | 538 ++ .../lib/register/hooks.js | 58 + .../lib/register/hooks.mjs | 3 + .../lib/register/register.js | 4 + .../lib/register/register.mjs | 3 + .../lib/utils/dedupe.js | 123 + .../monocart-coverage-reports/lib/utils/gc.js | 9 + .../lib/utils/markdown.js | 132 + .../lib/utils/merge/merge.js | 439 ++ .../lib/utils/merge/range-tree.js | 123 + .../lib/utils/request.js | 86 + .../lib/utils/snapshot.js | 348 + .../lib/utils/source-path.js | 251 + .../lib/utils/util.js | 963 +++ .../lib/v8/v8-summary.js | 138 + .../monocart-coverage-reports/lib/v8/v8.js | 343 + .../monocart-coverage-reports/package.json | 133 + node_modules/monocart-locator/LICENSE | 21 + node_modules/monocart-locator/README.md | 26 + .../monocart-locator/lib/comment-parser.js | 154 + node_modules/monocart-locator/lib/index.d.ts | 61 + node_modules/monocart-locator/lib/index.js | 10 + node_modules/monocart-locator/lib/index.mjs | 3 + .../monocart-locator/lib/line-parser.js | 100 + node_modules/monocart-locator/lib/locator.js | 53 + node_modules/monocart-locator/package.json | 32 + node_modules/path-key/index.d.ts | 40 + node_modules/path-key/index.js | 16 + node_modules/path-key/license | 9 + node_modules/path-key/package.json | 39 + node_modules/path-key/readme.md | 61 + node_modules/semver/LICENSE | 15 + node_modules/semver/README.md | 665 ++ node_modules/semver/bin/semver.js | 191 + node_modules/semver/classes/comparator.js | 143 + node_modules/semver/classes/index.js | 7 + node_modules/semver/classes/range.js | 557 ++ node_modules/semver/classes/semver.js | 333 + node_modules/semver/functions/clean.js | 8 + node_modules/semver/functions/cmp.js | 54 + node_modules/semver/functions/coerce.js | 62 + .../semver/functions/compare-build.js | 9 + .../semver/functions/compare-loose.js | 5 + node_modules/semver/functions/compare.js | 7 + node_modules/semver/functions/diff.js | 60 + node_modules/semver/functions/eq.js | 5 + node_modules/semver/functions/gt.js | 5 + node_modules/semver/functions/gte.js | 5 + node_modules/semver/functions/inc.js | 21 + node_modules/semver/functions/lt.js | 5 + node_modules/semver/functions/lte.js | 5 + node_modules/semver/functions/major.js | 5 + node_modules/semver/functions/minor.js | 5 + node_modules/semver/functions/neq.js | 5 + node_modules/semver/functions/parse.js | 18 + node_modules/semver/functions/patch.js | 5 + node_modules/semver/functions/prerelease.js | 8 + node_modules/semver/functions/rcompare.js | 5 + node_modules/semver/functions/rsort.js | 5 + node_modules/semver/functions/satisfies.js | 12 + node_modules/semver/functions/sort.js | 5 + node_modules/semver/functions/valid.js | 8 + node_modules/semver/index.js | 91 + node_modules/semver/internal/constants.js | 37 + node_modules/semver/internal/debug.js | 11 + node_modules/semver/internal/identifiers.js | 29 + node_modules/semver/internal/lrucache.js | 42 + node_modules/semver/internal/parse-options.js | 17 + node_modules/semver/internal/re.js | 223 + node_modules/semver/package.json | 78 + node_modules/semver/preload.js | 4 + node_modules/semver/range.bnf | 16 + node_modules/semver/ranges/gtr.js | 6 + node_modules/semver/ranges/intersects.js | 9 + node_modules/semver/ranges/ltr.js | 6 + node_modules/semver/ranges/max-satisfying.js | 27 + node_modules/semver/ranges/min-satisfying.js | 26 + node_modules/semver/ranges/min-version.js | 63 + node_modules/semver/ranges/outside.js | 82 + node_modules/semver/ranges/simplify.js | 49 + node_modules/semver/ranges/subset.js | 249 + node_modules/semver/ranges/to-comparators.js | 10 + node_modules/semver/ranges/valid.js | 13 + node_modules/shebang-command/index.js | 19 + node_modules/shebang-command/license | 9 + node_modules/shebang-command/package.json | 34 + node_modules/shebang-command/readme.md | 34 + node_modules/shebang-regex/index.d.ts | 22 + node_modules/shebang-regex/index.js | 2 + node_modules/shebang-regex/license | 9 + node_modules/shebang-regex/package.json | 35 + node_modules/shebang-regex/readme.md | 33 + node_modules/signal-exit/LICENSE.txt | 16 + node_modules/signal-exit/README.md | 74 + .../signal-exit/dist/cjs/browser.d.ts | 12 + .../signal-exit/dist/cjs/browser.d.ts.map | 1 + node_modules/signal-exit/dist/cjs/browser.js | 10 + .../signal-exit/dist/cjs/browser.js.map | 1 + node_modules/signal-exit/dist/cjs/index.d.ts | 48 + .../signal-exit/dist/cjs/index.d.ts.map | 1 + node_modules/signal-exit/dist/cjs/index.js | 279 + .../signal-exit/dist/cjs/index.js.map | 1 + .../signal-exit/dist/cjs/package.json | 3 + .../signal-exit/dist/cjs/signals.d.ts | 29 + .../signal-exit/dist/cjs/signals.d.ts.map | 1 + node_modules/signal-exit/dist/cjs/signals.js | 42 + .../signal-exit/dist/cjs/signals.js.map | 1 + .../signal-exit/dist/mjs/browser.d.ts | 12 + .../signal-exit/dist/mjs/browser.d.ts.map | 1 + node_modules/signal-exit/dist/mjs/browser.js | 4 + .../signal-exit/dist/mjs/browser.js.map | 1 + node_modules/signal-exit/dist/mjs/index.d.ts | 48 + .../signal-exit/dist/mjs/index.d.ts.map | 1 + node_modules/signal-exit/dist/mjs/index.js | 275 + .../signal-exit/dist/mjs/index.js.map | 1 + .../signal-exit/dist/mjs/package.json | 3 + .../signal-exit/dist/mjs/signals.d.ts | 29 + .../signal-exit/dist/mjs/signals.d.ts.map | 1 + node_modules/signal-exit/dist/mjs/signals.js | 39 + .../signal-exit/dist/mjs/signals.js.map | 1 + node_modules/signal-exit/package.json | 106 + node_modules/supports-color/browser.js | 5 + node_modules/supports-color/index.js | 135 + node_modules/supports-color/license | 9 + node_modules/supports-color/package.json | 53 + node_modules/supports-color/readme.md | 76 + node_modules/which/CHANGELOG.md | 166 + node_modules/which/LICENSE | 15 + node_modules/which/README.md | 54 + node_modules/which/bin/node-which | 52 + node_modules/which/package.json | 43 + node_modules/which/which.js | 125 + package-lock.json | 287 + package.json | 5 + pages/login_page.py | 20 + requirements.txt | 1 + tests/test_logged_in.py | 10 + 396 files changed, 60585 insertions(+) create mode 100644 API/api.py create mode 120000 node_modules/.bin/acorn create mode 120000 node_modules/.bin/mcr create mode 120000 node_modules/.bin/node-which create mode 120000 node_modules/.bin/semver create mode 100644 node_modules/.package-lock.json create mode 100644 node_modules/acorn-loose/CHANGELOG.md create mode 100644 node_modules/acorn-loose/LICENSE create mode 100644 node_modules/acorn-loose/README.md create mode 100644 node_modules/acorn-loose/dist/acorn-loose.d.mts create mode 100644 node_modules/acorn-loose/dist/acorn-loose.d.ts create mode 100644 node_modules/acorn-loose/dist/acorn-loose.js create mode 100644 node_modules/acorn-loose/dist/acorn-loose.mjs create mode 100644 node_modules/acorn-loose/package.json create mode 100644 node_modules/acorn-walk/CHANGELOG.md create mode 100644 node_modules/acorn-walk/LICENSE create mode 100644 node_modules/acorn-walk/README.md create mode 100644 node_modules/acorn-walk/dist/walk.d.mts create mode 100644 node_modules/acorn-walk/dist/walk.d.ts create mode 100644 node_modules/acorn-walk/dist/walk.js create mode 100644 node_modules/acorn-walk/dist/walk.mjs create mode 100644 node_modules/acorn-walk/package.json create mode 100644 node_modules/acorn/CHANGELOG.md create mode 100644 node_modules/acorn/LICENSE create mode 100644 node_modules/acorn/README.md create mode 100755 node_modules/acorn/bin/acorn create mode 100644 node_modules/acorn/dist/acorn.d.mts create mode 100644 node_modules/acorn/dist/acorn.d.ts create mode 100644 node_modules/acorn/dist/acorn.js create mode 100644 node_modules/acorn/dist/acorn.mjs create mode 100644 node_modules/acorn/dist/bin.js create mode 100644 node_modules/acorn/package.json create mode 100644 node_modules/commander/LICENSE create mode 100644 node_modules/commander/Readme.md create mode 100644 node_modules/commander/esm.mjs create mode 100644 node_modules/commander/index.js create mode 100644 node_modules/commander/lib/argument.js create mode 100644 node_modules/commander/lib/command.js create mode 100644 node_modules/commander/lib/error.js create mode 100644 node_modules/commander/lib/help.js create mode 100644 node_modules/commander/lib/option.js create mode 100644 node_modules/commander/lib/suggestSimilar.js create mode 100644 node_modules/commander/package-support.json create mode 100644 node_modules/commander/package.json create mode 100644 node_modules/commander/typings/esm.d.mts create mode 100644 node_modules/commander/typings/index.d.ts create mode 100644 node_modules/console-grid/LICENSE create mode 100644 node_modules/console-grid/README.md create mode 100644 node_modules/console-grid/lib/comparers.js create mode 100644 node_modules/console-grid/lib/get-char-length.js create mode 100644 node_modules/console-grid/lib/index.d.ts create mode 100644 node_modules/console-grid/lib/index.js create mode 100644 node_modules/console-grid/lib/index.mjs create mode 100644 node_modules/console-grid/package.json create mode 100644 node_modules/cross-spawn/LICENSE create mode 100644 node_modules/cross-spawn/README.md create mode 100644 node_modules/cross-spawn/index.js create mode 100644 node_modules/cross-spawn/lib/enoent.js create mode 100644 node_modules/cross-spawn/lib/parse.js create mode 100644 node_modules/cross-spawn/lib/util/escape.js create mode 100644 node_modules/cross-spawn/lib/util/readShebang.js create mode 100644 node_modules/cross-spawn/lib/util/resolveCommand.js create mode 100644 node_modules/cross-spawn/package.json create mode 100644 node_modules/eight-colors/LICENSE create mode 100644 node_modules/eight-colors/README.md create mode 100644 node_modules/eight-colors/dist/eight-colors.js create mode 100644 node_modules/eight-colors/lib/index.d.ts create mode 100644 node_modules/eight-colors/lib/index.js create mode 100644 node_modules/eight-colors/lib/index.mjs create mode 100644 node_modules/eight-colors/package.json create mode 100644 node_modules/foreground-child/LICENSE create mode 100644 node_modules/foreground-child/README.md create mode 100644 node_modules/foreground-child/dist/commonjs/all-signals.d.ts create mode 100644 node_modules/foreground-child/dist/commonjs/all-signals.d.ts.map create mode 100644 node_modules/foreground-child/dist/commonjs/all-signals.js create mode 100644 node_modules/foreground-child/dist/commonjs/all-signals.js.map create mode 100644 node_modules/foreground-child/dist/commonjs/index.d.ts create mode 100644 node_modules/foreground-child/dist/commonjs/index.d.ts.map create mode 100644 node_modules/foreground-child/dist/commonjs/index.js create mode 100644 node_modules/foreground-child/dist/commonjs/index.js.map create mode 100644 node_modules/foreground-child/dist/commonjs/package.json create mode 100644 node_modules/foreground-child/dist/commonjs/proxy-signals.d.ts create mode 100644 node_modules/foreground-child/dist/commonjs/proxy-signals.d.ts.map create mode 100644 node_modules/foreground-child/dist/commonjs/proxy-signals.js create mode 100644 node_modules/foreground-child/dist/commonjs/proxy-signals.js.map create mode 100644 node_modules/foreground-child/dist/commonjs/watchdog.d.ts create mode 100644 node_modules/foreground-child/dist/commonjs/watchdog.d.ts.map create mode 100644 node_modules/foreground-child/dist/commonjs/watchdog.js create mode 100644 node_modules/foreground-child/dist/commonjs/watchdog.js.map create mode 100644 node_modules/foreground-child/dist/esm/all-signals.d.ts create mode 100644 node_modules/foreground-child/dist/esm/all-signals.d.ts.map create mode 100644 node_modules/foreground-child/dist/esm/all-signals.js create mode 100644 node_modules/foreground-child/dist/esm/all-signals.js.map create mode 100644 node_modules/foreground-child/dist/esm/index.d.ts create mode 100644 node_modules/foreground-child/dist/esm/index.d.ts.map create mode 100644 node_modules/foreground-child/dist/esm/index.js create mode 100644 node_modules/foreground-child/dist/esm/index.js.map create mode 100644 node_modules/foreground-child/dist/esm/package.json create mode 100644 node_modules/foreground-child/dist/esm/proxy-signals.d.ts create mode 100644 node_modules/foreground-child/dist/esm/proxy-signals.d.ts.map create mode 100644 node_modules/foreground-child/dist/esm/proxy-signals.js create mode 100644 node_modules/foreground-child/dist/esm/proxy-signals.js.map create mode 100644 node_modules/foreground-child/dist/esm/watchdog.d.ts create mode 100644 node_modules/foreground-child/dist/esm/watchdog.d.ts.map create mode 100644 node_modules/foreground-child/dist/esm/watchdog.js create mode 100644 node_modules/foreground-child/dist/esm/watchdog.js.map create mode 100644 node_modules/foreground-child/package.json create mode 100644 node_modules/has-flag/index.d.ts create mode 100644 node_modules/has-flag/index.js create mode 100644 node_modules/has-flag/license create mode 100644 node_modules/has-flag/package.json create mode 100644 node_modules/has-flag/readme.md create mode 100644 node_modules/html-escaper/LICENSE.txt create mode 100644 node_modules/html-escaper/README.md create mode 100644 node_modules/html-escaper/cjs/index.js create mode 100644 node_modules/html-escaper/cjs/package.json create mode 100644 node_modules/html-escaper/esm/index.js create mode 100644 node_modules/html-escaper/index.js create mode 100644 node_modules/html-escaper/min.js create mode 100644 node_modules/html-escaper/package.json create mode 100644 node_modules/html-escaper/test/index.js create mode 100644 node_modules/html-escaper/test/package.json create mode 100644 node_modules/isexe/.npmignore create mode 100644 node_modules/isexe/LICENSE create mode 100644 node_modules/isexe/README.md create mode 100644 node_modules/isexe/index.js create mode 100644 node_modules/isexe/mode.js create mode 100644 node_modules/isexe/package.json create mode 100644 node_modules/isexe/test/basic.js create mode 100644 node_modules/isexe/windows.js create mode 100644 node_modules/istanbul-lib-coverage/CHANGELOG.md create mode 100644 node_modules/istanbul-lib-coverage/LICENSE create mode 100644 node_modules/istanbul-lib-coverage/README.md create mode 100644 node_modules/istanbul-lib-coverage/index.js create mode 100644 node_modules/istanbul-lib-coverage/lib/coverage-map.js create mode 100644 node_modules/istanbul-lib-coverage/lib/coverage-summary.js create mode 100644 node_modules/istanbul-lib-coverage/lib/data-properties.js create mode 100644 node_modules/istanbul-lib-coverage/lib/file-coverage.js create mode 100644 node_modules/istanbul-lib-coverage/lib/percent.js create mode 100644 node_modules/istanbul-lib-coverage/package.json create mode 100644 node_modules/istanbul-lib-report/CHANGELOG.md create mode 100644 node_modules/istanbul-lib-report/LICENSE create mode 100644 node_modules/istanbul-lib-report/README.md create mode 100644 node_modules/istanbul-lib-report/index.js create mode 100644 node_modules/istanbul-lib-report/lib/context.js create mode 100644 node_modules/istanbul-lib-report/lib/file-writer.js create mode 100644 node_modules/istanbul-lib-report/lib/path.js create mode 100644 node_modules/istanbul-lib-report/lib/report-base.js create mode 100644 node_modules/istanbul-lib-report/lib/summarizer-factory.js create mode 100644 node_modules/istanbul-lib-report/lib/tree.js create mode 100644 node_modules/istanbul-lib-report/lib/watermarks.js create mode 100644 node_modules/istanbul-lib-report/lib/xml-writer.js create mode 100644 node_modules/istanbul-lib-report/package.json create mode 100644 node_modules/istanbul-reports/CHANGELOG.md create mode 100644 node_modules/istanbul-reports/LICENSE create mode 100644 node_modules/istanbul-reports/README.md create mode 100644 node_modules/istanbul-reports/index.js create mode 100644 node_modules/istanbul-reports/lib/clover/index.js create mode 100644 node_modules/istanbul-reports/lib/cobertura/index.js create mode 100644 node_modules/istanbul-reports/lib/html-spa/.babelrc create mode 100644 node_modules/istanbul-reports/lib/html-spa/assets/bundle.js create mode 100644 node_modules/istanbul-reports/lib/html-spa/assets/sort-arrow-sprite.png create mode 100644 node_modules/istanbul-reports/lib/html-spa/assets/spa.css create mode 100644 node_modules/istanbul-reports/lib/html-spa/index.js create mode 100644 node_modules/istanbul-reports/lib/html-spa/src/fileBreadcrumbs.js create mode 100644 node_modules/istanbul-reports/lib/html-spa/src/filterToggle.js create mode 100644 node_modules/istanbul-reports/lib/html-spa/src/flattenToggle.js create mode 100644 node_modules/istanbul-reports/lib/html-spa/src/getChildData.js create mode 100644 node_modules/istanbul-reports/lib/html-spa/src/index.js create mode 100644 node_modules/istanbul-reports/lib/html-spa/src/routing.js create mode 100644 node_modules/istanbul-reports/lib/html-spa/src/summaryHeader.js create mode 100644 node_modules/istanbul-reports/lib/html-spa/src/summaryTableHeader.js create mode 100644 node_modules/istanbul-reports/lib/html-spa/src/summaryTableLine.js create mode 100644 node_modules/istanbul-reports/lib/html-spa/webpack.config.js create mode 100644 node_modules/istanbul-reports/lib/html/annotator.js create mode 100644 node_modules/istanbul-reports/lib/html/assets/base.css create mode 100644 node_modules/istanbul-reports/lib/html/assets/block-navigation.js create mode 100644 node_modules/istanbul-reports/lib/html/assets/favicon.png create mode 100644 node_modules/istanbul-reports/lib/html/assets/sort-arrow-sprite.png create mode 100644 node_modules/istanbul-reports/lib/html/assets/sorter.js create mode 100644 node_modules/istanbul-reports/lib/html/assets/vendor/prettify.css create mode 100644 node_modules/istanbul-reports/lib/html/assets/vendor/prettify.js create mode 100644 node_modules/istanbul-reports/lib/html/index.js create mode 100644 node_modules/istanbul-reports/lib/html/insertion-text.js create mode 100644 node_modules/istanbul-reports/lib/json-summary/index.js create mode 100644 node_modules/istanbul-reports/lib/json/index.js create mode 100644 node_modules/istanbul-reports/lib/lcov/index.js create mode 100644 node_modules/istanbul-reports/lib/lcovonly/index.js create mode 100644 node_modules/istanbul-reports/lib/none/index.js create mode 100644 node_modules/istanbul-reports/lib/teamcity/index.js create mode 100644 node_modules/istanbul-reports/lib/text-lcov/index.js create mode 100644 node_modules/istanbul-reports/lib/text-summary/index.js create mode 100644 node_modules/istanbul-reports/lib/text/index.js create mode 100644 node_modules/istanbul-reports/package.json create mode 100644 node_modules/lz-utils/LICENSE create mode 100644 node_modules/lz-utils/README.md create mode 100644 node_modules/lz-utils/dist/browser.js create mode 100644 node_modules/lz-utils/dist/compress.js create mode 100644 node_modules/lz-utils/dist/create-script-loader.js create mode 100644 node_modules/lz-utils/dist/decompress.js create mode 100644 node_modules/lz-utils/dist/deflate-sync.js create mode 100644 node_modules/lz-utils/dist/deflate.js create mode 100644 node_modules/lz-utils/dist/index.js create mode 100644 node_modules/lz-utils/dist/index.mjs create mode 100644 node_modules/lz-utils/dist/inflate-sync.js create mode 100644 node_modules/lz-utils/dist/inflate-worker-data.js create mode 100644 node_modules/lz-utils/dist/inflate-worker.js create mode 100644 node_modules/lz-utils/dist/inflate.js create mode 100644 node_modules/lz-utils/dist/script-loader-data.js create mode 100644 node_modules/lz-utils/dist/script-loader.js create mode 100644 node_modules/lz-utils/lib/browser.js create mode 100644 node_modules/lz-utils/lib/compress.js create mode 100644 node_modules/lz-utils/lib/create-script-loader.js create mode 100644 node_modules/lz-utils/lib/decompress.js create mode 100644 node_modules/lz-utils/lib/deflate-sync.js create mode 100644 node_modules/lz-utils/lib/deflate.js create mode 100644 node_modules/lz-utils/lib/index.d.ts create mode 100644 node_modules/lz-utils/lib/index.js create mode 100644 node_modules/lz-utils/lib/index.mjs create mode 100644 node_modules/lz-utils/lib/inflate-sync.js create mode 100644 node_modules/lz-utils/lib/inflate-worker.js create mode 100644 node_modules/lz-utils/lib/inflate.js create mode 100644 node_modules/lz-utils/lib/script-loader.js create mode 100644 node_modules/lz-utils/package.json create mode 100644 node_modules/make-dir/index.d.ts create mode 100644 node_modules/make-dir/index.js create mode 100644 node_modules/make-dir/license create mode 100644 node_modules/make-dir/package.json create mode 100644 node_modules/make-dir/readme.md create mode 100644 node_modules/monocart-coverage-reports/LICENSE create mode 100644 node_modules/monocart-coverage-reports/README.md create mode 100644 node_modules/monocart-coverage-reports/README.zh-Hans.md create mode 100644 node_modules/monocart-coverage-reports/lib/assets.js create mode 100755 node_modules/monocart-coverage-reports/lib/cli.js create mode 100644 node_modules/monocart-coverage-reports/lib/client/cdp-client.js create mode 100644 node_modules/monocart-coverage-reports/lib/client/coverage-client.js create mode 100644 node_modules/monocart-coverage-reports/lib/client/ws-session.js create mode 100644 node_modules/monocart-coverage-reports/lib/converter/ast-visitor.js create mode 100644 node_modules/monocart-coverage-reports/lib/converter/ast.js create mode 100644 node_modules/monocart-coverage-reports/lib/converter/collect-source-maps.js create mode 100644 node_modules/monocart-coverage-reports/lib/converter/converter.js create mode 100644 node_modules/monocart-coverage-reports/lib/converter/find-original-range.js create mode 100644 node_modules/monocart-coverage-reports/lib/converter/flatten-source-maps.js create mode 100644 node_modules/monocart-coverage-reports/lib/converter/ignore.js create mode 100644 node_modules/monocart-coverage-reports/lib/converter/info-branch.js create mode 100644 node_modules/monocart-coverage-reports/lib/converter/info-function.js create mode 100644 node_modules/monocart-coverage-reports/lib/converter/info-statement.js create mode 100644 node_modules/monocart-coverage-reports/lib/converter/untested.js create mode 100644 node_modules/monocart-coverage-reports/lib/default/options.js create mode 100644 node_modules/monocart-coverage-reports/lib/generate.js create mode 100644 node_modules/monocart-coverage-reports/lib/index.d.ts create mode 100644 node_modules/monocart-coverage-reports/lib/index.js create mode 100644 node_modules/monocart-coverage-reports/lib/index.mjs create mode 100644 node_modules/monocart-coverage-reports/lib/istanbul/istanbul-summary.js create mode 100644 node_modules/monocart-coverage-reports/lib/istanbul/istanbul.js create mode 100644 node_modules/monocart-coverage-reports/lib/packages/monocart-coverage-assets.js create mode 100644 node_modules/monocart-coverage-reports/lib/packages/monocart-coverage-vendor.js create mode 100644 node_modules/monocart-coverage-reports/lib/platform/concurrency.js create mode 100644 node_modules/monocart-coverage-reports/lib/platform/share.js create mode 100644 node_modules/monocart-coverage-reports/lib/register/hooks.js create mode 100644 node_modules/monocart-coverage-reports/lib/register/hooks.mjs create mode 100644 node_modules/monocart-coverage-reports/lib/register/register.js create mode 100644 node_modules/monocart-coverage-reports/lib/register/register.mjs create mode 100644 node_modules/monocart-coverage-reports/lib/utils/dedupe.js create mode 100644 node_modules/monocart-coverage-reports/lib/utils/gc.js create mode 100644 node_modules/monocart-coverage-reports/lib/utils/markdown.js create mode 100644 node_modules/monocart-coverage-reports/lib/utils/merge/merge.js create mode 100644 node_modules/monocart-coverage-reports/lib/utils/merge/range-tree.js create mode 100644 node_modules/monocart-coverage-reports/lib/utils/request.js create mode 100644 node_modules/monocart-coverage-reports/lib/utils/snapshot.js create mode 100644 node_modules/monocart-coverage-reports/lib/utils/source-path.js create mode 100644 node_modules/monocart-coverage-reports/lib/utils/util.js create mode 100644 node_modules/monocart-coverage-reports/lib/v8/v8-summary.js create mode 100644 node_modules/monocart-coverage-reports/lib/v8/v8.js create mode 100644 node_modules/monocart-coverage-reports/package.json create mode 100644 node_modules/monocart-locator/LICENSE create mode 100644 node_modules/monocart-locator/README.md create mode 100644 node_modules/monocart-locator/lib/comment-parser.js create mode 100644 node_modules/monocart-locator/lib/index.d.ts create mode 100644 node_modules/monocart-locator/lib/index.js create mode 100644 node_modules/monocart-locator/lib/index.mjs create mode 100644 node_modules/monocart-locator/lib/line-parser.js create mode 100644 node_modules/monocart-locator/lib/locator.js create mode 100644 node_modules/monocart-locator/package.json create mode 100644 node_modules/path-key/index.d.ts create mode 100644 node_modules/path-key/index.js create mode 100644 node_modules/path-key/license create mode 100644 node_modules/path-key/package.json create mode 100644 node_modules/path-key/readme.md create mode 100644 node_modules/semver/LICENSE create mode 100644 node_modules/semver/README.md create mode 100755 node_modules/semver/bin/semver.js create mode 100644 node_modules/semver/classes/comparator.js create mode 100644 node_modules/semver/classes/index.js create mode 100644 node_modules/semver/classes/range.js create mode 100644 node_modules/semver/classes/semver.js create mode 100644 node_modules/semver/functions/clean.js create mode 100644 node_modules/semver/functions/cmp.js create mode 100644 node_modules/semver/functions/coerce.js create mode 100644 node_modules/semver/functions/compare-build.js create mode 100644 node_modules/semver/functions/compare-loose.js create mode 100644 node_modules/semver/functions/compare.js create mode 100644 node_modules/semver/functions/diff.js create mode 100644 node_modules/semver/functions/eq.js create mode 100644 node_modules/semver/functions/gt.js create mode 100644 node_modules/semver/functions/gte.js create mode 100644 node_modules/semver/functions/inc.js create mode 100644 node_modules/semver/functions/lt.js create mode 100644 node_modules/semver/functions/lte.js create mode 100644 node_modules/semver/functions/major.js create mode 100644 node_modules/semver/functions/minor.js create mode 100644 node_modules/semver/functions/neq.js create mode 100644 node_modules/semver/functions/parse.js create mode 100644 node_modules/semver/functions/patch.js create mode 100644 node_modules/semver/functions/prerelease.js create mode 100644 node_modules/semver/functions/rcompare.js create mode 100644 node_modules/semver/functions/rsort.js create mode 100644 node_modules/semver/functions/satisfies.js create mode 100644 node_modules/semver/functions/sort.js create mode 100644 node_modules/semver/functions/valid.js create mode 100644 node_modules/semver/index.js create mode 100644 node_modules/semver/internal/constants.js create mode 100644 node_modules/semver/internal/debug.js create mode 100644 node_modules/semver/internal/identifiers.js create mode 100644 node_modules/semver/internal/lrucache.js create mode 100644 node_modules/semver/internal/parse-options.js create mode 100644 node_modules/semver/internal/re.js create mode 100644 node_modules/semver/package.json create mode 100644 node_modules/semver/preload.js create mode 100644 node_modules/semver/range.bnf create mode 100644 node_modules/semver/ranges/gtr.js create mode 100644 node_modules/semver/ranges/intersects.js create mode 100644 node_modules/semver/ranges/ltr.js create mode 100644 node_modules/semver/ranges/max-satisfying.js create mode 100644 node_modules/semver/ranges/min-satisfying.js create mode 100644 node_modules/semver/ranges/min-version.js create mode 100644 node_modules/semver/ranges/outside.js create mode 100644 node_modules/semver/ranges/simplify.js create mode 100644 node_modules/semver/ranges/subset.js create mode 100644 node_modules/semver/ranges/to-comparators.js create mode 100644 node_modules/semver/ranges/valid.js create mode 100644 node_modules/shebang-command/index.js create mode 100644 node_modules/shebang-command/license create mode 100644 node_modules/shebang-command/package.json create mode 100644 node_modules/shebang-command/readme.md create mode 100644 node_modules/shebang-regex/index.d.ts create mode 100644 node_modules/shebang-regex/index.js create mode 100644 node_modules/shebang-regex/license create mode 100644 node_modules/shebang-regex/package.json create mode 100644 node_modules/shebang-regex/readme.md create mode 100644 node_modules/signal-exit/LICENSE.txt create mode 100644 node_modules/signal-exit/README.md create mode 100644 node_modules/signal-exit/dist/cjs/browser.d.ts create mode 100644 node_modules/signal-exit/dist/cjs/browser.d.ts.map create mode 100644 node_modules/signal-exit/dist/cjs/browser.js create mode 100644 node_modules/signal-exit/dist/cjs/browser.js.map create mode 100644 node_modules/signal-exit/dist/cjs/index.d.ts create mode 100644 node_modules/signal-exit/dist/cjs/index.d.ts.map create mode 100644 node_modules/signal-exit/dist/cjs/index.js create mode 100644 node_modules/signal-exit/dist/cjs/index.js.map create mode 100644 node_modules/signal-exit/dist/cjs/package.json create mode 100644 node_modules/signal-exit/dist/cjs/signals.d.ts create mode 100644 node_modules/signal-exit/dist/cjs/signals.d.ts.map create mode 100644 node_modules/signal-exit/dist/cjs/signals.js create mode 100644 node_modules/signal-exit/dist/cjs/signals.js.map create mode 100644 node_modules/signal-exit/dist/mjs/browser.d.ts create mode 100644 node_modules/signal-exit/dist/mjs/browser.d.ts.map create mode 100644 node_modules/signal-exit/dist/mjs/browser.js create mode 100644 node_modules/signal-exit/dist/mjs/browser.js.map create mode 100644 node_modules/signal-exit/dist/mjs/index.d.ts create mode 100644 node_modules/signal-exit/dist/mjs/index.d.ts.map create mode 100644 node_modules/signal-exit/dist/mjs/index.js create mode 100644 node_modules/signal-exit/dist/mjs/index.js.map create mode 100644 node_modules/signal-exit/dist/mjs/package.json create mode 100644 node_modules/signal-exit/dist/mjs/signals.d.ts create mode 100644 node_modules/signal-exit/dist/mjs/signals.d.ts.map create mode 100644 node_modules/signal-exit/dist/mjs/signals.js create mode 100644 node_modules/signal-exit/dist/mjs/signals.js.map create mode 100644 node_modules/signal-exit/package.json create mode 100644 node_modules/supports-color/browser.js create mode 100644 node_modules/supports-color/index.js create mode 100644 node_modules/supports-color/license create mode 100644 node_modules/supports-color/package.json create mode 100644 node_modules/supports-color/readme.md create mode 100644 node_modules/which/CHANGELOG.md create mode 100644 node_modules/which/LICENSE create mode 100644 node_modules/which/README.md create mode 100755 node_modules/which/bin/node-which create mode 100644 node_modules/which/package.json create mode 100644 node_modules/which/which.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 pages/login_page.py diff --git a/API/api.py b/API/api.py new file mode 100644 index 0000000..9f75567 --- /dev/null +++ b/API/api.py @@ -0,0 +1,7 @@ +import requests + +for i in range(5): + url = "https://dog.ceo/api/breeds/image/random" + response = requests.get(url) + data = response.json() + print(data["message"]) \ No newline at end of file diff --git a/README.md b/README.md index ca3295a..21e332c 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,9 @@ A modular, pytest-based **Playwright (Python)** framework for web UI testing. ```bash python scripts/bootstrap_signup.py --name "Jane Doe" --email "jane@example.com" --password "StrongPass123" --storage "auth/storage_state.json" ``` + ```bash + python -m scripts.bootstrap_signup --name "Jane Doe" --email "test@example.com" --password "StrongPass123" --storage "auth/storage_state.json" + ``` 4. **Verify session works (smoke test)** ```bash @@ -74,6 +77,8 @@ playwright install Run the bootstrap script (signup → login → save session): ```bash python scripts/bootstrap_signup.py --name "Jane Doe" --email "jane@example.com" --password "StrongPass123" --storage "auth/storage_state.json" +```bash +python -m scripts.bootstrap_signup --name "Jane Doe" --email "test@example.com" --password "StrongPass123" --storage "auth/storage_state.json" ``` This will: - Open the demo **Sign Up** page (`/signup.html`) diff --git a/node_modules/.bin/acorn b/node_modules/.bin/acorn new file mode 120000 index 0000000..cf76760 --- /dev/null +++ b/node_modules/.bin/acorn @@ -0,0 +1 @@ +../acorn/bin/acorn \ No newline at end of file diff --git a/node_modules/.bin/mcr b/node_modules/.bin/mcr new file mode 120000 index 0000000..b7b9e27 --- /dev/null +++ b/node_modules/.bin/mcr @@ -0,0 +1 @@ +../monocart-coverage-reports/lib/cli.js \ No newline at end of file diff --git a/node_modules/.bin/node-which b/node_modules/.bin/node-which new file mode 120000 index 0000000..6f8415e --- /dev/null +++ b/node_modules/.bin/node-which @@ -0,0 +1 @@ +../which/bin/node-which \ No newline at end of file diff --git a/node_modules/.bin/semver b/node_modules/.bin/semver new file mode 120000 index 0000000..5aaadf4 --- /dev/null +++ b/node_modules/.bin/semver @@ -0,0 +1 @@ +../semver/bin/semver.js \ No newline at end of file diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json new file mode 100644 index 0000000..1fcc1e9 --- /dev/null +++ b/node_modules/.package-lock.json @@ -0,0 +1,282 @@ +{ + "name": "playwright_python_framework", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-loose": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/acorn-loose/-/acorn-loose-8.5.2.tgz", + "integrity": "sha512-PPvV6g8UGMGgjrMu+n/f9E/tCSkNQ2Y97eFvuVdJfG11+xdIeDcLyNdC8SHcrHbRqkfwLASdplyR6B6sKM1U4A==", + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/console-grid": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/console-grid/-/console-grid-2.2.3.tgz", + "integrity": "sha512-+mecFacaFxGl+1G31IsCx41taUXuW2FxX+4xIE0TIPhgML+Jb9JFcBWGhhWerd1/vhScubdmHqTwOhB0KCUUAg==", + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eight-colors": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/eight-colors/-/eight-colors-1.3.3.tgz", + "integrity": "sha512-4B54S2Qi4pJjeHmCbDIsveQZWQ/TSSQng4ixYJ9/SYHHpeS5nYK0pzcHvWzWUfRsvJQjwoIENhAwqg59thQceg==", + "license": "MIT" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lz-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lz-utils/-/lz-utils-2.1.0.tgz", + "integrity": "sha512-CMkfimAypidTtWjNDxY8a1bc1mJdyEh04V2FfEQ5Zh8Nx4v7k850EYa+dOWGn9hKG5xOyHP5MkuduAZCTHRvJw==", + "license": "MIT" + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/monocart-coverage-reports": { + "version": "2.12.9", + "resolved": "https://registry.npmjs.org/monocart-coverage-reports/-/monocart-coverage-reports-2.12.9.tgz", + "integrity": "sha512-vtFqbC3Egl4nVa1FSIrQvMPO6HZtb9lo+3IW7/crdvrLNW2IH8lUsxaK0TsKNmMO2mhFWwqQywLV2CZelqPgwA==", + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0", + "acorn-loose": "^8.5.2", + "acorn-walk": "^8.3.4", + "commander": "^14.0.0", + "console-grid": "^2.2.3", + "eight-colors": "^1.3.1", + "foreground-child": "^3.3.1", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.2.0", + "lz-utils": "^2.1.0", + "monocart-locator": "^1.0.2" + }, + "bin": { + "mcr": "lib/cli.js" + } + }, + "node_modules/monocart-locator": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/monocart-locator/-/monocart-locator-1.0.2.tgz", + "integrity": "sha512-v8W5hJLcWMIxLCcSi/MHh+VeefI+ycFmGz23Froer9QzWjrbg4J3gFJBuI/T1VLNoYxF47bVPPxq8ZlNX4gVCw==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "license": "MIT", + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + } + } +} diff --git a/node_modules/acorn-loose/CHANGELOG.md b/node_modules/acorn-loose/CHANGELOG.md new file mode 100644 index 0000000..c0b9098 --- /dev/null +++ b/node_modules/acorn-loose/CHANGELOG.md @@ -0,0 +1,165 @@ +## 8.5.2 (2025-07-01) + +### Bug fixes + +Use the proper version of `acorn` as a dependency. + +## 8.5.1 (2025-06-08) + +### Bug fixes + +Handle tokenizer exceptions raised by invalid numeric separators. + +## 8.5.0 (2025-04-17) + +### New features + +Support ES2025 import attributes. + +## 8.4.0 (2023-10-26) + +### Bug fixes + +Fix an issue where a slash after a call to a propery named the same as some keywords would be tokenized as a regular expression. + +Fix a bug where the parser would raise an error when an invalid escape was included in an identifier after a keyword. + +### New features + +Use a set of new, much more precise, TypeScript types. + +## 8.3.0 (2021-12-27) + +### New features + +Support quoted export names. + +Support class private fields with the `in` operator. + +### Bug fixes + +Fix a bug that caused semicolons after `export *` statements to be parsed as empty statements. + +## 8.2.1 (2021-09-06) + +### Bug fixes + +Depend on the proper version of acorn. + +## 8.2.0 (2021-09-06) + +### New features + +Add support for ES2022 class static blocks. + +## 8.1.0 (2021-04-24) + +### New features + +Add support for ES2022 class fields and private methods. + +## 8.0.2 (2021-01-25) + +### Bug fixes + +Adjust package.json to work with Node 12.16.0 and 13.0-13.6. + +## 8.0.1 (2020-10-11) + +### Bug fixes + +Allow `for await` at the top level. + +## 8.0.0 (2020-08-12) + +### New features + +The package can now be loaded directly as an ECMAScript module in node 13+. + +### Breaking changes + +The `ecmaVersion` option is now required. For the moment, omitting it will still work with a warning, but that will change in a future release. + +## 7.1.0 (2020-06-11) + +### Bug fixes + +Fix various issues in regexp validation. + +### New features + +Add support for `import.meta`. + +Add support for optional chaining (`?.`) and nullish coalescing (`??`). + +Support `export * as ns from "source"`. + +## 7.0.0 (2019-08-12) + +### Breaking changes + +Changes the node format for dynamic imports to use the `ImportExpression` node type, as defined in [ESTree](https://github.com/estree/estree/blob/master/es2020.md#importexpression). + +## 6.1.0 (2019-07-04) + +### New features + +Support bigint syntax. + +Support dynamic import. + +## 6.0.0 (2018-09-14) + +### Breaking changes + +This module has been moved into its own package, `acorn-loose`. + +Plugins work differently, and will have to be rewritten to work with this version. + +The `parse_dammit` function is now simply called `parse`. + +## 5.1.0 (2017-07-05) + +### Bug fixes + +Make the ES module version of the loose parser actually work. + +## 4.0.4 (2016-12-19) + +### Bug fixes + +Fix issue with loading acorn_loose.js with an AMD loader. + +## 3.2.0 (2016-06-07) + +### Bug fixes + +Don't crash when the loose parser is called without options object. + +## 3.1.0 (2016-04-18) + +### Bug fixes + +Fix issue where the loose parser created invalid TemplateElement nodes for unclosed template literals. + +## 2.7.0 (2016-01-04) + +### Fixes + +Make sure the loose parser always attaches a `local` property to `ImportNamespaceSpecifier` nodes. + +## 2.6.4 (2015-11-12) + +### Fixes + +Fix crash in loose parser when parsing invalid object pattern. + +### New features + +Support plugins in the loose parser. + +## 2.5.0 (2015-10-27) + +### Fixes + +In the loose parser, don't allow non-string-literals as import sources. diff --git a/node_modules/acorn-loose/LICENSE b/node_modules/acorn-loose/LICENSE new file mode 100644 index 0000000..d6be6db --- /dev/null +++ b/node_modules/acorn-loose/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (C) 2012-2020 by various contributors (see AUTHORS) + +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/node_modules/acorn-loose/README.md b/node_modules/acorn-loose/README.md new file mode 100644 index 0000000..ac1d2d3 --- /dev/null +++ b/node_modules/acorn-loose/README.md @@ -0,0 +1,64 @@ +# Acorn loose parser + +An error-tolerant JavaScript parser written in JavaScript. + +This parser will parse _any_ text into an +[ESTree](https://github.com/estree/estree) syntax tree that is a +reasonable approximation of what it might mean as a JavaScript +program. + +It will, to recover from missing brackets, treat whitespace as +significant, which has the downside that it might mis-parse a valid +but weirdly indented file. It is recommended to always try a parse +with the regular `acorn` parser first, and only fall back to this +parser when that one finds syntax errors. + +## Community + +Acorn is open source software released under an +[MIT license](https://github.com/acornjs/acorn/blob/master/acorn-loose/LICENSE). + +You are welcome to [report +bugs](https://github.com/acornjs/acorn/issues) or create pull requests +on [github](https://github.com/acornjs/acorn). + +## Installation + +The easiest way to install acorn-loose is from [`npm`](https://www.npmjs.com/): + +```sh +npm install acorn-loose +``` + +Alternately, you can download the source and build acorn yourself: + +```sh +git clone https://github.com/acornjs/acorn.git +cd acorn +npm install +``` + +## Interface + +**parse**`(input, options)` takes an input string and a set of options +(the same options as +[acorn](https://github.com/acornjs/acorn/blob/master/acorn/README.md) +takes), and returns a syntax tree, even if the code isn't +syntactically valid. It'll insert identifier nodes with name `"✖"` as +placeholders in places where it can't make sense of the input. Depends +on the `acorn` package, because it uses the same tokenizer. + +```javascript +var acornLoose = require("acorn-loose"); +console.log(acornLoose.parse("1 / * 4 )[2]", {ecmaVersion: 2020})); +``` + +Like the regular parser, the loose parser supports plugins. You can +take the **`LooseParser`** class exported by the module, and call its +static `extend` method with one or more plugins to get a customized +parser class. The class has a static `parse` method that acts like the +top-level `parse` method. + +**isDummy**`(node)` takes a `Node` and returns `true` if it is a dummy node +inserted by the parser. The function performs a simple equality check on the +node's name. diff --git a/node_modules/acorn-loose/dist/acorn-loose.d.mts b/node_modules/acorn-loose/dist/acorn-loose.d.mts new file mode 100644 index 0000000..b8f07d3 --- /dev/null +++ b/node_modules/acorn-loose/dist/acorn-loose.d.mts @@ -0,0 +1,10 @@ +import * as acorn from "acorn" + +export const LooseParser: typeof acorn.Parser + +export function parse (input: string, options: acorn.Options): acorn.Program + +/** + * returns `true` if it is a dummy node inserted by the parser. The function performs a simple equality check on the node's name. + */ +export function isDummy(node: acorn.Node): boolean diff --git a/node_modules/acorn-loose/dist/acorn-loose.d.ts b/node_modules/acorn-loose/dist/acorn-loose.d.ts new file mode 100644 index 0000000..b8f07d3 --- /dev/null +++ b/node_modules/acorn-loose/dist/acorn-loose.d.ts @@ -0,0 +1,10 @@ +import * as acorn from "acorn" + +export const LooseParser: typeof acorn.Parser + +export function parse (input: string, options: acorn.Options): acorn.Program + +/** + * returns `true` if it is a dummy node inserted by the parser. The function performs a simple equality check on the node's name. + */ +export function isDummy(node: acorn.Node): boolean diff --git a/node_modules/acorn-loose/dist/acorn-loose.js b/node_modules/acorn-loose/dist/acorn-loose.js new file mode 100644 index 0000000..57391f0 --- /dev/null +++ b/node_modules/acorn-loose/dist/acorn-loose.js @@ -0,0 +1,1638 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('acorn')) : + typeof define === 'function' && define.amd ? define(['exports', 'acorn'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.acorn = global.acorn || {}, global.acorn.loose = {}), global.acorn)); +})(this, (function (exports, acorn) { 'use strict'; + + var dummyValue = "✖"; + + function isDummy(node) { return node.name === dummyValue } + + function noop() {} + + var LooseParser = function LooseParser(input, options) { + if ( options === void 0 ) options = {}; + + this.toks = this.constructor.BaseParser.tokenizer(input, options); + this.options = this.toks.options; + this.input = this.toks.input; + this.tok = this.last = {type: acorn.tokTypes.eof, start: 0, end: 0}; + this.tok.validateRegExpFlags = noop; + this.tok.validateRegExpPattern = noop; + if (this.options.locations) { + var here = this.toks.curPosition(); + this.tok.loc = new acorn.SourceLocation(this.toks, here, here); + } + this.ahead = []; // Tokens ahead + this.context = []; // Indentation contexted + this.curIndent = 0; + this.curLineStart = 0; + this.nextLineStart = this.lineEnd(this.curLineStart) + 1; + this.inAsync = false; + this.inGenerator = false; + this.inFunction = false; + }; + + LooseParser.prototype.startNode = function startNode () { + return new acorn.Node(this.toks, this.tok.start, this.options.locations ? this.tok.loc.start : null) + }; + + LooseParser.prototype.storeCurrentPos = function storeCurrentPos () { + return this.options.locations ? [this.tok.start, this.tok.loc.start] : this.tok.start + }; + + LooseParser.prototype.startNodeAt = function startNodeAt (pos) { + if (this.options.locations) { + return new acorn.Node(this.toks, pos[0], pos[1]) + } else { + return new acorn.Node(this.toks, pos) + } + }; + + LooseParser.prototype.finishNode = function finishNode (node, type) { + node.type = type; + node.end = this.last.end; + if (this.options.locations) + { node.loc.end = this.last.loc.end; } + if (this.options.ranges) + { node.range[1] = this.last.end; } + return node + }; + + LooseParser.prototype.dummyNode = function dummyNode (type) { + var dummy = this.startNode(); + dummy.type = type; + dummy.end = dummy.start; + if (this.options.locations) + { dummy.loc.end = dummy.loc.start; } + if (this.options.ranges) + { dummy.range[1] = dummy.start; } + this.last = {type: acorn.tokTypes.name, start: dummy.start, end: dummy.start, loc: dummy.loc}; + return dummy + }; + + LooseParser.prototype.dummyIdent = function dummyIdent () { + var dummy = this.dummyNode("Identifier"); + dummy.name = dummyValue; + return dummy + }; + + LooseParser.prototype.dummyString = function dummyString () { + var dummy = this.dummyNode("Literal"); + dummy.value = dummy.raw = dummyValue; + return dummy + }; + + LooseParser.prototype.eat = function eat (type) { + if (this.tok.type === type) { + this.next(); + return true + } else { + return false + } + }; + + LooseParser.prototype.isContextual = function isContextual (name) { + return this.tok.type === acorn.tokTypes.name && this.tok.value === name + }; + + LooseParser.prototype.eatContextual = function eatContextual (name) { + return this.tok.value === name && this.eat(acorn.tokTypes.name) + }; + + LooseParser.prototype.canInsertSemicolon = function canInsertSemicolon () { + return this.tok.type === acorn.tokTypes.eof || this.tok.type === acorn.tokTypes.braceR || + acorn.lineBreak.test(this.input.slice(this.last.end, this.tok.start)) + }; + + LooseParser.prototype.semicolon = function semicolon () { + return this.eat(acorn.tokTypes.semi) + }; + + LooseParser.prototype.expect = function expect (type) { + if (this.eat(type)) { return true } + for (var i = 1; i <= 2; i++) { + if (this.lookAhead(i).type === type) { + for (var j = 0; j < i; j++) { this.next(); } + return true + } + } + }; + + LooseParser.prototype.pushCx = function pushCx () { + this.context.push(this.curIndent); + }; + + LooseParser.prototype.popCx = function popCx () { + this.curIndent = this.context.pop(); + }; + + LooseParser.prototype.lineEnd = function lineEnd (pos) { + while (pos < this.input.length && !acorn.isNewLine(this.input.charCodeAt(pos))) { ++pos; } + return pos + }; + + LooseParser.prototype.indentationAfter = function indentationAfter (pos) { + for (var count = 0;; ++pos) { + var ch = this.input.charCodeAt(pos); + if (ch === 32) { ++count; } + else if (ch === 9) { count += this.options.tabSize; } + else { return count } + } + }; + + LooseParser.prototype.closes = function closes (closeTok, indent, line, blockHeuristic) { + if (this.tok.type === closeTok || this.tok.type === acorn.tokTypes.eof) { return true } + return line !== this.curLineStart && this.curIndent < indent && this.tokenStartsLine() && + (!blockHeuristic || this.nextLineStart >= this.input.length || + this.indentationAfter(this.nextLineStart) < indent) + }; + + LooseParser.prototype.tokenStartsLine = function tokenStartsLine () { + for (var p = this.tok.start - 1; p >= this.curLineStart; --p) { + var ch = this.input.charCodeAt(p); + if (ch !== 9 && ch !== 32) { return false } + } + return true + }; + + LooseParser.prototype.extend = function extend (name, f) { + this[name] = f(this[name]); + }; + + LooseParser.prototype.parse = function parse () { + this.next(); + return this.parseTopLevel() + }; + + LooseParser.extend = function extend () { + var plugins = [], len = arguments.length; + while ( len-- ) plugins[ len ] = arguments[ len ]; + + var cls = this; + for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); } + return cls + }; + + LooseParser.parse = function parse (input, options) { + return new this(input, options).parse() + }; + + // Allows plugins to extend the base parser / tokenizer used + LooseParser.BaseParser = acorn.Parser; + + var lp$2 = LooseParser.prototype; + + function isSpace(ch) { + return (ch < 14 && ch > 8) || ch === 32 || ch === 160 || acorn.isNewLine(ch) + } + + lp$2.next = function() { + this.last = this.tok; + if (this.ahead.length) + { this.tok = this.ahead.shift(); } + else + { this.tok = this.readToken(); } + + if (this.tok.start >= this.nextLineStart) { + while (this.tok.start >= this.nextLineStart) { + this.curLineStart = this.nextLineStart; + this.nextLineStart = this.lineEnd(this.curLineStart) + 1; + } + this.curIndent = this.indentationAfter(this.curLineStart); + } + }; + + lp$2.readToken = function() { + for (;;) { + try { + this.toks.next(); + if (this.toks.type === acorn.tokTypes.dot && + this.input.substr(this.toks.end, 1) === "." && + this.options.ecmaVersion >= 6) { + this.toks.end++; + this.toks.type = acorn.tokTypes.ellipsis; + } + return new acorn.Token(this.toks) + } catch (e) { + if (!(e instanceof SyntaxError)) { throw e } + + // Try to skip some text, based on the error message, and then continue + var msg = e.message, pos = e.raisedAt, replace = true; + if (/unterminated/i.test(msg)) { + pos = this.lineEnd(e.pos + 1); + if (/string/.test(msg)) { + replace = {start: e.pos, end: pos, type: acorn.tokTypes.string, value: this.input.slice(e.pos + 1, pos)}; + } else if (/regular expr/i.test(msg)) { + var re = this.input.slice(e.pos, pos); + try { re = new RegExp(re); } catch (e$1) { /* ignore compilation error due to new syntax */ } + replace = {start: e.pos, end: pos, type: acorn.tokTypes.regexp, value: re}; + } else if (/template/.test(msg)) { + replace = { + start: e.pos, + end: pos, + type: acorn.tokTypes.template, + value: this.input.slice(e.pos, pos) + }; + } else { + replace = false; + } + } else if (/invalid (unicode|regexp|number)|expecting unicode|octal literal|is reserved|directly after number|expected number in radix|numeric separator/i.test(msg)) { + while (pos < this.input.length && !isSpace(this.input.charCodeAt(pos))) { ++pos; } + } else if (/character escape|expected hexadecimal/i.test(msg)) { + while (pos < this.input.length) { + var ch = this.input.charCodeAt(pos++); + if (ch === 34 || ch === 39 || acorn.isNewLine(ch)) { break } + } + } else if (/unexpected character/i.test(msg)) { + pos++; + replace = false; + } else if (/regular expression/i.test(msg)) { + replace = true; + } else { + throw e + } + this.resetTo(pos); + if (replace === true) { replace = {start: pos, end: pos, type: acorn.tokTypes.name, value: dummyValue}; } + if (replace) { + if (this.options.locations) + { replace.loc = new acorn.SourceLocation( + this.toks, + acorn.getLineInfo(this.input, replace.start), + acorn.getLineInfo(this.input, replace.end)); } + return replace + } + } + } + }; + + lp$2.resetTo = function(pos) { + this.toks.pos = pos; + this.toks.containsEsc = false; + var ch = this.input.charAt(pos - 1); + this.toks.exprAllowed = !ch || /[[{(,;:?/*=+\-~!|&%^<>]/.test(ch) || + /[enwfd]/.test(ch) && + /\b(case|else|return|throw|new|in|(instance|type)?of|delete|void)$/.test(this.input.slice(pos - 10, pos)); + + if (this.options.locations) { + this.toks.curLine = 1; + this.toks.lineStart = acorn.lineBreakG.lastIndex = 0; + var match; + while ((match = acorn.lineBreakG.exec(this.input)) && match.index < pos) { + ++this.toks.curLine; + this.toks.lineStart = match.index + match[0].length; + } + } + }; + + lp$2.lookAhead = function(n) { + while (n > this.ahead.length) + { this.ahead.push(this.readToken()); } + return this.ahead[n - 1] + }; + + var lp$1 = LooseParser.prototype; + + lp$1.parseTopLevel = function() { + var node = this.startNodeAt(this.options.locations ? [0, acorn.getLineInfo(this.input, 0)] : 0); + node.body = []; + while (this.tok.type !== acorn.tokTypes.eof) { node.body.push(this.parseStatement()); } + this.toks.adaptDirectivePrologue(node.body); + this.last = this.tok; + node.sourceType = this.options.sourceType === "commonjs" ? "script" : this.options.sourceType; + return this.finishNode(node, "Program") + }; + + lp$1.parseStatement = function() { + var starttype = this.tok.type, node = this.startNode(), kind; + + if (this.toks.isLet()) { + starttype = acorn.tokTypes._var; + kind = "let"; + } + + switch (starttype) { + case acorn.tokTypes._break: case acorn.tokTypes._continue: + this.next(); + var isBreak = starttype === acorn.tokTypes._break; + if (this.semicolon() || this.canInsertSemicolon()) { + node.label = null; + } else { + node.label = this.tok.type === acorn.tokTypes.name ? this.parseIdent() : null; + this.semicolon(); + } + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") + + case acorn.tokTypes._debugger: + this.next(); + this.semicolon(); + return this.finishNode(node, "DebuggerStatement") + + case acorn.tokTypes._do: + this.next(); + node.body = this.parseStatement(); + node.test = this.eat(acorn.tokTypes._while) ? this.parseParenExpression() : this.dummyIdent(); + this.semicolon(); + return this.finishNode(node, "DoWhileStatement") + + case acorn.tokTypes._for: + this.next(); // `for` keyword + var isAwait = this.options.ecmaVersion >= 9 && this.eatContextual("await"); + + this.pushCx(); + this.expect(acorn.tokTypes.parenL); + if (this.tok.type === acorn.tokTypes.semi) { return this.parseFor(node, null) } + var isLet = this.toks.isLet(); + var isAwaitUsing = this.toks.isAwaitUsing(true); + var isUsing = !isAwaitUsing && this.toks.isUsing(true); + + if (isLet || this.tok.type === acorn.tokTypes._var || this.tok.type === acorn.tokTypes._const || isUsing || isAwaitUsing) { + var kind$1 = isLet ? "let" : isUsing ? "using" : isAwaitUsing ? "await using" : this.tok.value; + var init$1 = this.startNode(); + if (isUsing || isAwaitUsing) { + if (isAwaitUsing) { this.next(); } + this.parseVar(init$1, true, kind$1); + } else { + init$1 = this.parseVar(init$1, true, kind$1); + } + + if (init$1.declarations.length === 1 && (this.tok.type === acorn.tokTypes._in || this.isContextual("of"))) { + if (this.options.ecmaVersion >= 9 && this.tok.type !== acorn.tokTypes._in) { + node.await = isAwait; + } + return this.parseForIn(node, init$1) + } + return this.parseFor(node, init$1) + } + var init = this.parseExpression(true); + if (this.tok.type === acorn.tokTypes._in || this.isContextual("of")) { + if (this.options.ecmaVersion >= 9 && this.tok.type !== acorn.tokTypes._in) { + node.await = isAwait; + } + return this.parseForIn(node, this.toAssignable(init)) + } + return this.parseFor(node, init) + + case acorn.tokTypes._function: + this.next(); + return this.parseFunction(node, true) + + case acorn.tokTypes._if: + this.next(); + node.test = this.parseParenExpression(); + node.consequent = this.parseStatement(); + node.alternate = this.eat(acorn.tokTypes._else) ? this.parseStatement() : null; + return this.finishNode(node, "IfStatement") + + case acorn.tokTypes._return: + this.next(); + if (this.eat(acorn.tokTypes.semi) || this.canInsertSemicolon()) { node.argument = null; } + else { node.argument = this.parseExpression(); this.semicolon(); } + return this.finishNode(node, "ReturnStatement") + + case acorn.tokTypes._switch: + var blockIndent = this.curIndent, line = this.curLineStart; + this.next(); + node.discriminant = this.parseParenExpression(); + node.cases = []; + this.pushCx(); + this.expect(acorn.tokTypes.braceL); + + var cur; + while (!this.closes(acorn.tokTypes.braceR, blockIndent, line, true)) { + if (this.tok.type === acorn.tokTypes._case || this.tok.type === acorn.tokTypes._default) { + var isCase = this.tok.type === acorn.tokTypes._case; + if (cur) { this.finishNode(cur, "SwitchCase"); } + node.cases.push(cur = this.startNode()); + cur.consequent = []; + this.next(); + if (isCase) { cur.test = this.parseExpression(); } + else { cur.test = null; } + this.expect(acorn.tokTypes.colon); + } else { + if (!cur) { + node.cases.push(cur = this.startNode()); + cur.consequent = []; + cur.test = null; + } + cur.consequent.push(this.parseStatement()); + } + } + if (cur) { this.finishNode(cur, "SwitchCase"); } + this.popCx(); + this.eat(acorn.tokTypes.braceR); + return this.finishNode(node, "SwitchStatement") + + case acorn.tokTypes._throw: + this.next(); + node.argument = this.parseExpression(); + this.semicolon(); + return this.finishNode(node, "ThrowStatement") + + case acorn.tokTypes._try: + this.next(); + node.block = this.parseBlock(); + node.handler = null; + if (this.tok.type === acorn.tokTypes._catch) { + var clause = this.startNode(); + this.next(); + if (this.eat(acorn.tokTypes.parenL)) { + clause.param = this.toAssignable(this.parseExprAtom(), true); + this.expect(acorn.tokTypes.parenR); + } else { + clause.param = null; + } + clause.body = this.parseBlock(); + node.handler = this.finishNode(clause, "CatchClause"); + } + node.finalizer = this.eat(acorn.tokTypes._finally) ? this.parseBlock() : null; + if (!node.handler && !node.finalizer) { return node.block } + return this.finishNode(node, "TryStatement") + + case acorn.tokTypes._var: + case acorn.tokTypes._const: + return this.parseVar(node, false, kind || this.tok.value) + + case acorn.tokTypes._while: + this.next(); + node.test = this.parseParenExpression(); + node.body = this.parseStatement(); + return this.finishNode(node, "WhileStatement") + + case acorn.tokTypes._with: + this.next(); + node.object = this.parseParenExpression(); + node.body = this.parseStatement(); + return this.finishNode(node, "WithStatement") + + case acorn.tokTypes.braceL: + return this.parseBlock() + + case acorn.tokTypes.semi: + this.next(); + return this.finishNode(node, "EmptyStatement") + + case acorn.tokTypes._class: + return this.parseClass(true) + + case acorn.tokTypes._import: + if (this.options.ecmaVersion > 10) { + var nextType = this.lookAhead(1).type; + if (nextType === acorn.tokTypes.parenL || nextType === acorn.tokTypes.dot) { + node.expression = this.parseExpression(); + this.semicolon(); + return this.finishNode(node, "ExpressionStatement") + } + } + + return this.parseImport() + + case acorn.tokTypes._export: + return this.parseExport() + + default: + if (this.toks.isAsyncFunction()) { + this.next(); + this.next(); + return this.parseFunction(node, true, true) + } + + if (this.toks.isUsing(false)) { + return this.parseVar(node, false, "using") + } + + if (this.toks.isAwaitUsing(false)) { + this.next(); + return this.parseVar(node, false, "await using") + } + + var expr = this.parseExpression(); + if (isDummy(expr)) { + this.next(); + if (this.tok.type === acorn.tokTypes.eof) { return this.finishNode(node, "EmptyStatement") } + return this.parseStatement() + } else if (starttype === acorn.tokTypes.name && expr.type === "Identifier" && this.eat(acorn.tokTypes.colon)) { + node.body = this.parseStatement(); + node.label = expr; + return this.finishNode(node, "LabeledStatement") + } else { + node.expression = expr; + this.semicolon(); + return this.finishNode(node, "ExpressionStatement") + } + } + }; + + lp$1.parseBlock = function() { + var node = this.startNode(); + this.pushCx(); + this.expect(acorn.tokTypes.braceL); + var blockIndent = this.curIndent, line = this.curLineStart; + node.body = []; + while (!this.closes(acorn.tokTypes.braceR, blockIndent, line, true)) + { node.body.push(this.parseStatement()); } + this.popCx(); + this.eat(acorn.tokTypes.braceR); + return this.finishNode(node, "BlockStatement") + }; + + lp$1.parseFor = function(node, init) { + node.init = init; + node.test = node.update = null; + if (this.eat(acorn.tokTypes.semi) && this.tok.type !== acorn.tokTypes.semi) { node.test = this.parseExpression(); } + if (this.eat(acorn.tokTypes.semi) && this.tok.type !== acorn.tokTypes.parenR) { node.update = this.parseExpression(); } + this.popCx(); + this.expect(acorn.tokTypes.parenR); + node.body = this.parseStatement(); + return this.finishNode(node, "ForStatement") + }; + + lp$1.parseForIn = function(node, init) { + var type = this.tok.type === acorn.tokTypes._in ? "ForInStatement" : "ForOfStatement"; + this.next(); + node.left = init; + node.right = this.parseExpression(); + this.popCx(); + this.expect(acorn.tokTypes.parenR); + node.body = this.parseStatement(); + return this.finishNode(node, type) + }; + + lp$1.parseVar = function(node, noIn, kind) { + node.kind = kind; + this.next(); + node.declarations = []; + do { + var decl = this.startNode(); + decl.id = this.options.ecmaVersion >= 6 ? this.toAssignable(this.parseExprAtom(), true) : this.parseIdent(); + decl.init = this.eat(acorn.tokTypes.eq) ? this.parseMaybeAssign(noIn) : null; + node.declarations.push(this.finishNode(decl, "VariableDeclarator")); + } while (this.eat(acorn.tokTypes.comma)) + if (!node.declarations.length) { + var decl$1 = this.startNode(); + decl$1.id = this.dummyIdent(); + node.declarations.push(this.finishNode(decl$1, "VariableDeclarator")); + } + if (!noIn) { this.semicolon(); } + return this.finishNode(node, "VariableDeclaration") + }; + + lp$1.parseClass = function(isStatement) { + var node = this.startNode(); + this.next(); + if (this.tok.type === acorn.tokTypes.name) { node.id = this.parseIdent(); } + else if (isStatement === true) { node.id = this.dummyIdent(); } + else { node.id = null; } + node.superClass = this.eat(acorn.tokTypes._extends) ? this.parseExpression() : null; + node.body = this.startNode(); + node.body.body = []; + this.pushCx(); + var indent = this.curIndent + 1, line = this.curLineStart; + this.eat(acorn.tokTypes.braceL); + if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart; } + while (!this.closes(acorn.tokTypes.braceR, indent, line)) { + var element = this.parseClassElement(); + if (element) { node.body.body.push(element); } + } + this.popCx(); + if (!this.eat(acorn.tokTypes.braceR)) { + // If there is no closing brace, make the node span to the start + // of the next token (this is useful for Tern) + this.last.end = this.tok.start; + if (this.options.locations) { this.last.loc.end = this.tok.loc.start; } + } + this.semicolon(); + this.finishNode(node.body, "ClassBody"); + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") + }; + + lp$1.parseClassElement = function() { + if (this.eat(acorn.tokTypes.semi)) { return null } + + var ref = this.options; + var ecmaVersion = ref.ecmaVersion; + var locations = ref.locations; + var indent = this.curIndent; + var line = this.curLineStart; + var node = this.startNode(); + var keyName = ""; + var isGenerator = false; + var isAsync = false; + var kind = "method"; + var isStatic = false; + + if (this.eatContextual("static")) { + // Parse static init block + if (ecmaVersion >= 13 && this.eat(acorn.tokTypes.braceL)) { + this.parseClassStaticBlock(node); + return node + } + if (this.isClassElementNameStart() || this.toks.type === acorn.tokTypes.star) { + isStatic = true; + } else { + keyName = "static"; + } + } + node.static = isStatic; + if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) { + if ((this.isClassElementNameStart() || this.toks.type === acorn.tokTypes.star) && !this.canInsertSemicolon()) { + isAsync = true; + } else { + keyName = "async"; + } + } + if (!keyName) { + isGenerator = this.eat(acorn.tokTypes.star); + var lastValue = this.toks.value; + if (this.eatContextual("get") || this.eatContextual("set")) { + if (this.isClassElementNameStart()) { + kind = lastValue; + } else { + keyName = lastValue; + } + } + } + + // Parse element name + if (keyName) { + // 'async', 'get', 'set', or 'static' were not a keyword contextually. + // The last token is any of those. Make it the element name. + node.computed = false; + node.key = this.startNodeAt(locations ? [this.toks.lastTokStart, this.toks.lastTokStartLoc] : this.toks.lastTokStart); + node.key.name = keyName; + this.finishNode(node.key, "Identifier"); + } else { + this.parseClassElementName(node); + + // From https://github.com/acornjs/acorn/blob/7deba41118d6384a2c498c61176b3cf434f69590/acorn-loose/src/statement.js#L291 + // Skip broken stuff. + if (isDummy(node.key)) { + if (isDummy(this.parseMaybeAssign())) { this.next(); } + this.eat(acorn.tokTypes.comma); + return null + } + } + + // Parse element value + if (ecmaVersion < 13 || this.toks.type === acorn.tokTypes.parenL || kind !== "method" || isGenerator || isAsync) { + // Method + var isConstructor = + !node.computed && + !node.static && + !isGenerator && + !isAsync && + kind === "method" && ( + node.key.type === "Identifier" && node.key.name === "constructor" || + node.key.type === "Literal" && node.key.value === "constructor" + ); + node.kind = isConstructor ? "constructor" : kind; + node.value = this.parseMethod(isGenerator, isAsync); + this.finishNode(node, "MethodDefinition"); + } else { + // Field + if (this.eat(acorn.tokTypes.eq)) { + if (this.curLineStart !== line && this.curIndent <= indent && this.tokenStartsLine()) { + // Estimated the next line is the next class element by indentations. + node.value = null; + } else { + var oldInAsync = this.inAsync; + var oldInGenerator = this.inGenerator; + this.inAsync = false; + this.inGenerator = false; + node.value = this.parseMaybeAssign(); + this.inAsync = oldInAsync; + this.inGenerator = oldInGenerator; + } + } else { + node.value = null; + } + this.semicolon(); + this.finishNode(node, "PropertyDefinition"); + } + + return node + }; + + lp$1.parseClassStaticBlock = function(node) { + var blockIndent = this.curIndent, line = this.curLineStart; + node.body = []; + this.pushCx(); + while (!this.closes(acorn.tokTypes.braceR, blockIndent, line, true)) + { node.body.push(this.parseStatement()); } + this.popCx(); + this.eat(acorn.tokTypes.braceR); + + return this.finishNode(node, "StaticBlock") + }; + + lp$1.isClassElementNameStart = function() { + return this.toks.isClassElementNameStart() + }; + + lp$1.parseClassElementName = function(element) { + if (this.toks.type === acorn.tokTypes.privateId) { + element.computed = false; + element.key = this.parsePrivateIdent(); + } else { + this.parsePropertyName(element); + } + }; + + lp$1.parseFunction = function(node, isStatement, isAsync) { + var oldInAsync = this.inAsync, oldInGenerator = this.inGenerator, oldInFunction = this.inFunction; + this.initFunction(node); + if (this.options.ecmaVersion >= 6) { + node.generator = this.eat(acorn.tokTypes.star); + } + if (this.options.ecmaVersion >= 8) { + node.async = !!isAsync; + } + if (this.tok.type === acorn.tokTypes.name) { node.id = this.parseIdent(); } + else if (isStatement === true) { node.id = this.dummyIdent(); } + this.inAsync = node.async; + this.inGenerator = node.generator; + this.inFunction = true; + node.params = this.parseFunctionParams(); + node.body = this.parseBlock(); + this.toks.adaptDirectivePrologue(node.body.body); + this.inAsync = oldInAsync; + this.inGenerator = oldInGenerator; + this.inFunction = oldInFunction; + return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") + }; + + lp$1.parseExport = function() { + var node = this.startNode(); + this.next(); + if (this.eat(acorn.tokTypes.star)) { + if (this.options.ecmaVersion >= 11) { + if (this.eatContextual("as")) { + node.exported = this.parseExprAtom(); + } else { + node.exported = null; + } + } + node.source = this.eatContextual("from") ? this.parseExprAtom() : this.dummyString(); + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } + this.semicolon(); + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(acorn.tokTypes._default)) { + // export default (function foo() {}) // This is FunctionExpression. + var isAsync; + if (this.tok.type === acorn.tokTypes._function || (isAsync = this.toks.isAsyncFunction())) { + var fNode = this.startNode(); + this.next(); + if (isAsync) { this.next(); } + node.declaration = this.parseFunction(fNode, "nullableID", isAsync); + } else if (this.tok.type === acorn.tokTypes._class) { + node.declaration = this.parseClass("nullableID"); + } else { + node.declaration = this.parseMaybeAssign(); + this.semicolon(); + } + return this.finishNode(node, "ExportDefaultDeclaration") + } + if (this.tok.type.keyword || this.toks.isLet() || this.toks.isAsyncFunction()) { + node.declaration = this.parseStatement(); + node.specifiers = []; + node.source = null; + } else { + node.declaration = null; + node.specifiers = this.parseExportSpecifierList(); + node.source = this.eatContextual("from") ? this.parseExprAtom() : null; + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } + this.semicolon(); + } + return this.finishNode(node, "ExportNamedDeclaration") + }; + + lp$1.parseImport = function() { + var node = this.startNode(); + this.next(); + if (this.tok.type === acorn.tokTypes.string) { + node.specifiers = []; + node.source = this.parseExprAtom(); + } else { + var elt; + if (this.tok.type === acorn.tokTypes.name && this.tok.value !== "from") { + elt = this.startNode(); + elt.local = this.parseIdent(); + this.finishNode(elt, "ImportDefaultSpecifier"); + this.eat(acorn.tokTypes.comma); + } + node.specifiers = this.parseImportSpecifiers(); + node.source = this.eatContextual("from") && this.tok.type === acorn.tokTypes.string ? this.parseExprAtom() : this.dummyString(); + if (elt) { node.specifiers.unshift(elt); } + } + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } + this.semicolon(); + return this.finishNode(node, "ImportDeclaration") + }; + + lp$1.parseImportSpecifiers = function() { + var elts = []; + if (this.tok.type === acorn.tokTypes.star) { + var elt = this.startNode(); + this.next(); + elt.local = this.eatContextual("as") ? this.parseIdent() : this.dummyIdent(); + elts.push(this.finishNode(elt, "ImportNamespaceSpecifier")); + } else { + var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart; + this.pushCx(); + this.eat(acorn.tokTypes.braceL); + if (this.curLineStart > continuedLine) { continuedLine = this.curLineStart; } + while (!this.closes(acorn.tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) { + var elt$1 = this.startNode(); + if (this.eat(acorn.tokTypes.star)) { + elt$1.local = this.eatContextual("as") ? this.parseModuleExportName() : this.dummyIdent(); + this.finishNode(elt$1, "ImportNamespaceSpecifier"); + } else { + if (this.isContextual("from")) { break } + elt$1.imported = this.parseModuleExportName(); + if (isDummy(elt$1.imported)) { break } + elt$1.local = this.eatContextual("as") ? this.parseModuleExportName() : elt$1.imported; + this.finishNode(elt$1, "ImportSpecifier"); + } + elts.push(elt$1); + this.eat(acorn.tokTypes.comma); + } + this.eat(acorn.tokTypes.braceR); + this.popCx(); + } + return elts + }; + + lp$1.parseWithClause = function() { + var nodes = []; + if (!this.eat(acorn.tokTypes._with)) { + return nodes + } + + var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart; + this.pushCx(); + this.eat(acorn.tokTypes.braceL); + if (this.curLineStart > continuedLine) { continuedLine = this.curLineStart; } + while (!this.closes(acorn.tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) { + var attr = this.startNode(); + attr.key = this.tok.type === acorn.tokTypes.string ? this.parseExprAtom() : this.parseIdent(); + if (this.eat(acorn.tokTypes.colon)) { + if (this.tok.type === acorn.tokTypes.string) + { attr.value = this.parseExprAtom(); } + else { attr.value = this.dummyString(); } + } else { + if (isDummy(attr.key)) { break } + if (this.tok.type === acorn.tokTypes.string) + { attr.value = this.parseExprAtom(); } + else { break } + } + nodes.push(this.finishNode(attr, "ImportAttribute")); + this.eat(acorn.tokTypes.comma); + } + this.eat(acorn.tokTypes.braceR); + this.popCx(); + return nodes + }; + + lp$1.parseExportSpecifierList = function() { + var elts = []; + var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart; + this.pushCx(); + this.eat(acorn.tokTypes.braceL); + if (this.curLineStart > continuedLine) { continuedLine = this.curLineStart; } + while (!this.closes(acorn.tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) { + if (this.isContextual("from")) { break } + var elt = this.startNode(); + elt.local = this.parseModuleExportName(); + if (isDummy(elt.local)) { break } + elt.exported = this.eatContextual("as") ? this.parseModuleExportName() : elt.local; + this.finishNode(elt, "ExportSpecifier"); + elts.push(elt); + this.eat(acorn.tokTypes.comma); + } + this.eat(acorn.tokTypes.braceR); + this.popCx(); + return elts + }; + + lp$1.parseModuleExportName = function() { + return this.options.ecmaVersion >= 13 && this.tok.type === acorn.tokTypes.string + ? this.parseExprAtom() + : this.parseIdent() + }; + + var lp = LooseParser.prototype; + + lp.checkLVal = function(expr) { + if (!expr) { return expr } + switch (expr.type) { + case "Identifier": + case "MemberExpression": + return expr + + case "ParenthesizedExpression": + expr.expression = this.checkLVal(expr.expression); + return expr + + default: + return this.dummyIdent() + } + }; + + lp.parseExpression = function(noIn) { + var start = this.storeCurrentPos(); + var expr = this.parseMaybeAssign(noIn); + if (this.tok.type === acorn.tokTypes.comma) { + var node = this.startNodeAt(start); + node.expressions = [expr]; + while (this.eat(acorn.tokTypes.comma)) { node.expressions.push(this.parseMaybeAssign(noIn)); } + return this.finishNode(node, "SequenceExpression") + } + return expr + }; + + lp.parseParenExpression = function() { + this.pushCx(); + this.expect(acorn.tokTypes.parenL); + var val = this.parseExpression(); + this.popCx(); + this.expect(acorn.tokTypes.parenR); + return val + }; + + lp.parseMaybeAssign = function(noIn) { + // `yield` should be an identifier reference if it's not in generator functions. + if (this.inGenerator && this.toks.isContextual("yield")) { + var node = this.startNode(); + this.next(); + if (this.semicolon() || this.canInsertSemicolon() || (this.tok.type !== acorn.tokTypes.star && !this.tok.type.startsExpr)) { + node.delegate = false; + node.argument = null; + } else { + node.delegate = this.eat(acorn.tokTypes.star); + node.argument = this.parseMaybeAssign(); + } + return this.finishNode(node, "YieldExpression") + } + + var start = this.storeCurrentPos(); + var left = this.parseMaybeConditional(noIn); + if (this.tok.type.isAssign) { + var node$1 = this.startNodeAt(start); + node$1.operator = this.tok.value; + node$1.left = this.tok.type === acorn.tokTypes.eq ? this.toAssignable(left) : this.checkLVal(left); + this.next(); + node$1.right = this.parseMaybeAssign(noIn); + return this.finishNode(node$1, "AssignmentExpression") + } + return left + }; + + lp.parseMaybeConditional = function(noIn) { + var start = this.storeCurrentPos(); + var expr = this.parseExprOps(noIn); + if (this.eat(acorn.tokTypes.question)) { + var node = this.startNodeAt(start); + node.test = expr; + node.consequent = this.parseMaybeAssign(); + node.alternate = this.expect(acorn.tokTypes.colon) ? this.parseMaybeAssign(noIn) : this.dummyIdent(); + return this.finishNode(node, "ConditionalExpression") + } + return expr + }; + + lp.parseExprOps = function(noIn) { + var start = this.storeCurrentPos(); + var indent = this.curIndent, line = this.curLineStart; + return this.parseExprOp(this.parseMaybeUnary(false), start, -1, noIn, indent, line) + }; + + lp.parseExprOp = function(left, start, minPrec, noIn, indent, line) { + if (this.curLineStart !== line && this.curIndent < indent && this.tokenStartsLine()) { return left } + var prec = this.tok.type.binop; + if (prec != null && (!noIn || this.tok.type !== acorn.tokTypes._in)) { + if (prec > minPrec) { + var node = this.startNodeAt(start); + node.left = left; + node.operator = this.tok.value; + this.next(); + if (this.curLineStart !== line && this.curIndent < indent && this.tokenStartsLine()) { + node.right = this.dummyIdent(); + } else { + var rightStart = this.storeCurrentPos(); + node.right = this.parseExprOp(this.parseMaybeUnary(false), rightStart, prec, noIn, indent, line); + } + this.finishNode(node, /&&|\|\||\?\?/.test(node.operator) ? "LogicalExpression" : "BinaryExpression"); + return this.parseExprOp(node, start, minPrec, noIn, indent, line) + } + } + return left + }; + + lp.parseMaybeUnary = function(sawUnary) { + var start = this.storeCurrentPos(), expr; + if (this.options.ecmaVersion >= 8 && this.toks.isContextual("await") && + (this.inAsync || (this.toks.inModule && this.options.ecmaVersion >= 13) || + (!this.inFunction && this.options.allowAwaitOutsideFunction))) { + expr = this.parseAwait(); + sawUnary = true; + } else if (this.tok.type.prefix) { + var node = this.startNode(), update = this.tok.type === acorn.tokTypes.incDec; + if (!update) { sawUnary = true; } + node.operator = this.tok.value; + node.prefix = true; + this.next(); + node.argument = this.parseMaybeUnary(true); + if (update) { node.argument = this.checkLVal(node.argument); } + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); + } else if (this.tok.type === acorn.tokTypes.ellipsis) { + var node$1 = this.startNode(); + this.next(); + node$1.argument = this.parseMaybeUnary(sawUnary); + expr = this.finishNode(node$1, "SpreadElement"); + } else if (!sawUnary && this.tok.type === acorn.tokTypes.privateId) { + expr = this.parsePrivateIdent(); + } else { + expr = this.parseExprSubscripts(); + while (this.tok.type.postfix && !this.canInsertSemicolon()) { + var node$2 = this.startNodeAt(start); + node$2.operator = this.tok.value; + node$2.prefix = false; + node$2.argument = this.checkLVal(expr); + this.next(); + expr = this.finishNode(node$2, "UpdateExpression"); + } + } + + if (!sawUnary && this.eat(acorn.tokTypes.starstar)) { + var node$3 = this.startNodeAt(start); + node$3.operator = "**"; + node$3.left = expr; + node$3.right = this.parseMaybeUnary(false); + return this.finishNode(node$3, "BinaryExpression") + } + + return expr + }; + + lp.parseExprSubscripts = function() { + var start = this.storeCurrentPos(); + return this.parseSubscripts(this.parseExprAtom(), start, false, this.curIndent, this.curLineStart) + }; + + lp.parseSubscripts = function(base, start, noCalls, startIndent, line) { + var optionalSupported = this.options.ecmaVersion >= 11; + var optionalChained = false; + for (;;) { + if (this.curLineStart !== line && this.curIndent <= startIndent && this.tokenStartsLine()) { + if (this.tok.type === acorn.tokTypes.dot && this.curIndent === startIndent) + { --startIndent; } + else + { break } + } + + var maybeAsyncArrow = base.type === "Identifier" && base.name === "async" && !this.canInsertSemicolon(); + var optional = optionalSupported && this.eat(acorn.tokTypes.questionDot); + if (optional) { + optionalChained = true; + } + + if ((optional && this.tok.type !== acorn.tokTypes.parenL && this.tok.type !== acorn.tokTypes.bracketL && this.tok.type !== acorn.tokTypes.backQuote) || this.eat(acorn.tokTypes.dot)) { + var node = this.startNodeAt(start); + node.object = base; + if (this.curLineStart !== line && this.curIndent <= startIndent && this.tokenStartsLine()) + { node.property = this.dummyIdent(); } + else + { node.property = this.parsePropertyAccessor() || this.dummyIdent(); } + node.computed = false; + if (optionalSupported) { + node.optional = optional; + } + base = this.finishNode(node, "MemberExpression"); + } else if (this.tok.type === acorn.tokTypes.bracketL) { + this.pushCx(); + this.next(); + var node$1 = this.startNodeAt(start); + node$1.object = base; + node$1.property = this.parseExpression(); + node$1.computed = true; + if (optionalSupported) { + node$1.optional = optional; + } + this.popCx(); + this.expect(acorn.tokTypes.bracketR); + base = this.finishNode(node$1, "MemberExpression"); + } else if (!noCalls && this.tok.type === acorn.tokTypes.parenL) { + var exprList = this.parseExprList(acorn.tokTypes.parenR); + if (maybeAsyncArrow && this.eat(acorn.tokTypes.arrow)) + { return this.parseArrowExpression(this.startNodeAt(start), exprList, true) } + var node$2 = this.startNodeAt(start); + node$2.callee = base; + node$2.arguments = exprList; + if (optionalSupported) { + node$2.optional = optional; + } + base = this.finishNode(node$2, "CallExpression"); + } else if (this.tok.type === acorn.tokTypes.backQuote) { + var node$3 = this.startNodeAt(start); + node$3.tag = base; + node$3.quasi = this.parseTemplate(); + base = this.finishNode(node$3, "TaggedTemplateExpression"); + } else { + break + } + } + + if (optionalChained) { + var chainNode = this.startNodeAt(start); + chainNode.expression = base; + base = this.finishNode(chainNode, "ChainExpression"); + } + return base + }; + + lp.parseExprAtom = function() { + var node; + switch (this.tok.type) { + case acorn.tokTypes._this: + case acorn.tokTypes._super: + var type = this.tok.type === acorn.tokTypes._this ? "ThisExpression" : "Super"; + node = this.startNode(); + this.next(); + return this.finishNode(node, type) + + case acorn.tokTypes.name: + var start = this.storeCurrentPos(); + var id = this.parseIdent(); + var isAsync = false; + if (id.name === "async" && !this.canInsertSemicolon()) { + if (this.eat(acorn.tokTypes._function)) { + this.toks.overrideContext(acorn.tokContexts.f_expr); + return this.parseFunction(this.startNodeAt(start), false, true) + } + if (this.tok.type === acorn.tokTypes.name) { + id = this.parseIdent(); + isAsync = true; + } + } + return this.eat(acorn.tokTypes.arrow) ? this.parseArrowExpression(this.startNodeAt(start), [id], isAsync) : id + + case acorn.tokTypes.regexp: + node = this.startNode(); + var val = this.tok.value; + node.regex = {pattern: val.pattern, flags: val.flags}; + node.value = val.value; + node.raw = this.input.slice(this.tok.start, this.tok.end); + this.next(); + return this.finishNode(node, "Literal") + + case acorn.tokTypes.num: case acorn.tokTypes.string: + node = this.startNode(); + node.value = this.tok.value; + node.raw = this.input.slice(this.tok.start, this.tok.end); + if (this.tok.type === acorn.tokTypes.num && node.raw.charCodeAt(node.raw.length - 1) === 110) + { node.bigint = node.value != null ? node.value.toString() : node.raw.slice(0, -1).replace(/_/g, ""); } + this.next(); + return this.finishNode(node, "Literal") + + case acorn.tokTypes._null: case acorn.tokTypes._true: case acorn.tokTypes._false: + node = this.startNode(); + node.value = this.tok.type === acorn.tokTypes._null ? null : this.tok.type === acorn.tokTypes._true; + node.raw = this.tok.type.keyword; + this.next(); + return this.finishNode(node, "Literal") + + case acorn.tokTypes.parenL: + var parenStart = this.storeCurrentPos(); + this.next(); + var inner = this.parseExpression(); + this.expect(acorn.tokTypes.parenR); + if (this.eat(acorn.tokTypes.arrow)) { + // (a,)=>a // SequenceExpression makes dummy in the last hole. Drop the dummy. + var params = inner.expressions || [inner]; + if (params.length && isDummy(params[params.length - 1])) + { params.pop(); } + return this.parseArrowExpression(this.startNodeAt(parenStart), params) + } + if (this.options.preserveParens) { + var par = this.startNodeAt(parenStart); + par.expression = inner; + inner = this.finishNode(par, "ParenthesizedExpression"); + } + return inner + + case acorn.tokTypes.bracketL: + node = this.startNode(); + node.elements = this.parseExprList(acorn.tokTypes.bracketR, true); + return this.finishNode(node, "ArrayExpression") + + case acorn.tokTypes.braceL: + this.toks.overrideContext(acorn.tokContexts.b_expr); + return this.parseObj() + + case acorn.tokTypes._class: + return this.parseClass(false) + + case acorn.tokTypes._function: + node = this.startNode(); + this.next(); + return this.parseFunction(node, false) + + case acorn.tokTypes._new: + return this.parseNew() + + case acorn.tokTypes.backQuote: + return this.parseTemplate() + + case acorn.tokTypes._import: + if (this.options.ecmaVersion >= 11) { + return this.parseExprImport() + } else { + return this.dummyIdent() + } + + default: + return this.dummyIdent() + } + }; + + lp.parseExprImport = function() { + var node = this.startNode(); + var meta = this.parseIdent(true); + switch (this.tok.type) { + case acorn.tokTypes.parenL: + return this.parseDynamicImport(node) + case acorn.tokTypes.dot: + node.meta = meta; + return this.parseImportMeta(node) + default: + node.name = "import"; + return this.finishNode(node, "Identifier") + } + }; + + lp.parseDynamicImport = function(node) { + var list = this.parseExprList(acorn.tokTypes.parenR); + node.source = list[0] || this.dummyString(); + node.options = list[1] || null; + return this.finishNode(node, "ImportExpression") + }; + + lp.parseImportMeta = function(node) { + this.next(); // skip '.' + node.property = this.parseIdent(true); + return this.finishNode(node, "MetaProperty") + }; + + lp.parseNew = function() { + var node = this.startNode(), startIndent = this.curIndent, line = this.curLineStart; + var meta = this.parseIdent(true); + if (this.options.ecmaVersion >= 6 && this.eat(acorn.tokTypes.dot)) { + node.meta = meta; + node.property = this.parseIdent(true); + return this.finishNode(node, "MetaProperty") + } + var start = this.storeCurrentPos(); + node.callee = this.parseSubscripts(this.parseExprAtom(), start, true, startIndent, line); + if (this.tok.type === acorn.tokTypes.parenL) { + node.arguments = this.parseExprList(acorn.tokTypes.parenR); + } else { + node.arguments = []; + } + return this.finishNode(node, "NewExpression") + }; + + lp.parseTemplateElement = function() { + var elem = this.startNode(); + + // The loose parser accepts invalid unicode escapes even in untagged templates. + if (this.tok.type === acorn.tokTypes.invalidTemplate) { + elem.value = { + raw: this.tok.value, + cooked: null + }; + } else { + elem.value = { + raw: this.input.slice(this.tok.start, this.tok.end).replace(/\r\n?/g, "\n"), + cooked: this.tok.value + }; + } + this.next(); + elem.tail = this.tok.type === acorn.tokTypes.backQuote; + return this.finishNode(elem, "TemplateElement") + }; + + lp.parseTemplate = function() { + var node = this.startNode(); + this.next(); + node.expressions = []; + var curElt = this.parseTemplateElement(); + node.quasis = [curElt]; + while (!curElt.tail) { + this.next(); + node.expressions.push(this.parseExpression()); + if (this.expect(acorn.tokTypes.braceR)) { + curElt = this.parseTemplateElement(); + } else { + curElt = this.startNode(); + curElt.value = {cooked: "", raw: ""}; + curElt.tail = true; + this.finishNode(curElt, "TemplateElement"); + } + node.quasis.push(curElt); + } + this.expect(acorn.tokTypes.backQuote); + return this.finishNode(node, "TemplateLiteral") + }; + + lp.parseObj = function() { + var node = this.startNode(); + node.properties = []; + this.pushCx(); + var indent = this.curIndent + 1, line = this.curLineStart; + this.eat(acorn.tokTypes.braceL); + if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart; } + while (!this.closes(acorn.tokTypes.braceR, indent, line)) { + var prop = this.startNode(), isGenerator = (void 0), isAsync = (void 0), start = (void 0); + if (this.options.ecmaVersion >= 9 && this.eat(acorn.tokTypes.ellipsis)) { + prop.argument = this.parseMaybeAssign(); + node.properties.push(this.finishNode(prop, "SpreadElement")); + this.eat(acorn.tokTypes.comma); + continue + } + if (this.options.ecmaVersion >= 6) { + start = this.storeCurrentPos(); + prop.method = false; + prop.shorthand = false; + isGenerator = this.eat(acorn.tokTypes.star); + } + this.parsePropertyName(prop); + if (this.toks.isAsyncProp(prop)) { + isAsync = true; + isGenerator = this.options.ecmaVersion >= 9 && this.eat(acorn.tokTypes.star); + this.parsePropertyName(prop); + } else { + isAsync = false; + } + if (isDummy(prop.key)) { if (isDummy(this.parseMaybeAssign())) { this.next(); } this.eat(acorn.tokTypes.comma); continue } + if (this.eat(acorn.tokTypes.colon)) { + prop.kind = "init"; + prop.value = this.parseMaybeAssign(); + } else if (this.options.ecmaVersion >= 6 && (this.tok.type === acorn.tokTypes.parenL || this.tok.type === acorn.tokTypes.braceL)) { + prop.kind = "init"; + prop.method = true; + prop.value = this.parseMethod(isGenerator, isAsync); + } else if (this.options.ecmaVersion >= 5 && prop.key.type === "Identifier" && + !prop.computed && (prop.key.name === "get" || prop.key.name === "set") && + (this.tok.type !== acorn.tokTypes.comma && this.tok.type !== acorn.tokTypes.braceR && this.tok.type !== acorn.tokTypes.eq)) { + prop.kind = prop.key.name; + this.parsePropertyName(prop); + prop.value = this.parseMethod(false); + } else { + prop.kind = "init"; + if (this.options.ecmaVersion >= 6) { + if (this.eat(acorn.tokTypes.eq)) { + var assign = this.startNodeAt(start); + assign.operator = "="; + assign.left = prop.key; + assign.right = this.parseMaybeAssign(); + prop.value = this.finishNode(assign, "AssignmentExpression"); + } else { + prop.value = prop.key; + } + } else { + prop.value = this.dummyIdent(); + } + prop.shorthand = true; + } + node.properties.push(this.finishNode(prop, "Property")); + this.eat(acorn.tokTypes.comma); + } + this.popCx(); + if (!this.eat(acorn.tokTypes.braceR)) { + // If there is no closing brace, make the node span to the start + // of the next token (this is useful for Tern) + this.last.end = this.tok.start; + if (this.options.locations) { this.last.loc.end = this.tok.loc.start; } + } + return this.finishNode(node, "ObjectExpression") + }; + + lp.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(acorn.tokTypes.bracketL)) { + prop.computed = true; + prop.key = this.parseExpression(); + this.expect(acorn.tokTypes.bracketR); + return + } else { + prop.computed = false; + } + } + var key = (this.tok.type === acorn.tokTypes.num || this.tok.type === acorn.tokTypes.string) ? this.parseExprAtom() : this.parseIdent(); + prop.key = key || this.dummyIdent(); + }; + + lp.parsePropertyAccessor = function() { + if (this.tok.type === acorn.tokTypes.name || this.tok.type.keyword) { return this.parseIdent() } + if (this.tok.type === acorn.tokTypes.privateId) { return this.parsePrivateIdent() } + }; + + lp.parseIdent = function() { + var name = this.tok.type === acorn.tokTypes.name ? this.tok.value : this.tok.type.keyword; + if (!name) { return this.dummyIdent() } + if (this.tok.type.keyword) { this.toks.type = acorn.tokTypes.name; } + var node = this.startNode(); + this.next(); + node.name = name; + return this.finishNode(node, "Identifier") + }; + + lp.parsePrivateIdent = function() { + var node = this.startNode(); + node.name = this.tok.value; + this.next(); + return this.finishNode(node, "PrivateIdentifier") + }; + + lp.initFunction = function(node) { + node.id = null; + node.params = []; + if (this.options.ecmaVersion >= 6) { + node.generator = false; + node.expression = false; + } + if (this.options.ecmaVersion >= 8) + { node.async = false; } + }; + + // Convert existing expression atom to assignable pattern + // if possible. + + lp.toAssignable = function(node, binding) { + if (!node || node.type === "Identifier" || (node.type === "MemberExpression" && !binding)) ; else if (node.type === "ParenthesizedExpression") { + this.toAssignable(node.expression, binding); + } else if (this.options.ecmaVersion < 6) { + return this.dummyIdent() + } else if (node.type === "ObjectExpression") { + node.type = "ObjectPattern"; + for (var i = 0, list = node.properties; i < list.length; i += 1) + { + var prop = list[i]; + + this.toAssignable(prop, binding); + } + } else if (node.type === "ArrayExpression") { + node.type = "ArrayPattern"; + this.toAssignableList(node.elements, binding); + } else if (node.type === "Property") { + this.toAssignable(node.value, binding); + } else if (node.type === "SpreadElement") { + node.type = "RestElement"; + this.toAssignable(node.argument, binding); + } else if (node.type === "AssignmentExpression") { + node.type = "AssignmentPattern"; + delete node.operator; + } else { + return this.dummyIdent() + } + return node + }; + + lp.toAssignableList = function(exprList, binding) { + for (var i = 0, list = exprList; i < list.length; i += 1) + { + var expr = list[i]; + + this.toAssignable(expr, binding); + } + return exprList + }; + + lp.parseFunctionParams = function(params) { + params = this.parseExprList(acorn.tokTypes.parenR); + return this.toAssignableList(params, true) + }; + + lp.parseMethod = function(isGenerator, isAsync) { + var node = this.startNode(), oldInAsync = this.inAsync, oldInGenerator = this.inGenerator, oldInFunction = this.inFunction; + this.initFunction(node); + if (this.options.ecmaVersion >= 6) + { node.generator = !!isGenerator; } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + this.inAsync = node.async; + this.inGenerator = node.generator; + this.inFunction = true; + node.params = this.parseFunctionParams(); + node.body = this.parseBlock(); + this.toks.adaptDirectivePrologue(node.body.body); + this.inAsync = oldInAsync; + this.inGenerator = oldInGenerator; + this.inFunction = oldInFunction; + return this.finishNode(node, "FunctionExpression") + }; + + lp.parseArrowExpression = function(node, params, isAsync) { + var oldInAsync = this.inAsync, oldInGenerator = this.inGenerator, oldInFunction = this.inFunction; + this.initFunction(node); + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + this.inAsync = node.async; + this.inGenerator = false; + this.inFunction = true; + node.params = this.toAssignableList(params, true); + node.expression = this.tok.type !== acorn.tokTypes.braceL; + if (node.expression) { + node.body = this.parseMaybeAssign(); + } else { + node.body = this.parseBlock(); + this.toks.adaptDirectivePrologue(node.body.body); + } + this.inAsync = oldInAsync; + this.inGenerator = oldInGenerator; + this.inFunction = oldInFunction; + return this.finishNode(node, "ArrowFunctionExpression") + }; + + lp.parseExprList = function(close, allowEmpty) { + this.pushCx(); + var indent = this.curIndent, line = this.curLineStart, elts = []; + this.next(); // Opening bracket + while (!this.closes(close, indent + 1, line)) { + if (this.eat(acorn.tokTypes.comma)) { + elts.push(allowEmpty ? null : this.dummyIdent()); + continue + } + var elt = this.parseMaybeAssign(); + if (isDummy(elt)) { + if (this.closes(close, indent, line)) { break } + this.next(); + } else { + elts.push(elt); + } + this.eat(acorn.tokTypes.comma); + } + this.popCx(); + if (!this.eat(close)) { + // If there is no closing brace, make the node span to the start + // of the next token (this is useful for Tern) + this.last.end = this.tok.start; + if (this.options.locations) { this.last.loc.end = this.tok.loc.start; } + } + return elts + }; + + lp.parseAwait = function() { + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeUnary(); + return this.finishNode(node, "AwaitExpression") + }; + + // Acorn: Loose parser + // + // This module provides an alternative parser that exposes that same + // interface as the main module's `parse` function, but will try to + // parse anything as JavaScript, repairing syntax error the best it + // can. There are circumstances in which it will raise an error and + // give up, but they are very rare. The resulting AST will be a mostly + // valid JavaScript AST (as per the [ESTree spec][estree], except + // that: + // + // - Return outside functions is allowed + // + // - Label consistency (no conflicts, break only to existing labels) + // is not enforced. + // + // - Bogus Identifier nodes with a name of `"✖"` are inserted whenever + // the parser got too confused to return anything meaningful. + // + // [estree]: https://github.com/estree/estree + // + // The expected use for this is to *first* try `acorn.parse`, and only + // if that fails switch to the loose parser. The loose parser might + // parse badly indented code incorrectly, so **don't** use it as your + // default parser. + // + // Quite a lot of acorn.js is duplicated here. The alternative was to + // add a *lot* of extra cruft to that file, making it less readable + // and slower. Copying and editing the code allowed me to make + // invasive changes and simplifications without creating a complicated + // tangle. + + + acorn.defaultOptions.tabSize = 4; + + function parse(input, options) { + return LooseParser.parse(input, options) + } + + exports.LooseParser = LooseParser; + exports.isDummy = isDummy; + exports.parse = parse; + +})); diff --git a/node_modules/acorn-loose/dist/acorn-loose.mjs b/node_modules/acorn-loose/dist/acorn-loose.mjs new file mode 100644 index 0000000..7dffe3c --- /dev/null +++ b/node_modules/acorn-loose/dist/acorn-loose.mjs @@ -0,0 +1,1630 @@ +import { tokTypes, SourceLocation, Node, lineBreak, isNewLine, Parser, Token, getLineInfo, lineBreakG, tokContexts, defaultOptions } from 'acorn'; + +var dummyValue = "✖"; + +function isDummy(node) { return node.name === dummyValue } + +function noop() {} + +var LooseParser = function LooseParser(input, options) { + if ( options === void 0 ) options = {}; + + this.toks = this.constructor.BaseParser.tokenizer(input, options); + this.options = this.toks.options; + this.input = this.toks.input; + this.tok = this.last = {type: tokTypes.eof, start: 0, end: 0}; + this.tok.validateRegExpFlags = noop; + this.tok.validateRegExpPattern = noop; + if (this.options.locations) { + var here = this.toks.curPosition(); + this.tok.loc = new SourceLocation(this.toks, here, here); + } + this.ahead = []; // Tokens ahead + this.context = []; // Indentation contexted + this.curIndent = 0; + this.curLineStart = 0; + this.nextLineStart = this.lineEnd(this.curLineStart) + 1; + this.inAsync = false; + this.inGenerator = false; + this.inFunction = false; +}; + +LooseParser.prototype.startNode = function startNode () { + return new Node(this.toks, this.tok.start, this.options.locations ? this.tok.loc.start : null) +}; + +LooseParser.prototype.storeCurrentPos = function storeCurrentPos () { + return this.options.locations ? [this.tok.start, this.tok.loc.start] : this.tok.start +}; + +LooseParser.prototype.startNodeAt = function startNodeAt (pos) { + if (this.options.locations) { + return new Node(this.toks, pos[0], pos[1]) + } else { + return new Node(this.toks, pos) + } +}; + +LooseParser.prototype.finishNode = function finishNode (node, type) { + node.type = type; + node.end = this.last.end; + if (this.options.locations) + { node.loc.end = this.last.loc.end; } + if (this.options.ranges) + { node.range[1] = this.last.end; } + return node +}; + +LooseParser.prototype.dummyNode = function dummyNode (type) { + var dummy = this.startNode(); + dummy.type = type; + dummy.end = dummy.start; + if (this.options.locations) + { dummy.loc.end = dummy.loc.start; } + if (this.options.ranges) + { dummy.range[1] = dummy.start; } + this.last = {type: tokTypes.name, start: dummy.start, end: dummy.start, loc: dummy.loc}; + return dummy +}; + +LooseParser.prototype.dummyIdent = function dummyIdent () { + var dummy = this.dummyNode("Identifier"); + dummy.name = dummyValue; + return dummy +}; + +LooseParser.prototype.dummyString = function dummyString () { + var dummy = this.dummyNode("Literal"); + dummy.value = dummy.raw = dummyValue; + return dummy +}; + +LooseParser.prototype.eat = function eat (type) { + if (this.tok.type === type) { + this.next(); + return true + } else { + return false + } +}; + +LooseParser.prototype.isContextual = function isContextual (name) { + return this.tok.type === tokTypes.name && this.tok.value === name +}; + +LooseParser.prototype.eatContextual = function eatContextual (name) { + return this.tok.value === name && this.eat(tokTypes.name) +}; + +LooseParser.prototype.canInsertSemicolon = function canInsertSemicolon () { + return this.tok.type === tokTypes.eof || this.tok.type === tokTypes.braceR || + lineBreak.test(this.input.slice(this.last.end, this.tok.start)) +}; + +LooseParser.prototype.semicolon = function semicolon () { + return this.eat(tokTypes.semi) +}; + +LooseParser.prototype.expect = function expect (type) { + if (this.eat(type)) { return true } + for (var i = 1; i <= 2; i++) { + if (this.lookAhead(i).type === type) { + for (var j = 0; j < i; j++) { this.next(); } + return true + } + } +}; + +LooseParser.prototype.pushCx = function pushCx () { + this.context.push(this.curIndent); +}; + +LooseParser.prototype.popCx = function popCx () { + this.curIndent = this.context.pop(); +}; + +LooseParser.prototype.lineEnd = function lineEnd (pos) { + while (pos < this.input.length && !isNewLine(this.input.charCodeAt(pos))) { ++pos; } + return pos +}; + +LooseParser.prototype.indentationAfter = function indentationAfter (pos) { + for (var count = 0;; ++pos) { + var ch = this.input.charCodeAt(pos); + if (ch === 32) { ++count; } + else if (ch === 9) { count += this.options.tabSize; } + else { return count } + } +}; + +LooseParser.prototype.closes = function closes (closeTok, indent, line, blockHeuristic) { + if (this.tok.type === closeTok || this.tok.type === tokTypes.eof) { return true } + return line !== this.curLineStart && this.curIndent < indent && this.tokenStartsLine() && + (!blockHeuristic || this.nextLineStart >= this.input.length || + this.indentationAfter(this.nextLineStart) < indent) +}; + +LooseParser.prototype.tokenStartsLine = function tokenStartsLine () { + for (var p = this.tok.start - 1; p >= this.curLineStart; --p) { + var ch = this.input.charCodeAt(p); + if (ch !== 9 && ch !== 32) { return false } + } + return true +}; + +LooseParser.prototype.extend = function extend (name, f) { + this[name] = f(this[name]); +}; + +LooseParser.prototype.parse = function parse () { + this.next(); + return this.parseTopLevel() +}; + +LooseParser.extend = function extend () { + var plugins = [], len = arguments.length; + while ( len-- ) plugins[ len ] = arguments[ len ]; + + var cls = this; + for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); } + return cls +}; + +LooseParser.parse = function parse (input, options) { + return new this(input, options).parse() +}; + +// Allows plugins to extend the base parser / tokenizer used +LooseParser.BaseParser = Parser; + +var lp$2 = LooseParser.prototype; + +function isSpace(ch) { + return (ch < 14 && ch > 8) || ch === 32 || ch === 160 || isNewLine(ch) +} + +lp$2.next = function() { + this.last = this.tok; + if (this.ahead.length) + { this.tok = this.ahead.shift(); } + else + { this.tok = this.readToken(); } + + if (this.tok.start >= this.nextLineStart) { + while (this.tok.start >= this.nextLineStart) { + this.curLineStart = this.nextLineStart; + this.nextLineStart = this.lineEnd(this.curLineStart) + 1; + } + this.curIndent = this.indentationAfter(this.curLineStart); + } +}; + +lp$2.readToken = function() { + for (;;) { + try { + this.toks.next(); + if (this.toks.type === tokTypes.dot && + this.input.substr(this.toks.end, 1) === "." && + this.options.ecmaVersion >= 6) { + this.toks.end++; + this.toks.type = tokTypes.ellipsis; + } + return new Token(this.toks) + } catch (e) { + if (!(e instanceof SyntaxError)) { throw e } + + // Try to skip some text, based on the error message, and then continue + var msg = e.message, pos = e.raisedAt, replace = true; + if (/unterminated/i.test(msg)) { + pos = this.lineEnd(e.pos + 1); + if (/string/.test(msg)) { + replace = {start: e.pos, end: pos, type: tokTypes.string, value: this.input.slice(e.pos + 1, pos)}; + } else if (/regular expr/i.test(msg)) { + var re = this.input.slice(e.pos, pos); + try { re = new RegExp(re); } catch (e$1) { /* ignore compilation error due to new syntax */ } + replace = {start: e.pos, end: pos, type: tokTypes.regexp, value: re}; + } else if (/template/.test(msg)) { + replace = { + start: e.pos, + end: pos, + type: tokTypes.template, + value: this.input.slice(e.pos, pos) + }; + } else { + replace = false; + } + } else if (/invalid (unicode|regexp|number)|expecting unicode|octal literal|is reserved|directly after number|expected number in radix|numeric separator/i.test(msg)) { + while (pos < this.input.length && !isSpace(this.input.charCodeAt(pos))) { ++pos; } + } else if (/character escape|expected hexadecimal/i.test(msg)) { + while (pos < this.input.length) { + var ch = this.input.charCodeAt(pos++); + if (ch === 34 || ch === 39 || isNewLine(ch)) { break } + } + } else if (/unexpected character/i.test(msg)) { + pos++; + replace = false; + } else if (/regular expression/i.test(msg)) { + replace = true; + } else { + throw e + } + this.resetTo(pos); + if (replace === true) { replace = {start: pos, end: pos, type: tokTypes.name, value: dummyValue}; } + if (replace) { + if (this.options.locations) + { replace.loc = new SourceLocation( + this.toks, + getLineInfo(this.input, replace.start), + getLineInfo(this.input, replace.end)); } + return replace + } + } + } +}; + +lp$2.resetTo = function(pos) { + this.toks.pos = pos; + this.toks.containsEsc = false; + var ch = this.input.charAt(pos - 1); + this.toks.exprAllowed = !ch || /[[{(,;:?/*=+\-~!|&%^<>]/.test(ch) || + /[enwfd]/.test(ch) && + /\b(case|else|return|throw|new|in|(instance|type)?of|delete|void)$/.test(this.input.slice(pos - 10, pos)); + + if (this.options.locations) { + this.toks.curLine = 1; + this.toks.lineStart = lineBreakG.lastIndex = 0; + var match; + while ((match = lineBreakG.exec(this.input)) && match.index < pos) { + ++this.toks.curLine; + this.toks.lineStart = match.index + match[0].length; + } + } +}; + +lp$2.lookAhead = function(n) { + while (n > this.ahead.length) + { this.ahead.push(this.readToken()); } + return this.ahead[n - 1] +}; + +var lp$1 = LooseParser.prototype; + +lp$1.parseTopLevel = function() { + var node = this.startNodeAt(this.options.locations ? [0, getLineInfo(this.input, 0)] : 0); + node.body = []; + while (this.tok.type !== tokTypes.eof) { node.body.push(this.parseStatement()); } + this.toks.adaptDirectivePrologue(node.body); + this.last = this.tok; + node.sourceType = this.options.sourceType === "commonjs" ? "script" : this.options.sourceType; + return this.finishNode(node, "Program") +}; + +lp$1.parseStatement = function() { + var starttype = this.tok.type, node = this.startNode(), kind; + + if (this.toks.isLet()) { + starttype = tokTypes._var; + kind = "let"; + } + + switch (starttype) { + case tokTypes._break: case tokTypes._continue: + this.next(); + var isBreak = starttype === tokTypes._break; + if (this.semicolon() || this.canInsertSemicolon()) { + node.label = null; + } else { + node.label = this.tok.type === tokTypes.name ? this.parseIdent() : null; + this.semicolon(); + } + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") + + case tokTypes._debugger: + this.next(); + this.semicolon(); + return this.finishNode(node, "DebuggerStatement") + + case tokTypes._do: + this.next(); + node.body = this.parseStatement(); + node.test = this.eat(tokTypes._while) ? this.parseParenExpression() : this.dummyIdent(); + this.semicolon(); + return this.finishNode(node, "DoWhileStatement") + + case tokTypes._for: + this.next(); // `for` keyword + var isAwait = this.options.ecmaVersion >= 9 && this.eatContextual("await"); + + this.pushCx(); + this.expect(tokTypes.parenL); + if (this.tok.type === tokTypes.semi) { return this.parseFor(node, null) } + var isLet = this.toks.isLet(); + var isAwaitUsing = this.toks.isAwaitUsing(true); + var isUsing = !isAwaitUsing && this.toks.isUsing(true); + + if (isLet || this.tok.type === tokTypes._var || this.tok.type === tokTypes._const || isUsing || isAwaitUsing) { + var kind$1 = isLet ? "let" : isUsing ? "using" : isAwaitUsing ? "await using" : this.tok.value; + var init$1 = this.startNode(); + if (isUsing || isAwaitUsing) { + if (isAwaitUsing) { this.next(); } + this.parseVar(init$1, true, kind$1); + } else { + init$1 = this.parseVar(init$1, true, kind$1); + } + + if (init$1.declarations.length === 1 && (this.tok.type === tokTypes._in || this.isContextual("of"))) { + if (this.options.ecmaVersion >= 9 && this.tok.type !== tokTypes._in) { + node.await = isAwait; + } + return this.parseForIn(node, init$1) + } + return this.parseFor(node, init$1) + } + var init = this.parseExpression(true); + if (this.tok.type === tokTypes._in || this.isContextual("of")) { + if (this.options.ecmaVersion >= 9 && this.tok.type !== tokTypes._in) { + node.await = isAwait; + } + return this.parseForIn(node, this.toAssignable(init)) + } + return this.parseFor(node, init) + + case tokTypes._function: + this.next(); + return this.parseFunction(node, true) + + case tokTypes._if: + this.next(); + node.test = this.parseParenExpression(); + node.consequent = this.parseStatement(); + node.alternate = this.eat(tokTypes._else) ? this.parseStatement() : null; + return this.finishNode(node, "IfStatement") + + case tokTypes._return: + this.next(); + if (this.eat(tokTypes.semi) || this.canInsertSemicolon()) { node.argument = null; } + else { node.argument = this.parseExpression(); this.semicolon(); } + return this.finishNode(node, "ReturnStatement") + + case tokTypes._switch: + var blockIndent = this.curIndent, line = this.curLineStart; + this.next(); + node.discriminant = this.parseParenExpression(); + node.cases = []; + this.pushCx(); + this.expect(tokTypes.braceL); + + var cur; + while (!this.closes(tokTypes.braceR, blockIndent, line, true)) { + if (this.tok.type === tokTypes._case || this.tok.type === tokTypes._default) { + var isCase = this.tok.type === tokTypes._case; + if (cur) { this.finishNode(cur, "SwitchCase"); } + node.cases.push(cur = this.startNode()); + cur.consequent = []; + this.next(); + if (isCase) { cur.test = this.parseExpression(); } + else { cur.test = null; } + this.expect(tokTypes.colon); + } else { + if (!cur) { + node.cases.push(cur = this.startNode()); + cur.consequent = []; + cur.test = null; + } + cur.consequent.push(this.parseStatement()); + } + } + if (cur) { this.finishNode(cur, "SwitchCase"); } + this.popCx(); + this.eat(tokTypes.braceR); + return this.finishNode(node, "SwitchStatement") + + case tokTypes._throw: + this.next(); + node.argument = this.parseExpression(); + this.semicolon(); + return this.finishNode(node, "ThrowStatement") + + case tokTypes._try: + this.next(); + node.block = this.parseBlock(); + node.handler = null; + if (this.tok.type === tokTypes._catch) { + var clause = this.startNode(); + this.next(); + if (this.eat(tokTypes.parenL)) { + clause.param = this.toAssignable(this.parseExprAtom(), true); + this.expect(tokTypes.parenR); + } else { + clause.param = null; + } + clause.body = this.parseBlock(); + node.handler = this.finishNode(clause, "CatchClause"); + } + node.finalizer = this.eat(tokTypes._finally) ? this.parseBlock() : null; + if (!node.handler && !node.finalizer) { return node.block } + return this.finishNode(node, "TryStatement") + + case tokTypes._var: + case tokTypes._const: + return this.parseVar(node, false, kind || this.tok.value) + + case tokTypes._while: + this.next(); + node.test = this.parseParenExpression(); + node.body = this.parseStatement(); + return this.finishNode(node, "WhileStatement") + + case tokTypes._with: + this.next(); + node.object = this.parseParenExpression(); + node.body = this.parseStatement(); + return this.finishNode(node, "WithStatement") + + case tokTypes.braceL: + return this.parseBlock() + + case tokTypes.semi: + this.next(); + return this.finishNode(node, "EmptyStatement") + + case tokTypes._class: + return this.parseClass(true) + + case tokTypes._import: + if (this.options.ecmaVersion > 10) { + var nextType = this.lookAhead(1).type; + if (nextType === tokTypes.parenL || nextType === tokTypes.dot) { + node.expression = this.parseExpression(); + this.semicolon(); + return this.finishNode(node, "ExpressionStatement") + } + } + + return this.parseImport() + + case tokTypes._export: + return this.parseExport() + + default: + if (this.toks.isAsyncFunction()) { + this.next(); + this.next(); + return this.parseFunction(node, true, true) + } + + if (this.toks.isUsing(false)) { + return this.parseVar(node, false, "using") + } + + if (this.toks.isAwaitUsing(false)) { + this.next(); + return this.parseVar(node, false, "await using") + } + + var expr = this.parseExpression(); + if (isDummy(expr)) { + this.next(); + if (this.tok.type === tokTypes.eof) { return this.finishNode(node, "EmptyStatement") } + return this.parseStatement() + } else if (starttype === tokTypes.name && expr.type === "Identifier" && this.eat(tokTypes.colon)) { + node.body = this.parseStatement(); + node.label = expr; + return this.finishNode(node, "LabeledStatement") + } else { + node.expression = expr; + this.semicolon(); + return this.finishNode(node, "ExpressionStatement") + } + } +}; + +lp$1.parseBlock = function() { + var node = this.startNode(); + this.pushCx(); + this.expect(tokTypes.braceL); + var blockIndent = this.curIndent, line = this.curLineStart; + node.body = []; + while (!this.closes(tokTypes.braceR, blockIndent, line, true)) + { node.body.push(this.parseStatement()); } + this.popCx(); + this.eat(tokTypes.braceR); + return this.finishNode(node, "BlockStatement") +}; + +lp$1.parseFor = function(node, init) { + node.init = init; + node.test = node.update = null; + if (this.eat(tokTypes.semi) && this.tok.type !== tokTypes.semi) { node.test = this.parseExpression(); } + if (this.eat(tokTypes.semi) && this.tok.type !== tokTypes.parenR) { node.update = this.parseExpression(); } + this.popCx(); + this.expect(tokTypes.parenR); + node.body = this.parseStatement(); + return this.finishNode(node, "ForStatement") +}; + +lp$1.parseForIn = function(node, init) { + var type = this.tok.type === tokTypes._in ? "ForInStatement" : "ForOfStatement"; + this.next(); + node.left = init; + node.right = this.parseExpression(); + this.popCx(); + this.expect(tokTypes.parenR); + node.body = this.parseStatement(); + return this.finishNode(node, type) +}; + +lp$1.parseVar = function(node, noIn, kind) { + node.kind = kind; + this.next(); + node.declarations = []; + do { + var decl = this.startNode(); + decl.id = this.options.ecmaVersion >= 6 ? this.toAssignable(this.parseExprAtom(), true) : this.parseIdent(); + decl.init = this.eat(tokTypes.eq) ? this.parseMaybeAssign(noIn) : null; + node.declarations.push(this.finishNode(decl, "VariableDeclarator")); + } while (this.eat(tokTypes.comma)) + if (!node.declarations.length) { + var decl$1 = this.startNode(); + decl$1.id = this.dummyIdent(); + node.declarations.push(this.finishNode(decl$1, "VariableDeclarator")); + } + if (!noIn) { this.semicolon(); } + return this.finishNode(node, "VariableDeclaration") +}; + +lp$1.parseClass = function(isStatement) { + var node = this.startNode(); + this.next(); + if (this.tok.type === tokTypes.name) { node.id = this.parseIdent(); } + else if (isStatement === true) { node.id = this.dummyIdent(); } + else { node.id = null; } + node.superClass = this.eat(tokTypes._extends) ? this.parseExpression() : null; + node.body = this.startNode(); + node.body.body = []; + this.pushCx(); + var indent = this.curIndent + 1, line = this.curLineStart; + this.eat(tokTypes.braceL); + if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart; } + while (!this.closes(tokTypes.braceR, indent, line)) { + var element = this.parseClassElement(); + if (element) { node.body.body.push(element); } + } + this.popCx(); + if (!this.eat(tokTypes.braceR)) { + // If there is no closing brace, make the node span to the start + // of the next token (this is useful for Tern) + this.last.end = this.tok.start; + if (this.options.locations) { this.last.loc.end = this.tok.loc.start; } + } + this.semicolon(); + this.finishNode(node.body, "ClassBody"); + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") +}; + +lp$1.parseClassElement = function() { + if (this.eat(tokTypes.semi)) { return null } + + var ref = this.options; + var ecmaVersion = ref.ecmaVersion; + var locations = ref.locations; + var indent = this.curIndent; + var line = this.curLineStart; + var node = this.startNode(); + var keyName = ""; + var isGenerator = false; + var isAsync = false; + var kind = "method"; + var isStatic = false; + + if (this.eatContextual("static")) { + // Parse static init block + if (ecmaVersion >= 13 && this.eat(tokTypes.braceL)) { + this.parseClassStaticBlock(node); + return node + } + if (this.isClassElementNameStart() || this.toks.type === tokTypes.star) { + isStatic = true; + } else { + keyName = "static"; + } + } + node.static = isStatic; + if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) { + if ((this.isClassElementNameStart() || this.toks.type === tokTypes.star) && !this.canInsertSemicolon()) { + isAsync = true; + } else { + keyName = "async"; + } + } + if (!keyName) { + isGenerator = this.eat(tokTypes.star); + var lastValue = this.toks.value; + if (this.eatContextual("get") || this.eatContextual("set")) { + if (this.isClassElementNameStart()) { + kind = lastValue; + } else { + keyName = lastValue; + } + } + } + + // Parse element name + if (keyName) { + // 'async', 'get', 'set', or 'static' were not a keyword contextually. + // The last token is any of those. Make it the element name. + node.computed = false; + node.key = this.startNodeAt(locations ? [this.toks.lastTokStart, this.toks.lastTokStartLoc] : this.toks.lastTokStart); + node.key.name = keyName; + this.finishNode(node.key, "Identifier"); + } else { + this.parseClassElementName(node); + + // From https://github.com/acornjs/acorn/blob/7deba41118d6384a2c498c61176b3cf434f69590/acorn-loose/src/statement.js#L291 + // Skip broken stuff. + if (isDummy(node.key)) { + if (isDummy(this.parseMaybeAssign())) { this.next(); } + this.eat(tokTypes.comma); + return null + } + } + + // Parse element value + if (ecmaVersion < 13 || this.toks.type === tokTypes.parenL || kind !== "method" || isGenerator || isAsync) { + // Method + var isConstructor = + !node.computed && + !node.static && + !isGenerator && + !isAsync && + kind === "method" && ( + node.key.type === "Identifier" && node.key.name === "constructor" || + node.key.type === "Literal" && node.key.value === "constructor" + ); + node.kind = isConstructor ? "constructor" : kind; + node.value = this.parseMethod(isGenerator, isAsync); + this.finishNode(node, "MethodDefinition"); + } else { + // Field + if (this.eat(tokTypes.eq)) { + if (this.curLineStart !== line && this.curIndent <= indent && this.tokenStartsLine()) { + // Estimated the next line is the next class element by indentations. + node.value = null; + } else { + var oldInAsync = this.inAsync; + var oldInGenerator = this.inGenerator; + this.inAsync = false; + this.inGenerator = false; + node.value = this.parseMaybeAssign(); + this.inAsync = oldInAsync; + this.inGenerator = oldInGenerator; + } + } else { + node.value = null; + } + this.semicolon(); + this.finishNode(node, "PropertyDefinition"); + } + + return node +}; + +lp$1.parseClassStaticBlock = function(node) { + var blockIndent = this.curIndent, line = this.curLineStart; + node.body = []; + this.pushCx(); + while (!this.closes(tokTypes.braceR, blockIndent, line, true)) + { node.body.push(this.parseStatement()); } + this.popCx(); + this.eat(tokTypes.braceR); + + return this.finishNode(node, "StaticBlock") +}; + +lp$1.isClassElementNameStart = function() { + return this.toks.isClassElementNameStart() +}; + +lp$1.parseClassElementName = function(element) { + if (this.toks.type === tokTypes.privateId) { + element.computed = false; + element.key = this.parsePrivateIdent(); + } else { + this.parsePropertyName(element); + } +}; + +lp$1.parseFunction = function(node, isStatement, isAsync) { + var oldInAsync = this.inAsync, oldInGenerator = this.inGenerator, oldInFunction = this.inFunction; + this.initFunction(node); + if (this.options.ecmaVersion >= 6) { + node.generator = this.eat(tokTypes.star); + } + if (this.options.ecmaVersion >= 8) { + node.async = !!isAsync; + } + if (this.tok.type === tokTypes.name) { node.id = this.parseIdent(); } + else if (isStatement === true) { node.id = this.dummyIdent(); } + this.inAsync = node.async; + this.inGenerator = node.generator; + this.inFunction = true; + node.params = this.parseFunctionParams(); + node.body = this.parseBlock(); + this.toks.adaptDirectivePrologue(node.body.body); + this.inAsync = oldInAsync; + this.inGenerator = oldInGenerator; + this.inFunction = oldInFunction; + return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") +}; + +lp$1.parseExport = function() { + var node = this.startNode(); + this.next(); + if (this.eat(tokTypes.star)) { + if (this.options.ecmaVersion >= 11) { + if (this.eatContextual("as")) { + node.exported = this.parseExprAtom(); + } else { + node.exported = null; + } + } + node.source = this.eatContextual("from") ? this.parseExprAtom() : this.dummyString(); + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } + this.semicolon(); + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(tokTypes._default)) { + // export default (function foo() {}) // This is FunctionExpression. + var isAsync; + if (this.tok.type === tokTypes._function || (isAsync = this.toks.isAsyncFunction())) { + var fNode = this.startNode(); + this.next(); + if (isAsync) { this.next(); } + node.declaration = this.parseFunction(fNode, "nullableID", isAsync); + } else if (this.tok.type === tokTypes._class) { + node.declaration = this.parseClass("nullableID"); + } else { + node.declaration = this.parseMaybeAssign(); + this.semicolon(); + } + return this.finishNode(node, "ExportDefaultDeclaration") + } + if (this.tok.type.keyword || this.toks.isLet() || this.toks.isAsyncFunction()) { + node.declaration = this.parseStatement(); + node.specifiers = []; + node.source = null; + } else { + node.declaration = null; + node.specifiers = this.parseExportSpecifierList(); + node.source = this.eatContextual("from") ? this.parseExprAtom() : null; + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } + this.semicolon(); + } + return this.finishNode(node, "ExportNamedDeclaration") +}; + +lp$1.parseImport = function() { + var node = this.startNode(); + this.next(); + if (this.tok.type === tokTypes.string) { + node.specifiers = []; + node.source = this.parseExprAtom(); + } else { + var elt; + if (this.tok.type === tokTypes.name && this.tok.value !== "from") { + elt = this.startNode(); + elt.local = this.parseIdent(); + this.finishNode(elt, "ImportDefaultSpecifier"); + this.eat(tokTypes.comma); + } + node.specifiers = this.parseImportSpecifiers(); + node.source = this.eatContextual("from") && this.tok.type === tokTypes.string ? this.parseExprAtom() : this.dummyString(); + if (elt) { node.specifiers.unshift(elt); } + } + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } + this.semicolon(); + return this.finishNode(node, "ImportDeclaration") +}; + +lp$1.parseImportSpecifiers = function() { + var elts = []; + if (this.tok.type === tokTypes.star) { + var elt = this.startNode(); + this.next(); + elt.local = this.eatContextual("as") ? this.parseIdent() : this.dummyIdent(); + elts.push(this.finishNode(elt, "ImportNamespaceSpecifier")); + } else { + var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart; + this.pushCx(); + this.eat(tokTypes.braceL); + if (this.curLineStart > continuedLine) { continuedLine = this.curLineStart; } + while (!this.closes(tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) { + var elt$1 = this.startNode(); + if (this.eat(tokTypes.star)) { + elt$1.local = this.eatContextual("as") ? this.parseModuleExportName() : this.dummyIdent(); + this.finishNode(elt$1, "ImportNamespaceSpecifier"); + } else { + if (this.isContextual("from")) { break } + elt$1.imported = this.parseModuleExportName(); + if (isDummy(elt$1.imported)) { break } + elt$1.local = this.eatContextual("as") ? this.parseModuleExportName() : elt$1.imported; + this.finishNode(elt$1, "ImportSpecifier"); + } + elts.push(elt$1); + this.eat(tokTypes.comma); + } + this.eat(tokTypes.braceR); + this.popCx(); + } + return elts +}; + +lp$1.parseWithClause = function() { + var nodes = []; + if (!this.eat(tokTypes._with)) { + return nodes + } + + var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart; + this.pushCx(); + this.eat(tokTypes.braceL); + if (this.curLineStart > continuedLine) { continuedLine = this.curLineStart; } + while (!this.closes(tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) { + var attr = this.startNode(); + attr.key = this.tok.type === tokTypes.string ? this.parseExprAtom() : this.parseIdent(); + if (this.eat(tokTypes.colon)) { + if (this.tok.type === tokTypes.string) + { attr.value = this.parseExprAtom(); } + else { attr.value = this.dummyString(); } + } else { + if (isDummy(attr.key)) { break } + if (this.tok.type === tokTypes.string) + { attr.value = this.parseExprAtom(); } + else { break } + } + nodes.push(this.finishNode(attr, "ImportAttribute")); + this.eat(tokTypes.comma); + } + this.eat(tokTypes.braceR); + this.popCx(); + return nodes +}; + +lp$1.parseExportSpecifierList = function() { + var elts = []; + var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart; + this.pushCx(); + this.eat(tokTypes.braceL); + if (this.curLineStart > continuedLine) { continuedLine = this.curLineStart; } + while (!this.closes(tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) { + if (this.isContextual("from")) { break } + var elt = this.startNode(); + elt.local = this.parseModuleExportName(); + if (isDummy(elt.local)) { break } + elt.exported = this.eatContextual("as") ? this.parseModuleExportName() : elt.local; + this.finishNode(elt, "ExportSpecifier"); + elts.push(elt); + this.eat(tokTypes.comma); + } + this.eat(tokTypes.braceR); + this.popCx(); + return elts +}; + +lp$1.parseModuleExportName = function() { + return this.options.ecmaVersion >= 13 && this.tok.type === tokTypes.string + ? this.parseExprAtom() + : this.parseIdent() +}; + +var lp = LooseParser.prototype; + +lp.checkLVal = function(expr) { + if (!expr) { return expr } + switch (expr.type) { + case "Identifier": + case "MemberExpression": + return expr + + case "ParenthesizedExpression": + expr.expression = this.checkLVal(expr.expression); + return expr + + default: + return this.dummyIdent() + } +}; + +lp.parseExpression = function(noIn) { + var start = this.storeCurrentPos(); + var expr = this.parseMaybeAssign(noIn); + if (this.tok.type === tokTypes.comma) { + var node = this.startNodeAt(start); + node.expressions = [expr]; + while (this.eat(tokTypes.comma)) { node.expressions.push(this.parseMaybeAssign(noIn)); } + return this.finishNode(node, "SequenceExpression") + } + return expr +}; + +lp.parseParenExpression = function() { + this.pushCx(); + this.expect(tokTypes.parenL); + var val = this.parseExpression(); + this.popCx(); + this.expect(tokTypes.parenR); + return val +}; + +lp.parseMaybeAssign = function(noIn) { + // `yield` should be an identifier reference if it's not in generator functions. + if (this.inGenerator && this.toks.isContextual("yield")) { + var node = this.startNode(); + this.next(); + if (this.semicolon() || this.canInsertSemicolon() || (this.tok.type !== tokTypes.star && !this.tok.type.startsExpr)) { + node.delegate = false; + node.argument = null; + } else { + node.delegate = this.eat(tokTypes.star); + node.argument = this.parseMaybeAssign(); + } + return this.finishNode(node, "YieldExpression") + } + + var start = this.storeCurrentPos(); + var left = this.parseMaybeConditional(noIn); + if (this.tok.type.isAssign) { + var node$1 = this.startNodeAt(start); + node$1.operator = this.tok.value; + node$1.left = this.tok.type === tokTypes.eq ? this.toAssignable(left) : this.checkLVal(left); + this.next(); + node$1.right = this.parseMaybeAssign(noIn); + return this.finishNode(node$1, "AssignmentExpression") + } + return left +}; + +lp.parseMaybeConditional = function(noIn) { + var start = this.storeCurrentPos(); + var expr = this.parseExprOps(noIn); + if (this.eat(tokTypes.question)) { + var node = this.startNodeAt(start); + node.test = expr; + node.consequent = this.parseMaybeAssign(); + node.alternate = this.expect(tokTypes.colon) ? this.parseMaybeAssign(noIn) : this.dummyIdent(); + return this.finishNode(node, "ConditionalExpression") + } + return expr +}; + +lp.parseExprOps = function(noIn) { + var start = this.storeCurrentPos(); + var indent = this.curIndent, line = this.curLineStart; + return this.parseExprOp(this.parseMaybeUnary(false), start, -1, noIn, indent, line) +}; + +lp.parseExprOp = function(left, start, minPrec, noIn, indent, line) { + if (this.curLineStart !== line && this.curIndent < indent && this.tokenStartsLine()) { return left } + var prec = this.tok.type.binop; + if (prec != null && (!noIn || this.tok.type !== tokTypes._in)) { + if (prec > minPrec) { + var node = this.startNodeAt(start); + node.left = left; + node.operator = this.tok.value; + this.next(); + if (this.curLineStart !== line && this.curIndent < indent && this.tokenStartsLine()) { + node.right = this.dummyIdent(); + } else { + var rightStart = this.storeCurrentPos(); + node.right = this.parseExprOp(this.parseMaybeUnary(false), rightStart, prec, noIn, indent, line); + } + this.finishNode(node, /&&|\|\||\?\?/.test(node.operator) ? "LogicalExpression" : "BinaryExpression"); + return this.parseExprOp(node, start, minPrec, noIn, indent, line) + } + } + return left +}; + +lp.parseMaybeUnary = function(sawUnary) { + var start = this.storeCurrentPos(), expr; + if (this.options.ecmaVersion >= 8 && this.toks.isContextual("await") && + (this.inAsync || (this.toks.inModule && this.options.ecmaVersion >= 13) || + (!this.inFunction && this.options.allowAwaitOutsideFunction))) { + expr = this.parseAwait(); + sawUnary = true; + } else if (this.tok.type.prefix) { + var node = this.startNode(), update = this.tok.type === tokTypes.incDec; + if (!update) { sawUnary = true; } + node.operator = this.tok.value; + node.prefix = true; + this.next(); + node.argument = this.parseMaybeUnary(true); + if (update) { node.argument = this.checkLVal(node.argument); } + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); + } else if (this.tok.type === tokTypes.ellipsis) { + var node$1 = this.startNode(); + this.next(); + node$1.argument = this.parseMaybeUnary(sawUnary); + expr = this.finishNode(node$1, "SpreadElement"); + } else if (!sawUnary && this.tok.type === tokTypes.privateId) { + expr = this.parsePrivateIdent(); + } else { + expr = this.parseExprSubscripts(); + while (this.tok.type.postfix && !this.canInsertSemicolon()) { + var node$2 = this.startNodeAt(start); + node$2.operator = this.tok.value; + node$2.prefix = false; + node$2.argument = this.checkLVal(expr); + this.next(); + expr = this.finishNode(node$2, "UpdateExpression"); + } + } + + if (!sawUnary && this.eat(tokTypes.starstar)) { + var node$3 = this.startNodeAt(start); + node$3.operator = "**"; + node$3.left = expr; + node$3.right = this.parseMaybeUnary(false); + return this.finishNode(node$3, "BinaryExpression") + } + + return expr +}; + +lp.parseExprSubscripts = function() { + var start = this.storeCurrentPos(); + return this.parseSubscripts(this.parseExprAtom(), start, false, this.curIndent, this.curLineStart) +}; + +lp.parseSubscripts = function(base, start, noCalls, startIndent, line) { + var optionalSupported = this.options.ecmaVersion >= 11; + var optionalChained = false; + for (;;) { + if (this.curLineStart !== line && this.curIndent <= startIndent && this.tokenStartsLine()) { + if (this.tok.type === tokTypes.dot && this.curIndent === startIndent) + { --startIndent; } + else + { break } + } + + var maybeAsyncArrow = base.type === "Identifier" && base.name === "async" && !this.canInsertSemicolon(); + var optional = optionalSupported && this.eat(tokTypes.questionDot); + if (optional) { + optionalChained = true; + } + + if ((optional && this.tok.type !== tokTypes.parenL && this.tok.type !== tokTypes.bracketL && this.tok.type !== tokTypes.backQuote) || this.eat(tokTypes.dot)) { + var node = this.startNodeAt(start); + node.object = base; + if (this.curLineStart !== line && this.curIndent <= startIndent && this.tokenStartsLine()) + { node.property = this.dummyIdent(); } + else + { node.property = this.parsePropertyAccessor() || this.dummyIdent(); } + node.computed = false; + if (optionalSupported) { + node.optional = optional; + } + base = this.finishNode(node, "MemberExpression"); + } else if (this.tok.type === tokTypes.bracketL) { + this.pushCx(); + this.next(); + var node$1 = this.startNodeAt(start); + node$1.object = base; + node$1.property = this.parseExpression(); + node$1.computed = true; + if (optionalSupported) { + node$1.optional = optional; + } + this.popCx(); + this.expect(tokTypes.bracketR); + base = this.finishNode(node$1, "MemberExpression"); + } else if (!noCalls && this.tok.type === tokTypes.parenL) { + var exprList = this.parseExprList(tokTypes.parenR); + if (maybeAsyncArrow && this.eat(tokTypes.arrow)) + { return this.parseArrowExpression(this.startNodeAt(start), exprList, true) } + var node$2 = this.startNodeAt(start); + node$2.callee = base; + node$2.arguments = exprList; + if (optionalSupported) { + node$2.optional = optional; + } + base = this.finishNode(node$2, "CallExpression"); + } else if (this.tok.type === tokTypes.backQuote) { + var node$3 = this.startNodeAt(start); + node$3.tag = base; + node$3.quasi = this.parseTemplate(); + base = this.finishNode(node$3, "TaggedTemplateExpression"); + } else { + break + } + } + + if (optionalChained) { + var chainNode = this.startNodeAt(start); + chainNode.expression = base; + base = this.finishNode(chainNode, "ChainExpression"); + } + return base +}; + +lp.parseExprAtom = function() { + var node; + switch (this.tok.type) { + case tokTypes._this: + case tokTypes._super: + var type = this.tok.type === tokTypes._this ? "ThisExpression" : "Super"; + node = this.startNode(); + this.next(); + return this.finishNode(node, type) + + case tokTypes.name: + var start = this.storeCurrentPos(); + var id = this.parseIdent(); + var isAsync = false; + if (id.name === "async" && !this.canInsertSemicolon()) { + if (this.eat(tokTypes._function)) { + this.toks.overrideContext(tokContexts.f_expr); + return this.parseFunction(this.startNodeAt(start), false, true) + } + if (this.tok.type === tokTypes.name) { + id = this.parseIdent(); + isAsync = true; + } + } + return this.eat(tokTypes.arrow) ? this.parseArrowExpression(this.startNodeAt(start), [id], isAsync) : id + + case tokTypes.regexp: + node = this.startNode(); + var val = this.tok.value; + node.regex = {pattern: val.pattern, flags: val.flags}; + node.value = val.value; + node.raw = this.input.slice(this.tok.start, this.tok.end); + this.next(); + return this.finishNode(node, "Literal") + + case tokTypes.num: case tokTypes.string: + node = this.startNode(); + node.value = this.tok.value; + node.raw = this.input.slice(this.tok.start, this.tok.end); + if (this.tok.type === tokTypes.num && node.raw.charCodeAt(node.raw.length - 1) === 110) + { node.bigint = node.value != null ? node.value.toString() : node.raw.slice(0, -1).replace(/_/g, ""); } + this.next(); + return this.finishNode(node, "Literal") + + case tokTypes._null: case tokTypes._true: case tokTypes._false: + node = this.startNode(); + node.value = this.tok.type === tokTypes._null ? null : this.tok.type === tokTypes._true; + node.raw = this.tok.type.keyword; + this.next(); + return this.finishNode(node, "Literal") + + case tokTypes.parenL: + var parenStart = this.storeCurrentPos(); + this.next(); + var inner = this.parseExpression(); + this.expect(tokTypes.parenR); + if (this.eat(tokTypes.arrow)) { + // (a,)=>a // SequenceExpression makes dummy in the last hole. Drop the dummy. + var params = inner.expressions || [inner]; + if (params.length && isDummy(params[params.length - 1])) + { params.pop(); } + return this.parseArrowExpression(this.startNodeAt(parenStart), params) + } + if (this.options.preserveParens) { + var par = this.startNodeAt(parenStart); + par.expression = inner; + inner = this.finishNode(par, "ParenthesizedExpression"); + } + return inner + + case tokTypes.bracketL: + node = this.startNode(); + node.elements = this.parseExprList(tokTypes.bracketR, true); + return this.finishNode(node, "ArrayExpression") + + case tokTypes.braceL: + this.toks.overrideContext(tokContexts.b_expr); + return this.parseObj() + + case tokTypes._class: + return this.parseClass(false) + + case tokTypes._function: + node = this.startNode(); + this.next(); + return this.parseFunction(node, false) + + case tokTypes._new: + return this.parseNew() + + case tokTypes.backQuote: + return this.parseTemplate() + + case tokTypes._import: + if (this.options.ecmaVersion >= 11) { + return this.parseExprImport() + } else { + return this.dummyIdent() + } + + default: + return this.dummyIdent() + } +}; + +lp.parseExprImport = function() { + var node = this.startNode(); + var meta = this.parseIdent(true); + switch (this.tok.type) { + case tokTypes.parenL: + return this.parseDynamicImport(node) + case tokTypes.dot: + node.meta = meta; + return this.parseImportMeta(node) + default: + node.name = "import"; + return this.finishNode(node, "Identifier") + } +}; + +lp.parseDynamicImport = function(node) { + var list = this.parseExprList(tokTypes.parenR); + node.source = list[0] || this.dummyString(); + node.options = list[1] || null; + return this.finishNode(node, "ImportExpression") +}; + +lp.parseImportMeta = function(node) { + this.next(); // skip '.' + node.property = this.parseIdent(true); + return this.finishNode(node, "MetaProperty") +}; + +lp.parseNew = function() { + var node = this.startNode(), startIndent = this.curIndent, line = this.curLineStart; + var meta = this.parseIdent(true); + if (this.options.ecmaVersion >= 6 && this.eat(tokTypes.dot)) { + node.meta = meta; + node.property = this.parseIdent(true); + return this.finishNode(node, "MetaProperty") + } + var start = this.storeCurrentPos(); + node.callee = this.parseSubscripts(this.parseExprAtom(), start, true, startIndent, line); + if (this.tok.type === tokTypes.parenL) { + node.arguments = this.parseExprList(tokTypes.parenR); + } else { + node.arguments = []; + } + return this.finishNode(node, "NewExpression") +}; + +lp.parseTemplateElement = function() { + var elem = this.startNode(); + + // The loose parser accepts invalid unicode escapes even in untagged templates. + if (this.tok.type === tokTypes.invalidTemplate) { + elem.value = { + raw: this.tok.value, + cooked: null + }; + } else { + elem.value = { + raw: this.input.slice(this.tok.start, this.tok.end).replace(/\r\n?/g, "\n"), + cooked: this.tok.value + }; + } + this.next(); + elem.tail = this.tok.type === tokTypes.backQuote; + return this.finishNode(elem, "TemplateElement") +}; + +lp.parseTemplate = function() { + var node = this.startNode(); + this.next(); + node.expressions = []; + var curElt = this.parseTemplateElement(); + node.quasis = [curElt]; + while (!curElt.tail) { + this.next(); + node.expressions.push(this.parseExpression()); + if (this.expect(tokTypes.braceR)) { + curElt = this.parseTemplateElement(); + } else { + curElt = this.startNode(); + curElt.value = {cooked: "", raw: ""}; + curElt.tail = true; + this.finishNode(curElt, "TemplateElement"); + } + node.quasis.push(curElt); + } + this.expect(tokTypes.backQuote); + return this.finishNode(node, "TemplateLiteral") +}; + +lp.parseObj = function() { + var node = this.startNode(); + node.properties = []; + this.pushCx(); + var indent = this.curIndent + 1, line = this.curLineStart; + this.eat(tokTypes.braceL); + if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart; } + while (!this.closes(tokTypes.braceR, indent, line)) { + var prop = this.startNode(), isGenerator = (void 0), isAsync = (void 0), start = (void 0); + if (this.options.ecmaVersion >= 9 && this.eat(tokTypes.ellipsis)) { + prop.argument = this.parseMaybeAssign(); + node.properties.push(this.finishNode(prop, "SpreadElement")); + this.eat(tokTypes.comma); + continue + } + if (this.options.ecmaVersion >= 6) { + start = this.storeCurrentPos(); + prop.method = false; + prop.shorthand = false; + isGenerator = this.eat(tokTypes.star); + } + this.parsePropertyName(prop); + if (this.toks.isAsyncProp(prop)) { + isAsync = true; + isGenerator = this.options.ecmaVersion >= 9 && this.eat(tokTypes.star); + this.parsePropertyName(prop); + } else { + isAsync = false; + } + if (isDummy(prop.key)) { if (isDummy(this.parseMaybeAssign())) { this.next(); } this.eat(tokTypes.comma); continue } + if (this.eat(tokTypes.colon)) { + prop.kind = "init"; + prop.value = this.parseMaybeAssign(); + } else if (this.options.ecmaVersion >= 6 && (this.tok.type === tokTypes.parenL || this.tok.type === tokTypes.braceL)) { + prop.kind = "init"; + prop.method = true; + prop.value = this.parseMethod(isGenerator, isAsync); + } else if (this.options.ecmaVersion >= 5 && prop.key.type === "Identifier" && + !prop.computed && (prop.key.name === "get" || prop.key.name === "set") && + (this.tok.type !== tokTypes.comma && this.tok.type !== tokTypes.braceR && this.tok.type !== tokTypes.eq)) { + prop.kind = prop.key.name; + this.parsePropertyName(prop); + prop.value = this.parseMethod(false); + } else { + prop.kind = "init"; + if (this.options.ecmaVersion >= 6) { + if (this.eat(tokTypes.eq)) { + var assign = this.startNodeAt(start); + assign.operator = "="; + assign.left = prop.key; + assign.right = this.parseMaybeAssign(); + prop.value = this.finishNode(assign, "AssignmentExpression"); + } else { + prop.value = prop.key; + } + } else { + prop.value = this.dummyIdent(); + } + prop.shorthand = true; + } + node.properties.push(this.finishNode(prop, "Property")); + this.eat(tokTypes.comma); + } + this.popCx(); + if (!this.eat(tokTypes.braceR)) { + // If there is no closing brace, make the node span to the start + // of the next token (this is useful for Tern) + this.last.end = this.tok.start; + if (this.options.locations) { this.last.loc.end = this.tok.loc.start; } + } + return this.finishNode(node, "ObjectExpression") +}; + +lp.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(tokTypes.bracketL)) { + prop.computed = true; + prop.key = this.parseExpression(); + this.expect(tokTypes.bracketR); + return + } else { + prop.computed = false; + } + } + var key = (this.tok.type === tokTypes.num || this.tok.type === tokTypes.string) ? this.parseExprAtom() : this.parseIdent(); + prop.key = key || this.dummyIdent(); +}; + +lp.parsePropertyAccessor = function() { + if (this.tok.type === tokTypes.name || this.tok.type.keyword) { return this.parseIdent() } + if (this.tok.type === tokTypes.privateId) { return this.parsePrivateIdent() } +}; + +lp.parseIdent = function() { + var name = this.tok.type === tokTypes.name ? this.tok.value : this.tok.type.keyword; + if (!name) { return this.dummyIdent() } + if (this.tok.type.keyword) { this.toks.type = tokTypes.name; } + var node = this.startNode(); + this.next(); + node.name = name; + return this.finishNode(node, "Identifier") +}; + +lp.parsePrivateIdent = function() { + var node = this.startNode(); + node.name = this.tok.value; + this.next(); + return this.finishNode(node, "PrivateIdentifier") +}; + +lp.initFunction = function(node) { + node.id = null; + node.params = []; + if (this.options.ecmaVersion >= 6) { + node.generator = false; + node.expression = false; + } + if (this.options.ecmaVersion >= 8) + { node.async = false; } +}; + +// Convert existing expression atom to assignable pattern +// if possible. + +lp.toAssignable = function(node, binding) { + if (!node || node.type === "Identifier" || (node.type === "MemberExpression" && !binding)) ; else if (node.type === "ParenthesizedExpression") { + this.toAssignable(node.expression, binding); + } else if (this.options.ecmaVersion < 6) { + return this.dummyIdent() + } else if (node.type === "ObjectExpression") { + node.type = "ObjectPattern"; + for (var i = 0, list = node.properties; i < list.length; i += 1) + { + var prop = list[i]; + + this.toAssignable(prop, binding); + } + } else if (node.type === "ArrayExpression") { + node.type = "ArrayPattern"; + this.toAssignableList(node.elements, binding); + } else if (node.type === "Property") { + this.toAssignable(node.value, binding); + } else if (node.type === "SpreadElement") { + node.type = "RestElement"; + this.toAssignable(node.argument, binding); + } else if (node.type === "AssignmentExpression") { + node.type = "AssignmentPattern"; + delete node.operator; + } else { + return this.dummyIdent() + } + return node +}; + +lp.toAssignableList = function(exprList, binding) { + for (var i = 0, list = exprList; i < list.length; i += 1) + { + var expr = list[i]; + + this.toAssignable(expr, binding); + } + return exprList +}; + +lp.parseFunctionParams = function(params) { + params = this.parseExprList(tokTypes.parenR); + return this.toAssignableList(params, true) +}; + +lp.parseMethod = function(isGenerator, isAsync) { + var node = this.startNode(), oldInAsync = this.inAsync, oldInGenerator = this.inGenerator, oldInFunction = this.inFunction; + this.initFunction(node); + if (this.options.ecmaVersion >= 6) + { node.generator = !!isGenerator; } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + this.inAsync = node.async; + this.inGenerator = node.generator; + this.inFunction = true; + node.params = this.parseFunctionParams(); + node.body = this.parseBlock(); + this.toks.adaptDirectivePrologue(node.body.body); + this.inAsync = oldInAsync; + this.inGenerator = oldInGenerator; + this.inFunction = oldInFunction; + return this.finishNode(node, "FunctionExpression") +}; + +lp.parseArrowExpression = function(node, params, isAsync) { + var oldInAsync = this.inAsync, oldInGenerator = this.inGenerator, oldInFunction = this.inFunction; + this.initFunction(node); + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + this.inAsync = node.async; + this.inGenerator = false; + this.inFunction = true; + node.params = this.toAssignableList(params, true); + node.expression = this.tok.type !== tokTypes.braceL; + if (node.expression) { + node.body = this.parseMaybeAssign(); + } else { + node.body = this.parseBlock(); + this.toks.adaptDirectivePrologue(node.body.body); + } + this.inAsync = oldInAsync; + this.inGenerator = oldInGenerator; + this.inFunction = oldInFunction; + return this.finishNode(node, "ArrowFunctionExpression") +}; + +lp.parseExprList = function(close, allowEmpty) { + this.pushCx(); + var indent = this.curIndent, line = this.curLineStart, elts = []; + this.next(); // Opening bracket + while (!this.closes(close, indent + 1, line)) { + if (this.eat(tokTypes.comma)) { + elts.push(allowEmpty ? null : this.dummyIdent()); + continue + } + var elt = this.parseMaybeAssign(); + if (isDummy(elt)) { + if (this.closes(close, indent, line)) { break } + this.next(); + } else { + elts.push(elt); + } + this.eat(tokTypes.comma); + } + this.popCx(); + if (!this.eat(close)) { + // If there is no closing brace, make the node span to the start + // of the next token (this is useful for Tern) + this.last.end = this.tok.start; + if (this.options.locations) { this.last.loc.end = this.tok.loc.start; } + } + return elts +}; + +lp.parseAwait = function() { + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeUnary(); + return this.finishNode(node, "AwaitExpression") +}; + +// Acorn: Loose parser +// +// This module provides an alternative parser that exposes that same +// interface as the main module's `parse` function, but will try to +// parse anything as JavaScript, repairing syntax error the best it +// can. There are circumstances in which it will raise an error and +// give up, but they are very rare. The resulting AST will be a mostly +// valid JavaScript AST (as per the [ESTree spec][estree], except +// that: +// +// - Return outside functions is allowed +// +// - Label consistency (no conflicts, break only to existing labels) +// is not enforced. +// +// - Bogus Identifier nodes with a name of `"✖"` are inserted whenever +// the parser got too confused to return anything meaningful. +// +// [estree]: https://github.com/estree/estree +// +// The expected use for this is to *first* try `acorn.parse`, and only +// if that fails switch to the loose parser. The loose parser might +// parse badly indented code incorrectly, so **don't** use it as your +// default parser. +// +// Quite a lot of acorn.js is duplicated here. The alternative was to +// add a *lot* of extra cruft to that file, making it less readable +// and slower. Copying and editing the code allowed me to make +// invasive changes and simplifications without creating a complicated +// tangle. + + +defaultOptions.tabSize = 4; + +function parse(input, options) { + return LooseParser.parse(input, options) +} + +export { LooseParser, isDummy, parse }; diff --git a/node_modules/acorn-loose/package.json b/node_modules/acorn-loose/package.json new file mode 100644 index 0000000..6bf5980 --- /dev/null +++ b/node_modules/acorn-loose/package.json @@ -0,0 +1,50 @@ +{ + "name": "acorn-loose", + "description": "Error-tolerant ECMAScript parser", + "homepage": "https://github.com/acornjs/acorn", + "main": "dist/acorn-loose.js", + "module": "dist/acorn-loose.mjs", + "types": "dist/acorn-loose.d.ts", + "exports": { + ".": [ + { + "import": "./dist/acorn-loose.mjs", + "require": "./dist/acorn-loose.js", + "default": "./dist/acorn-loose.js" + }, + "./dist/acorn-loose.js" + ], + "./package.json": "./package.json" + }, + "version": "8.5.2", + "engines": { + "node": ">=0.4.0" + }, + "dependencies": { + "acorn": "^8.15.0" + }, + "maintainers": [ + { + "name": "Marijn Haverbeke", + "email": "marijnh@gmail.com", + "web": "https://marijnhaverbeke.nl" + }, + { + "name": "Ingvar Stepanyan", + "email": "me@rreverser.com", + "web": "https://rreverser.com/" + }, + { + "name": "Adrian Heine", + "web": "http://adrianheine.de" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/acornjs/acorn.git" + }, + "scripts": { + "prepare": "cd ..; npm run build:loose" + }, + "license": "MIT" +} diff --git a/node_modules/acorn-walk/CHANGELOG.md b/node_modules/acorn-walk/CHANGELOG.md new file mode 100644 index 0000000..de4168f --- /dev/null +++ b/node_modules/acorn-walk/CHANGELOG.md @@ -0,0 +1,209 @@ +## 8.3.5 (2026-02-19) + +### Bug fixes + +Emit a more informative error message when trying to walk a node type that has no walker function. + +Specify callbacks in types to receive `AnyNode` type, so that they can be narrowed more easily. + +Support import attributes. + +## 8.3.4 (2024-09-09) + +### Bug fixes + +Walk SwitchCase nodes as separate nodes. + +## 8.3.3 (2024-01-11) + +### Bug fixes + +Make acorn a dependency because acorn-walk uses the types from that package. + +## 8.3.2 (2024-01-11) + +### Bug fixes + +Add missing type for `findNodeBefore`. + +## 8.3.1 (2023-12-06) + +### Bug fixes + +Add `Function` and `Class` to the `AggregateType` type, so that they can be used in walkers without raising a type error. + +Visitor functions are now called in such a way that their `this` refers to the object they are part of. + +## 8.3.0 (2023-10-26) + +### New features + +Use a set of new, much more precise, TypeScript types. + +## 8.2.0 (2021-09-06) + +### New features + +Add support for walking ES2022 class static blocks. + +## 8.1.1 (2021-06-29) + +### Bug fixes + +Include `base` in the type declarations. + +## 8.1.0 (2021-04-24) + +### New features + +Support node types for class fields and private methods. + +## 8.0.2 (2021-01-25) + +### Bug fixes + +Adjust package.json to work with Node 12.16.0 and 13.0-13.6. + +## 8.0.0 (2021-01-05) + +### Bug fixes + +Fix a bug where `full` and `fullAncestor` would skip nodes with overridden types. + +## 8.0.0 (2020-08-12) + +### New features + +The package can now be loaded directly as an ECMAScript module in node 13+. + +## 7.2.0 (2020-06-17) + +### New features + +Support optional chaining and nullish coalescing. + +Support `import.meta`. + +Add support for `export * as ns from "source"`. + +## 7.1.1 (2020-02-13) + +### Bug fixes + +Clean up the type definitions to actually work well with the main parser. + +## 7.1.0 (2020-02-11) + +### New features + +Add a TypeScript definition file for the library. + +## 7.0.0 (2017-08-12) + +### New features + +Support walking `ImportExpression` nodes. + +## 6.2.0 (2017-07-04) + +### New features + +Add support for `Import` nodes. + +## 6.1.0 (2018-09-28) + +### New features + +The walker now walks `TemplateElement` nodes. + +## 6.0.1 (2018-09-14) + +### Bug fixes + +Fix bad "main" field in package.json. + +## 6.0.0 (2018-09-14) + +### Breaking changes + +This is now a separate package, `acorn-walk`, rather than part of the main `acorn` package. + +The `ScopeBody` and `ScopeExpression` meta-node-types are no longer supported. + +## 5.7.1 (2018-06-15) + +### Bug fixes + +Make sure the walker and bin files are rebuilt on release (the previous release didn't get the up-to-date versions). + +## 5.7.0 (2018-06-15) + +### Bug fixes + +Fix crash in walker when walking a binding-less catch node. + +## 5.6.2 (2018-06-05) + +### Bug fixes + +In the walker, go back to allowing the `baseVisitor` argument to be null to default to the default base everywhere. + +## 5.6.1 (2018-06-01) + +### Bug fixes + +Fix regression when passing `null` as fourth argument to `walk.recursive`. + +## 5.6.0 (2018-05-31) + +### Bug fixes + +Fix a bug in the walker that caused a crash when walking an object pattern spread. + +## 5.5.1 (2018-03-06) + +### Bug fixes + +Fix regression in walker causing property values in object patterns to be walked as expressions. + +## 5.5.0 (2018-02-27) + +### Bug fixes + +Support object spread in the AST walker. + +## 5.4.1 (2018-02-02) + +### Bug fixes + +5.4.0 somehow accidentally included an old version of walk.js. + +## 5.2.0 (2017-10-30) + +### Bug fixes + +The `full` and `fullAncestor` walkers no longer visit nodes multiple times. + +## 5.1.0 (2017-07-05) + +### New features + +New walker functions `full` and `fullAncestor`. + +## 3.2.0 (2016-06-07) + +### New features + +Make it possible to use `visit.ancestor` with a walk state. + +## 3.1.0 (2016-04-18) + +### New features + +The walker now allows defining handlers for `CatchClause` nodes. + +## 2.5.2 (2015-10-27) + +### Fixes + +Fix bug where the walker walked an exported `let` statement as an expression. diff --git a/node_modules/acorn-walk/LICENSE b/node_modules/acorn-walk/LICENSE new file mode 100644 index 0000000..d6be6db --- /dev/null +++ b/node_modules/acorn-walk/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (C) 2012-2020 by various contributors (see AUTHORS) + +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/node_modules/acorn-walk/README.md b/node_modules/acorn-walk/README.md new file mode 100644 index 0000000..eaec57f --- /dev/null +++ b/node_modules/acorn-walk/README.md @@ -0,0 +1,124 @@ +# Acorn AST walker + +An abstract syntax tree walker for the +[ESTree](https://github.com/estree/estree) format. + +## Community + +Acorn is open source software released under an +[MIT license](https://github.com/acornjs/acorn/blob/master/acorn-walk/LICENSE). + +You are welcome to +[report bugs](https://github.com/acornjs/acorn/issues) or create pull +requests on [github](https://github.com/acornjs/acorn). + +## Installation + +The easiest way to install acorn is from [`npm`](https://www.npmjs.com/): + +```sh +npm install acorn-walk +``` + +Alternately, you can download the source and build acorn yourself: + +```sh +git clone https://github.com/acornjs/acorn.git +cd acorn +npm install +``` + +## Interface + +An algorithm for recursing through a syntax tree is stored as an +object, with a property for each tree node type holding a function +that will recurse through such a node. There are several ways to run +such a walker. + +**simple**`(node, visitors, base, state)` does a 'simple' walk over a +tree. `node` should be the AST node to walk, and `visitors` an object +with properties whose names correspond to node types in the [ESTree +spec](https://github.com/estree/estree). The properties should contain +functions that will be called with the node object and, if applicable +the state at that point. The last two arguments are optional. `base` +is a walker algorithm, and `state` is a start state. The default +walker will simply visit all statements and expressions and not +produce a meaningful state. (An example of a use of state is to track +scope at each point in the tree.) + +```js +import * as acorn from "acorn" +import * as walk from "acorn-walk" + +walk.simple(acorn.parse("let x = 10"), { + Literal(node) { + console.log(`Found a literal: ${node.value}`) + } +}) +``` + +**ancestor**`(node, visitors, base, state)` does a 'simple' walk over +a tree, building up an array of ancestor nodes (including the current node) +and passing the array to the callbacks as a third parameter. + +```js +import * as acorn from "acorn" +import * as walk from "acorn-walk" + +walk.ancestor(acorn.parse("foo('hi')"), { + Literal(_node, _state, ancestors) { + console.log("This literal's ancestors are:", ancestors.map(n => n.type)) + } +}) +``` + +**recursive**`(node, state, functions, base)` does a 'recursive' +walk, where the walker functions are responsible for continuing the +walk on the child nodes of their target node. `state` is the start +state, and `functions` should contain an object that maps node types +to walker functions. Such functions are called with `(node, state, c)` +arguments, and can cause the walk to continue on a sub-node by calling +the `c` argument on it with `(node, state)` arguments. The optional +`base` argument provides the fallback walker functions for node types +that aren't handled in the `functions` object. If not given, the +default walkers will be used. + +**make**`(functions, base)` builds a new walker object by using the +walker functions in `functions` and filling in the missing ones by +taking defaults from `base`. + +**full**`(node, callback, base, state)` does a 'full' walk over a +tree, calling the callback with the arguments (node, state, type) for +each node + +**fullAncestor**`(node, callback, base, state)` does a 'full' walk +over a tree, building up an array of ancestor nodes (including the +current node) and passing the array to the callbacks as a third +parameter. + +```js +import * as acorn from "acorn" +import * as walk from "acorn-walk" + +walk.full(acorn.parse("1 + 1"), node => { + console.log(`There's a ${node.type} node at ${node.ch}`) +}) +``` + +**findNodeAt**`(node, start, end, test, base, state)` tries to locate +a node in a tree at the given start and/or end offsets, which +satisfies the predicate `test`. `start` and `end` can be either `null` +(as wildcard) or a number. `test` may be a string (indicating a node +type) or a function that takes `(nodeType, node)` arguments and +returns a boolean indicating whether this node is interesting. `base` +and `state` are optional, and can be used to specify a custom walker. +Nodes are tested from inner to outer, so if two nodes match the +boundaries, the inner one will be preferred. + +**findNodeAround**`(node, pos, test, base, state)` is a lot like +`findNodeAt`, but will match any node that exists 'around' (spanning) +the given position. + +**findNodeAfter**`(node, pos, test, base, state)` is similar to +`findNodeAround`, but will match all nodes *after* the given position +(testing outer nodes before inner nodes). diff --git a/node_modules/acorn-walk/dist/walk.d.mts b/node_modules/acorn-walk/dist/walk.d.mts new file mode 100644 index 0000000..199c8a0 --- /dev/null +++ b/node_modules/acorn-walk/dist/walk.d.mts @@ -0,0 +1,152 @@ +import * as acorn from "acorn" + +export type FullWalkerCallback = ( + node: acorn.AnyNode, + state: TState, + type: string +) => void + +export type FullAncestorWalkerCallback = ( + node: acorn.AnyNode, + state: TState, + ancestors: acorn.AnyNode[], + type: string +) => void + +type AggregateType = { + Expression: acorn.Expression, + Statement: acorn.Statement, + Function: acorn.Function, + Class: acorn.Class, + Pattern: acorn.Pattern, + ForInit: acorn.VariableDeclaration | acorn.Expression +} + +export type SimpleVisitors = { + [type in acorn.AnyNode["type"]]?: (node: Extract, state: TState) => void +} & { + [type in keyof AggregateType]?: (node: AggregateType[type], state: TState) => void +} + +export type AncestorVisitors = { + [type in acorn.AnyNode["type"]]?: ( node: Extract, state: TState, ancestors: acorn.AnyNode[] +) => void +} & { + [type in keyof AggregateType]?: (node: AggregateType[type], state: TState, ancestors: acorn.AnyNode[]) => void +} + +export type WalkerCallback = (node: acorn.AnyNode, state: TState) => void + +export type RecursiveVisitors = { + [type in acorn.AnyNode["type"]]?: ( node: Extract, state: TState, callback: WalkerCallback) => void +} & { + [type in keyof AggregateType]?: (node: AggregateType[type], state: TState, callback: WalkerCallback) => void +} + +export type FindPredicate = (type: string, node: acorn.AnyNode) => boolean + +export interface Found { + node: acorn.AnyNode, + state: TState +} + +/** + * does a 'simple' walk over a tree + * @param node the AST node to walk + * @param visitors an object with properties whose names correspond to node types in the {@link https://github.com/estree/estree | ESTree spec}. The properties should contain functions that will be called with the node object and, if applicable the state at that point. + * @param base a walker algorithm + * @param state a start state. The default walker will simply visit all statements and expressions and not produce a meaningful state. (An example of a use of state is to track scope at each point in the tree.) + */ +export function simple( + node: acorn.Node, + visitors: SimpleVisitors, + base?: RecursiveVisitors, + state?: TState +): void + +/** + * does a 'simple' walk over a tree, building up an array of ancestor nodes (including the current node) and passing the array to the callbacks as a third parameter. + */ +export function ancestor( + node: acorn.Node, + visitors: AncestorVisitors, + base?: RecursiveVisitors, + state?: TState + ): void + +/** + * does a 'recursive' walk, where the walker functions are responsible for continuing the walk on the child nodes of their target node. + * @param node + * @param state the start state + * @param functions contain an object that maps node types to walker functions + * @param base provides the fallback walker functions for node types that aren't handled in the {@link functions} object. If not given, the default walkers will be used. + */ +export function recursive( + node: acorn.Node, + state: TState, + functions: RecursiveVisitors, + base?: RecursiveVisitors +): void + +/** + * does a 'full' walk over a tree, calling the {@link callback} with the arguments (node, state, type) for each node + */ +export function full( + node: acorn.Node, + callback: FullWalkerCallback, + base?: RecursiveVisitors, + state?: TState +): void + +/** + * does a 'full' walk over a tree, building up an array of ancestor nodes (including the current node) and passing the array to the callbacks as a third parameter. + */ +export function fullAncestor( + node: acorn.Node, + callback: FullAncestorWalkerCallback, + base?: RecursiveVisitors, + state?: TState +): void + +/** + * builds a new walker object by using the walker functions in {@link functions} and filling in the missing ones by taking defaults from {@link base}. + */ +export function make( + functions: RecursiveVisitors, + base?: RecursiveVisitors +): RecursiveVisitors + +/** + * tries to locate a node in a tree at the given start and/or end offsets, which satisfies the predicate test. {@link start} and {@link end} can be either `null` (as wildcard) or a `number`. {@link test} may be a string (indicating a node type) or a function that takes (nodeType, node) arguments and returns a boolean indicating whether this node is interesting. {@link base} and {@link state} are optional, and can be used to specify a custom walker. Nodes are tested from inner to outer, so if two nodes match the boundaries, the inner one will be preferred. + */ +export function findNodeAt( + node: acorn.Node, + start: number | undefined | null, + end?: number | undefined | null, + type?: FindPredicate | string, + base?: RecursiveVisitors, + state?: TState +): Found | undefined + +/** + * like {@link findNodeAt}, but will match any node that exists 'around' (spanning) the given position. + */ +export function findNodeAround( + node: acorn.Node, + start: number | undefined | null, + type?: FindPredicate | string, + base?: RecursiveVisitors, + state?: TState +): Found | undefined + +/** + * Find the outermost matching node after a given position. + */ +export const findNodeAfter: typeof findNodeAround + +/** + * Find the outermost matching node before a given position. + */ +export const findNodeBefore: typeof findNodeAround + +export const base: RecursiveVisitors diff --git a/node_modules/acorn-walk/dist/walk.d.ts b/node_modules/acorn-walk/dist/walk.d.ts new file mode 100644 index 0000000..199c8a0 --- /dev/null +++ b/node_modules/acorn-walk/dist/walk.d.ts @@ -0,0 +1,152 @@ +import * as acorn from "acorn" + +export type FullWalkerCallback = ( + node: acorn.AnyNode, + state: TState, + type: string +) => void + +export type FullAncestorWalkerCallback = ( + node: acorn.AnyNode, + state: TState, + ancestors: acorn.AnyNode[], + type: string +) => void + +type AggregateType = { + Expression: acorn.Expression, + Statement: acorn.Statement, + Function: acorn.Function, + Class: acorn.Class, + Pattern: acorn.Pattern, + ForInit: acorn.VariableDeclaration | acorn.Expression +} + +export type SimpleVisitors = { + [type in acorn.AnyNode["type"]]?: (node: Extract, state: TState) => void +} & { + [type in keyof AggregateType]?: (node: AggregateType[type], state: TState) => void +} + +export type AncestorVisitors = { + [type in acorn.AnyNode["type"]]?: ( node: Extract, state: TState, ancestors: acorn.AnyNode[] +) => void +} & { + [type in keyof AggregateType]?: (node: AggregateType[type], state: TState, ancestors: acorn.AnyNode[]) => void +} + +export type WalkerCallback = (node: acorn.AnyNode, state: TState) => void + +export type RecursiveVisitors = { + [type in acorn.AnyNode["type"]]?: ( node: Extract, state: TState, callback: WalkerCallback) => void +} & { + [type in keyof AggregateType]?: (node: AggregateType[type], state: TState, callback: WalkerCallback) => void +} + +export type FindPredicate = (type: string, node: acorn.AnyNode) => boolean + +export interface Found { + node: acorn.AnyNode, + state: TState +} + +/** + * does a 'simple' walk over a tree + * @param node the AST node to walk + * @param visitors an object with properties whose names correspond to node types in the {@link https://github.com/estree/estree | ESTree spec}. The properties should contain functions that will be called with the node object and, if applicable the state at that point. + * @param base a walker algorithm + * @param state a start state. The default walker will simply visit all statements and expressions and not produce a meaningful state. (An example of a use of state is to track scope at each point in the tree.) + */ +export function simple( + node: acorn.Node, + visitors: SimpleVisitors, + base?: RecursiveVisitors, + state?: TState +): void + +/** + * does a 'simple' walk over a tree, building up an array of ancestor nodes (including the current node) and passing the array to the callbacks as a third parameter. + */ +export function ancestor( + node: acorn.Node, + visitors: AncestorVisitors, + base?: RecursiveVisitors, + state?: TState + ): void + +/** + * does a 'recursive' walk, where the walker functions are responsible for continuing the walk on the child nodes of their target node. + * @param node + * @param state the start state + * @param functions contain an object that maps node types to walker functions + * @param base provides the fallback walker functions for node types that aren't handled in the {@link functions} object. If not given, the default walkers will be used. + */ +export function recursive( + node: acorn.Node, + state: TState, + functions: RecursiveVisitors, + base?: RecursiveVisitors +): void + +/** + * does a 'full' walk over a tree, calling the {@link callback} with the arguments (node, state, type) for each node + */ +export function full( + node: acorn.Node, + callback: FullWalkerCallback, + base?: RecursiveVisitors, + state?: TState +): void + +/** + * does a 'full' walk over a tree, building up an array of ancestor nodes (including the current node) and passing the array to the callbacks as a third parameter. + */ +export function fullAncestor( + node: acorn.Node, + callback: FullAncestorWalkerCallback, + base?: RecursiveVisitors, + state?: TState +): void + +/** + * builds a new walker object by using the walker functions in {@link functions} and filling in the missing ones by taking defaults from {@link base}. + */ +export function make( + functions: RecursiveVisitors, + base?: RecursiveVisitors +): RecursiveVisitors + +/** + * tries to locate a node in a tree at the given start and/or end offsets, which satisfies the predicate test. {@link start} and {@link end} can be either `null` (as wildcard) or a `number`. {@link test} may be a string (indicating a node type) or a function that takes (nodeType, node) arguments and returns a boolean indicating whether this node is interesting. {@link base} and {@link state} are optional, and can be used to specify a custom walker. Nodes are tested from inner to outer, so if two nodes match the boundaries, the inner one will be preferred. + */ +export function findNodeAt( + node: acorn.Node, + start: number | undefined | null, + end?: number | undefined | null, + type?: FindPredicate | string, + base?: RecursiveVisitors, + state?: TState +): Found | undefined + +/** + * like {@link findNodeAt}, but will match any node that exists 'around' (spanning) the given position. + */ +export function findNodeAround( + node: acorn.Node, + start: number | undefined | null, + type?: FindPredicate | string, + base?: RecursiveVisitors, + state?: TState +): Found | undefined + +/** + * Find the outermost matching node after a given position. + */ +export const findNodeAfter: typeof findNodeAround + +/** + * Find the outermost matching node before a given position. + */ +export const findNodeBefore: typeof findNodeAround + +export const base: RecursiveVisitors diff --git a/node_modules/acorn-walk/dist/walk.js b/node_modules/acorn-walk/dist/walk.js new file mode 100644 index 0000000..fe4d197 --- /dev/null +++ b/node_modules/acorn-walk/dist/walk.js @@ -0,0 +1,485 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.acorn = global.acorn || {}, global.acorn.walk = {}))); +})(this, (function (exports) { 'use strict'; + + // AST walker module for ESTree compatible trees + + // A simple walk is one where you simply specify callbacks to be + // called on specific nodes. The last two arguments are optional. A + // simple use would be + // + // walk.simple(myTree, { + // Expression: function(node) { ... } + // }); + // + // to do something with all expressions. All ESTree node types + // can be used to identify node types, as well as Expression and + // Statement, which denote categories of nodes. + // + // The base argument can be used to pass a custom (recursive) + // walker, and state can be used to give this walked an initial + // state. + + function simple(node, visitors, baseVisitor, state, override) { + if (!baseVisitor) { baseVisitor = base + ; }(function c(node, st, override) { + var type = override || node.type; + visitNode(baseVisitor, type, node, st, c); + if (visitors[type]) { visitors[type](node, st); } + })(node, state, override); + } + + // An ancestor walk keeps an array of ancestor nodes (including the + // current node) and passes them to the callback as third parameter + // (and also as state parameter when no other state is present). + function ancestor(node, visitors, baseVisitor, state, override) { + var ancestors = []; + if (!baseVisitor) { baseVisitor = base + ; }(function c(node, st, override) { + var type = override || node.type; + var isNew = node !== ancestors[ancestors.length - 1]; + if (isNew) { ancestors.push(node); } + visitNode(baseVisitor, type, node, st, c); + if (visitors[type]) { visitors[type](node, st || ancestors, ancestors); } + if (isNew) { ancestors.pop(); } + })(node, state, override); + } + + // A recursive walk is one where your functions override the default + // walkers. They can modify and replace the state parameter that's + // threaded through the walk, and can opt how and whether to walk + // their child nodes (by calling their third argument on these + // nodes). + function recursive(node, state, funcs, baseVisitor, override) { + var visitor = funcs ? make(funcs, baseVisitor || undefined) : baseVisitor + ;(function c(node, st, override) { + visitor[override || node.type](node, st, c); + })(node, state, override); + } + + function makeTest(test) { + if (typeof test === "string") + { return function (type) { return type === test; } } + else if (!test) + { return function () { return true; } } + else + { return test } + } + + var Found = function Found(node, state) { this.node = node; this.state = state; }; + + // A full walk triggers the callback on each node + function full(node, callback, baseVisitor, state, override) { + if (!baseVisitor) { baseVisitor = base; } + var last + ;(function c(node, st, override) { + var type = override || node.type; + visitNode(baseVisitor, type, node, st, c); + if (last !== node) { + callback(node, st, type); + last = node; + } + })(node, state, override); + } + + // An fullAncestor walk is like an ancestor walk, but triggers + // the callback on each node + function fullAncestor(node, callback, baseVisitor, state) { + if (!baseVisitor) { baseVisitor = base; } + var ancestors = [], last + ;(function c(node, st, override) { + var type = override || node.type; + var isNew = node !== ancestors[ancestors.length - 1]; + if (isNew) { ancestors.push(node); } + visitNode(baseVisitor, type, node, st, c); + if (last !== node) { + callback(node, st || ancestors, ancestors, type); + last = node; + } + if (isNew) { ancestors.pop(); } + })(node, state); + } + + // Find a node with a given start, end, and type (all are optional, + // null can be used as wildcard). Returns a {node, state} object, or + // undefined when it doesn't find a matching node. + function findNodeAt(node, start, end, test, baseVisitor, state) { + if (!baseVisitor) { baseVisitor = base; } + test = makeTest(test); + try { + (function c(node, st, override) { + var type = override || node.type; + if ((start == null || node.start <= start) && + (end == null || node.end >= end)) + { visitNode(baseVisitor, type, node, st, c); } + if ((start == null || node.start === start) && + (end == null || node.end === end) && + test(type, node)) + { throw new Found(node, st) } + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } + } + + // Find the innermost node of a given type that contains the given + // position. Interface similar to findNodeAt. + function findNodeAround(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + try { + (function c(node, st, override) { + var type = override || node.type; + if (node.start > pos || node.end < pos) { return } + visitNode(baseVisitor, type, node, st, c); + if (test(type, node)) { throw new Found(node, st) } + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } + } + + // Find the outermost matching node after a given position. + function findNodeAfter(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + try { + (function c(node, st, override) { + if (node.end < pos) { return } + var type = override || node.type; + if (node.start >= pos && test(type, node)) { throw new Found(node, st) } + visitNode(baseVisitor, type, node, st, c); + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } + } + + // Find the outermost matching node before a given position. + function findNodeBefore(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + var max + ;(function c(node, st, override) { + if (node.start > pos) { return } + var type = override || node.type; + if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node)) + { max = new Found(node, st); } + visitNode(baseVisitor, type, node, st, c); + })(node, state); + return max + } + + // Used to create a custom walker. Will fill in all missing node + // type properties with the defaults. + function make(funcs, baseVisitor) { + var visitor = Object.create(baseVisitor || base); + for (var type in funcs) { visitor[type] = funcs[type]; } + return visitor + } + + function skipThrough(node, st, c) { c(node, st); } + function ignore(_node, _st, _c) {} + + function visitNode(baseVisitor, type, node, st, c) { + if (baseVisitor[type] == null) { throw new Error(("No walker function defined for node type " + type)) } + baseVisitor[type](node, st, c); + } + + // Node walkers. + + var base = {}; + + base.Program = base.BlockStatement = base.StaticBlock = function (node, st, c) { + for (var i = 0, list = node.body; i < list.length; i += 1) + { + var stmt = list[i]; + + c(stmt, st, "Statement"); + } + }; + base.Statement = skipThrough; + base.EmptyStatement = ignore; + base.ExpressionStatement = base.ParenthesizedExpression = base.ChainExpression = + function (node, st, c) { return c(node.expression, st, "Expression"); }; + base.IfStatement = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.consequent, st, "Statement"); + if (node.alternate) { c(node.alternate, st, "Statement"); } + }; + base.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); }; + base.BreakStatement = base.ContinueStatement = ignore; + base.WithStatement = function (node, st, c) { + c(node.object, st, "Expression"); + c(node.body, st, "Statement"); + }; + base.SwitchStatement = function (node, st, c) { + c(node.discriminant, st, "Expression"); + for (var i = 0, list = node.cases; i < list.length; i += 1) { + var cs = list[i]; + + c(cs, st); + } + }; + base.SwitchCase = function (node, st, c) { + if (node.test) { c(node.test, st, "Expression"); } + for (var i = 0, list = node.consequent; i < list.length; i += 1) + { + var cons = list[i]; + + c(cons, st, "Statement"); + } + }; + base.ReturnStatement = base.YieldExpression = base.AwaitExpression = function (node, st, c) { + if (node.argument) { c(node.argument, st, "Expression"); } + }; + base.ThrowStatement = base.SpreadElement = + function (node, st, c) { return c(node.argument, st, "Expression"); }; + base.TryStatement = function (node, st, c) { + c(node.block, st, "Statement"); + if (node.handler) { c(node.handler, st); } + if (node.finalizer) { c(node.finalizer, st, "Statement"); } + }; + base.CatchClause = function (node, st, c) { + if (node.param) { c(node.param, st, "Pattern"); } + c(node.body, st, "Statement"); + }; + base.WhileStatement = base.DoWhileStatement = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.body, st, "Statement"); + }; + base.ForStatement = function (node, st, c) { + if (node.init) { c(node.init, st, "ForInit"); } + if (node.test) { c(node.test, st, "Expression"); } + if (node.update) { c(node.update, st, "Expression"); } + c(node.body, st, "Statement"); + }; + base.ForInStatement = base.ForOfStatement = function (node, st, c) { + c(node.left, st, "ForInit"); + c(node.right, st, "Expression"); + c(node.body, st, "Statement"); + }; + base.ForInit = function (node, st, c) { + if (node.type === "VariableDeclaration") { c(node, st); } + else { c(node, st, "Expression"); } + }; + base.DebuggerStatement = ignore; + + base.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); }; + base.VariableDeclaration = function (node, st, c) { + for (var i = 0, list = node.declarations; i < list.length; i += 1) + { + var decl = list[i]; + + c(decl, st); + } + }; + base.VariableDeclarator = function (node, st, c) { + c(node.id, st, "Pattern"); + if (node.init) { c(node.init, st, "Expression"); } + }; + + base.Function = function (node, st, c) { + if (node.id) { c(node.id, st, "Pattern"); } + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; + + c(param, st, "Pattern"); + } + c(node.body, st, node.expression ? "Expression" : "Statement"); + }; + + base.Pattern = function (node, st, c) { + if (node.type === "Identifier") + { c(node, st, "VariablePattern"); } + else if (node.type === "MemberExpression") + { c(node, st, "MemberPattern"); } + else + { c(node, st); } + }; + base.VariablePattern = ignore; + base.MemberPattern = skipThrough; + base.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); }; + base.ArrayPattern = function (node, st, c) { + for (var i = 0, list = node.elements; i < list.length; i += 1) { + var elt = list[i]; + + if (elt) { c(elt, st, "Pattern"); } + } + }; + base.ObjectPattern = function (node, st, c) { + for (var i = 0, list = node.properties; i < list.length; i += 1) { + var prop = list[i]; + + if (prop.type === "Property") { + if (prop.computed) { c(prop.key, st, "Expression"); } + c(prop.value, st, "Pattern"); + } else if (prop.type === "RestElement") { + c(prop.argument, st, "Pattern"); + } + } + }; + + base.Expression = skipThrough; + base.ThisExpression = base.Super = base.MetaProperty = ignore; + base.ArrayExpression = function (node, st, c) { + for (var i = 0, list = node.elements; i < list.length; i += 1) { + var elt = list[i]; + + if (elt) { c(elt, st, "Expression"); } + } + }; + base.ObjectExpression = function (node, st, c) { + for (var i = 0, list = node.properties; i < list.length; i += 1) + { + var prop = list[i]; + + c(prop, st); + } + }; + base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration; + base.SequenceExpression = function (node, st, c) { + for (var i = 0, list = node.expressions; i < list.length; i += 1) + { + var expr = list[i]; + + c(expr, st, "Expression"); + } + }; + base.TemplateLiteral = function (node, st, c) { + for (var i = 0, list = node.quasis; i < list.length; i += 1) + { + var quasi = list[i]; + + c(quasi, st); + } + + for (var i$1 = 0, list$1 = node.expressions; i$1 < list$1.length; i$1 += 1) + { + var expr = list$1[i$1]; + + c(expr, st, "Expression"); + } + }; + base.TemplateElement = ignore; + base.UnaryExpression = base.UpdateExpression = function (node, st, c) { + c(node.argument, st, "Expression"); + }; + base.BinaryExpression = base.LogicalExpression = function (node, st, c) { + c(node.left, st, "Expression"); + c(node.right, st, "Expression"); + }; + base.AssignmentExpression = base.AssignmentPattern = function (node, st, c) { + c(node.left, st, "Pattern"); + c(node.right, st, "Expression"); + }; + base.ConditionalExpression = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.consequent, st, "Expression"); + c(node.alternate, st, "Expression"); + }; + base.NewExpression = base.CallExpression = function (node, st, c) { + c(node.callee, st, "Expression"); + if (node.arguments) + { for (var i = 0, list = node.arguments; i < list.length; i += 1) + { + var arg = list[i]; + + c(arg, st, "Expression"); + } } + }; + base.MemberExpression = function (node, st, c) { + c(node.object, st, "Expression"); + if (node.computed) { c(node.property, st, "Expression"); } + }; + base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) { + if (node.declaration) + { c(node.declaration, st, node.type === "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression"); } + if (node.source) { c(node.source, st, "Expression"); } + if (node.attributes) + { for (var i = 0, list = node.attributes; i < list.length; i += 1) + { + var attr = list[i]; + + c(attr, st); + } } + }; + base.ExportAllDeclaration = function (node, st, c) { + if (node.exported) + { c(node.exported, st); } + c(node.source, st, "Expression"); + if (node.attributes) + { for (var i = 0, list = node.attributes; i < list.length; i += 1) + { + var attr = list[i]; + + c(attr, st); + } } + }; + base.ImportAttribute = function (node, st, c) { + c(node.value, st, "Expression"); + }; + base.ImportDeclaration = function (node, st, c) { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) + { + var spec = list[i]; + + c(spec, st); + } + c(node.source, st, "Expression"); + if (node.attributes) + { for (var i$1 = 0, list$1 = node.attributes; i$1 < list$1.length; i$1 += 1) + { + var attr = list$1[i$1]; + + c(attr, st); + } } + }; + base.ImportExpression = function (node, st, c) { + c(node.source, st, "Expression"); + if (node.options) { c(node.options, st, "Expression"); } + }; + base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.PrivateIdentifier = base.Literal = ignore; + + base.TaggedTemplateExpression = function (node, st, c) { + c(node.tag, st, "Expression"); + c(node.quasi, st, "Expression"); + }; + base.ClassDeclaration = base.ClassExpression = function (node, st, c) { return c(node, st, "Class"); }; + base.Class = function (node, st, c) { + if (node.id) { c(node.id, st, "Pattern"); } + if (node.superClass) { c(node.superClass, st, "Expression"); } + c(node.body, st); + }; + base.ClassBody = function (node, st, c) { + for (var i = 0, list = node.body; i < list.length; i += 1) + { + var elt = list[i]; + + c(elt, st); + } + }; + base.MethodDefinition = base.PropertyDefinition = base.Property = function (node, st, c) { + if (node.computed) { c(node.key, st, "Expression"); } + if (node.value) { c(node.value, st, "Expression"); } + }; + + exports.ancestor = ancestor; + exports.base = base; + exports.findNodeAfter = findNodeAfter; + exports.findNodeAround = findNodeAround; + exports.findNodeAt = findNodeAt; + exports.findNodeBefore = findNodeBefore; + exports.full = full; + exports.fullAncestor = fullAncestor; + exports.make = make; + exports.recursive = recursive; + exports.simple = simple; + +})); diff --git a/node_modules/acorn-walk/dist/walk.mjs b/node_modules/acorn-walk/dist/walk.mjs new file mode 100644 index 0000000..88f18bb --- /dev/null +++ b/node_modules/acorn-walk/dist/walk.mjs @@ -0,0 +1,467 @@ +// AST walker module for ESTree compatible trees + +// A simple walk is one where you simply specify callbacks to be +// called on specific nodes. The last two arguments are optional. A +// simple use would be +// +// walk.simple(myTree, { +// Expression: function(node) { ... } +// }); +// +// to do something with all expressions. All ESTree node types +// can be used to identify node types, as well as Expression and +// Statement, which denote categories of nodes. +// +// The base argument can be used to pass a custom (recursive) +// walker, and state can be used to give this walked an initial +// state. + +function simple(node, visitors, baseVisitor, state, override) { + if (!baseVisitor) { baseVisitor = base + ; }(function c(node, st, override) { + var type = override || node.type; + visitNode(baseVisitor, type, node, st, c); + if (visitors[type]) { visitors[type](node, st); } + })(node, state, override); +} + +// An ancestor walk keeps an array of ancestor nodes (including the +// current node) and passes them to the callback as third parameter +// (and also as state parameter when no other state is present). +function ancestor(node, visitors, baseVisitor, state, override) { + var ancestors = []; + if (!baseVisitor) { baseVisitor = base + ; }(function c(node, st, override) { + var type = override || node.type; + var isNew = node !== ancestors[ancestors.length - 1]; + if (isNew) { ancestors.push(node); } + visitNode(baseVisitor, type, node, st, c); + if (visitors[type]) { visitors[type](node, st || ancestors, ancestors); } + if (isNew) { ancestors.pop(); } + })(node, state, override); +} + +// A recursive walk is one where your functions override the default +// walkers. They can modify and replace the state parameter that's +// threaded through the walk, and can opt how and whether to walk +// their child nodes (by calling their third argument on these +// nodes). +function recursive(node, state, funcs, baseVisitor, override) { + var visitor = funcs ? make(funcs, baseVisitor || undefined) : baseVisitor + ;(function c(node, st, override) { + visitor[override || node.type](node, st, c); + })(node, state, override); +} + +function makeTest(test) { + if (typeof test === "string") + { return function (type) { return type === test; } } + else if (!test) + { return function () { return true; } } + else + { return test } +} + +var Found = function Found(node, state) { this.node = node; this.state = state; }; + +// A full walk triggers the callback on each node +function full(node, callback, baseVisitor, state, override) { + if (!baseVisitor) { baseVisitor = base; } + var last + ;(function c(node, st, override) { + var type = override || node.type; + visitNode(baseVisitor, type, node, st, c); + if (last !== node) { + callback(node, st, type); + last = node; + } + })(node, state, override); +} + +// An fullAncestor walk is like an ancestor walk, but triggers +// the callback on each node +function fullAncestor(node, callback, baseVisitor, state) { + if (!baseVisitor) { baseVisitor = base; } + var ancestors = [], last + ;(function c(node, st, override) { + var type = override || node.type; + var isNew = node !== ancestors[ancestors.length - 1]; + if (isNew) { ancestors.push(node); } + visitNode(baseVisitor, type, node, st, c); + if (last !== node) { + callback(node, st || ancestors, ancestors, type); + last = node; + } + if (isNew) { ancestors.pop(); } + })(node, state); +} + +// Find a node with a given start, end, and type (all are optional, +// null can be used as wildcard). Returns a {node, state} object, or +// undefined when it doesn't find a matching node. +function findNodeAt(node, start, end, test, baseVisitor, state) { + if (!baseVisitor) { baseVisitor = base; } + test = makeTest(test); + try { + (function c(node, st, override) { + var type = override || node.type; + if ((start == null || node.start <= start) && + (end == null || node.end >= end)) + { visitNode(baseVisitor, type, node, st, c); } + if ((start == null || node.start === start) && + (end == null || node.end === end) && + test(type, node)) + { throw new Found(node, st) } + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } +} + +// Find the innermost node of a given type that contains the given +// position. Interface similar to findNodeAt. +function findNodeAround(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + try { + (function c(node, st, override) { + var type = override || node.type; + if (node.start > pos || node.end < pos) { return } + visitNode(baseVisitor, type, node, st, c); + if (test(type, node)) { throw new Found(node, st) } + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } +} + +// Find the outermost matching node after a given position. +function findNodeAfter(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + try { + (function c(node, st, override) { + if (node.end < pos) { return } + var type = override || node.type; + if (node.start >= pos && test(type, node)) { throw new Found(node, st) } + visitNode(baseVisitor, type, node, st, c); + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } +} + +// Find the outermost matching node before a given position. +function findNodeBefore(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + var max + ;(function c(node, st, override) { + if (node.start > pos) { return } + var type = override || node.type; + if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node)) + { max = new Found(node, st); } + visitNode(baseVisitor, type, node, st, c); + })(node, state); + return max +} + +// Used to create a custom walker. Will fill in all missing node +// type properties with the defaults. +function make(funcs, baseVisitor) { + var visitor = Object.create(baseVisitor || base); + for (var type in funcs) { visitor[type] = funcs[type]; } + return visitor +} + +function skipThrough(node, st, c) { c(node, st); } +function ignore(_node, _st, _c) {} + +function visitNode(baseVisitor, type, node, st, c) { + if (baseVisitor[type] == null) { throw new Error(("No walker function defined for node type " + type)) } + baseVisitor[type](node, st, c); +} + +// Node walkers. + +var base = {}; + +base.Program = base.BlockStatement = base.StaticBlock = function (node, st, c) { + for (var i = 0, list = node.body; i < list.length; i += 1) + { + var stmt = list[i]; + + c(stmt, st, "Statement"); + } +}; +base.Statement = skipThrough; +base.EmptyStatement = ignore; +base.ExpressionStatement = base.ParenthesizedExpression = base.ChainExpression = + function (node, st, c) { return c(node.expression, st, "Expression"); }; +base.IfStatement = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.consequent, st, "Statement"); + if (node.alternate) { c(node.alternate, st, "Statement"); } +}; +base.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); }; +base.BreakStatement = base.ContinueStatement = ignore; +base.WithStatement = function (node, st, c) { + c(node.object, st, "Expression"); + c(node.body, st, "Statement"); +}; +base.SwitchStatement = function (node, st, c) { + c(node.discriminant, st, "Expression"); + for (var i = 0, list = node.cases; i < list.length; i += 1) { + var cs = list[i]; + + c(cs, st); + } +}; +base.SwitchCase = function (node, st, c) { + if (node.test) { c(node.test, st, "Expression"); } + for (var i = 0, list = node.consequent; i < list.length; i += 1) + { + var cons = list[i]; + + c(cons, st, "Statement"); + } +}; +base.ReturnStatement = base.YieldExpression = base.AwaitExpression = function (node, st, c) { + if (node.argument) { c(node.argument, st, "Expression"); } +}; +base.ThrowStatement = base.SpreadElement = + function (node, st, c) { return c(node.argument, st, "Expression"); }; +base.TryStatement = function (node, st, c) { + c(node.block, st, "Statement"); + if (node.handler) { c(node.handler, st); } + if (node.finalizer) { c(node.finalizer, st, "Statement"); } +}; +base.CatchClause = function (node, st, c) { + if (node.param) { c(node.param, st, "Pattern"); } + c(node.body, st, "Statement"); +}; +base.WhileStatement = base.DoWhileStatement = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.body, st, "Statement"); +}; +base.ForStatement = function (node, st, c) { + if (node.init) { c(node.init, st, "ForInit"); } + if (node.test) { c(node.test, st, "Expression"); } + if (node.update) { c(node.update, st, "Expression"); } + c(node.body, st, "Statement"); +}; +base.ForInStatement = base.ForOfStatement = function (node, st, c) { + c(node.left, st, "ForInit"); + c(node.right, st, "Expression"); + c(node.body, st, "Statement"); +}; +base.ForInit = function (node, st, c) { + if (node.type === "VariableDeclaration") { c(node, st); } + else { c(node, st, "Expression"); } +}; +base.DebuggerStatement = ignore; + +base.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); }; +base.VariableDeclaration = function (node, st, c) { + for (var i = 0, list = node.declarations; i < list.length; i += 1) + { + var decl = list[i]; + + c(decl, st); + } +}; +base.VariableDeclarator = function (node, st, c) { + c(node.id, st, "Pattern"); + if (node.init) { c(node.init, st, "Expression"); } +}; + +base.Function = function (node, st, c) { + if (node.id) { c(node.id, st, "Pattern"); } + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; + + c(param, st, "Pattern"); + } + c(node.body, st, node.expression ? "Expression" : "Statement"); +}; + +base.Pattern = function (node, st, c) { + if (node.type === "Identifier") + { c(node, st, "VariablePattern"); } + else if (node.type === "MemberExpression") + { c(node, st, "MemberPattern"); } + else + { c(node, st); } +}; +base.VariablePattern = ignore; +base.MemberPattern = skipThrough; +base.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); }; +base.ArrayPattern = function (node, st, c) { + for (var i = 0, list = node.elements; i < list.length; i += 1) { + var elt = list[i]; + + if (elt) { c(elt, st, "Pattern"); } + } +}; +base.ObjectPattern = function (node, st, c) { + for (var i = 0, list = node.properties; i < list.length; i += 1) { + var prop = list[i]; + + if (prop.type === "Property") { + if (prop.computed) { c(prop.key, st, "Expression"); } + c(prop.value, st, "Pattern"); + } else if (prop.type === "RestElement") { + c(prop.argument, st, "Pattern"); + } + } +}; + +base.Expression = skipThrough; +base.ThisExpression = base.Super = base.MetaProperty = ignore; +base.ArrayExpression = function (node, st, c) { + for (var i = 0, list = node.elements; i < list.length; i += 1) { + var elt = list[i]; + + if (elt) { c(elt, st, "Expression"); } + } +}; +base.ObjectExpression = function (node, st, c) { + for (var i = 0, list = node.properties; i < list.length; i += 1) + { + var prop = list[i]; + + c(prop, st); + } +}; +base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration; +base.SequenceExpression = function (node, st, c) { + for (var i = 0, list = node.expressions; i < list.length; i += 1) + { + var expr = list[i]; + + c(expr, st, "Expression"); + } +}; +base.TemplateLiteral = function (node, st, c) { + for (var i = 0, list = node.quasis; i < list.length; i += 1) + { + var quasi = list[i]; + + c(quasi, st); + } + + for (var i$1 = 0, list$1 = node.expressions; i$1 < list$1.length; i$1 += 1) + { + var expr = list$1[i$1]; + + c(expr, st, "Expression"); + } +}; +base.TemplateElement = ignore; +base.UnaryExpression = base.UpdateExpression = function (node, st, c) { + c(node.argument, st, "Expression"); +}; +base.BinaryExpression = base.LogicalExpression = function (node, st, c) { + c(node.left, st, "Expression"); + c(node.right, st, "Expression"); +}; +base.AssignmentExpression = base.AssignmentPattern = function (node, st, c) { + c(node.left, st, "Pattern"); + c(node.right, st, "Expression"); +}; +base.ConditionalExpression = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.consequent, st, "Expression"); + c(node.alternate, st, "Expression"); +}; +base.NewExpression = base.CallExpression = function (node, st, c) { + c(node.callee, st, "Expression"); + if (node.arguments) + { for (var i = 0, list = node.arguments; i < list.length; i += 1) + { + var arg = list[i]; + + c(arg, st, "Expression"); + } } +}; +base.MemberExpression = function (node, st, c) { + c(node.object, st, "Expression"); + if (node.computed) { c(node.property, st, "Expression"); } +}; +base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) { + if (node.declaration) + { c(node.declaration, st, node.type === "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression"); } + if (node.source) { c(node.source, st, "Expression"); } + if (node.attributes) + { for (var i = 0, list = node.attributes; i < list.length; i += 1) + { + var attr = list[i]; + + c(attr, st); + } } +}; +base.ExportAllDeclaration = function (node, st, c) { + if (node.exported) + { c(node.exported, st); } + c(node.source, st, "Expression"); + if (node.attributes) + { for (var i = 0, list = node.attributes; i < list.length; i += 1) + { + var attr = list[i]; + + c(attr, st); + } } +}; +base.ImportAttribute = function (node, st, c) { + c(node.value, st, "Expression"); +}; +base.ImportDeclaration = function (node, st, c) { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) + { + var spec = list[i]; + + c(spec, st); + } + c(node.source, st, "Expression"); + if (node.attributes) + { for (var i$1 = 0, list$1 = node.attributes; i$1 < list$1.length; i$1 += 1) + { + var attr = list$1[i$1]; + + c(attr, st); + } } +}; +base.ImportExpression = function (node, st, c) { + c(node.source, st, "Expression"); + if (node.options) { c(node.options, st, "Expression"); } +}; +base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.PrivateIdentifier = base.Literal = ignore; + +base.TaggedTemplateExpression = function (node, st, c) { + c(node.tag, st, "Expression"); + c(node.quasi, st, "Expression"); +}; +base.ClassDeclaration = base.ClassExpression = function (node, st, c) { return c(node, st, "Class"); }; +base.Class = function (node, st, c) { + if (node.id) { c(node.id, st, "Pattern"); } + if (node.superClass) { c(node.superClass, st, "Expression"); } + c(node.body, st); +}; +base.ClassBody = function (node, st, c) { + for (var i = 0, list = node.body; i < list.length; i += 1) + { + var elt = list[i]; + + c(elt, st); + } +}; +base.MethodDefinition = base.PropertyDefinition = base.Property = function (node, st, c) { + if (node.computed) { c(node.key, st, "Expression"); } + if (node.value) { c(node.value, st, "Expression"); } +}; + +export { ancestor, base, findNodeAfter, findNodeAround, findNodeAt, findNodeBefore, full, fullAncestor, make, recursive, simple }; diff --git a/node_modules/acorn-walk/package.json b/node_modules/acorn-walk/package.json new file mode 100644 index 0000000..362add8 --- /dev/null +++ b/node_modules/acorn-walk/package.json @@ -0,0 +1,50 @@ +{ + "name": "acorn-walk", + "description": "ECMAScript (ESTree) AST walker", + "homepage": "https://github.com/acornjs/acorn", + "main": "dist/walk.js", + "types": "dist/walk.d.ts", + "module": "dist/walk.mjs", + "exports": { + ".": [ + { + "import": "./dist/walk.mjs", + "require": "./dist/walk.js", + "default": "./dist/walk.js" + }, + "./dist/walk.js" + ], + "./package.json": "./package.json" + }, + "version": "8.3.5", + "engines": { + "node": ">=0.4.0" + }, + "dependencies": { + "acorn": "^8.11.0" + }, + "maintainers": [ + { + "name": "Marijn Haverbeke", + "email": "marijnh@gmail.com", + "web": "https://marijnhaverbeke.nl" + }, + { + "name": "Ingvar Stepanyan", + "email": "me@rreverser.com", + "web": "https://rreverser.com/" + }, + { + "name": "Adrian Heine", + "web": "http://adrianheine.de" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/acornjs/acorn.git" + }, + "scripts": { + "prepare": "cd ..; npm run build:walk" + }, + "license": "MIT" +} diff --git a/node_modules/acorn/CHANGELOG.md b/node_modules/acorn/CHANGELOG.md new file mode 100644 index 0000000..d18759a --- /dev/null +++ b/node_modules/acorn/CHANGELOG.md @@ -0,0 +1,972 @@ +## 8.16.0 (2026-02-19) + +### New features + +The `sourceType` option can now be set to `"commonjs"` to have the parser treat the top level scope as a function scope. + +Add support for Unicode 17. + +### Bug fixes + +Don't recognize `await using` as contextual keywords when followed directly by a backslash. + +Fix an issue where the parser would allow `return` statements in `static` blocks when `allowReturnOutsideFunction` was enabled. + +Properly reject `using` declarations that appear directly in `switch` or `for` head scopes. + +Fix some corner case issues in the recognition of `using` syntax. + +## 8.15.0 (2025-06-08) + +### New features + +Support `using` and `await using` syntax. + +The `AnyNode` type is now defined in such a way that plugins can extend it. + +### Bug fixes + +Fix an issue where the `bigint` property of literal nodes for non-decimal bigints had the wrong format. + +The `acorn` CLI tool no longer crashes when emitting a tree that contains a bigint. + +## 8.14.1 (2025-03-05) + +### Bug fixes + +Fix an issue where `await` expressions in class field initializers were inappropriately allowed. + +Properly allow await inside an async arrow function inside a class field initializer. + +Mention the source file name in syntax error messages when given. + +Properly add an empty `attributes` property to every form of `ExportNamedDeclaration`. + +## 8.14.0 (2024-10-27) + +### New features + +Support ES2025 import attributes. + +Support ES2025 RegExp modifiers. + +### Bug fixes + +Support some missing Unicode properties. + +## 8.13.0 (2024-10-16) + +### New features + +Upgrade to Unicode 16.0. + +## 8.12.1 (2024-07-03) + +### Bug fixes + +Fix a regression that caused Acorn to no longer run on Node versions <8.10. + +## 8.12.0 (2024-06-14) + +### New features + +Support ES2025 duplicate capture group names in regular expressions. + +### Bug fixes + +Include `VariableDeclarator` in the `AnyNode` type so that walker objects can refer to it without getting a type error. + +Properly raise a parse error for invalid `for`/`of` statements using `async` as binding name. + +Properly recognize \"use strict\" when preceded by a string with an escaped newline. + +Mark the `Parser` constructor as protected, not private, so plugins can extend it without type errors. + +Fix a bug where some invalid `delete` expressions were let through when the operand was parenthesized and `preserveParens` was enabled. + +Properly normalize line endings in raw strings of invalid template tokens. + +Properly track line numbers for escaped newlines in strings. + +Fix a bug that broke line number accounting after a template literal with invalid escape sequences. + +## 8.11.3 (2023-12-29) + +### Bug fixes + +Add `Function` and `Class` to the `AggregateType` type, so that they can be used in walkers without raising a type error. + +Make sure `onToken` get an `import` keyword token when parsing `import.meta`. + +Fix a bug where `.loc.start` could be undefined for `new.target` `meta` nodes. + +## 8.11.2 (2023-10-27) + +### Bug fixes + +Fix a bug that caused regular expressions after colon tokens to not be properly tokenized in some circumstances. + +## 8.11.1 (2023-10-26) + +### Bug fixes + +Fix a regression where `onToken` would receive 'name' tokens for 'new' keyword tokens. + +## 8.11.0 (2023-10-26) + +### Bug fixes + +Fix an issue where tokenizing (without parsing) an object literal with a property named `class` or `function` could, in some circumstance, put the tokenizer into an invalid state. + +Fix an issue where a slash after a call to a propery named the same as some keywords would be tokenized as a regular expression. + +### New features + +Upgrade to Unicode 15.1. + +Use a set of new, much more precise, TypeScript types. + +## 8.10.0 (2023-07-05) + +### New features + +Add a `checkPrivateFields` option that disables strict checking of private property use. + +## 8.9.0 (2023-06-16) + +### Bug fixes + +Forbid dynamic import after `new`, even when part of a member expression. + +### New features + +Add Unicode properties for ES2023. + +Add support for the `v` flag to regular expressions. + +## 8.8.2 (2023-01-23) + +### Bug fixes + +Fix a bug that caused `allowHashBang` to be set to false when not provided, even with `ecmaVersion >= 14`. + +Fix an exception when passing no option object to `parse` or `new Parser`. + +Fix incorrect parse error on `if (0) let\n[astral identifier char]`. + +## 8.8.1 (2022-10-24) + +### Bug fixes + +Make type for `Comment` compatible with estree types. + +## 8.8.0 (2022-07-21) + +### Bug fixes + +Allow parentheses around spread args in destructuring object assignment. + +Fix an issue where the tree contained `directive` properties in when parsing with a language version that doesn't support them. + +### New features + +Support hashbang comments by default in ECMAScript 2023 and later. + +## 8.7.1 (2021-04-26) + +### Bug fixes + +Stop handling `"use strict"` directives in ECMAScript versions before 5. + +Fix an issue where duplicate quoted export names in `export *` syntax were incorrectly checked. + +Add missing type for `tokTypes`. + +## 8.7.0 (2021-12-27) + +### New features + +Support quoted export names. + +Upgrade to Unicode 14. + +Add support for Unicode 13 properties in regular expressions. + +### Bug fixes + +Use a loop to find line breaks, because the existing regexp search would overrun the end of the searched range and waste a lot of time in minified code. + +## 8.6.0 (2021-11-18) + +### Bug fixes + +Fix a bug where an object literal with multiple `__proto__` properties would incorrectly be accepted if a later property value held an assigment. + +### New features + +Support class private fields with the `in` operator. + +## 8.5.0 (2021-09-06) + +### Bug fixes + +Improve context-dependent tokenization in a number of corner cases. + +Fix location tracking after a 0x2028 or 0x2029 character in a string literal (which before did not increase the line number). + +Fix an issue where arrow function bodies in for loop context would inappropriately consume `in` operators. + +Fix wrong end locations stored on SequenceExpression nodes. + +Implement restriction that `for`/`of` loop LHS can't start with `let`. + +### New features + +Add support for ES2022 class static blocks. + +Allow multiple input files to be passed to the CLI tool. + +## 8.4.1 (2021-06-24) + +### Bug fixes + +Fix a bug where `allowAwaitOutsideFunction` would allow `await` in class field initializers, and setting `ecmaVersion` to 13 or higher would allow top-level await in non-module sources. + +## 8.4.0 (2021-06-11) + +### New features + +A new option, `allowSuperOutsideMethod`, can be used to suppress the error when `super` is used in the wrong context. + +## 8.3.0 (2021-05-31) + +### New features + +Default `allowAwaitOutsideFunction` to true for ECMAScript 2022 an higher. + +Add support for the `d` ([indices](https://github.com/tc39/proposal-regexp-match-indices)) regexp flag. + +## 8.2.4 (2021-05-04) + +### Bug fixes + +Fix spec conformity in corner case 'for await (async of ...)'. + +## 8.2.3 (2021-05-04) + +### Bug fixes + +Fix an issue where the library couldn't parse 'for (async of ...)'. + +Fix a bug in UTF-16 decoding that would read characters incorrectly in some circumstances. + +## 8.2.2 (2021-04-29) + +### Bug fixes + +Fix a bug where a class field initialized to an async arrow function wouldn't allow await inside it. Same issue existed for generator arrow functions with yield. + +## 8.2.1 (2021-04-24) + +### Bug fixes + +Fix a regression introduced in 8.2.0 where static or async class methods with keyword names fail to parse. + +## 8.2.0 (2021-04-24) + +### New features + +Add support for ES2022 class fields and private methods. + +## 8.1.1 (2021-04-12) + +### Various + +Stop shipping source maps in the NPM package. + +## 8.1.0 (2021-03-09) + +### Bug fixes + +Fix a spurious error in nested destructuring arrays. + +### New features + +Expose `allowAwaitOutsideFunction` in CLI interface. + +Make `allowImportExportAnywhere` also apply to `import.meta`. + +## 8.0.5 (2021-01-25) + +### Bug fixes + +Adjust package.json to work with Node 12.16.0 and 13.0-13.6. + +## 8.0.4 (2020-10-05) + +### Bug fixes + +Make `await x ** y` an error, following the spec. + +Fix potentially exponential regular expression. + +## 8.0.3 (2020-10-02) + +### Bug fixes + +Fix a wasteful loop during `Parser` creation when setting `ecmaVersion` to `"latest"`. + +## 8.0.2 (2020-09-30) + +### Bug fixes + +Make the TypeScript types reflect the current allowed values for `ecmaVersion`. + +Fix another regexp/division tokenizer issue. + +## 8.0.1 (2020-08-12) + +### Bug fixes + +Provide the correct value in the `version` export. + +## 8.0.0 (2020-08-12) + +### Bug fixes + +Disallow expressions like `(a = b) = c`. + +Make non-octal escape sequences a syntax error in strict mode. + +### New features + +The package can now be loaded directly as an ECMAScript module in node 13+. + +Update to the set of Unicode properties from ES2021. + +### Breaking changes + +The `ecmaVersion` option is now required. For the moment, omitting it will still work with a warning, but that will change in a future release. + +Some changes to method signatures that may be used by plugins. + +## 7.4.0 (2020-08-03) + +### New features + +Add support for logical assignment operators. + +Add support for numeric separators. + +## 7.3.1 (2020-06-11) + +### Bug fixes + +Make the string in the `version` export match the actual library version. + +## 7.3.0 (2020-06-11) + +### Bug fixes + +Fix a bug that caused parsing of object patterns with a property named `set` that had a default value to fail. + +### New features + +Add support for optional chaining (`?.`). + +## 7.2.0 (2020-05-09) + +### Bug fixes + +Fix precedence issue in parsing of async arrow functions. + +### New features + +Add support for nullish coalescing. + +Add support for `import.meta`. + +Support `export * as ...` syntax. + +Upgrade to Unicode 13. + +## 6.4.1 (2020-03-09) + +### Bug fixes + +More carefully check for valid UTF16 surrogate pairs in regexp validator. + +## 7.1.1 (2020-03-01) + +### Bug fixes + +Treat `\8` and `\9` as invalid escapes in template strings. + +Allow unicode escapes in property names that are keywords. + +Don't error on an exponential operator expression as argument to `await`. + +More carefully check for valid UTF16 surrogate pairs in regexp validator. + +## 7.1.0 (2019-09-24) + +### Bug fixes + +Disallow trailing object literal commas when ecmaVersion is less than 5. + +### New features + +Add a static `acorn` property to the `Parser` class that contains the entire module interface, to allow plugins to access the instance of the library that they are acting on. + +## 7.0.0 (2019-08-13) + +### Breaking changes + +Changes the node format for dynamic imports to use the `ImportExpression` node type, as defined in [ESTree](https://github.com/estree/estree/blob/master/es2020.md#importexpression). + +Makes 10 (ES2019) the default value for the `ecmaVersion` option. + +## 6.3.0 (2019-08-12) + +### New features + +`sourceType: "module"` can now be used even when `ecmaVersion` is less than 6, to parse module-style code that otherwise conforms to an older standard. + +## 6.2.1 (2019-07-21) + +### Bug fixes + +Fix bug causing Acorn to treat some characters as identifier characters that shouldn't be treated as such. + +Fix issue where setting the `allowReserved` option to `"never"` allowed reserved words in some circumstances. + +## 6.2.0 (2019-07-04) + +### Bug fixes + +Improve valid assignment checking in `for`/`in` and `for`/`of` loops. + +Disallow binding `let` in patterns. + +### New features + +Support bigint syntax with `ecmaVersion` >= 11. + +Support dynamic `import` syntax with `ecmaVersion` >= 11. + +Upgrade to Unicode version 12. + +## 6.1.1 (2019-02-27) + +### Bug fixes + +Fix bug that caused parsing default exports of with names to fail. + +## 6.1.0 (2019-02-08) + +### Bug fixes + +Fix scope checking when redefining a `var` as a lexical binding. + +### New features + +Split up `parseSubscripts` to use an internal `parseSubscript` method to make it easier to extend with plugins. + +## 6.0.7 (2019-02-04) + +### Bug fixes + +Check that exported bindings are defined. + +Don't treat `\u180e` as a whitespace character. + +Check for duplicate parameter names in methods. + +Don't allow shorthand properties when they are generators or async methods. + +Forbid binding `await` in async arrow function's parameter list. + +## 6.0.6 (2019-01-30) + +### Bug fixes + +The content of class declarations and expressions is now always parsed in strict mode. + +Don't allow `let` or `const` to bind the variable name `let`. + +Treat class declarations as lexical. + +Don't allow a generator function declaration as the sole body of an `if` or `else`. + +Ignore `"use strict"` when after an empty statement. + +Allow string line continuations with special line terminator characters. + +Treat `for` bodies as part of the `for` scope when checking for conflicting bindings. + +Fix bug with parsing `yield` in a `for` loop initializer. + +Implement special cases around scope checking for functions. + +## 6.0.5 (2019-01-02) + +### Bug fixes + +Fix TypeScript type for `Parser.extend` and add `allowAwaitOutsideFunction` to options type. + +Don't treat `let` as a keyword when the next token is `{` on the next line. + +Fix bug that broke checking for parentheses around an object pattern in a destructuring assignment when `preserveParens` was on. + +## 6.0.4 (2018-11-05) + +### Bug fixes + +Further improvements to tokenizing regular expressions in corner cases. + +## 6.0.3 (2018-11-04) + +### Bug fixes + +Fix bug in tokenizing an expression-less return followed by a function followed by a regular expression. + +Remove stray symlink in the package tarball. + +## 6.0.2 (2018-09-26) + +### Bug fixes + +Fix bug where default expressions could fail to parse inside an object destructuring assignment expression. + +## 6.0.1 (2018-09-14) + +### Bug fixes + +Fix wrong value in `version` export. + +## 6.0.0 (2018-09-14) + +### Bug fixes + +Better handle variable-redefinition checks for catch bindings and functions directly under if statements. + +Forbid `new.target` in top-level arrow functions. + +Fix issue with parsing a regexp after `yield` in some contexts. + +### New features + +The package now comes with TypeScript definitions. + +### Breaking changes + +The default value of the `ecmaVersion` option is now 9 (2018). + +Plugins work differently, and will have to be rewritten to work with this version. + +The loose parser and walker have been moved into separate packages (`acorn-loose` and `acorn-walk`). + +## 5.7.3 (2018-09-10) + +### Bug fixes + +Fix failure to tokenize regexps after expressions like `x.of`. + +Better error message for unterminated template literals. + +## 5.7.2 (2018-08-24) + +### Bug fixes + +Properly handle `allowAwaitOutsideFunction` in for statements. + +Treat function declarations at the top level of modules like let bindings. + +Don't allow async function declarations as the only statement under a label. + +## 5.7.0 (2018-06-15) + +### New features + +Upgraded to Unicode 11. + +## 5.6.0 (2018-05-31) + +### New features + +Allow U+2028 and U+2029 in string when ECMAVersion >= 10. + +Allow binding-less catch statements when ECMAVersion >= 10. + +Add `allowAwaitOutsideFunction` option for parsing top-level `await`. + +## 5.5.3 (2018-03-08) + +### Bug fixes + +A _second_ republish of the code in 5.5.1, this time with yarn, to hopefully get valid timestamps. + +## 5.5.2 (2018-03-08) + +### Bug fixes + +A republish of the code in 5.5.1 in an attempt to solve an issue with the file timestamps in the npm package being 0. + +## 5.5.1 (2018-03-06) + +### Bug fixes + +Fix misleading error message for octal escapes in template strings. + +## 5.5.0 (2018-02-27) + +### New features + +The identifier character categorization is now based on Unicode version 10. + +Acorn will now validate the content of regular expressions, including new ES9 features. + +## 5.4.0 (2018-02-01) + +### Bug fixes + +Disallow duplicate or escaped flags on regular expressions. + +Disallow octal escapes in strings in strict mode. + +### New features + +Add support for async iteration. + +Add support for object spread and rest. + +## 5.3.0 (2017-12-28) + +### Bug fixes + +Fix parsing of floating point literals with leading zeroes in loose mode. + +Allow duplicate property names in object patterns. + +Don't allow static class methods named `prototype`. + +Disallow async functions directly under `if` or `else`. + +Parse right-hand-side of `for`/`of` as an assignment expression. + +Stricter parsing of `for`/`in`. + +Don't allow unicode escapes in contextual keywords. + +### New features + +Parsing class members was factored into smaller methods to allow plugins to hook into it. + +## 5.2.1 (2017-10-30) + +### Bug fixes + +Fix a token context corruption bug. + +## 5.2.0 (2017-10-30) + +### Bug fixes + +Fix token context tracking for `class` and `function` in property-name position. + +Make sure `%*` isn't parsed as a valid operator. + +Allow shorthand properties `get` and `set` to be followed by default values. + +Disallow `super` when not in callee or object position. + +### New features + +Support [`directive` property](https://github.com/estree/estree/compare/b3de58c9997504d6fba04b72f76e6dd1619ee4eb...1da8e603237144f44710360f8feb7a9977e905e0) on directive expression statements. + +## 5.1.2 (2017-09-04) + +### Bug fixes + +Disable parsing of legacy HTML-style comments in modules. + +Fix parsing of async methods whose names are keywords. + +## 5.1.1 (2017-07-06) + +### Bug fixes + +Fix problem with disambiguating regexp and division after a class. + +## 5.1.0 (2017-07-05) + +### Bug fixes + +Fix tokenizing of regexps in an object-desctructuring `for`/`of` loop and after `yield`. + +Parse zero-prefixed numbers with non-octal digits as decimal. + +Allow object/array patterns in rest parameters. + +Don't error when `yield` is used as a property name. + +Allow `async` as a shorthand object property. + +### New features + +Implement the [template literal revision proposal](https://github.com/tc39/proposal-template-literal-revision) for ES9. + +## 5.0.3 (2017-04-01) + +### Bug fixes + +Fix spurious duplicate variable definition errors for named functions. + +## 5.0.2 (2017-03-30) + +### Bug fixes + +A binary operator after a parenthesized arrow expression is no longer incorrectly treated as an error. + +## 5.0.0 (2017-03-28) + +### Bug fixes + +Raise an error for duplicated lexical bindings. + +Fix spurious error when an assignement expression occurred after a spread expression. + +Accept regular expressions after `of` (in `for`/`of`), `yield` (in a generator), and braced arrow functions. + +Allow labels in front or `var` declarations, even in strict mode. + +### Breaking changes + +Parse declarations following `export default` as declaration nodes, not expressions. This means that class and function declarations nodes can now have `null` as their `id`. + +## 4.0.11 (2017-02-07) + +### Bug fixes + +Allow all forms of member expressions to be parenthesized as lvalue. + +## 4.0.10 (2017-02-07) + +### Bug fixes + +Don't expect semicolons after default-exported functions or classes, even when they are expressions. + +Check for use of `'use strict'` directives in non-simple parameter functions, even when already in strict mode. + +## 4.0.9 (2017-02-06) + +### Bug fixes + +Fix incorrect error raised for parenthesized simple assignment targets, so that `(x) = 1` parses again. + +## 4.0.8 (2017-02-03) + +### Bug fixes + +Solve spurious parenthesized pattern errors by temporarily erring on the side of accepting programs that our delayed errors don't handle correctly yet. + +## 4.0.7 (2017-02-02) + +### Bug fixes + +Accept invalidly rejected code like `(x).y = 2` again. + +Don't raise an error when a function _inside_ strict code has a non-simple parameter list. + +## 4.0.6 (2017-02-02) + +### Bug fixes + +Fix exponential behavior (manifesting itself as a complete hang for even relatively small source files) introduced by the new 'use strict' check. + +## 4.0.5 (2017-02-02) + +### Bug fixes + +Disallow parenthesized pattern expressions. + +Allow keywords as export names. + +Don't allow the `async` keyword to be parenthesized. + +Properly raise an error when a keyword contains a character escape. + +Allow `"use strict"` to appear after other string literal expressions. + +Disallow labeled declarations. + +## 4.0.4 (2016-12-19) + +### Bug fixes + +Fix crash when `export` was followed by a keyword that can't be +exported. + +## 4.0.3 (2016-08-16) + +### Bug fixes + +Allow regular function declarations inside single-statement `if` branches in loose mode. Forbid them entirely in strict mode. + +Properly parse properties named `async` in ES2017 mode. + +Fix bug where reserved words were broken in ES2017 mode. + +## 4.0.2 (2016-08-11) + +### Bug fixes + +Don't ignore period or 'e' characters after octal numbers. + +Fix broken parsing for call expressions in default parameter values of arrow functions. + +## 4.0.1 (2016-08-08) + +### Bug fixes + +Fix false positives in duplicated export name errors. + +## 4.0.0 (2016-08-07) + +### Breaking changes + +The default `ecmaVersion` option value is now 7. + +A number of internal method signatures changed, so plugins might need to be updated. + +### Bug fixes + +The parser now raises errors on duplicated export names. + +`arguments` and `eval` can now be used in shorthand properties. + +Duplicate parameter names in non-simple argument lists now always produce an error. + +### New features + +The `ecmaVersion` option now also accepts year-style version numbers +(2015, etc). + +Support for `async`/`await` syntax when `ecmaVersion` is >= 8. + +Support for trailing commas in call expressions when `ecmaVersion` is >= 8. + +## 3.3.0 (2016-07-25) + +### Bug fixes + +Fix bug in tokenizing of regexp operator after a function declaration. + +Fix parser crash when parsing an array pattern with a hole. + +### New features + +Implement check against complex argument lists in functions that enable strict mode in ES7. + +## 3.2.0 (2016-06-07) + +### Bug fixes + +Improve handling of lack of unicode regexp support in host +environment. + +Properly reject shorthand properties whose name is a keyword. + +### New features + +Visitors created with `visit.make` now have their base as _prototype_, rather than copying properties into a fresh object. + +## 3.1.0 (2016-04-18) + +### Bug fixes + +Properly tokenize the division operator directly after a function expression. + +Allow trailing comma in destructuring arrays. + +## 3.0.4 (2016-02-25) + +### Fixes + +Allow update expressions as left-hand-side of the ES7 exponential operator. + +## 3.0.2 (2016-02-10) + +### Fixes + +Fix bug that accidentally made `undefined` a reserved word when parsing ES7. + +## 3.0.0 (2016-02-10) + +### Breaking changes + +The default value of the `ecmaVersion` option is now 6 (used to be 5). + +Support for comprehension syntax (which was dropped from the draft spec) has been removed. + +### Fixes + +`let` and `yield` are now “contextual keywords”, meaning you can mostly use them as identifiers in ES5 non-strict code. + +A parenthesized class or function expression after `export default` is now parsed correctly. + +### New features + +When `ecmaVersion` is set to 7, Acorn will parse the exponentiation operator (`**`). + +The identifier character ranges are now based on Unicode 8.0.0. + +Plugins can now override the `raiseRecoverable` method to override the way non-critical errors are handled. + +## 2.7.0 (2016-01-04) + +### Fixes + +Stop allowing rest parameters in setters. + +Disallow `y` rexexp flag in ES5. + +Disallow `\00` and `\000` escapes in strict mode. + +Raise an error when an import name is a reserved word. + +## 2.6.2 (2015-11-10) + +### Fixes + +Don't crash when no options object is passed. + +## 2.6.0 (2015-11-09) + +### Fixes + +Add `await` as a reserved word in module sources. + +Disallow `yield` in a parameter default value for a generator. + +Forbid using a comma after a rest pattern in an array destructuring. + +### New features + +Support parsing stdin in command-line tool. + +## 2.5.0 (2015-10-27) + +### Fixes + +Fix tokenizer support in the command-line tool. + +Stop allowing `new.target` outside of functions. + +Remove legacy `guard` and `guardedHandler` properties from try nodes. + +Stop allowing multiple `__proto__` properties on an object literal in strict mode. + +Don't allow rest parameters to be non-identifier patterns. + +Check for duplicate paramter names in arrow functions. diff --git a/node_modules/acorn/LICENSE b/node_modules/acorn/LICENSE new file mode 100644 index 0000000..9d71cc6 --- /dev/null +++ b/node_modules/acorn/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (C) 2012-2022 by various contributors (see AUTHORS) + +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/node_modules/acorn/README.md b/node_modules/acorn/README.md new file mode 100644 index 0000000..962de02 --- /dev/null +++ b/node_modules/acorn/README.md @@ -0,0 +1,301 @@ +# Acorn + +A tiny, fast JavaScript parser written in JavaScript. + +## Community + +Acorn is open source software released under an +[MIT license](https://github.com/acornjs/acorn/blob/master/acorn/LICENSE). + +You are welcome to +[report bugs](https://github.com/acornjs/acorn/issues) or create pull +requests on [github](https://github.com/acornjs/acorn). + +## Installation + +The easiest way to install acorn is from [`npm`](https://www.npmjs.com/): + +```sh +npm install acorn +``` + +Alternately, you can download the source and build acorn yourself: + +```sh +git clone https://github.com/acornjs/acorn.git +cd acorn +npm install +``` +## Importing acorn + +ESM as well as CommonJS is supported for all 3: `acorn`, `acorn-walk` and `acorn-loose`. + +ESM example for `acorn`: + +```js +import * as acorn from "acorn" +``` + +CommonJS example for `acorn`: + +```js +let acorn = require("acorn") +``` + +ESM is preferred, as it allows better editor auto-completions by offering TypeScript support. +For this reason, following examples will use ESM imports. + +## Interface + +**parse**`(input, options)` is the main interface to the library. The +`input` parameter is a string, `options` must be an object setting +some of the options listed below. The return value will be an abstract +syntax tree object as specified by the [ESTree +spec](https://github.com/estree/estree). + +```javascript +import * as acorn from "acorn" +console.log(acorn.parse("1 + 1", {ecmaVersion: 2020})) +``` + +When encountering a syntax error, the parser will raise a +`SyntaxError` object with a meaningful message. The error object will +have a `pos` property that indicates the string offset at which the +error occurred, and a `loc` object that contains a `{line, column}` +object referring to that same position. + +Options are provided by in a second argument, which should be an +object containing any of these fields (only `ecmaVersion` is +required): + +- **ecmaVersion**: Indicates the ECMAScript version to parse. Can be a + number, either in year (`2022`) or plain version number (`6`) form, + or `"latest"` (the latest the library supports). This influences + support for strict mode, the set of reserved words, and support for + new syntax features. + + **NOTE**: Only 'stage 4' (finalized) ECMAScript features are being + implemented by Acorn. Other proposed new features must be + implemented through plugins. + +- **sourceType**: Indicate the mode the code should be parsed in. Can be + either `"script"`, `"module"` or `"commonjs"`. This influences global strict mode + and parsing of `import` and `export` declarations. + + **NOTE**: If set to `"module"`, then static `import` / `export` syntax + will be valid, even if `ecmaVersion` is less than 6. If set to `"commonjs"`, + it is the same as `"script"` except that the top-level scope behaves like a function. + +- **onInsertedSemicolon**: If given a callback, that callback will be + called whenever a missing semicolon is inserted by the parser. The + callback will be given the character offset of the point where the + semicolon is inserted as argument, and if `locations` is on, also a + `{line, column}` object representing this position. + +- **onTrailingComma**: Like `onInsertedSemicolon`, but for trailing + commas. + +- **allowReserved**: If `false`, using a reserved word will generate + an error. Defaults to `true` for `ecmaVersion` 3, `false` for higher + versions. When given the value `"never"`, reserved words and + keywords can also not be used as property names (as in Internet + Explorer's old parser). + +- **allowReturnOutsideFunction**: By default, a return statement at + the top level raises an error. Set this to `true` to accept such + code. + +- **allowImportExportEverywhere**: By default, `import` and `export` + declarations can only appear at a program's top level. Setting this + option to `true` allows them anywhere where a statement is allowed, + and also allows `import.meta` expressions to appear in scripts + (when `sourceType` is not `"module"`). + +- **allowAwaitOutsideFunction**: If `false`, `await` expressions can + only appear inside `async` functions. Defaults to `true` in modules + for `ecmaVersion` 2022 and later, `false` for lower versions. + Setting this option to `true` allows to have top-level `await` + expressions. They are still not allowed in non-`async` functions, + though. Setting this option to `true` is not allowed when `sourceType: "commonjs"`. + +- **allowSuperOutsideMethod**: By default, `super` outside a method + raises an error. Set this to `true` to accept such code. + +- **allowHashBang**: When this is enabled, if the code starts with the + characters `#!` (as in a shellscript), the first line will be + treated as a comment. Defaults to true when `ecmaVersion` >= 2023. + +- **checkPrivateFields**: By default, the parser will verify that + private properties are only used in places where they are valid and + have been declared. Set this to false to turn such checks off. + +- **locations**: When `true`, each node has a `loc` object attached + with `start` and `end` subobjects, each of which contains the + one-based line and zero-based column numbers in `{line, column}` + form. Default is `false`. + +- **onToken**: If a function is passed for this option, each found + token will be passed in same format as tokens returned from + `tokenizer().getToken()`. + + If array is passed, each found token is pushed to it. + + Note that you are not allowed to call the parser from the + callback—that will corrupt its internal state. + +- **onComment**: If a function is passed for this option, whenever a + comment is encountered the function will be called with the + following parameters: + + - `block`: `true` if the comment is a block comment, false if it + is a line comment. + - `text`: The content of the comment. + - `start`: Character offset of the start of the comment. + - `end`: Character offset of the end of the comment. + + When the `locations` options is on, the `{line, column}` locations + of the comment’s start and end are passed as two additional + parameters. + + If array is passed for this option, each found comment is pushed + to it as object in Esprima format: + + ```javascript + { + "type": "Line" | "Block", + "value": "comment text", + "start": Number, + "end": Number, + // If `locations` option is on: + "loc": { + "start": {line: Number, column: Number} + "end": {line: Number, column: Number} + }, + // If `ranges` option is on: + "range": [Number, Number] + } + ``` + + Note that you are not allowed to call the parser from the + callback—that will corrupt its internal state. + +- **ranges**: Nodes have their start and end characters offsets + recorded in `start` and `end` properties (directly on the node, + rather than the `loc` object, which holds line/column data. To also + add a + [semi-standardized](https://bugzilla.mozilla.org/show_bug.cgi?id=745678) + `range` property holding a `[start, end]` array with the same + numbers, set the `ranges` option to `true`. + +- **program**: It is possible to parse multiple files into a single + AST by passing the tree produced by parsing the first file as the + `program` option in subsequent parses. This will add the toplevel + forms of the parsed file to the "Program" (top) node of an existing + parse tree. + +- **sourceFile**: When the `locations` option is `true`, you can pass + this option to add a `source` attribute in every node’s `loc` + object. Note that the contents of this option are not examined or + processed in any way; you are free to use whatever format you + choose. + +- **directSourceFile**: Like `sourceFile`, but a `sourceFile` property + will be added (regardless of the `location` option) directly to the + nodes, rather than the `loc` object. + +- **preserveParens**: If this option is `true`, parenthesized expressions + are represented by (non-standard) `ParenthesizedExpression` nodes + that have a single `expression` property containing the expression + inside parentheses. + +**parseExpressionAt**`(input, offset, options)` will parse a single +expression in a string, and return its AST. It will not complain if +there is more of the string left after the expression. + +**tokenizer**`(input, options)` returns an object with a `getToken` +method that can be called repeatedly to get the next token, a `{start, +end, type, value}` object (with added `loc` property when the +`locations` option is enabled and `range` property when the `ranges` +option is enabled). When the token's type is `tokTypes.eof`, you +should stop calling the method, since it will keep returning that same +token forever. + +Note that tokenizing JavaScript without parsing it is, in modern +versions of the language, not really possible due to the way syntax is +overloaded in ways that can only be disambiguated by the parse +context. This package applies a bunch of heuristics to try and do a +reasonable job, but you are advised to use `parse` with the `onToken` +option instead of this. + +In ES6 environment, returned result can be used as any other +protocol-compliant iterable: + +```javascript +for (let token of acorn.tokenizer(str)) { + // iterate over the tokens +} + +// transform code to array of tokens: +var tokens = [...acorn.tokenizer(str)] +``` + +**tokTypes** holds an object mapping names to the token type objects +that end up in the `type` properties of tokens. + +**getLineInfo**`(input, offset)` can be used to get a `{line, +column}` object for a given program string and offset. + +### The `Parser` class + +Instances of the **`Parser`** class contain all the state and logic +that drives a parse. It has static methods `parse`, +`parseExpressionAt`, and `tokenizer` that match the top-level +functions by the same name. + +When extending the parser with plugins, you need to call these methods +on the extended version of the class. To extend a parser with plugins, +you can use its static `extend` method. + +```javascript +var acorn = require("acorn") +var jsx = require("acorn-jsx") +var JSXParser = acorn.Parser.extend(jsx()) +JSXParser.parse("foo()", {ecmaVersion: 2020}) +``` + +The `extend` method takes any number of plugin values, and returns a +new `Parser` class that includes the extra parser logic provided by +the plugins. + +## Command line interface + +The `bin/acorn` utility can be used to parse a file from the command +line. It accepts as arguments its input file and the following +options: + +- `--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9|--ecma10`: Sets the ECMAScript version + to parse. Default is version 9. + +- `--module`: Sets the parsing mode to `"module"`. Is set to `"script"` otherwise. + +- `--locations`: Attaches a "loc" object to each node with "start" and + "end" subobjects, each of which contains the one-based line and + zero-based column numbers in `{line, column}` form. + +- `--allow-hash-bang`: If the code starts with the characters #! (as + in a shellscript), the first line will be treated as a comment. + +- `--allow-await-outside-function`: Allows top-level `await` expressions. + See the `allowAwaitOutsideFunction` option for more information. + +- `--compact`: No whitespace is used in the AST output. + +- `--silent`: Do not output the AST, just return the exit status. + +- `--help`: Print the usage information and quit. + +The utility spits out the syntax tree as JSON data. + +## Existing plugins + + - [`acorn-jsx`](https://github.com/RReverser/acorn-jsx): Parse [Facebook JSX syntax extensions](https://github.com/facebook/jsx) diff --git a/node_modules/acorn/bin/acorn b/node_modules/acorn/bin/acorn new file mode 100755 index 0000000..3ef3c12 --- /dev/null +++ b/node_modules/acorn/bin/acorn @@ -0,0 +1,4 @@ +#!/usr/bin/env node +"use strict" + +require("../dist/bin.js") diff --git a/node_modules/acorn/dist/acorn.d.mts b/node_modules/acorn/dist/acorn.d.mts new file mode 100644 index 0000000..afbd913 --- /dev/null +++ b/node_modules/acorn/dist/acorn.d.mts @@ -0,0 +1,883 @@ +export interface Node { + start: number + end: number + type: string + range?: [number, number] + loc?: SourceLocation | null +} + +export interface SourceLocation { + source?: string | null + start: Position + end: Position +} + +export interface Position { + /** 1-based */ + line: number + /** 0-based */ + column: number +} + +export interface Identifier extends Node { + type: "Identifier" + name: string +} + +export interface Literal extends Node { + type: "Literal" + value?: string | boolean | null | number | RegExp | bigint + raw?: string + regex?: { + pattern: string + flags: string + } + bigint?: string +} + +export interface Program extends Node { + type: "Program" + body: Array + sourceType: "script" | "module" +} + +export interface Function extends Node { + id?: Identifier | null + params: Array + body: BlockStatement | Expression + generator: boolean + expression: boolean + async: boolean +} + +export interface ExpressionStatement extends Node { + type: "ExpressionStatement" + expression: Expression | Literal + directive?: string +} + +export interface BlockStatement extends Node { + type: "BlockStatement" + body: Array +} + +export interface EmptyStatement extends Node { + type: "EmptyStatement" +} + +export interface DebuggerStatement extends Node { + type: "DebuggerStatement" +} + +export interface WithStatement extends Node { + type: "WithStatement" + object: Expression + body: Statement +} + +export interface ReturnStatement extends Node { + type: "ReturnStatement" + argument?: Expression | null +} + +export interface LabeledStatement extends Node { + type: "LabeledStatement" + label: Identifier + body: Statement +} + +export interface BreakStatement extends Node { + type: "BreakStatement" + label?: Identifier | null +} + +export interface ContinueStatement extends Node { + type: "ContinueStatement" + label?: Identifier | null +} + +export interface IfStatement extends Node { + type: "IfStatement" + test: Expression + consequent: Statement + alternate?: Statement | null +} + +export interface SwitchStatement extends Node { + type: "SwitchStatement" + discriminant: Expression + cases: Array +} + +export interface SwitchCase extends Node { + type: "SwitchCase" + test?: Expression | null + consequent: Array +} + +export interface ThrowStatement extends Node { + type: "ThrowStatement" + argument: Expression +} + +export interface TryStatement extends Node { + type: "TryStatement" + block: BlockStatement + handler?: CatchClause | null + finalizer?: BlockStatement | null +} + +export interface CatchClause extends Node { + type: "CatchClause" + param?: Pattern | null + body: BlockStatement +} + +export interface WhileStatement extends Node { + type: "WhileStatement" + test: Expression + body: Statement +} + +export interface DoWhileStatement extends Node { + type: "DoWhileStatement" + body: Statement + test: Expression +} + +export interface ForStatement extends Node { + type: "ForStatement" + init?: VariableDeclaration | Expression | null + test?: Expression | null + update?: Expression | null + body: Statement +} + +export interface ForInStatement extends Node { + type: "ForInStatement" + left: VariableDeclaration | Pattern + right: Expression + body: Statement +} + +export interface FunctionDeclaration extends Function { + type: "FunctionDeclaration" + id: Identifier + body: BlockStatement +} + +export interface VariableDeclaration extends Node { + type: "VariableDeclaration" + declarations: Array + kind: "var" | "let" | "const" | "using" | "await using" +} + +export interface VariableDeclarator extends Node { + type: "VariableDeclarator" + id: Pattern + init?: Expression | null +} + +export interface ThisExpression extends Node { + type: "ThisExpression" +} + +export interface ArrayExpression extends Node { + type: "ArrayExpression" + elements: Array +} + +export interface ObjectExpression extends Node { + type: "ObjectExpression" + properties: Array +} + +export interface Property extends Node { + type: "Property" + key: Expression + value: Expression + kind: "init" | "get" | "set" + method: boolean + shorthand: boolean + computed: boolean +} + +export interface FunctionExpression extends Function { + type: "FunctionExpression" + body: BlockStatement +} + +export interface UnaryExpression extends Node { + type: "UnaryExpression" + operator: UnaryOperator + prefix: boolean + argument: Expression +} + +export type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete" + +export interface UpdateExpression extends Node { + type: "UpdateExpression" + operator: UpdateOperator + argument: Expression + prefix: boolean +} + +export type UpdateOperator = "++" | "--" + +export interface BinaryExpression extends Node { + type: "BinaryExpression" + operator: BinaryOperator + left: Expression | PrivateIdentifier + right: Expression +} + +export type BinaryOperator = "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "|" | "^" | "&" | "in" | "instanceof" | "**" + +export interface AssignmentExpression extends Node { + type: "AssignmentExpression" + operator: AssignmentOperator + left: Pattern + right: Expression +} + +export type AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | ">>>=" | "|=" | "^=" | "&=" | "**=" | "||=" | "&&=" | "??=" + +export interface LogicalExpression extends Node { + type: "LogicalExpression" + operator: LogicalOperator + left: Expression + right: Expression +} + +export type LogicalOperator = "||" | "&&" | "??" + +export interface MemberExpression extends Node { + type: "MemberExpression" + object: Expression | Super + property: Expression | PrivateIdentifier + computed: boolean + optional: boolean +} + +export interface ConditionalExpression extends Node { + type: "ConditionalExpression" + test: Expression + alternate: Expression + consequent: Expression +} + +export interface CallExpression extends Node { + type: "CallExpression" + callee: Expression | Super + arguments: Array + optional: boolean +} + +export interface NewExpression extends Node { + type: "NewExpression" + callee: Expression + arguments: Array +} + +export interface SequenceExpression extends Node { + type: "SequenceExpression" + expressions: Array +} + +export interface ForOfStatement extends Node { + type: "ForOfStatement" + left: VariableDeclaration | Pattern + right: Expression + body: Statement + await: boolean +} + +export interface Super extends Node { + type: "Super" +} + +export interface SpreadElement extends Node { + type: "SpreadElement" + argument: Expression +} + +export interface ArrowFunctionExpression extends Function { + type: "ArrowFunctionExpression" +} + +export interface YieldExpression extends Node { + type: "YieldExpression" + argument?: Expression | null + delegate: boolean +} + +export interface TemplateLiteral extends Node { + type: "TemplateLiteral" + quasis: Array + expressions: Array +} + +export interface TaggedTemplateExpression extends Node { + type: "TaggedTemplateExpression" + tag: Expression + quasi: TemplateLiteral +} + +export interface TemplateElement extends Node { + type: "TemplateElement" + tail: boolean + value: { + cooked?: string | null + raw: string + } +} + +export interface AssignmentProperty extends Node { + type: "Property" + key: Expression + value: Pattern + kind: "init" + method: false + shorthand: boolean + computed: boolean +} + +export interface ObjectPattern extends Node { + type: "ObjectPattern" + properties: Array +} + +export interface ArrayPattern extends Node { + type: "ArrayPattern" + elements: Array +} + +export interface RestElement extends Node { + type: "RestElement" + argument: Pattern +} + +export interface AssignmentPattern extends Node { + type: "AssignmentPattern" + left: Pattern + right: Expression +} + +export interface Class extends Node { + id?: Identifier | null + superClass?: Expression | null + body: ClassBody +} + +export interface ClassBody extends Node { + type: "ClassBody" + body: Array +} + +export interface MethodDefinition extends Node { + type: "MethodDefinition" + key: Expression | PrivateIdentifier + value: FunctionExpression + kind: "constructor" | "method" | "get" | "set" + computed: boolean + static: boolean +} + +export interface ClassDeclaration extends Class { + type: "ClassDeclaration" + id: Identifier +} + +export interface ClassExpression extends Class { + type: "ClassExpression" +} + +export interface MetaProperty extends Node { + type: "MetaProperty" + meta: Identifier + property: Identifier +} + +export interface ImportDeclaration extends Node { + type: "ImportDeclaration" + specifiers: Array + source: Literal + attributes: Array +} + +export interface ImportSpecifier extends Node { + type: "ImportSpecifier" + imported: Identifier | Literal + local: Identifier +} + +export interface ImportDefaultSpecifier extends Node { + type: "ImportDefaultSpecifier" + local: Identifier +} + +export interface ImportNamespaceSpecifier extends Node { + type: "ImportNamespaceSpecifier" + local: Identifier +} + +export interface ImportAttribute extends Node { + type: "ImportAttribute" + key: Identifier | Literal + value: Literal +} + +export interface ExportNamedDeclaration extends Node { + type: "ExportNamedDeclaration" + declaration?: Declaration | null + specifiers: Array + source?: Literal | null + attributes: Array +} + +export interface ExportSpecifier extends Node { + type: "ExportSpecifier" + exported: Identifier | Literal + local: Identifier | Literal +} + +export interface AnonymousFunctionDeclaration extends Function { + type: "FunctionDeclaration" + id: null + body: BlockStatement +} + +export interface AnonymousClassDeclaration extends Class { + type: "ClassDeclaration" + id: null +} + +export interface ExportDefaultDeclaration extends Node { + type: "ExportDefaultDeclaration" + declaration: AnonymousFunctionDeclaration | FunctionDeclaration | AnonymousClassDeclaration | ClassDeclaration | Expression +} + +export interface ExportAllDeclaration extends Node { + type: "ExportAllDeclaration" + source: Literal + exported?: Identifier | Literal | null + attributes: Array +} + +export interface AwaitExpression extends Node { + type: "AwaitExpression" + argument: Expression +} + +export interface ChainExpression extends Node { + type: "ChainExpression" + expression: MemberExpression | CallExpression +} + +export interface ImportExpression extends Node { + type: "ImportExpression" + source: Expression + options: Expression | null +} + +export interface ParenthesizedExpression extends Node { + type: "ParenthesizedExpression" + expression: Expression +} + +export interface PropertyDefinition extends Node { + type: "PropertyDefinition" + key: Expression | PrivateIdentifier + value?: Expression | null + computed: boolean + static: boolean +} + +export interface PrivateIdentifier extends Node { + type: "PrivateIdentifier" + name: string +} + +export interface StaticBlock extends Node { + type: "StaticBlock" + body: Array +} + +export type Statement = +| ExpressionStatement +| BlockStatement +| EmptyStatement +| DebuggerStatement +| WithStatement +| ReturnStatement +| LabeledStatement +| BreakStatement +| ContinueStatement +| IfStatement +| SwitchStatement +| ThrowStatement +| TryStatement +| WhileStatement +| DoWhileStatement +| ForStatement +| ForInStatement +| ForOfStatement +| Declaration + +export type Declaration = +| FunctionDeclaration +| VariableDeclaration +| ClassDeclaration + +export type Expression = +| Identifier +| Literal +| ThisExpression +| ArrayExpression +| ObjectExpression +| FunctionExpression +| UnaryExpression +| UpdateExpression +| BinaryExpression +| AssignmentExpression +| LogicalExpression +| MemberExpression +| ConditionalExpression +| CallExpression +| NewExpression +| SequenceExpression +| ArrowFunctionExpression +| YieldExpression +| TemplateLiteral +| TaggedTemplateExpression +| ClassExpression +| MetaProperty +| AwaitExpression +| ChainExpression +| ImportExpression +| ParenthesizedExpression + +export type Pattern = +| Identifier +| MemberExpression +| ObjectPattern +| ArrayPattern +| RestElement +| AssignmentPattern + +export type ModuleDeclaration = +| ImportDeclaration +| ExportNamedDeclaration +| ExportDefaultDeclaration +| ExportAllDeclaration + +/** + * This interface is only used for defining {@link AnyNode}. + * It exists so that it can be extended by plugins: + * + * @example + * ```typescript + * declare module 'acorn' { + * interface NodeTypes { + * pluginName: FirstNode | SecondNode | ThirdNode | ... | LastNode + * } + * } + * ``` + */ +interface NodeTypes { + core: Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportAttribute | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator +} + +export type AnyNode = NodeTypes[keyof NodeTypes] + +export function parse(input: string, options: Options): Program + +export function parseExpressionAt(input: string, pos: number, options: Options): Expression + +export function tokenizer(input: string, options: Options): { + getToken(): Token + [Symbol.iterator](): Iterator +} + +export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | "latest" + +export interface Options { + /** + * `ecmaVersion` indicates the ECMAScript version to parse. Can be a + * number, either in year (`2022`) or plain version number (`6`) form, + * or `"latest"` (the latest the library supports). This influences + * support for strict mode, the set of reserved words, and support for + * new syntax features. + */ + ecmaVersion: ecmaVersion + + /** + * `sourceType` indicates the mode the code should be parsed in. + * Can be either `"script"`, `"module"` or `"commonjs"`. This influences global + * strict mode and parsing of `import` and `export` declarations. + */ + sourceType?: "script" | "module" | "commonjs" + + /** + * a callback that will be called when a semicolon is automatically inserted. + * @param lastTokEnd the position of the comma as an offset + * @param lastTokEndLoc location if {@link locations} is enabled + */ + onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void + + /** + * similar to `onInsertedSemicolon`, but for trailing commas + * @param lastTokEnd the position of the comma as an offset + * @param lastTokEndLoc location if `locations` is enabled + */ + onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void + + /** + * By default, reserved words are only enforced if ecmaVersion >= 5. + * Set `allowReserved` to a boolean value to explicitly turn this on + * an off. When this option has the value "never", reserved words + * and keywords can also not be used as property names. + */ + allowReserved?: boolean | "never" + + /** + * When enabled, a return at the top level is not considered an error. + */ + allowReturnOutsideFunction?: boolean + + /** + * When enabled, import/export statements are not constrained to + * appearing at the top of the program, and an import.meta expression + * in a script isn't considered an error. + */ + allowImportExportEverywhere?: boolean + + /** + * By default, `await` identifiers are allowed to appear at the top-level scope only if {@link ecmaVersion} >= 2022. + * When enabled, await identifiers are allowed to appear at the top-level scope, + * but they are still not allowed in non-async functions. + */ + allowAwaitOutsideFunction?: boolean + + /** + * When enabled, super identifiers are not constrained to + * appearing in methods and do not raise an error when they appear elsewhere. + */ + allowSuperOutsideMethod?: boolean + + /** + * When enabled, hashbang directive in the beginning of file is + * allowed and treated as a line comment. Enabled by default when + * {@link ecmaVersion} >= 2023. + */ + allowHashBang?: boolean + + /** + * By default, the parser will verify that private properties are + * only used in places where they are valid and have been declared. + * Set this to false to turn such checks off. + */ + checkPrivateFields?: boolean + + /** + * When `locations` is on, `loc` properties holding objects with + * `start` and `end` properties as {@link Position} objects will be attached to the + * nodes. + */ + locations?: boolean + + /** + * a callback that will cause Acorn to call that export function with object in the same + * format as tokens returned from `tokenizer().getToken()`. Note + * that you are not allowed to call the parser from the + * callback—that will corrupt its internal state. + */ + onToken?: ((token: Token) => void) | Token[] + + + /** + * This takes a export function or an array. + * + * When a export function is passed, Acorn will call that export function with `(block, text, start, + * end)` parameters whenever a comment is skipped. `block` is a + * boolean indicating whether this is a block (`/* *\/`) comment, + * `text` is the content of the comment, and `start` and `end` are + * character offsets that denote the start and end of the comment. + * When the {@link locations} option is on, two more parameters are + * passed, the full locations of {@link Position} export type of the start and + * end of the comments. + * + * When a array is passed, each found comment of {@link Comment} export type is pushed to the array. + * + * Note that you are not allowed to call the + * parser from the callback—that will corrupt its internal state. + */ + onComment?: (( + isBlock: boolean, text: string, start: number, end: number, startLoc?: Position, + endLoc?: Position + ) => void) | Comment[] + + /** + * Nodes have their start and end characters offsets recorded in + * `start` and `end` properties (directly on the node, rather than + * the `loc` object, which holds line/column data. To also add a + * [semi-standardized][range] `range` property holding a `[start, + * end]` array with the same numbers, set the `ranges` option to + * `true`. + */ + ranges?: boolean + + /** + * It is possible to parse multiple files into a single AST by + * passing the tree produced by parsing the first file as + * `program` option in subsequent parses. This will add the + * toplevel forms of the parsed file to the `Program` (top) node + * of an existing parse tree. + */ + program?: Node + + /** + * When {@link locations} is on, you can pass this to record the source + * file in every node's `loc` object. + */ + sourceFile?: string + + /** + * This value, if given, is stored in every node, whether {@link locations} is on or off. + */ + directSourceFile?: string + + /** + * When enabled, parenthesized expressions are represented by + * (non-standard) ParenthesizedExpression nodes + */ + preserveParens?: boolean +} + +export class Parser { + options: Options + input: string + + protected constructor(options: Options, input: string, startPos?: number) + parse(): Program + + static parse(input: string, options: Options): Program + static parseExpressionAt(input: string, pos: number, options: Options): Expression + static tokenizer(input: string, options: Options): { + getToken(): Token + [Symbol.iterator](): Iterator + } + static extend(...plugins: ((BaseParser: typeof Parser) => typeof Parser)[]): typeof Parser +} + +export const defaultOptions: Options + +export function getLineInfo(input: string, offset: number): Position + +export class TokenType { + label: string + keyword: string | undefined +} + +export const tokTypes: { + num: TokenType + regexp: TokenType + string: TokenType + name: TokenType + privateId: TokenType + eof: TokenType + + bracketL: TokenType + bracketR: TokenType + braceL: TokenType + braceR: TokenType + parenL: TokenType + parenR: TokenType + comma: TokenType + semi: TokenType + colon: TokenType + dot: TokenType + question: TokenType + questionDot: TokenType + arrow: TokenType + template: TokenType + invalidTemplate: TokenType + ellipsis: TokenType + backQuote: TokenType + dollarBraceL: TokenType + + eq: TokenType + assign: TokenType + incDec: TokenType + prefix: TokenType + logicalOR: TokenType + logicalAND: TokenType + bitwiseOR: TokenType + bitwiseXOR: TokenType + bitwiseAND: TokenType + equality: TokenType + relational: TokenType + bitShift: TokenType + plusMin: TokenType + modulo: TokenType + star: TokenType + slash: TokenType + starstar: TokenType + coalesce: TokenType + + _break: TokenType + _case: TokenType + _catch: TokenType + _continue: TokenType + _debugger: TokenType + _default: TokenType + _do: TokenType + _else: TokenType + _finally: TokenType + _for: TokenType + _function: TokenType + _if: TokenType + _return: TokenType + _switch: TokenType + _throw: TokenType + _try: TokenType + _var: TokenType + _const: TokenType + _while: TokenType + _with: TokenType + _new: TokenType + _this: TokenType + _super: TokenType + _class: TokenType + _extends: TokenType + _export: TokenType + _import: TokenType + _null: TokenType + _true: TokenType + _false: TokenType + _in: TokenType + _instanceof: TokenType + _typeof: TokenType + _void: TokenType + _delete: TokenType +} + +export interface Comment { + type: "Line" | "Block" + value: string + start: number + end: number + loc?: SourceLocation + range?: [number, number] +} + +export class Token { + type: TokenType + start: number + end: number + loc?: SourceLocation + range?: [number, number] +} + +export const version: string diff --git a/node_modules/acorn/dist/acorn.d.ts b/node_modules/acorn/dist/acorn.d.ts new file mode 100644 index 0000000..afbd913 --- /dev/null +++ b/node_modules/acorn/dist/acorn.d.ts @@ -0,0 +1,883 @@ +export interface Node { + start: number + end: number + type: string + range?: [number, number] + loc?: SourceLocation | null +} + +export interface SourceLocation { + source?: string | null + start: Position + end: Position +} + +export interface Position { + /** 1-based */ + line: number + /** 0-based */ + column: number +} + +export interface Identifier extends Node { + type: "Identifier" + name: string +} + +export interface Literal extends Node { + type: "Literal" + value?: string | boolean | null | number | RegExp | bigint + raw?: string + regex?: { + pattern: string + flags: string + } + bigint?: string +} + +export interface Program extends Node { + type: "Program" + body: Array + sourceType: "script" | "module" +} + +export interface Function extends Node { + id?: Identifier | null + params: Array + body: BlockStatement | Expression + generator: boolean + expression: boolean + async: boolean +} + +export interface ExpressionStatement extends Node { + type: "ExpressionStatement" + expression: Expression | Literal + directive?: string +} + +export interface BlockStatement extends Node { + type: "BlockStatement" + body: Array +} + +export interface EmptyStatement extends Node { + type: "EmptyStatement" +} + +export interface DebuggerStatement extends Node { + type: "DebuggerStatement" +} + +export interface WithStatement extends Node { + type: "WithStatement" + object: Expression + body: Statement +} + +export interface ReturnStatement extends Node { + type: "ReturnStatement" + argument?: Expression | null +} + +export interface LabeledStatement extends Node { + type: "LabeledStatement" + label: Identifier + body: Statement +} + +export interface BreakStatement extends Node { + type: "BreakStatement" + label?: Identifier | null +} + +export interface ContinueStatement extends Node { + type: "ContinueStatement" + label?: Identifier | null +} + +export interface IfStatement extends Node { + type: "IfStatement" + test: Expression + consequent: Statement + alternate?: Statement | null +} + +export interface SwitchStatement extends Node { + type: "SwitchStatement" + discriminant: Expression + cases: Array +} + +export interface SwitchCase extends Node { + type: "SwitchCase" + test?: Expression | null + consequent: Array +} + +export interface ThrowStatement extends Node { + type: "ThrowStatement" + argument: Expression +} + +export interface TryStatement extends Node { + type: "TryStatement" + block: BlockStatement + handler?: CatchClause | null + finalizer?: BlockStatement | null +} + +export interface CatchClause extends Node { + type: "CatchClause" + param?: Pattern | null + body: BlockStatement +} + +export interface WhileStatement extends Node { + type: "WhileStatement" + test: Expression + body: Statement +} + +export interface DoWhileStatement extends Node { + type: "DoWhileStatement" + body: Statement + test: Expression +} + +export interface ForStatement extends Node { + type: "ForStatement" + init?: VariableDeclaration | Expression | null + test?: Expression | null + update?: Expression | null + body: Statement +} + +export interface ForInStatement extends Node { + type: "ForInStatement" + left: VariableDeclaration | Pattern + right: Expression + body: Statement +} + +export interface FunctionDeclaration extends Function { + type: "FunctionDeclaration" + id: Identifier + body: BlockStatement +} + +export interface VariableDeclaration extends Node { + type: "VariableDeclaration" + declarations: Array + kind: "var" | "let" | "const" | "using" | "await using" +} + +export interface VariableDeclarator extends Node { + type: "VariableDeclarator" + id: Pattern + init?: Expression | null +} + +export interface ThisExpression extends Node { + type: "ThisExpression" +} + +export interface ArrayExpression extends Node { + type: "ArrayExpression" + elements: Array +} + +export interface ObjectExpression extends Node { + type: "ObjectExpression" + properties: Array +} + +export interface Property extends Node { + type: "Property" + key: Expression + value: Expression + kind: "init" | "get" | "set" + method: boolean + shorthand: boolean + computed: boolean +} + +export interface FunctionExpression extends Function { + type: "FunctionExpression" + body: BlockStatement +} + +export interface UnaryExpression extends Node { + type: "UnaryExpression" + operator: UnaryOperator + prefix: boolean + argument: Expression +} + +export type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete" + +export interface UpdateExpression extends Node { + type: "UpdateExpression" + operator: UpdateOperator + argument: Expression + prefix: boolean +} + +export type UpdateOperator = "++" | "--" + +export interface BinaryExpression extends Node { + type: "BinaryExpression" + operator: BinaryOperator + left: Expression | PrivateIdentifier + right: Expression +} + +export type BinaryOperator = "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "|" | "^" | "&" | "in" | "instanceof" | "**" + +export interface AssignmentExpression extends Node { + type: "AssignmentExpression" + operator: AssignmentOperator + left: Pattern + right: Expression +} + +export type AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | ">>>=" | "|=" | "^=" | "&=" | "**=" | "||=" | "&&=" | "??=" + +export interface LogicalExpression extends Node { + type: "LogicalExpression" + operator: LogicalOperator + left: Expression + right: Expression +} + +export type LogicalOperator = "||" | "&&" | "??" + +export interface MemberExpression extends Node { + type: "MemberExpression" + object: Expression | Super + property: Expression | PrivateIdentifier + computed: boolean + optional: boolean +} + +export interface ConditionalExpression extends Node { + type: "ConditionalExpression" + test: Expression + alternate: Expression + consequent: Expression +} + +export interface CallExpression extends Node { + type: "CallExpression" + callee: Expression | Super + arguments: Array + optional: boolean +} + +export interface NewExpression extends Node { + type: "NewExpression" + callee: Expression + arguments: Array +} + +export interface SequenceExpression extends Node { + type: "SequenceExpression" + expressions: Array +} + +export interface ForOfStatement extends Node { + type: "ForOfStatement" + left: VariableDeclaration | Pattern + right: Expression + body: Statement + await: boolean +} + +export interface Super extends Node { + type: "Super" +} + +export interface SpreadElement extends Node { + type: "SpreadElement" + argument: Expression +} + +export interface ArrowFunctionExpression extends Function { + type: "ArrowFunctionExpression" +} + +export interface YieldExpression extends Node { + type: "YieldExpression" + argument?: Expression | null + delegate: boolean +} + +export interface TemplateLiteral extends Node { + type: "TemplateLiteral" + quasis: Array + expressions: Array +} + +export interface TaggedTemplateExpression extends Node { + type: "TaggedTemplateExpression" + tag: Expression + quasi: TemplateLiteral +} + +export interface TemplateElement extends Node { + type: "TemplateElement" + tail: boolean + value: { + cooked?: string | null + raw: string + } +} + +export interface AssignmentProperty extends Node { + type: "Property" + key: Expression + value: Pattern + kind: "init" + method: false + shorthand: boolean + computed: boolean +} + +export interface ObjectPattern extends Node { + type: "ObjectPattern" + properties: Array +} + +export interface ArrayPattern extends Node { + type: "ArrayPattern" + elements: Array +} + +export interface RestElement extends Node { + type: "RestElement" + argument: Pattern +} + +export interface AssignmentPattern extends Node { + type: "AssignmentPattern" + left: Pattern + right: Expression +} + +export interface Class extends Node { + id?: Identifier | null + superClass?: Expression | null + body: ClassBody +} + +export interface ClassBody extends Node { + type: "ClassBody" + body: Array +} + +export interface MethodDefinition extends Node { + type: "MethodDefinition" + key: Expression | PrivateIdentifier + value: FunctionExpression + kind: "constructor" | "method" | "get" | "set" + computed: boolean + static: boolean +} + +export interface ClassDeclaration extends Class { + type: "ClassDeclaration" + id: Identifier +} + +export interface ClassExpression extends Class { + type: "ClassExpression" +} + +export interface MetaProperty extends Node { + type: "MetaProperty" + meta: Identifier + property: Identifier +} + +export interface ImportDeclaration extends Node { + type: "ImportDeclaration" + specifiers: Array + source: Literal + attributes: Array +} + +export interface ImportSpecifier extends Node { + type: "ImportSpecifier" + imported: Identifier | Literal + local: Identifier +} + +export interface ImportDefaultSpecifier extends Node { + type: "ImportDefaultSpecifier" + local: Identifier +} + +export interface ImportNamespaceSpecifier extends Node { + type: "ImportNamespaceSpecifier" + local: Identifier +} + +export interface ImportAttribute extends Node { + type: "ImportAttribute" + key: Identifier | Literal + value: Literal +} + +export interface ExportNamedDeclaration extends Node { + type: "ExportNamedDeclaration" + declaration?: Declaration | null + specifiers: Array + source?: Literal | null + attributes: Array +} + +export interface ExportSpecifier extends Node { + type: "ExportSpecifier" + exported: Identifier | Literal + local: Identifier | Literal +} + +export interface AnonymousFunctionDeclaration extends Function { + type: "FunctionDeclaration" + id: null + body: BlockStatement +} + +export interface AnonymousClassDeclaration extends Class { + type: "ClassDeclaration" + id: null +} + +export interface ExportDefaultDeclaration extends Node { + type: "ExportDefaultDeclaration" + declaration: AnonymousFunctionDeclaration | FunctionDeclaration | AnonymousClassDeclaration | ClassDeclaration | Expression +} + +export interface ExportAllDeclaration extends Node { + type: "ExportAllDeclaration" + source: Literal + exported?: Identifier | Literal | null + attributes: Array +} + +export interface AwaitExpression extends Node { + type: "AwaitExpression" + argument: Expression +} + +export interface ChainExpression extends Node { + type: "ChainExpression" + expression: MemberExpression | CallExpression +} + +export interface ImportExpression extends Node { + type: "ImportExpression" + source: Expression + options: Expression | null +} + +export interface ParenthesizedExpression extends Node { + type: "ParenthesizedExpression" + expression: Expression +} + +export interface PropertyDefinition extends Node { + type: "PropertyDefinition" + key: Expression | PrivateIdentifier + value?: Expression | null + computed: boolean + static: boolean +} + +export interface PrivateIdentifier extends Node { + type: "PrivateIdentifier" + name: string +} + +export interface StaticBlock extends Node { + type: "StaticBlock" + body: Array +} + +export type Statement = +| ExpressionStatement +| BlockStatement +| EmptyStatement +| DebuggerStatement +| WithStatement +| ReturnStatement +| LabeledStatement +| BreakStatement +| ContinueStatement +| IfStatement +| SwitchStatement +| ThrowStatement +| TryStatement +| WhileStatement +| DoWhileStatement +| ForStatement +| ForInStatement +| ForOfStatement +| Declaration + +export type Declaration = +| FunctionDeclaration +| VariableDeclaration +| ClassDeclaration + +export type Expression = +| Identifier +| Literal +| ThisExpression +| ArrayExpression +| ObjectExpression +| FunctionExpression +| UnaryExpression +| UpdateExpression +| BinaryExpression +| AssignmentExpression +| LogicalExpression +| MemberExpression +| ConditionalExpression +| CallExpression +| NewExpression +| SequenceExpression +| ArrowFunctionExpression +| YieldExpression +| TemplateLiteral +| TaggedTemplateExpression +| ClassExpression +| MetaProperty +| AwaitExpression +| ChainExpression +| ImportExpression +| ParenthesizedExpression + +export type Pattern = +| Identifier +| MemberExpression +| ObjectPattern +| ArrayPattern +| RestElement +| AssignmentPattern + +export type ModuleDeclaration = +| ImportDeclaration +| ExportNamedDeclaration +| ExportDefaultDeclaration +| ExportAllDeclaration + +/** + * This interface is only used for defining {@link AnyNode}. + * It exists so that it can be extended by plugins: + * + * @example + * ```typescript + * declare module 'acorn' { + * interface NodeTypes { + * pluginName: FirstNode | SecondNode | ThirdNode | ... | LastNode + * } + * } + * ``` + */ +interface NodeTypes { + core: Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportAttribute | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator +} + +export type AnyNode = NodeTypes[keyof NodeTypes] + +export function parse(input: string, options: Options): Program + +export function parseExpressionAt(input: string, pos: number, options: Options): Expression + +export function tokenizer(input: string, options: Options): { + getToken(): Token + [Symbol.iterator](): Iterator +} + +export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | "latest" + +export interface Options { + /** + * `ecmaVersion` indicates the ECMAScript version to parse. Can be a + * number, either in year (`2022`) or plain version number (`6`) form, + * or `"latest"` (the latest the library supports). This influences + * support for strict mode, the set of reserved words, and support for + * new syntax features. + */ + ecmaVersion: ecmaVersion + + /** + * `sourceType` indicates the mode the code should be parsed in. + * Can be either `"script"`, `"module"` or `"commonjs"`. This influences global + * strict mode and parsing of `import` and `export` declarations. + */ + sourceType?: "script" | "module" | "commonjs" + + /** + * a callback that will be called when a semicolon is automatically inserted. + * @param lastTokEnd the position of the comma as an offset + * @param lastTokEndLoc location if {@link locations} is enabled + */ + onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void + + /** + * similar to `onInsertedSemicolon`, but for trailing commas + * @param lastTokEnd the position of the comma as an offset + * @param lastTokEndLoc location if `locations` is enabled + */ + onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void + + /** + * By default, reserved words are only enforced if ecmaVersion >= 5. + * Set `allowReserved` to a boolean value to explicitly turn this on + * an off. When this option has the value "never", reserved words + * and keywords can also not be used as property names. + */ + allowReserved?: boolean | "never" + + /** + * When enabled, a return at the top level is not considered an error. + */ + allowReturnOutsideFunction?: boolean + + /** + * When enabled, import/export statements are not constrained to + * appearing at the top of the program, and an import.meta expression + * in a script isn't considered an error. + */ + allowImportExportEverywhere?: boolean + + /** + * By default, `await` identifiers are allowed to appear at the top-level scope only if {@link ecmaVersion} >= 2022. + * When enabled, await identifiers are allowed to appear at the top-level scope, + * but they are still not allowed in non-async functions. + */ + allowAwaitOutsideFunction?: boolean + + /** + * When enabled, super identifiers are not constrained to + * appearing in methods and do not raise an error when they appear elsewhere. + */ + allowSuperOutsideMethod?: boolean + + /** + * When enabled, hashbang directive in the beginning of file is + * allowed and treated as a line comment. Enabled by default when + * {@link ecmaVersion} >= 2023. + */ + allowHashBang?: boolean + + /** + * By default, the parser will verify that private properties are + * only used in places where they are valid and have been declared. + * Set this to false to turn such checks off. + */ + checkPrivateFields?: boolean + + /** + * When `locations` is on, `loc` properties holding objects with + * `start` and `end` properties as {@link Position} objects will be attached to the + * nodes. + */ + locations?: boolean + + /** + * a callback that will cause Acorn to call that export function with object in the same + * format as tokens returned from `tokenizer().getToken()`. Note + * that you are not allowed to call the parser from the + * callback—that will corrupt its internal state. + */ + onToken?: ((token: Token) => void) | Token[] + + + /** + * This takes a export function or an array. + * + * When a export function is passed, Acorn will call that export function with `(block, text, start, + * end)` parameters whenever a comment is skipped. `block` is a + * boolean indicating whether this is a block (`/* *\/`) comment, + * `text` is the content of the comment, and `start` and `end` are + * character offsets that denote the start and end of the comment. + * When the {@link locations} option is on, two more parameters are + * passed, the full locations of {@link Position} export type of the start and + * end of the comments. + * + * When a array is passed, each found comment of {@link Comment} export type is pushed to the array. + * + * Note that you are not allowed to call the + * parser from the callback—that will corrupt its internal state. + */ + onComment?: (( + isBlock: boolean, text: string, start: number, end: number, startLoc?: Position, + endLoc?: Position + ) => void) | Comment[] + + /** + * Nodes have their start and end characters offsets recorded in + * `start` and `end` properties (directly on the node, rather than + * the `loc` object, which holds line/column data. To also add a + * [semi-standardized][range] `range` property holding a `[start, + * end]` array with the same numbers, set the `ranges` option to + * `true`. + */ + ranges?: boolean + + /** + * It is possible to parse multiple files into a single AST by + * passing the tree produced by parsing the first file as + * `program` option in subsequent parses. This will add the + * toplevel forms of the parsed file to the `Program` (top) node + * of an existing parse tree. + */ + program?: Node + + /** + * When {@link locations} is on, you can pass this to record the source + * file in every node's `loc` object. + */ + sourceFile?: string + + /** + * This value, if given, is stored in every node, whether {@link locations} is on or off. + */ + directSourceFile?: string + + /** + * When enabled, parenthesized expressions are represented by + * (non-standard) ParenthesizedExpression nodes + */ + preserveParens?: boolean +} + +export class Parser { + options: Options + input: string + + protected constructor(options: Options, input: string, startPos?: number) + parse(): Program + + static parse(input: string, options: Options): Program + static parseExpressionAt(input: string, pos: number, options: Options): Expression + static tokenizer(input: string, options: Options): { + getToken(): Token + [Symbol.iterator](): Iterator + } + static extend(...plugins: ((BaseParser: typeof Parser) => typeof Parser)[]): typeof Parser +} + +export const defaultOptions: Options + +export function getLineInfo(input: string, offset: number): Position + +export class TokenType { + label: string + keyword: string | undefined +} + +export const tokTypes: { + num: TokenType + regexp: TokenType + string: TokenType + name: TokenType + privateId: TokenType + eof: TokenType + + bracketL: TokenType + bracketR: TokenType + braceL: TokenType + braceR: TokenType + parenL: TokenType + parenR: TokenType + comma: TokenType + semi: TokenType + colon: TokenType + dot: TokenType + question: TokenType + questionDot: TokenType + arrow: TokenType + template: TokenType + invalidTemplate: TokenType + ellipsis: TokenType + backQuote: TokenType + dollarBraceL: TokenType + + eq: TokenType + assign: TokenType + incDec: TokenType + prefix: TokenType + logicalOR: TokenType + logicalAND: TokenType + bitwiseOR: TokenType + bitwiseXOR: TokenType + bitwiseAND: TokenType + equality: TokenType + relational: TokenType + bitShift: TokenType + plusMin: TokenType + modulo: TokenType + star: TokenType + slash: TokenType + starstar: TokenType + coalesce: TokenType + + _break: TokenType + _case: TokenType + _catch: TokenType + _continue: TokenType + _debugger: TokenType + _default: TokenType + _do: TokenType + _else: TokenType + _finally: TokenType + _for: TokenType + _function: TokenType + _if: TokenType + _return: TokenType + _switch: TokenType + _throw: TokenType + _try: TokenType + _var: TokenType + _const: TokenType + _while: TokenType + _with: TokenType + _new: TokenType + _this: TokenType + _super: TokenType + _class: TokenType + _extends: TokenType + _export: TokenType + _import: TokenType + _null: TokenType + _true: TokenType + _false: TokenType + _in: TokenType + _instanceof: TokenType + _typeof: TokenType + _void: TokenType + _delete: TokenType +} + +export interface Comment { + type: "Line" | "Block" + value: string + start: number + end: number + loc?: SourceLocation + range?: [number, number] +} + +export class Token { + type: TokenType + start: number + end: number + loc?: SourceLocation + range?: [number, number] +} + +export const version: string diff --git a/node_modules/acorn/dist/acorn.js b/node_modules/acorn/dist/acorn.js new file mode 100644 index 0000000..b4f281a --- /dev/null +++ b/node_modules/acorn/dist/acorn.js @@ -0,0 +1,6295 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.acorn = {})); +})(this, (function (exports) { 'use strict'; + + // This file was generated. Do not modify manually! + var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 7, 9, 32, 4, 318, 1, 78, 5, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 68, 8, 2, 0, 3, 0, 2, 3, 2, 4, 2, 0, 15, 1, 83, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 7, 19, 58, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 199, 7, 137, 9, 54, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 55, 9, 266, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 10, 5350, 0, 7, 14, 11465, 27, 2343, 9, 87, 9, 39, 4, 60, 6, 26, 9, 535, 9, 470, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4178, 9, 519, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 245, 1, 2, 9, 233, 0, 3, 0, 8, 1, 6, 0, 475, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; + + // This file was generated. Do not modify manually! + var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 4, 51, 13, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 7, 25, 39, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 39, 27, 10, 22, 251, 41, 7, 1, 17, 5, 57, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 31, 9, 2, 0, 3, 0, 2, 37, 2, 0, 26, 0, 2, 0, 45, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 200, 32, 32, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 24, 43, 261, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 26, 3994, 6, 582, 6842, 29, 1763, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 433, 44, 212, 63, 33, 24, 3, 24, 45, 74, 6, 0, 67, 12, 65, 1, 2, 0, 15, 4, 10, 7381, 42, 31, 98, 114, 8702, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 229, 29, 3, 0, 208, 30, 2, 2, 2, 1, 2, 6, 3, 4, 10, 1, 225, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4381, 3, 5773, 3, 7472, 16, 621, 2467, 541, 1507, 4938, 6, 8489]; + + // This file was generated. Do not modify manually! + var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0897-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1add\u1ae0-\u1aeb\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f\uff65"; + + // This file was generated. Do not modify manually! + var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088f\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5c\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdc-\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c8a\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7dc\ua7f1-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; + + // These are a run-length and offset encoded representation of the + // >0xffff code points that are a valid part of identifiers. The + // offset starts at 0x10000, and each pair of numbers represents an + // offset to the next range, and then a size of the range. + + // Reserved word lists for various dialects of the language + + var reservedWords = { + 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", + 5: "class enum extends super const export import", + 6: "enum", + strict: "implements interface let package private protected public static yield", + strictBind: "eval arguments" + }; + + // And the keywords + + var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"; + + var keywords$1 = { + 5: ecma5AndLessKeywords, + "5module": ecma5AndLessKeywords + " export import", + 6: ecma5AndLessKeywords + " const class extends export import super" + }; + + var keywordRelationalOperator = /^in(stanceof)?$/; + + // ## Character categories + + var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); + var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); + + // This has a complexity linear to the value of the code. The + // assumption is that looking up astral identifier characters is + // rare. + function isInAstralSet(code, set) { + var pos = 0x10000; + for (var i = 0; i < set.length; i += 2) { + pos += set[i]; + if (pos > code) { return false } + pos += set[i + 1]; + if (pos >= code) { return true } + } + return false + } + + // Test whether a given character code starts an identifier. + + function isIdentifierStart(code, astral) { + if (code < 65) { return code === 36 } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) + } + + // Test whether a given character is part of an identifier. + + function isIdentifierChar(code, astral) { + if (code < 48) { return code === 36 } + if (code < 58) { return true } + if (code < 65) { return false } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) + } + + // ## Token types + + // The assignment of fine-grained, information-carrying type objects + // allows the tokenizer to store the information it has about a + // token in a way that is very cheap for the parser to look up. + + // All token type variables start with an underscore, to make them + // easy to recognize. + + // The `beforeExpr` property is used to disambiguate between regular + // expressions and divisions. It is set on all token types that can + // be followed by an expression (thus, a slash after them would be a + // regular expression). + // + // The `startsExpr` property is used to check if the token ends a + // `yield` expression. It is set on all token types that either can + // directly start an expression (like a quotation mark) or can + // continue an expression (like the body of a string). + // + // `isLoop` marks a keyword as starting a loop, which is important + // to know when parsing a label, in order to allow or disallow + // continue jumps to that label. + + var TokenType = function TokenType(label, conf) { + if ( conf === void 0 ) conf = {}; + + this.label = label; + this.keyword = conf.keyword; + this.beforeExpr = !!conf.beforeExpr; + this.startsExpr = !!conf.startsExpr; + this.isLoop = !!conf.isLoop; + this.isAssign = !!conf.isAssign; + this.prefix = !!conf.prefix; + this.postfix = !!conf.postfix; + this.binop = conf.binop || null; + this.updateContext = null; + }; + + function binop(name, prec) { + return new TokenType(name, {beforeExpr: true, binop: prec}) + } + var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true}; + + // Map keyword names to token types. + + var keywords = {}; + + // Succinct definitions of keyword token types + function kw(name, options) { + if ( options === void 0 ) options = {}; + + options.keyword = name; + return keywords[name] = new TokenType(name, options) + } + + var types$1 = { + num: new TokenType("num", startsExpr), + regexp: new TokenType("regexp", startsExpr), + string: new TokenType("string", startsExpr), + name: new TokenType("name", startsExpr), + privateId: new TokenType("privateId", startsExpr), + eof: new TokenType("eof"), + + // Punctuation token types. + bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), + bracketR: new TokenType("]"), + braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), + braceR: new TokenType("}"), + parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), + parenR: new TokenType(")"), + comma: new TokenType(",", beforeExpr), + semi: new TokenType(";", beforeExpr), + colon: new TokenType(":", beforeExpr), + dot: new TokenType("."), + question: new TokenType("?", beforeExpr), + questionDot: new TokenType("?."), + arrow: new TokenType("=>", beforeExpr), + template: new TokenType("template"), + invalidTemplate: new TokenType("invalidTemplate"), + ellipsis: new TokenType("...", beforeExpr), + backQuote: new TokenType("`", startsExpr), + dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), + + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. + + eq: new TokenType("=", {beforeExpr: true, isAssign: true}), + assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), + incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), + prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}), + logicalOR: binop("||", 1), + logicalAND: binop("&&", 2), + bitwiseOR: binop("|", 3), + bitwiseXOR: binop("^", 4), + bitwiseAND: binop("&", 5), + equality: binop("==/!=/===/!==", 6), + relational: binop("/<=/>=", 7), + bitShift: binop("<>/>>>", 8), + plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), + modulo: binop("%", 10), + star: binop("*", 10), + slash: binop("/", 10), + starstar: new TokenType("**", {beforeExpr: true}), + coalesce: binop("??", 1), + + // Keyword token types. + _break: kw("break"), + _case: kw("case", beforeExpr), + _catch: kw("catch"), + _continue: kw("continue"), + _debugger: kw("debugger"), + _default: kw("default", beforeExpr), + _do: kw("do", {isLoop: true, beforeExpr: true}), + _else: kw("else", beforeExpr), + _finally: kw("finally"), + _for: kw("for", {isLoop: true}), + _function: kw("function", startsExpr), + _if: kw("if"), + _return: kw("return", beforeExpr), + _switch: kw("switch"), + _throw: kw("throw", beforeExpr), + _try: kw("try"), + _var: kw("var"), + _const: kw("const"), + _while: kw("while", {isLoop: true}), + _with: kw("with"), + _new: kw("new", {beforeExpr: true, startsExpr: true}), + _this: kw("this", startsExpr), + _super: kw("super", startsExpr), + _class: kw("class", startsExpr), + _extends: kw("extends", beforeExpr), + _export: kw("export"), + _import: kw("import", startsExpr), + _null: kw("null", startsExpr), + _true: kw("true", startsExpr), + _false: kw("false", startsExpr), + _in: kw("in", {beforeExpr: true, binop: 7}), + _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), + _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), + _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), + _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) + }; + + // Matches a whole line break (where CRLF is considered a single + // line break). Used to count lines. + + var lineBreak = /\r\n?|\n|\u2028|\u2029/; + var lineBreakG = new RegExp(lineBreak.source, "g"); + + function isNewLine(code) { + return code === 10 || code === 13 || code === 0x2028 || code === 0x2029 + } + + function nextLineBreak(code, from, end) { + if ( end === void 0 ) end = code.length; + + for (var i = from; i < end; i++) { + var next = code.charCodeAt(i); + if (isNewLine(next)) + { return i < end - 1 && next === 13 && code.charCodeAt(i + 1) === 10 ? i + 2 : i + 1 } + } + return -1 + } + + var nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/; + + var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; + + var ref = Object.prototype; + var hasOwnProperty = ref.hasOwnProperty; + var toString = ref.toString; + + var hasOwn = Object.hasOwn || (function (obj, propName) { return ( + hasOwnProperty.call(obj, propName) + ); }); + + var isArray = Array.isArray || (function (obj) { return ( + toString.call(obj) === "[object Array]" + ); }); + + var regexpCache = Object.create(null); + + function wordsRegexp(words) { + return regexpCache[words] || (regexpCache[words] = new RegExp("^(?:" + words.replace(/ /g, "|") + ")$")) + } + + function codePointToString(code) { + // UTF-16 Decoding + if (code <= 0xFFFF) { return String.fromCharCode(code) } + code -= 0x10000; + return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00) + } + + var loneSurrogate = /(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/; + + // These are used when `options.locations` is on, for the + // `startLoc` and `endLoc` properties. + + var Position = function Position(line, col) { + this.line = line; + this.column = col; + }; + + Position.prototype.offset = function offset (n) { + return new Position(this.line, this.column + n) + }; + + var SourceLocation = function SourceLocation(p, start, end) { + this.start = start; + this.end = end; + if (p.sourceFile !== null) { this.source = p.sourceFile; } + }; + + // The `getLineInfo` function is mostly useful when the + // `locations` option is off (for performance reasons) and you + // want to find the line/column position for a given character + // offset. `input` should be the code string that the offset refers + // into. + + function getLineInfo(input, offset) { + for (var line = 1, cur = 0;;) { + var nextBreak = nextLineBreak(input, cur, offset); + if (nextBreak < 0) { return new Position(line, offset - cur) } + ++line; + cur = nextBreak; + } + } + + // A second argument must be given to configure the parser process. + // These options are recognized (only `ecmaVersion` is required): + + var defaultOptions = { + // `ecmaVersion` indicates the ECMAScript version to parse. Must be + // either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10 + // (2019), 11 (2020), 12 (2021), 13 (2022), 14 (2023), or `"latest"` + // (the latest version the library supports). This influences + // support for strict mode, the set of reserved words, and support + // for new syntax features. + ecmaVersion: null, + // `sourceType` indicates the mode the code should be parsed in. + // Can be either `"script"`, `"module"` or `"commonjs"`. This influences global + // strict mode and parsing of `import` and `export` declarations. + sourceType: "script", + // `onInsertedSemicolon` can be a callback that will be called when + // a semicolon is automatically inserted. It will be passed the + // position of the inserted semicolon as an offset, and if + // `locations` is enabled, it is given the location as a `{line, + // column}` object as second argument. + onInsertedSemicolon: null, + // `onTrailingComma` is similar to `onInsertedSemicolon`, but for + // trailing commas. + onTrailingComma: null, + // By default, reserved words are only enforced if ecmaVersion >= 5. + // Set `allowReserved` to a boolean value to explicitly turn this on + // an off. When this option has the value "never", reserved words + // and keywords can also not be used as property names. + allowReserved: null, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program, and an import.meta expression + // in a script isn't considered an error. + allowImportExportEverywhere: false, + // By default, await identifiers are allowed to appear at the top-level scope only if ecmaVersion >= 2022. + // When enabled, await identifiers are allowed to appear at the top-level scope, + // but they are still not allowed in non-async functions. + allowAwaitOutsideFunction: null, + // When enabled, super identifiers are not constrained to + // appearing in methods and do not raise an error when they appear elsewhere. + allowSuperOutsideMethod: null, + // When enabled, hashbang directive in the beginning of file is + // allowed and treated as a line comment. Enabled by default when + // `ecmaVersion` >= 2023. + allowHashBang: false, + // By default, the parser will verify that private properties are + // only used in places where they are valid and have been declared. + // Set this to false to turn such checks off. + checkPrivateFields: true, + // When `locations` is on, `loc` properties holding objects with + // `start` and `end` properties in `{line, column}` form (with + // line being 1-based and column 0-based) will be attached to the + // nodes. + locations: false, + // A function can be passed as `onToken` option, which will + // cause Acorn to call that function with object in the same + // format as tokens returned from `tokenizer().getToken()`. Note + // that you are not allowed to call the parser from the + // callback—that will corrupt its internal state. + onToken: null, + // A function can be passed as `onComment` option, which will + // cause Acorn to call that function with `(block, text, start, + // end)` parameters whenever a comment is skipped. `block` is a + // boolean indicating whether this is a block (`/* */`) comment, + // `text` is the content of the comment, and `start` and `end` are + // character offsets that denote the start and end of the comment. + // When the `locations` option is on, two more parameters are + // passed, the full `{line, column}` locations of the start and + // end of the comments. Note that you are not allowed to call the + // parser from the callback—that will corrupt its internal state. + // When this option has an array as value, objects representing the + // comments are pushed to it. + onComment: null, + // Nodes have their start and end characters offsets recorded in + // `start` and `end` properties (directly on the node, rather than + // the `loc` object, which holds line/column data. To also add a + // [semi-standardized][range] `range` property holding a `[start, + // end]` array with the same numbers, set the `ranges` option to + // `true`. + // + // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + ranges: false, + // It is possible to parse multiple files into a single AST by + // passing the tree produced by parsing the first file as + // `program` option in subsequent parses. This will add the + // toplevel forms of the parsed file to the `Program` (top) node + // of an existing parse tree. + program: null, + // When `locations` is on, you can pass this to record the source + // file in every node's `loc` object. + sourceFile: null, + // This value, if given, is stored in every node, whether + // `locations` is on or off. + directSourceFile: null, + // When enabled, parenthesized expressions are represented by + // (non-standard) ParenthesizedExpression nodes + preserveParens: false + }; + + // Interpret and default an options object + + var warnedAboutEcmaVersion = false; + + function getOptions(opts) { + var options = {}; + + for (var opt in defaultOptions) + { options[opt] = opts && hasOwn(opts, opt) ? opts[opt] : defaultOptions[opt]; } + + if (options.ecmaVersion === "latest") { + options.ecmaVersion = 1e8; + } else if (options.ecmaVersion == null) { + if (!warnedAboutEcmaVersion && typeof console === "object" && console.warn) { + warnedAboutEcmaVersion = true; + console.warn("Since Acorn 8.0.0, options.ecmaVersion is required.\nDefaulting to 2020, but this will stop working in the future."); + } + options.ecmaVersion = 11; + } else if (options.ecmaVersion >= 2015) { + options.ecmaVersion -= 2009; + } + + if (options.allowReserved == null) + { options.allowReserved = options.ecmaVersion < 5; } + + if (!opts || opts.allowHashBang == null) + { options.allowHashBang = options.ecmaVersion >= 14; } + + if (isArray(options.onToken)) { + var tokens = options.onToken; + options.onToken = function (token) { return tokens.push(token); }; + } + if (isArray(options.onComment)) + { options.onComment = pushComment(options, options.onComment); } + + if (options.sourceType === "commonjs" && options.allowAwaitOutsideFunction) + { throw new Error("Cannot use allowAwaitOutsideFunction with sourceType: commonjs") } + + return options + } + + function pushComment(options, array) { + return function(block, text, start, end, startLoc, endLoc) { + var comment = { + type: block ? "Block" : "Line", + value: text, + start: start, + end: end + }; + if (options.locations) + { comment.loc = new SourceLocation(this, startLoc, endLoc); } + if (options.ranges) + { comment.range = [start, end]; } + array.push(comment); + } + } + + // Each scope gets a bitset that may contain these flags + var + SCOPE_TOP = 1, + SCOPE_FUNCTION = 2, + SCOPE_ASYNC = 4, + SCOPE_GENERATOR = 8, + SCOPE_ARROW = 16, + SCOPE_SIMPLE_CATCH = 32, + SCOPE_SUPER = 64, + SCOPE_DIRECT_SUPER = 128, + SCOPE_CLASS_STATIC_BLOCK = 256, + SCOPE_CLASS_FIELD_INIT = 512, + SCOPE_SWITCH = 1024, + SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK; + + function functionFlags(async, generator) { + return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0) + } + + // Used in checkLVal* and declareName to determine the type of a binding + var + BIND_NONE = 0, // Not a binding + BIND_VAR = 1, // Var-style binding + BIND_LEXICAL = 2, // Let- or const-style binding + BIND_FUNCTION = 3, // Function declaration + BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding + BIND_OUTSIDE = 5; // Special case for function names as bound inside the function + + var Parser = function Parser(options, input, startPos) { + this.options = options = getOptions(options); + this.sourceFile = options.sourceFile; + this.keywords = wordsRegexp(keywords$1[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]); + var reserved = ""; + if (options.allowReserved !== true) { + reserved = reservedWords[options.ecmaVersion >= 6 ? 6 : options.ecmaVersion === 5 ? 5 : 3]; + if (options.sourceType === "module") { reserved += " await"; } + } + this.reservedWords = wordsRegexp(reserved); + var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict; + this.reservedWordsStrict = wordsRegexp(reservedStrict); + this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind); + this.input = String(input); + + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + this.containsEsc = false; + + // Set up token state + + // The current position of the tokenizer in the input. + if (startPos) { + this.pos = startPos; + this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1; + this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length; + } else { + this.pos = this.lineStart = 0; + this.curLine = 1; + } + + // Properties of the current token: + // Its type + this.type = types$1.eof; + // For tokens that include more information than their type, the value + this.value = null; + // Its start and end offset + this.start = this.end = this.pos; + // And, if locations are used, the {line, column} object + // corresponding to those offsets + this.startLoc = this.endLoc = this.curPosition(); + + // Position information for the previous token + this.lastTokEndLoc = this.lastTokStartLoc = null; + this.lastTokStart = this.lastTokEnd = this.pos; + + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + this.context = this.initialContext(); + this.exprAllowed = true; + + // Figure out if it's a module code. + this.inModule = options.sourceType === "module"; + this.strict = this.inModule || this.strictDirective(this.pos); + + // Used to signify the start of a potential arrow function + this.potentialArrowAt = -1; + this.potentialArrowInForAwait = false; + + // Positions to delayed-check that yield/await does not exist in default parameters. + this.yieldPos = this.awaitPos = this.awaitIdentPos = 0; + // Labels in scope. + this.labels = []; + // Thus-far undefined exports. + this.undefinedExports = Object.create(null); + + // If enabled, skip leading hashbang line. + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") + { this.skipLineComment(2); } + + // Scope tracking for duplicate variable names (see scope.js) + this.scopeStack = []; + this.enterScope( + this.options.sourceType === "commonjs" + // In commonjs, the top-level scope behaves like a function scope + ? SCOPE_FUNCTION + : SCOPE_TOP + ); + + // For RegExp validation + this.regexpState = null; + + // The stack of private names. + // Each element has two properties: 'declared' and 'used'. + // When it exited from the outermost class definition, all used private names must be declared. + this.privateNameStack = []; + }; + + var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowReturn: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },allowNewDotTarget: { configurable: true },allowUsing: { configurable: true },inClassStaticBlock: { configurable: true } }; + + Parser.prototype.parse = function parse () { + var node = this.options.program || this.startNode(); + this.nextToken(); + return this.parseTopLevel(node) + }; + + prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 }; + + prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 }; + + prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 }; + + prototypeAccessors.canAwait.get = function () { + for (var i = this.scopeStack.length - 1; i >= 0; i--) { + var ref = this.scopeStack[i]; + var flags = ref.flags; + if (flags & (SCOPE_CLASS_STATIC_BLOCK | SCOPE_CLASS_FIELD_INIT)) { return false } + if (flags & SCOPE_FUNCTION) { return (flags & SCOPE_ASYNC) > 0 } + } + return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction + }; + + prototypeAccessors.allowReturn.get = function () { + if (this.inFunction) { return true } + if (this.options.allowReturnOutsideFunction && this.currentVarScope().flags & SCOPE_TOP) { return true } + return false + }; + + prototypeAccessors.allowSuper.get = function () { + var ref = this.currentThisScope(); + var flags = ref.flags; + return (flags & SCOPE_SUPER) > 0 || this.options.allowSuperOutsideMethod + }; + + prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 }; + + prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) }; + + prototypeAccessors.allowNewDotTarget.get = function () { + for (var i = this.scopeStack.length - 1; i >= 0; i--) { + var ref = this.scopeStack[i]; + var flags = ref.flags; + if (flags & (SCOPE_CLASS_STATIC_BLOCK | SCOPE_CLASS_FIELD_INIT) || + ((flags & SCOPE_FUNCTION) && !(flags & SCOPE_ARROW))) { return true } + } + return false + }; + + prototypeAccessors.allowUsing.get = function () { + var ref = this.currentScope(); + var flags = ref.flags; + if (flags & SCOPE_SWITCH) { return false } + if (!this.inModule && flags & SCOPE_TOP) { return false } + return true + }; + + prototypeAccessors.inClassStaticBlock.get = function () { + return (this.currentVarScope().flags & SCOPE_CLASS_STATIC_BLOCK) > 0 + }; + + Parser.extend = function extend () { + var plugins = [], len = arguments.length; + while ( len-- ) plugins[ len ] = arguments[ len ]; + + var cls = this; + for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); } + return cls + }; + + Parser.parse = function parse (input, options) { + return new this(options, input).parse() + }; + + Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) { + var parser = new this(options, input, pos); + parser.nextToken(); + return parser.parseExpression() + }; + + Parser.tokenizer = function tokenizer (input, options) { + return new this(options, input) + }; + + Object.defineProperties( Parser.prototype, prototypeAccessors ); + + var pp$9 = Parser.prototype; + + // ## Parser utilities + + var literal = /^(?:'((?:\\[^]|[^'\\])*?)'|"((?:\\[^]|[^"\\])*?)")/; + pp$9.strictDirective = function(start) { + if (this.options.ecmaVersion < 5) { return false } + for (;;) { + // Try to find string literal. + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this.input)[0].length; + var match = literal.exec(this.input.slice(start)); + if (!match) { return false } + if ((match[1] || match[2]) === "use strict") { + skipWhiteSpace.lastIndex = start + match[0].length; + var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length; + var next = this.input.charAt(end); + return next === ";" || next === "}" || + (lineBreak.test(spaceAfter[0]) && + !(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "=")) + } + start += match[0].length; + + // Skip semicolon, if any. + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this.input)[0].length; + if (this.input[start] === ";") + { start++; } + } + }; + + // Predicate that tests whether the next token is of the given + // type, and if yes, consumes it as a side effect. + + pp$9.eat = function(type) { + if (this.type === type) { + this.next(); + return true + } else { + return false + } + }; + + // Tests whether parsed token is a contextual keyword. + + pp$9.isContextual = function(name) { + return this.type === types$1.name && this.value === name && !this.containsEsc + }; + + // Consumes contextual keyword if possible. + + pp$9.eatContextual = function(name) { + if (!this.isContextual(name)) { return false } + this.next(); + return true + }; + + // Asserts that following token is given contextual keyword. + + pp$9.expectContextual = function(name) { + if (!this.eatContextual(name)) { this.unexpected(); } + }; + + // Test whether a semicolon can be inserted at the current position. + + pp$9.canInsertSemicolon = function() { + return this.type === types$1.eof || + this.type === types$1.braceR || + lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + }; + + pp$9.insertSemicolon = function() { + if (this.canInsertSemicolon()) { + if (this.options.onInsertedSemicolon) + { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); } + return true + } + }; + + // Consume a semicolon, or, failing that, see if we are allowed to + // pretend that there is a semicolon at this position. + + pp$9.semicolon = function() { + if (!this.eat(types$1.semi) && !this.insertSemicolon()) { this.unexpected(); } + }; + + pp$9.afterTrailingComma = function(tokType, notNext) { + if (this.type === tokType) { + if (this.options.onTrailingComma) + { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); } + if (!notNext) + { this.next(); } + return true + } + }; + + // Expect a token of a given type. If found, consume it, otherwise, + // raise an unexpected token error. + + pp$9.expect = function(type) { + this.eat(type) || this.unexpected(); + }; + + // Raise an unexpected token error. + + pp$9.unexpected = function(pos) { + this.raise(pos != null ? pos : this.start, "Unexpected token"); + }; + + var DestructuringErrors = function DestructuringErrors() { + this.shorthandAssign = + this.trailingComma = + this.parenthesizedAssign = + this.parenthesizedBind = + this.doubleProto = + -1; + }; + + pp$9.checkPatternErrors = function(refDestructuringErrors, isAssign) { + if (!refDestructuringErrors) { return } + if (refDestructuringErrors.trailingComma > -1) + { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); } + var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind; + if (parens > -1) { this.raiseRecoverable(parens, isAssign ? "Assigning to rvalue" : "Parenthesized pattern"); } + }; + + pp$9.checkExpressionErrors = function(refDestructuringErrors, andThrow) { + if (!refDestructuringErrors) { return false } + var shorthandAssign = refDestructuringErrors.shorthandAssign; + var doubleProto = refDestructuringErrors.doubleProto; + if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 } + if (shorthandAssign >= 0) + { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); } + if (doubleProto >= 0) + { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); } + }; + + pp$9.checkYieldAwaitInDefaultParams = function() { + if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) + { this.raise(this.yieldPos, "Yield expression cannot be a default value"); } + if (this.awaitPos) + { this.raise(this.awaitPos, "Await expression cannot be a default value"); } + }; + + pp$9.isSimpleAssignTarget = function(expr) { + if (expr.type === "ParenthesizedExpression") + { return this.isSimpleAssignTarget(expr.expression) } + return expr.type === "Identifier" || expr.type === "MemberExpression" + }; + + var pp$8 = Parser.prototype; + + // ### Statement parsing + + // Parse a program. Initializes the parser, reads any number of + // statements, and wraps them in a Program node. Optionally takes a + // `program` argument. If present, the statements will be appended + // to its body instead of creating a new node. + + pp$8.parseTopLevel = function(node) { + var exports = Object.create(null); + if (!node.body) { node.body = []; } + while (this.type !== types$1.eof) { + var stmt = this.parseStatement(null, true, exports); + node.body.push(stmt); + } + if (this.inModule) + { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1) + { + var name = list[i]; + + this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined")); + } } + this.adaptDirectivePrologue(node.body); + this.next(); + node.sourceType = this.options.sourceType === "commonjs" ? "script" : this.options.sourceType; + return this.finishNode(node, "Program") + }; + + var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"}; + + pp$8.isLet = function(context) { + if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false } + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, nextCh = this.fullCharCodeAt(next); + // For ambiguous cases, determine if a LexicalDeclaration (or only a + // Statement) is allowed here. If context is not empty then only a Statement + // is allowed. However, `let [` is an explicit negative lookahead for + // ExpressionStatement, so special-case it first. + if (nextCh === 91 || nextCh === 92) { return true } // '[', '\' + if (context) { return false } + + if (nextCh === 123) { return true } // '{' + if (isIdentifierStart(nextCh)) { + var start = next; + do { next += nextCh <= 0xffff ? 1 : 2; } + while (isIdentifierChar(nextCh = this.fullCharCodeAt(next))) + if (nextCh === 92) { return true } + var ident = this.input.slice(start, next); + if (!keywordRelationalOperator.test(ident)) { return true } + } + return false + }; + + // check 'async [no LineTerminator here] function' + // - 'async /*foo*/ function' is OK. + // - 'async /*\n*/ function' is invalid. + pp$8.isAsyncFunction = function() { + if (this.options.ecmaVersion < 8 || !this.isContextual("async")) + { return false } + + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, after; + return !lineBreak.test(this.input.slice(this.pos, next)) && + this.input.slice(next, next + 8) === "function" && + (next + 8 === this.input.length || + !(isIdentifierChar(after = this.fullCharCodeAt(next + 8)) || after === 92 /* '\' */)) + }; + + pp$8.isUsingKeyword = function(isAwaitUsing, isFor) { + if (this.options.ecmaVersion < 17 || !this.isContextual(isAwaitUsing ? "await" : "using")) + { return false } + + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length; + + if (lineBreak.test(this.input.slice(this.pos, next))) { return false } + + if (isAwaitUsing) { + var usingEndPos = next + 5 /* using */, after; + if (this.input.slice(next, usingEndPos) !== "using" || + usingEndPos === this.input.length || + isIdentifierChar(after = this.fullCharCodeAt(usingEndPos)) || + after === 92 /* '\' */ + ) { return false } + + skipWhiteSpace.lastIndex = usingEndPos; + var skipAfterUsing = skipWhiteSpace.exec(this.input); + next = usingEndPos + skipAfterUsing[0].length; + if (skipAfterUsing && lineBreak.test(this.input.slice(usingEndPos, next))) { return false } + } + + var ch = this.fullCharCodeAt(next); + if (!isIdentifierStart(ch) && ch !== 92 /* '\' */) { return false } + var idStart = next; + do { next += ch <= 0xffff ? 1 : 2; } + while (isIdentifierChar(ch = this.fullCharCodeAt(next))) + if (ch === 92) { return true } + var id = this.input.slice(idStart, next); + if (keywordRelationalOperator.test(id) || isFor && id === "of") { return false } + return true + }; + + pp$8.isAwaitUsing = function(isFor) { + return this.isUsingKeyword(true, isFor) + }; + + pp$8.isUsing = function(isFor) { + return this.isUsingKeyword(false, isFor) + }; + + // Parse a single statement. + // + // If expecting a statement and finding a slash operator, parse a + // regular expression literal. This is to handle cases like + // `if (foo) /blah/.exec(foo)`, where looking at the previous token + // does not help. + + pp$8.parseStatement = function(context, topLevel, exports) { + var starttype = this.type, node = this.startNode(), kind; + + if (this.isLet(context)) { + starttype = types$1._var; + kind = "let"; + } + + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. + + switch (starttype) { + case types$1._break: case types$1._continue: return this.parseBreakContinueStatement(node, starttype.keyword) + case types$1._debugger: return this.parseDebuggerStatement(node) + case types$1._do: return this.parseDoStatement(node) + case types$1._for: return this.parseForStatement(node) + case types$1._function: + // Function as sole body of either an if statement or a labeled statement + // works, but not when it is part of a labeled statement that is the sole + // body of an if statement. + if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); } + return this.parseFunctionStatement(node, false, !context) + case types$1._class: + if (context) { this.unexpected(); } + return this.parseClass(node, true) + case types$1._if: return this.parseIfStatement(node) + case types$1._return: return this.parseReturnStatement(node) + case types$1._switch: return this.parseSwitchStatement(node) + case types$1._throw: return this.parseThrowStatement(node) + case types$1._try: return this.parseTryStatement(node) + case types$1._const: case types$1._var: + kind = kind || this.value; + if (context && kind !== "var") { this.unexpected(); } + return this.parseVarStatement(node, kind) + case types$1._while: return this.parseWhileStatement(node) + case types$1._with: return this.parseWithStatement(node) + case types$1.braceL: return this.parseBlock(true, node) + case types$1.semi: return this.parseEmptyStatement(node) + case types$1._export: + case types$1._import: + if (this.options.ecmaVersion > 10 && starttype === types$1._import) { + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); + if (nextCh === 40 || nextCh === 46) // '(' or '.' + { return this.parseExpressionStatement(node, this.parseExpression()) } + } + + if (!this.options.allowImportExportEverywhere) { + if (!topLevel) + { this.raise(this.start, "'import' and 'export' may only appear at the top level"); } + if (!this.inModule) + { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); } + } + return starttype === types$1._import ? this.parseImport(node) : this.parseExport(node, exports) + + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + default: + if (this.isAsyncFunction()) { + if (context) { this.unexpected(); } + this.next(); + return this.parseFunctionStatement(node, true, !context) + } + + var usingKind = this.isAwaitUsing(false) ? "await using" : this.isUsing(false) ? "using" : null; + if (usingKind) { + if (!this.allowUsing) { + this.raise(this.start, "Using declaration cannot appear in the top level when source type is `script` or in the bare case statement"); + } + if (usingKind === "await using") { + if (!this.canAwait) { + this.raise(this.start, "Await using cannot appear outside of async function"); + } + this.next(); + } + this.next(); + this.parseVar(node, false, usingKind); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration") + } + + var maybeName = this.value, expr = this.parseExpression(); + if (starttype === types$1.name && expr.type === "Identifier" && this.eat(types$1.colon)) + { return this.parseLabeledStatement(node, maybeName, expr, context) } + else { return this.parseExpressionStatement(node, expr) } + } + }; + + pp$8.parseBreakContinueStatement = function(node, keyword) { + var isBreak = keyword === "break"; + this.next(); + if (this.eat(types$1.semi) || this.insertSemicolon()) { node.label = null; } + else if (this.type !== types$1.name) { this.unexpected(); } + else { + node.label = this.parseIdent(); + this.semicolon(); + } + + // Verify that there is an actual destination to break or + // continue to. + var i = 0; + for (; i < this.labels.length; ++i) { + var lab = this.labels[i]; + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) { break } + if (node.label && isBreak) { break } + } + } + if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); } + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") + }; + + pp$8.parseDebuggerStatement = function(node) { + this.next(); + this.semicolon(); + return this.finishNode(node, "DebuggerStatement") + }; + + pp$8.parseDoStatement = function(node) { + this.next(); + this.labels.push(loopLabel); + node.body = this.parseStatement("do"); + this.labels.pop(); + this.expect(types$1._while); + node.test = this.parseParenExpression(); + if (this.options.ecmaVersion >= 6) + { this.eat(types$1.semi); } + else + { this.semicolon(); } + return this.finishNode(node, "DoWhileStatement") + }; + + // Disambiguating between a `for` and a `for`/`in` or `for`/`of` + // loop is non-trivial. Basically, we have to parse the init `var` + // statement or expression, disallowing the `in` operator (see + // the second parameter to `parseExpression`), and then check + // whether the next token is `in` or `of`. When there is no init + // part (semicolon immediately after the opening parenthesis), it + // is a regular `for` loop. + + pp$8.parseForStatement = function(node) { + this.next(); + var awaitAt = (this.options.ecmaVersion >= 9 && this.canAwait && this.eatContextual("await")) ? this.lastTokStart : -1; + this.labels.push(loopLabel); + this.enterScope(0); + this.expect(types$1.parenL); + if (this.type === types$1.semi) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, null) + } + var isLet = this.isLet(); + if (this.type === types$1._var || this.type === types$1._const || isLet) { + var init$1 = this.startNode(), kind = isLet ? "let" : this.value; + this.next(); + this.parseVar(init$1, true, kind); + this.finishNode(init$1, "VariableDeclaration"); + return this.parseForAfterInit(node, init$1, awaitAt) + } + var startsWithLet = this.isContextual("let"), isForOf = false; + + var usingKind = this.isUsing(true) ? "using" : this.isAwaitUsing(true) ? "await using" : null; + if (usingKind) { + var init$2 = this.startNode(); + this.next(); + if (usingKind === "await using") { + if (!this.canAwait) { + this.raise(this.start, "Await using cannot appear outside of async function"); + } + this.next(); + } + this.parseVar(init$2, true, usingKind); + this.finishNode(init$2, "VariableDeclaration"); + return this.parseForAfterInit(node, init$2, awaitAt) + } + var containsEsc = this.containsEsc; + var refDestructuringErrors = new DestructuringErrors; + var initPos = this.start; + var init = awaitAt > -1 + ? this.parseExprSubscripts(refDestructuringErrors, "await") + : this.parseExpression(true, refDestructuringErrors); + if (this.type === types$1._in || (isForOf = this.options.ecmaVersion >= 6 && this.isContextual("of"))) { + if (awaitAt > -1) { // implies `ecmaVersion >= 9` (see declaration of awaitAt) + if (this.type === types$1._in) { this.unexpected(awaitAt); } + node.await = true; + } else if (isForOf && this.options.ecmaVersion >= 8) { + if (init.start === initPos && !containsEsc && init.type === "Identifier" && init.name === "async") { this.unexpected(); } + else if (this.options.ecmaVersion >= 9) { node.await = false; } + } + if (startsWithLet && isForOf) { this.raise(init.start, "The left-hand side of a for-of loop may not start with 'let'."); } + this.toAssignable(init, false, refDestructuringErrors); + this.checkLValPattern(init); + return this.parseForIn(node, init) + } else { + this.checkExpressionErrors(refDestructuringErrors, true); + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) + }; + + // Helper method to parse for loop after variable initialization + pp$8.parseForAfterInit = function(node, init, awaitAt) { + if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init.declarations.length === 1) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types$1._in) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + } else { node.await = awaitAt > -1; } + } + return this.parseForIn(node, init) + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) + }; + + pp$8.parseFunctionStatement = function(node, isAsync, declarationPosition) { + this.next(); + return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync) + }; + + pp$8.parseIfStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + // allow function declarations in branches, but only in non-strict mode + node.consequent = this.parseStatement("if"); + node.alternate = this.eat(types$1._else) ? this.parseStatement("if") : null; + return this.finishNode(node, "IfStatement") + }; + + pp$8.parseReturnStatement = function(node) { + if (!this.allowReturn) + { this.raise(this.start, "'return' outside of function"); } + this.next(); + + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. + + if (this.eat(types$1.semi) || this.insertSemicolon()) { node.argument = null; } + else { node.argument = this.parseExpression(); this.semicolon(); } + return this.finishNode(node, "ReturnStatement") + }; + + pp$8.parseSwitchStatement = function(node) { + this.next(); + node.discriminant = this.parseParenExpression(); + node.cases = []; + this.expect(types$1.braceL); + this.labels.push(switchLabel); + this.enterScope(SCOPE_SWITCH); + + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. + + var cur; + for (var sawDefault = false; this.type !== types$1.braceR;) { + if (this.type === types$1._case || this.type === types$1._default) { + var isCase = this.type === types$1._case; + if (cur) { this.finishNode(cur, "SwitchCase"); } + node.cases.push(cur = this.startNode()); + cur.consequent = []; + this.next(); + if (isCase) { + cur.test = this.parseExpression(); + } else { + if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); } + sawDefault = true; + cur.test = null; + } + this.expect(types$1.colon); + } else { + if (!cur) { this.unexpected(); } + cur.consequent.push(this.parseStatement(null)); + } + } + this.exitScope(); + if (cur) { this.finishNode(cur, "SwitchCase"); } + this.next(); // Closing brace + this.labels.pop(); + return this.finishNode(node, "SwitchStatement") + }; + + pp$8.parseThrowStatement = function(node) { + this.next(); + if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) + { this.raise(this.lastTokEnd, "Illegal newline after throw"); } + node.argument = this.parseExpression(); + this.semicolon(); + return this.finishNode(node, "ThrowStatement") + }; + + // Reused empty array added for node fields that are always empty. + + var empty$1 = []; + + pp$8.parseCatchClauseParam = function() { + var param = this.parseBindingAtom(); + var simple = param.type === "Identifier"; + this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0); + this.checkLValPattern(param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL); + this.expect(types$1.parenR); + + return param + }; + + pp$8.parseTryStatement = function(node) { + this.next(); + node.block = this.parseBlock(); + node.handler = null; + if (this.type === types$1._catch) { + var clause = this.startNode(); + this.next(); + if (this.eat(types$1.parenL)) { + clause.param = this.parseCatchClauseParam(); + } else { + if (this.options.ecmaVersion < 10) { this.unexpected(); } + clause.param = null; + this.enterScope(0); + } + clause.body = this.parseBlock(false); + this.exitScope(); + node.handler = this.finishNode(clause, "CatchClause"); + } + node.finalizer = this.eat(types$1._finally) ? this.parseBlock() : null; + if (!node.handler && !node.finalizer) + { this.raise(node.start, "Missing catch or finally clause"); } + return this.finishNode(node, "TryStatement") + }; + + pp$8.parseVarStatement = function(node, kind, allowMissingInitializer) { + this.next(); + this.parseVar(node, false, kind, allowMissingInitializer); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration") + }; + + pp$8.parseWhileStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + this.labels.push(loopLabel); + node.body = this.parseStatement("while"); + this.labels.pop(); + return this.finishNode(node, "WhileStatement") + }; + + pp$8.parseWithStatement = function(node) { + if (this.strict) { this.raise(this.start, "'with' in strict mode"); } + this.next(); + node.object = this.parseParenExpression(); + node.body = this.parseStatement("with"); + return this.finishNode(node, "WithStatement") + }; + + pp$8.parseEmptyStatement = function(node) { + this.next(); + return this.finishNode(node, "EmptyStatement") + }; + + pp$8.parseLabeledStatement = function(node, maybeName, expr, context) { + for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1) + { + var label = list[i$1]; + + if (label.name === maybeName) + { this.raise(expr.start, "Label '" + maybeName + "' is already declared"); + } } + var kind = this.type.isLoop ? "loop" : this.type === types$1._switch ? "switch" : null; + for (var i = this.labels.length - 1; i >= 0; i--) { + var label$1 = this.labels[i]; + if (label$1.statementStart === node.start) { + // Update information about previous labels on this node + label$1.statementStart = this.start; + label$1.kind = kind; + } else { break } + } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}); + node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label"); + this.labels.pop(); + node.label = expr; + return this.finishNode(node, "LabeledStatement") + }; + + pp$8.parseExpressionStatement = function(node, expr) { + node.expression = expr; + this.semicolon(); + return this.finishNode(node, "ExpressionStatement") + }; + + // Parse a semicolon-enclosed block of statements, handling `"use + // strict"` declarations when `allowStrict` is true (used for + // function bodies). + + pp$8.parseBlock = function(createNewLexicalScope, node, exitStrict) { + if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true; + if ( node === void 0 ) node = this.startNode(); + + node.body = []; + this.expect(types$1.braceL); + if (createNewLexicalScope) { this.enterScope(0); } + while (this.type !== types$1.braceR) { + var stmt = this.parseStatement(null); + node.body.push(stmt); + } + if (exitStrict) { this.strict = false; } + this.next(); + if (createNewLexicalScope) { this.exitScope(); } + return this.finishNode(node, "BlockStatement") + }; + + // Parse a regular `for` loop. The disambiguation code in + // `parseStatement` will already have parsed the init statement or + // expression. + + pp$8.parseFor = function(node, init) { + node.init = init; + this.expect(types$1.semi); + node.test = this.type === types$1.semi ? null : this.parseExpression(); + this.expect(types$1.semi); + node.update = this.type === types$1.parenR ? null : this.parseExpression(); + this.expect(types$1.parenR); + node.body = this.parseStatement("for"); + this.exitScope(); + this.labels.pop(); + return this.finishNode(node, "ForStatement") + }; + + // Parse a `for`/`in` and `for`/`of` loop, which are almost + // same from parser's perspective. + + pp$8.parseForIn = function(node, init) { + var isForIn = this.type === types$1._in; + this.next(); + + if ( + init.type === "VariableDeclaration" && + init.declarations[0].init != null && + ( + !isForIn || + this.options.ecmaVersion < 8 || + this.strict || + init.kind !== "var" || + init.declarations[0].id.type !== "Identifier" + ) + ) { + this.raise( + init.start, + ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer") + ); + } + node.left = init; + node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign(); + this.expect(types$1.parenR); + node.body = this.parseStatement("for"); + this.exitScope(); + this.labels.pop(); + return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement") + }; + + // Parse a list of variable declarations. + + pp$8.parseVar = function(node, isFor, kind, allowMissingInitializer) { + node.declarations = []; + node.kind = kind; + for (;;) { + var decl = this.startNode(); + this.parseVarId(decl, kind); + if (this.eat(types$1.eq)) { + decl.init = this.parseMaybeAssign(isFor); + } else if (!allowMissingInitializer && kind === "const" && !(this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) { + this.unexpected(); + } else if (!allowMissingInitializer && (kind === "using" || kind === "await using") && this.options.ecmaVersion >= 17 && this.type !== types$1._in && !this.isContextual("of")) { + this.raise(this.lastTokEnd, ("Missing initializer in " + kind + " declaration")); + } else if (!allowMissingInitializer && decl.id.type !== "Identifier" && !(isFor && (this.type === types$1._in || this.isContextual("of")))) { + this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value"); + } else { + decl.init = null; + } + node.declarations.push(this.finishNode(decl, "VariableDeclarator")); + if (!this.eat(types$1.comma)) { break } + } + return node + }; + + pp$8.parseVarId = function(decl, kind) { + decl.id = kind === "using" || kind === "await using" + ? this.parseIdent() + : this.parseBindingAtom(); + + this.checkLValPattern(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false); + }; + + var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4; + + // Parse a function declaration or literal (depending on the + // `statement & FUNC_STATEMENT`). + + // Remove `allowExpressionBody` for 7.0.0, as it is only called with false + pp$8.parseFunction = function(node, statement, allowExpressionBody, isAsync, forInit) { + this.initFunction(node); + if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) { + if (this.type === types$1.star && (statement & FUNC_HANGING_STATEMENT)) + { this.unexpected(); } + node.generator = this.eat(types$1.star); + } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + if (statement & FUNC_STATEMENT) { + node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types$1.name ? null : this.parseIdent(); + if (node.id && !(statement & FUNC_HANGING_STATEMENT)) + // If it is a regular function declaration in sloppy mode, then it is + // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding + // mode depends on properties of the current scope (see + // treatFunctionsAsVar). + { this.checkLValSimple(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); } + } + + var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + this.enterScope(functionFlags(node.async, node.generator)); + + if (!(statement & FUNC_STATEMENT)) + { node.id = this.type === types$1.name ? this.parseIdent() : null; } + + this.parseFunctionParams(node); + this.parseFunctionBody(node, allowExpressionBody, false, forInit); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression") + }; + + pp$8.parseFunctionParams = function(node) { + this.expect(types$1.parenL); + node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + }; + + // Parse a class declaration or literal (depending on the + // `isStatement` parameter). + + pp$8.parseClass = function(node, isStatement) { + this.next(); + + // ecma-262 14.6 Class Definitions + // A class definition is always strict mode code. + var oldStrict = this.strict; + this.strict = true; + + this.parseClassId(node, isStatement); + this.parseClassSuper(node); + var privateNameMap = this.enterClassBody(); + var classBody = this.startNode(); + var hadConstructor = false; + classBody.body = []; + this.expect(types$1.braceL); + while (this.type !== types$1.braceR) { + var element = this.parseClassElement(node.superClass !== null); + if (element) { + classBody.body.push(element); + if (element.type === "MethodDefinition" && element.kind === "constructor") { + if (hadConstructor) { this.raiseRecoverable(element.start, "Duplicate constructor in the same class"); } + hadConstructor = true; + } else if (element.key && element.key.type === "PrivateIdentifier" && isPrivateNameConflicted(privateNameMap, element)) { + this.raiseRecoverable(element.key.start, ("Identifier '#" + (element.key.name) + "' has already been declared")); + } + } + } + this.strict = oldStrict; + this.next(); + node.body = this.finishNode(classBody, "ClassBody"); + this.exitClassBody(); + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") + }; + + pp$8.parseClassElement = function(constructorAllowsSuper) { + if (this.eat(types$1.semi)) { return null } + + var ecmaVersion = this.options.ecmaVersion; + var node = this.startNode(); + var keyName = ""; + var isGenerator = false; + var isAsync = false; + var kind = "method"; + var isStatic = false; + + if (this.eatContextual("static")) { + // Parse static init block + if (ecmaVersion >= 13 && this.eat(types$1.braceL)) { + this.parseClassStaticBlock(node); + return node + } + if (this.isClassElementNameStart() || this.type === types$1.star) { + isStatic = true; + } else { + keyName = "static"; + } + } + node.static = isStatic; + if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) { + if ((this.isClassElementNameStart() || this.type === types$1.star) && !this.canInsertSemicolon()) { + isAsync = true; + } else { + keyName = "async"; + } + } + if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types$1.star)) { + isGenerator = true; + } + if (!keyName && !isAsync && !isGenerator) { + var lastValue = this.value; + if (this.eatContextual("get") || this.eatContextual("set")) { + if (this.isClassElementNameStart()) { + kind = lastValue; + } else { + keyName = lastValue; + } + } + } + + // Parse element name + if (keyName) { + // 'async', 'get', 'set', or 'static' were not a keyword contextually. + // The last token is any of those. Make it the element name. + node.computed = false; + node.key = this.startNodeAt(this.lastTokStart, this.lastTokStartLoc); + node.key.name = keyName; + this.finishNode(node.key, "Identifier"); + } else { + this.parseClassElementName(node); + } + + // Parse element value + if (ecmaVersion < 13 || this.type === types$1.parenL || kind !== "method" || isGenerator || isAsync) { + var isConstructor = !node.static && checkKeyName(node, "constructor"); + var allowsDirectSuper = isConstructor && constructorAllowsSuper; + // Couldn't move this check into the 'parseClassMethod' method for backward compatibility. + if (isConstructor && kind !== "method") { this.raise(node.key.start, "Constructor can't have get/set modifier"); } + node.kind = isConstructor ? "constructor" : kind; + this.parseClassMethod(node, isGenerator, isAsync, allowsDirectSuper); + } else { + this.parseClassField(node); + } + + return node + }; + + pp$8.isClassElementNameStart = function() { + return ( + this.type === types$1.name || + this.type === types$1.privateId || + this.type === types$1.num || + this.type === types$1.string || + this.type === types$1.bracketL || + this.type.keyword + ) + }; + + pp$8.parseClassElementName = function(element) { + if (this.type === types$1.privateId) { + if (this.value === "constructor") { + this.raise(this.start, "Classes can't have an element named '#constructor'"); + } + element.computed = false; + element.key = this.parsePrivateIdent(); + } else { + this.parsePropertyName(element); + } + }; + + pp$8.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) { + // Check key and flags + var key = method.key; + if (method.kind === "constructor") { + if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); } + if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); } + } else if (method.static && checkKeyName(method, "prototype")) { + this.raise(key.start, "Classes may not have a static property named prototype"); + } + + // Parse value + var value = method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper); + + // Check value + if (method.kind === "get" && value.params.length !== 0) + { this.raiseRecoverable(value.start, "getter should have no params"); } + if (method.kind === "set" && value.params.length !== 1) + { this.raiseRecoverable(value.start, "setter should have exactly one param"); } + if (method.kind === "set" && value.params[0].type === "RestElement") + { this.raiseRecoverable(value.params[0].start, "Setter cannot use rest params"); } + + return this.finishNode(method, "MethodDefinition") + }; + + pp$8.parseClassField = function(field) { + if (checkKeyName(field, "constructor")) { + this.raise(field.key.start, "Classes can't have a field named 'constructor'"); + } else if (field.static && checkKeyName(field, "prototype")) { + this.raise(field.key.start, "Classes can't have a static field named 'prototype'"); + } + + if (this.eat(types$1.eq)) { + // To raise SyntaxError if 'arguments' exists in the initializer. + this.enterScope(SCOPE_CLASS_FIELD_INIT | SCOPE_SUPER); + field.value = this.parseMaybeAssign(); + this.exitScope(); + } else { + field.value = null; + } + this.semicolon(); + + return this.finishNode(field, "PropertyDefinition") + }; + + pp$8.parseClassStaticBlock = function(node) { + node.body = []; + + var oldLabels = this.labels; + this.labels = []; + this.enterScope(SCOPE_CLASS_STATIC_BLOCK | SCOPE_SUPER); + while (this.type !== types$1.braceR) { + var stmt = this.parseStatement(null); + node.body.push(stmt); + } + this.next(); + this.exitScope(); + this.labels = oldLabels; + + return this.finishNode(node, "StaticBlock") + }; + + pp$8.parseClassId = function(node, isStatement) { + if (this.type === types$1.name) { + node.id = this.parseIdent(); + if (isStatement) + { this.checkLValSimple(node.id, BIND_LEXICAL, false); } + } else { + if (isStatement === true) + { this.unexpected(); } + node.id = null; + } + }; + + pp$8.parseClassSuper = function(node) { + node.superClass = this.eat(types$1._extends) ? this.parseExprSubscripts(null, false) : null; + }; + + pp$8.enterClassBody = function() { + var element = {declared: Object.create(null), used: []}; + this.privateNameStack.push(element); + return element.declared + }; + + pp$8.exitClassBody = function() { + var ref = this.privateNameStack.pop(); + var declared = ref.declared; + var used = ref.used; + if (!this.options.checkPrivateFields) { return } + var len = this.privateNameStack.length; + var parent = len === 0 ? null : this.privateNameStack[len - 1]; + for (var i = 0; i < used.length; ++i) { + var id = used[i]; + if (!hasOwn(declared, id.name)) { + if (parent) { + parent.used.push(id); + } else { + this.raiseRecoverable(id.start, ("Private field '#" + (id.name) + "' must be declared in an enclosing class")); + } + } + } + }; + + function isPrivateNameConflicted(privateNameMap, element) { + var name = element.key.name; + var curr = privateNameMap[name]; + + var next = "true"; + if (element.type === "MethodDefinition" && (element.kind === "get" || element.kind === "set")) { + next = (element.static ? "s" : "i") + element.kind; + } + + // `class { get #a(){}; static set #a(_){} }` is also conflict. + if ( + curr === "iget" && next === "iset" || + curr === "iset" && next === "iget" || + curr === "sget" && next === "sset" || + curr === "sset" && next === "sget" + ) { + privateNameMap[name] = "true"; + return false + } else if (!curr) { + privateNameMap[name] = next; + return false + } else { + return true + } + } + + function checkKeyName(node, name) { + var computed = node.computed; + var key = node.key; + return !computed && ( + key.type === "Identifier" && key.name === name || + key.type === "Literal" && key.value === name + ) + } + + // Parses module export declaration. + + pp$8.parseExportAllDeclaration = function(node, exports) { + if (this.options.ecmaVersion >= 11) { + if (this.eatContextual("as")) { + node.exported = this.parseModuleExportName(); + this.checkExport(exports, node.exported, this.lastTokStart); + } else { + node.exported = null; + } + } + this.expectContextual("from"); + if (this.type !== types$1.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } + this.semicolon(); + return this.finishNode(node, "ExportAllDeclaration") + }; + + pp$8.parseExport = function(node, exports) { + this.next(); + // export * from '...' + if (this.eat(types$1.star)) { + return this.parseExportAllDeclaration(node, exports) + } + if (this.eat(types$1._default)) { // export default ... + this.checkExport(exports, "default", this.lastTokStart); + node.declaration = this.parseExportDefaultDeclaration(); + return this.finishNode(node, "ExportDefaultDeclaration") + } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseExportDeclaration(node); + if (node.declaration.type === "VariableDeclaration") + { this.checkVariableExport(exports, node.declaration.declarations); } + else + { this.checkExport(exports, node.declaration.id, node.declaration.id.start); } + node.specifiers = []; + node.source = null; + if (this.options.ecmaVersion >= 16) + { node.attributes = []; } + } else { // export { x, y as z } [from '...'] + node.declaration = null; + node.specifiers = this.parseExportSpecifiers(exports); + if (this.eatContextual("from")) { + if (this.type !== types$1.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } + } else { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) { + // check for keywords used as local names + var spec = list[i]; + + this.checkUnreserved(spec.local); + // check if export is defined + this.checkLocalExport(spec.local); + + if (spec.local.type === "Literal") { + this.raise(spec.local.start, "A string literal cannot be used as an exported binding without `from`."); + } + } + + node.source = null; + if (this.options.ecmaVersion >= 16) + { node.attributes = []; } + } + this.semicolon(); + } + return this.finishNode(node, "ExportNamedDeclaration") + }; + + pp$8.parseExportDeclaration = function(node) { + return this.parseStatement(null) + }; + + pp$8.parseExportDefaultDeclaration = function() { + var isAsync; + if (this.type === types$1._function || (isAsync = this.isAsyncFunction())) { + var fNode = this.startNode(); + this.next(); + if (isAsync) { this.next(); } + return this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync) + } else if (this.type === types$1._class) { + var cNode = this.startNode(); + return this.parseClass(cNode, "nullableID") + } else { + var declaration = this.parseMaybeAssign(); + this.semicolon(); + return declaration + } + }; + + pp$8.checkExport = function(exports, name, pos) { + if (!exports) { return } + if (typeof name !== "string") + { name = name.type === "Identifier" ? name.name : name.value; } + if (hasOwn(exports, name)) + { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); } + exports[name] = true; + }; + + pp$8.checkPatternExport = function(exports, pat) { + var type = pat.type; + if (type === "Identifier") + { this.checkExport(exports, pat, pat.start); } + else if (type === "ObjectPattern") + { for (var i = 0, list = pat.properties; i < list.length; i += 1) + { + var prop = list[i]; + + this.checkPatternExport(exports, prop); + } } + else if (type === "ArrayPattern") + { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) { + var elt = list$1[i$1]; + + if (elt) { this.checkPatternExport(exports, elt); } + } } + else if (type === "Property") + { this.checkPatternExport(exports, pat.value); } + else if (type === "AssignmentPattern") + { this.checkPatternExport(exports, pat.left); } + else if (type === "RestElement") + { this.checkPatternExport(exports, pat.argument); } + }; + + pp$8.checkVariableExport = function(exports, decls) { + if (!exports) { return } + for (var i = 0, list = decls; i < list.length; i += 1) + { + var decl = list[i]; + + this.checkPatternExport(exports, decl.id); + } + }; + + pp$8.shouldParseExportStatement = function() { + return this.type.keyword === "var" || + this.type.keyword === "const" || + this.type.keyword === "class" || + this.type.keyword === "function" || + this.isLet() || + this.isAsyncFunction() + }; + + // Parses a comma-separated list of module exports. + + pp$8.parseExportSpecifier = function(exports) { + var node = this.startNode(); + node.local = this.parseModuleExportName(); + + node.exported = this.eatContextual("as") ? this.parseModuleExportName() : node.local; + this.checkExport( + exports, + node.exported, + node.exported.start + ); + + return this.finishNode(node, "ExportSpecifier") + }; + + pp$8.parseExportSpecifiers = function(exports) { + var nodes = [], first = true; + // export { x, y as z } [from '...'] + this.expect(types$1.braceL); + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } + + nodes.push(this.parseExportSpecifier(exports)); + } + return nodes + }; + + // Parses import declaration. + + pp$8.parseImport = function(node) { + this.next(); + + // import '...' + if (this.type === types$1.string) { + node.specifiers = empty$1; + node.source = this.parseExprAtom(); + } else { + node.specifiers = this.parseImportSpecifiers(); + this.expectContextual("from"); + node.source = this.type === types$1.string ? this.parseExprAtom() : this.unexpected(); + } + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } + this.semicolon(); + return this.finishNode(node, "ImportDeclaration") + }; + + // Parses a comma-separated list of module imports. + + pp$8.parseImportSpecifier = function() { + var node = this.startNode(); + node.imported = this.parseModuleExportName(); + + if (this.eatContextual("as")) { + node.local = this.parseIdent(); + } else { + this.checkUnreserved(node.imported); + node.local = node.imported; + } + this.checkLValSimple(node.local, BIND_LEXICAL); + + return this.finishNode(node, "ImportSpecifier") + }; + + pp$8.parseImportDefaultSpecifier = function() { + // import defaultObj, { x, y as z } from '...' + var node = this.startNode(); + node.local = this.parseIdent(); + this.checkLValSimple(node.local, BIND_LEXICAL); + return this.finishNode(node, "ImportDefaultSpecifier") + }; + + pp$8.parseImportNamespaceSpecifier = function() { + var node = this.startNode(); + this.next(); + this.expectContextual("as"); + node.local = this.parseIdent(); + this.checkLValSimple(node.local, BIND_LEXICAL); + return this.finishNode(node, "ImportNamespaceSpecifier") + }; + + pp$8.parseImportSpecifiers = function() { + var nodes = [], first = true; + if (this.type === types$1.name) { + nodes.push(this.parseImportDefaultSpecifier()); + if (!this.eat(types$1.comma)) { return nodes } + } + if (this.type === types$1.star) { + nodes.push(this.parseImportNamespaceSpecifier()); + return nodes + } + this.expect(types$1.braceL); + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } + + nodes.push(this.parseImportSpecifier()); + } + return nodes + }; + + pp$8.parseWithClause = function() { + var nodes = []; + if (!this.eat(types$1._with)) { + return nodes + } + this.expect(types$1.braceL); + var attributeKeys = {}; + var first = true; + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } + + var attr = this.parseImportAttribute(); + var keyName = attr.key.type === "Identifier" ? attr.key.name : attr.key.value; + if (hasOwn(attributeKeys, keyName)) + { this.raiseRecoverable(attr.key.start, "Duplicate attribute key '" + keyName + "'"); } + attributeKeys[keyName] = true; + nodes.push(attr); + } + return nodes + }; + + pp$8.parseImportAttribute = function() { + var node = this.startNode(); + node.key = this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never"); + this.expect(types$1.colon); + if (this.type !== types$1.string) { + this.unexpected(); + } + node.value = this.parseExprAtom(); + return this.finishNode(node, "ImportAttribute") + }; + + pp$8.parseModuleExportName = function() { + if (this.options.ecmaVersion >= 13 && this.type === types$1.string) { + var stringLiteral = this.parseLiteral(this.value); + if (loneSurrogate.test(stringLiteral.value)) { + this.raise(stringLiteral.start, "An export name cannot include a lone surrogate."); + } + return stringLiteral + } + return this.parseIdent(true) + }; + + // Set `ExpressionStatement#directive` property for directive prologues. + pp$8.adaptDirectivePrologue = function(statements) { + for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) { + statements[i].directive = statements[i].expression.raw.slice(1, -1); + } + }; + pp$8.isDirectiveCandidate = function(statement) { + return ( + this.options.ecmaVersion >= 5 && + statement.type === "ExpressionStatement" && + statement.expression.type === "Literal" && + typeof statement.expression.value === "string" && + // Reject parenthesized strings. + (this.input[statement.start] === "\"" || this.input[statement.start] === "'") + ) + }; + + var pp$7 = Parser.prototype; + + // Convert existing expression atom to assignable pattern + // if possible. + + pp$7.toAssignable = function(node, isBinding, refDestructuringErrors) { + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + if (this.inAsync && node.name === "await") + { this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); } + break + + case "ObjectPattern": + case "ArrayPattern": + case "AssignmentPattern": + case "RestElement": + break + + case "ObjectExpression": + node.type = "ObjectPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + for (var i = 0, list = node.properties; i < list.length; i += 1) { + var prop = list[i]; + + this.toAssignable(prop, isBinding); + // Early error: + // AssignmentRestProperty[Yield, Await] : + // `...` DestructuringAssignmentTarget[Yield, Await] + // + // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|. + if ( + prop.type === "RestElement" && + (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") + ) { + this.raise(prop.argument.start, "Unexpected token"); + } + } + break + + case "Property": + // AssignmentProperty has type === "Property" + if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); } + this.toAssignable(node.value, isBinding); + break + + case "ArrayExpression": + node.type = "ArrayPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + this.toAssignableList(node.elements, isBinding); + break + + case "SpreadElement": + node.type = "RestElement"; + this.toAssignable(node.argument, isBinding); + if (node.argument.type === "AssignmentPattern") + { this.raise(node.argument.start, "Rest elements cannot have a default value"); } + break + + case "AssignmentExpression": + if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); } + node.type = "AssignmentPattern"; + delete node.operator; + this.toAssignable(node.left, isBinding); + break + + case "ParenthesizedExpression": + this.toAssignable(node.expression, isBinding, refDestructuringErrors); + break + + case "ChainExpression": + this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side"); + break + + case "MemberExpression": + if (!isBinding) { break } + + default: + this.raise(node.start, "Assigning to rvalue"); + } + } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + return node + }; + + // Convert list of expression atoms to binding list. + + pp$7.toAssignableList = function(exprList, isBinding) { + var end = exprList.length; + for (var i = 0; i < end; i++) { + var elt = exprList[i]; + if (elt) { this.toAssignable(elt, isBinding); } + } + if (end) { + var last = exprList[end - 1]; + if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") + { this.unexpected(last.argument.start); } + } + return exprList + }; + + // Parses spread element. + + pp$7.parseSpread = function(refDestructuringErrors) { + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeAssign(false, refDestructuringErrors); + return this.finishNode(node, "SpreadElement") + }; + + pp$7.parseRestBinding = function() { + var node = this.startNode(); + this.next(); + + // RestElement inside of a function parameter must be an identifier + if (this.options.ecmaVersion === 6 && this.type !== types$1.name) + { this.unexpected(); } + + node.argument = this.parseBindingAtom(); + + return this.finishNode(node, "RestElement") + }; + + // Parses lvalue (assignable) atom. + + pp$7.parseBindingAtom = function() { + if (this.options.ecmaVersion >= 6) { + switch (this.type) { + case types$1.bracketL: + var node = this.startNode(); + this.next(); + node.elements = this.parseBindingList(types$1.bracketR, true, true); + return this.finishNode(node, "ArrayPattern") + + case types$1.braceL: + return this.parseObj(true) + } + } + return this.parseIdent() + }; + + pp$7.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowModifiers) { + var elts = [], first = true; + while (!this.eat(close)) { + if (first) { first = false; } + else { this.expect(types$1.comma); } + if (allowEmpty && this.type === types$1.comma) { + elts.push(null); + } else if (allowTrailingComma && this.afterTrailingComma(close)) { + break + } else if (this.type === types$1.ellipsis) { + var rest = this.parseRestBinding(); + this.parseBindingListItem(rest); + elts.push(rest); + if (this.type === types$1.comma) { this.raiseRecoverable(this.start, "Comma is not permitted after the rest element"); } + this.expect(close); + break + } else { + elts.push(this.parseAssignableListItem(allowModifiers)); + } + } + return elts + }; + + pp$7.parseAssignableListItem = function(allowModifiers) { + var elem = this.parseMaybeDefault(this.start, this.startLoc); + this.parseBindingListItem(elem); + return elem + }; + + pp$7.parseBindingListItem = function(param) { + return param + }; + + // Parses assignment pattern around given atom if possible. + + pp$7.parseMaybeDefault = function(startPos, startLoc, left) { + left = left || this.parseBindingAtom(); + if (this.options.ecmaVersion < 6 || !this.eat(types$1.eq)) { return left } + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.right = this.parseMaybeAssign(); + return this.finishNode(node, "AssignmentPattern") + }; + + // The following three functions all verify that a node is an lvalue — + // something that can be bound, or assigned to. In order to do so, they perform + // a variety of checks: + // + // - Check that none of the bound/assigned-to identifiers are reserved words. + // - Record name declarations for bindings in the appropriate scope. + // - Check duplicate argument names, if checkClashes is set. + // + // If a complex binding pattern is encountered (e.g., object and array + // destructuring), the entire pattern is recursively checked. + // + // There are three versions of checkLVal*() appropriate for different + // circumstances: + // + // - checkLValSimple() shall be used if the syntactic construct supports + // nothing other than identifiers and member expressions. Parenthesized + // expressions are also correctly handled. This is generally appropriate for + // constructs for which the spec says + // + // > It is a Syntax Error if AssignmentTargetType of [the production] is not + // > simple. + // + // It is also appropriate for checking if an identifier is valid and not + // defined elsewhere, like import declarations or function/class identifiers. + // + // Examples where this is used include: + // a += …; + // import a from '…'; + // where a is the node to be checked. + // + // - checkLValPattern() shall be used if the syntactic construct supports + // anything checkLValSimple() supports, as well as object and array + // destructuring patterns. This is generally appropriate for constructs for + // which the spec says + // + // > It is a Syntax Error if [the production] is neither an ObjectLiteral nor + // > an ArrayLiteral and AssignmentTargetType of [the production] is not + // > simple. + // + // Examples where this is used include: + // (a = …); + // const a = …; + // try { … } catch (a) { … } + // where a is the node to be checked. + // + // - checkLValInnerPattern() shall be used if the syntactic construct supports + // anything checkLValPattern() supports, as well as default assignment + // patterns, rest elements, and other constructs that may appear within an + // object or array destructuring pattern. + // + // As a special case, function parameters also use checkLValInnerPattern(), + // as they also support defaults and rest constructs. + // + // These functions deliberately support both assignment and binding constructs, + // as the logic for both is exceedingly similar. If the node is the target of + // an assignment, then bindingType should be set to BIND_NONE. Otherwise, it + // should be set to the appropriate BIND_* constant, like BIND_VAR or + // BIND_LEXICAL. + // + // If the function is called with a non-BIND_NONE bindingType, then + // additionally a checkClashes object may be specified to allow checking for + // duplicate argument names. checkClashes is ignored if the provided construct + // is an assignment (i.e., bindingType is BIND_NONE). + + pp$7.checkLValSimple = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + var isBind = bindingType !== BIND_NONE; + + switch (expr.type) { + case "Identifier": + if (this.strict && this.reservedWordsStrictBind.test(expr.name)) + { this.raiseRecoverable(expr.start, (isBind ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); } + if (isBind) { + if (bindingType === BIND_LEXICAL && expr.name === "let") + { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); } + if (checkClashes) { + if (hasOwn(checkClashes, expr.name)) + { this.raiseRecoverable(expr.start, "Argument name clash"); } + checkClashes[expr.name] = true; + } + if (bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); } + } + break + + case "ChainExpression": + this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side"); + break + + case "MemberExpression": + if (isBind) { this.raiseRecoverable(expr.start, "Binding member expression"); } + break + + case "ParenthesizedExpression": + if (isBind) { this.raiseRecoverable(expr.start, "Binding parenthesized expression"); } + return this.checkLValSimple(expr.expression, bindingType, checkClashes) + + default: + this.raise(expr.start, (isBind ? "Binding" : "Assigning to") + " rvalue"); + } + }; + + pp$7.checkLValPattern = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + switch (expr.type) { + case "ObjectPattern": + for (var i = 0, list = expr.properties; i < list.length; i += 1) { + var prop = list[i]; + + this.checkLValInnerPattern(prop, bindingType, checkClashes); + } + break + + case "ArrayPattern": + for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) { + var elem = list$1[i$1]; + + if (elem) { this.checkLValInnerPattern(elem, bindingType, checkClashes); } + } + break + + default: + this.checkLValSimple(expr, bindingType, checkClashes); + } + }; + + pp$7.checkLValInnerPattern = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + switch (expr.type) { + case "Property": + // AssignmentProperty has type === "Property" + this.checkLValInnerPattern(expr.value, bindingType, checkClashes); + break + + case "AssignmentPattern": + this.checkLValPattern(expr.left, bindingType, checkClashes); + break + + case "RestElement": + this.checkLValPattern(expr.argument, bindingType, checkClashes); + break + + default: + this.checkLValPattern(expr, bindingType, checkClashes); + } + }; + + // The algorithm used to determine whether a regexp can appear at a + // given point in the program is loosely based on sweet.js' approach. + // See https://github.com/mozilla/sweet.js/wiki/design + + + var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) { + this.token = token; + this.isExpr = !!isExpr; + this.preserveSpace = !!preserveSpace; + this.override = override; + this.generator = !!generator; + }; + + var types = { + b_stat: new TokContext("{", false), + b_expr: new TokContext("{", true), + b_tmpl: new TokContext("${", false), + p_stat: new TokContext("(", false), + p_expr: new TokContext("(", true), + q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }), + f_stat: new TokContext("function", false), + f_expr: new TokContext("function", true), + f_expr_gen: new TokContext("function", true, false, null, true), + f_gen: new TokContext("function", false, false, null, true) + }; + + var pp$6 = Parser.prototype; + + pp$6.initialContext = function() { + return [types.b_stat] + }; + + pp$6.curContext = function() { + return this.context[this.context.length - 1] + }; + + pp$6.braceIsBlock = function(prevType) { + var parent = this.curContext(); + if (parent === types.f_expr || parent === types.f_stat) + { return true } + if (prevType === types$1.colon && (parent === types.b_stat || parent === types.b_expr)) + { return !parent.isExpr } + + // The check for `tt.name && exprAllowed` detects whether we are + // after a `yield` or `of` construct. See the `updateContext` for + // `tt.name`. + if (prevType === types$1._return || prevType === types$1.name && this.exprAllowed) + { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) } + if (prevType === types$1._else || prevType === types$1.semi || prevType === types$1.eof || prevType === types$1.parenR || prevType === types$1.arrow) + { return true } + if (prevType === types$1.braceL) + { return parent === types.b_stat } + if (prevType === types$1._var || prevType === types$1._const || prevType === types$1.name) + { return false } + return !this.exprAllowed + }; + + pp$6.inGeneratorContext = function() { + for (var i = this.context.length - 1; i >= 1; i--) { + var context = this.context[i]; + if (context.token === "function") + { return context.generator } + } + return false + }; + + pp$6.updateContext = function(prevType) { + var update, type = this.type; + if (type.keyword && prevType === types$1.dot) + { this.exprAllowed = false; } + else if (update = type.updateContext) + { update.call(this, prevType); } + else + { this.exprAllowed = type.beforeExpr; } + }; + + // Used to handle edge cases when token context could not be inferred correctly during tokenization phase + + pp$6.overrideContext = function(tokenCtx) { + if (this.curContext() !== tokenCtx) { + this.context[this.context.length - 1] = tokenCtx; + } + }; + + // Token-specific context update code + + types$1.parenR.updateContext = types$1.braceR.updateContext = function() { + if (this.context.length === 1) { + this.exprAllowed = true; + return + } + var out = this.context.pop(); + if (out === types.b_stat && this.curContext().token === "function") { + out = this.context.pop(); + } + this.exprAllowed = !out.isExpr; + }; + + types$1.braceL.updateContext = function(prevType) { + this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr); + this.exprAllowed = true; + }; + + types$1.dollarBraceL.updateContext = function() { + this.context.push(types.b_tmpl); + this.exprAllowed = true; + }; + + types$1.parenL.updateContext = function(prevType) { + var statementParens = prevType === types$1._if || prevType === types$1._for || prevType === types$1._with || prevType === types$1._while; + this.context.push(statementParens ? types.p_stat : types.p_expr); + this.exprAllowed = true; + }; + + types$1.incDec.updateContext = function() { + // tokExprAllowed stays unchanged + }; + + types$1._function.updateContext = types$1._class.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== types$1._else && + !(prevType === types$1.semi && this.curContext() !== types.p_stat) && + !(prevType === types$1._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) && + !((prevType === types$1.colon || prevType === types$1.braceL) && this.curContext() === types.b_stat)) + { this.context.push(types.f_expr); } + else + { this.context.push(types.f_stat); } + this.exprAllowed = false; + }; + + types$1.colon.updateContext = function() { + if (this.curContext().token === "function") { this.context.pop(); } + this.exprAllowed = true; + }; + + types$1.backQuote.updateContext = function() { + if (this.curContext() === types.q_tmpl) + { this.context.pop(); } + else + { this.context.push(types.q_tmpl); } + this.exprAllowed = false; + }; + + types$1.star.updateContext = function(prevType) { + if (prevType === types$1._function) { + var index = this.context.length - 1; + if (this.context[index] === types.f_expr) + { this.context[index] = types.f_expr_gen; } + else + { this.context[index] = types.f_gen; } + } + this.exprAllowed = true; + }; + + types$1.name.updateContext = function(prevType) { + var allowed = false; + if (this.options.ecmaVersion >= 6 && prevType !== types$1.dot) { + if (this.value === "of" && !this.exprAllowed || + this.value === "yield" && this.inGeneratorContext()) + { allowed = true; } + } + this.exprAllowed = allowed; + }; + + // A recursive descent parser operates by defining functions for all + // syntactic elements, and recursively calling those, each function + // advancing the input stream and returning an AST node. Precedence + // of constructs (for example, the fact that `!x[1]` means `!(x[1])` + // instead of `(!x)[1]` is handled by the fact that the parser + // function that parses unary prefix operators is called first, and + // in turn calls the function that parses `[]` subscripts — that + // way, it'll receive the node for `x[1]` already parsed, and wraps + // *that* in the unary operator node. + // + // Acorn uses an [operator precedence parser][opp] to handle binary + // operator precedence, because it is much more compact than using + // the technique outlined above, which uses different, nesting + // functions to specify precedence, for all of the ten binary + // precedence levels that JavaScript defines. + // + // [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser + + + var pp$5 = Parser.prototype; + + // Check if property name clashes with already added. + // Object/class getters and setters are not allowed to clash — + // either with each other or with an init property — and in + // strict mode, init properties are also not allowed to be repeated. + + pp$5.checkPropClash = function(prop, propHash, refDestructuringErrors) { + if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement") + { return } + if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) + { return } + var key = prop.key; + var name; + switch (key.type) { + case "Identifier": name = key.name; break + case "Literal": name = String(key.value); break + default: return + } + var kind = prop.kind; + if (this.options.ecmaVersion >= 6) { + if (name === "__proto__" && kind === "init") { + if (propHash.proto) { + if (refDestructuringErrors) { + if (refDestructuringErrors.doubleProto < 0) { + refDestructuringErrors.doubleProto = key.start; + } + } else { + this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); + } + } + propHash.proto = true; + } + return + } + name = "$" + name; + var other = propHash[name]; + if (other) { + var redefinition; + if (kind === "init") { + redefinition = this.strict && other.init || other.get || other.set; + } else { + redefinition = other.init || other[kind]; + } + if (redefinition) + { this.raiseRecoverable(key.start, "Redefinition of property"); } + } else { + other = propHash[name] = { + init: false, + get: false, + set: false + }; + } + other[kind] = true; + }; + + // ### Expression parsing + + // These nest, from the most general expression type at the top to + // 'atomic', nondivisible expression types at the bottom. Most of + // the functions will simply let the function(s) below them parse, + // and, *if* the syntactic construct they handle is present, wrap + // the AST node that the inner parser gave them in another node. + + // Parse a full expression. The optional arguments are used to + // forbid the `in` operator (in for loops initalization expressions) + // and provide reference for storing '=' operator inside shorthand + // property assignment in contexts where both object expression + // and object pattern might appear (so it's possible to raise + // delayed syntax error at correct position). + + pp$5.parseExpression = function(forInit, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseMaybeAssign(forInit, refDestructuringErrors); + if (this.type === types$1.comma) { + var node = this.startNodeAt(startPos, startLoc); + node.expressions = [expr]; + while (this.eat(types$1.comma)) { node.expressions.push(this.parseMaybeAssign(forInit, refDestructuringErrors)); } + return this.finishNode(node, "SequenceExpression") + } + return expr + }; + + // Parse an assignment expression. This includes applications of + // operators like `+=`. + + pp$5.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) { + if (this.isContextual("yield")) { + if (this.inGenerator) { return this.parseYield(forInit) } + // The tokenizer will assume an expression is allowed after + // `yield`, but this isn't that kind of yield + else { this.exprAllowed = false; } + } + + var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1, oldDoubleProto = -1; + if (refDestructuringErrors) { + oldParenAssign = refDestructuringErrors.parenthesizedAssign; + oldTrailingComma = refDestructuringErrors.trailingComma; + oldDoubleProto = refDestructuringErrors.doubleProto; + refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1; + } else { + refDestructuringErrors = new DestructuringErrors; + ownDestructuringErrors = true; + } + + var startPos = this.start, startLoc = this.startLoc; + if (this.type === types$1.parenL || this.type === types$1.name) { + this.potentialArrowAt = this.start; + this.potentialArrowInForAwait = forInit === "await"; + } + var left = this.parseMaybeConditional(forInit, refDestructuringErrors); + if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); } + if (this.type.isAssign) { + var node = this.startNodeAt(startPos, startLoc); + node.operator = this.value; + if (this.type === types$1.eq) + { left = this.toAssignable(left, false, refDestructuringErrors); } + if (!ownDestructuringErrors) { + refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1; + } + if (refDestructuringErrors.shorthandAssign >= left.start) + { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly + if (this.type === types$1.eq) + { this.checkLValPattern(left); } + else + { this.checkLValSimple(left); } + node.left = left; + this.next(); + node.right = this.parseMaybeAssign(forInit); + if (oldDoubleProto > -1) { refDestructuringErrors.doubleProto = oldDoubleProto; } + return this.finishNode(node, "AssignmentExpression") + } else { + if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); } + } + if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; } + if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; } + return left + }; + + // Parse a ternary conditional (`?:`) operator. + + pp$5.parseMaybeConditional = function(forInit, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprOps(forInit, refDestructuringErrors); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + if (this.eat(types$1.question)) { + var node = this.startNodeAt(startPos, startLoc); + node.test = expr; + node.consequent = this.parseMaybeAssign(); + this.expect(types$1.colon); + node.alternate = this.parseMaybeAssign(forInit); + return this.finishNode(node, "ConditionalExpression") + } + return expr + }; + + // Start the precedence parser. + + pp$5.parseExprOps = function(forInit, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseMaybeUnary(refDestructuringErrors, false, false, forInit); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, forInit) + }; + + // Parse binary operators with the operator precedence parsing + // algorithm. `left` is the left-hand side of the operator. + // `minPrec` provides context that allows the function to stop and + // defer further parser to one of its callers when it encounters an + // operator that has a lower precedence than the set it is parsing. + + pp$5.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit) { + var prec = this.type.binop; + if (prec != null && (!forInit || this.type !== types$1._in)) { + if (prec > minPrec) { + var logical = this.type === types$1.logicalOR || this.type === types$1.logicalAND; + var coalesce = this.type === types$1.coalesce; + if (coalesce) { + // Handle the precedence of `tt.coalesce` as equal to the range of logical expressions. + // In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error. + prec = types$1.logicalAND.binop; + } + var op = this.value; + this.next(); + var startPos = this.start, startLoc = this.startLoc; + var right = this.parseExprOp(this.parseMaybeUnary(null, false, false, forInit), startPos, startLoc, prec, forInit); + var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce); + if ((logical && this.type === types$1.coalesce) || (coalesce && (this.type === types$1.logicalOR || this.type === types$1.logicalAND))) { + this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses"); + } + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit) + } + } + return left + }; + + pp$5.buildBinary = function(startPos, startLoc, left, right, op, logical) { + if (right.type === "PrivateIdentifier") { this.raise(right.start, "Private identifier can only be left side of binary expression"); } + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.operator = op; + node.right = right; + return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") + }; + + // Parse unary operators, both prefix and postfix. + + pp$5.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec, forInit) { + var startPos = this.start, startLoc = this.startLoc, expr; + if (this.isContextual("await") && this.canAwait) { + expr = this.parseAwait(forInit); + sawUnary = true; + } else if (this.type.prefix) { + var node = this.startNode(), update = this.type === types$1.incDec; + node.operator = this.value; + node.prefix = true; + this.next(); + node.argument = this.parseMaybeUnary(null, true, update, forInit); + this.checkExpressionErrors(refDestructuringErrors, true); + if (update) { this.checkLValSimple(node.argument); } + else if (this.strict && node.operator === "delete" && isLocalVariableAccess(node.argument)) + { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } + else if (node.operator === "delete" && isPrivateFieldAccess(node.argument)) + { this.raiseRecoverable(node.start, "Private fields can not be deleted"); } + else { sawUnary = true; } + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); + } else if (!sawUnary && this.type === types$1.privateId) { + if ((forInit || this.privateNameStack.length === 0) && this.options.checkPrivateFields) { this.unexpected(); } + expr = this.parsePrivateIdent(); + // only could be private fields in 'in', such as #x in obj + if (this.type !== types$1._in) { this.unexpected(); } + } else { + expr = this.parseExprSubscripts(refDestructuringErrors, forInit); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + while (this.type.postfix && !this.canInsertSemicolon()) { + var node$1 = this.startNodeAt(startPos, startLoc); + node$1.operator = this.value; + node$1.prefix = false; + node$1.argument = expr; + this.checkLValSimple(expr); + this.next(); + expr = this.finishNode(node$1, "UpdateExpression"); + } + } + + if (!incDec && this.eat(types$1.starstar)) { + if (sawUnary) + { this.unexpected(this.lastTokStart); } + else + { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false, false, forInit), "**", false) } + } else { + return expr + } + }; + + function isLocalVariableAccess(node) { + return ( + node.type === "Identifier" || + node.type === "ParenthesizedExpression" && isLocalVariableAccess(node.expression) + ) + } + + function isPrivateFieldAccess(node) { + return ( + node.type === "MemberExpression" && node.property.type === "PrivateIdentifier" || + node.type === "ChainExpression" && isPrivateFieldAccess(node.expression) || + node.type === "ParenthesizedExpression" && isPrivateFieldAccess(node.expression) + ) + } + + // Parse call, dot, and `[]`-subscript expressions. + + pp$5.parseExprSubscripts = function(refDestructuringErrors, forInit) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprAtom(refDestructuringErrors, forInit); + if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")") + { return expr } + var result = this.parseSubscripts(expr, startPos, startLoc, false, forInit); + if (refDestructuringErrors && result.type === "MemberExpression") { + if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; } + if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; } + if (refDestructuringErrors.trailingComma >= result.start) { refDestructuringErrors.trailingComma = -1; } + } + return result + }; + + pp$5.parseSubscripts = function(base, startPos, startLoc, noCalls, forInit) { + var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && + this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && + this.potentialArrowAt === base.start; + var optionalChained = false; + + while (true) { + var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit); + + if (element.optional) { optionalChained = true; } + if (element === base || element.type === "ArrowFunctionExpression") { + if (optionalChained) { + var chainNode = this.startNodeAt(startPos, startLoc); + chainNode.expression = element; + element = this.finishNode(chainNode, "ChainExpression"); + } + return element + } + + base = element; + } + }; + + pp$5.shouldParseAsyncArrow = function() { + return !this.canInsertSemicolon() && this.eat(types$1.arrow) + }; + + pp$5.parseSubscriptAsyncArrow = function(startPos, startLoc, exprList, forInit) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true, forInit) + }; + + pp$5.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) { + var optionalSupported = this.options.ecmaVersion >= 11; + var optional = optionalSupported && this.eat(types$1.questionDot); + if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); } + + var computed = this.eat(types$1.bracketL); + if (computed || (optional && this.type !== types$1.parenL && this.type !== types$1.backQuote) || this.eat(types$1.dot)) { + var node = this.startNodeAt(startPos, startLoc); + node.object = base; + if (computed) { + node.property = this.parseExpression(); + this.expect(types$1.bracketR); + } else if (this.type === types$1.privateId && base.type !== "Super") { + node.property = this.parsePrivateIdent(); + } else { + node.property = this.parseIdent(this.options.allowReserved !== "never"); + } + node.computed = !!computed; + if (optionalSupported) { + node.optional = optional; + } + base = this.finishNode(node, "MemberExpression"); + } else if (!noCalls && this.eat(types$1.parenL)) { + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + var exprList = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors); + if (maybeAsyncArrow && !optional && this.shouldParseAsyncArrow()) { + this.checkPatternErrors(refDestructuringErrors, false); + this.checkYieldAwaitInDefaultParams(); + if (this.awaitIdentPos > 0) + { this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); } + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.parseSubscriptAsyncArrow(startPos, startLoc, exprList, forInit) + } + this.checkExpressionErrors(refDestructuringErrors, true); + this.yieldPos = oldYieldPos || this.yieldPos; + this.awaitPos = oldAwaitPos || this.awaitPos; + this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos; + var node$1 = this.startNodeAt(startPos, startLoc); + node$1.callee = base; + node$1.arguments = exprList; + if (optionalSupported) { + node$1.optional = optional; + } + base = this.finishNode(node$1, "CallExpression"); + } else if (this.type === types$1.backQuote) { + if (optional || optionalChained) { + this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions"); + } + var node$2 = this.startNodeAt(startPos, startLoc); + node$2.tag = base; + node$2.quasi = this.parseTemplate({isTagged: true}); + base = this.finishNode(node$2, "TaggedTemplateExpression"); + } + return base + }; + + // Parse an atomic expression — either a single token that is an + // expression, an expression started by a keyword like `function` or + // `new`, or an expression wrapped in punctuation like `()`, `[]`, + // or `{}`. + + pp$5.parseExprAtom = function(refDestructuringErrors, forInit, forNew) { + // If a division operator appears in an expression position, the + // tokenizer got confused, and we force it to read a regexp instead. + if (this.type === types$1.slash) { this.readRegexp(); } + + var node, canBeArrow = this.potentialArrowAt === this.start; + switch (this.type) { + case types$1._super: + if (!this.allowSuper) + { this.raise(this.start, "'super' keyword outside a method"); } + node = this.startNode(); + this.next(); + if (this.type === types$1.parenL && !this.allowDirectSuper) + { this.raise(node.start, "super() call outside constructor of a subclass"); } + // The `super` keyword can appear at below: + // SuperProperty: + // super [ Expression ] + // super . IdentifierName + // SuperCall: + // super ( Arguments ) + if (this.type !== types$1.dot && this.type !== types$1.bracketL && this.type !== types$1.parenL) + { this.unexpected(); } + return this.finishNode(node, "Super") + + case types$1._this: + node = this.startNode(); + this.next(); + return this.finishNode(node, "ThisExpression") + + case types$1.name: + var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc; + var id = this.parseIdent(false); + if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types$1._function)) { + this.overrideContext(types.f_expr); + return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true, forInit) + } + if (canBeArrow && !this.canInsertSemicolon()) { + if (this.eat(types$1.arrow)) + { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false, forInit) } + if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types$1.name && !containsEsc && + (!this.potentialArrowInForAwait || this.value !== "of" || this.containsEsc)) { + id = this.parseIdent(false); + if (this.canInsertSemicolon() || !this.eat(types$1.arrow)) + { this.unexpected(); } + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true, forInit) + } + } + return id + + case types$1.regexp: + var value = this.value; + node = this.parseLiteral(value.value); + node.regex = {pattern: value.pattern, flags: value.flags}; + return node + + case types$1.num: case types$1.string: + return this.parseLiteral(this.value) + + case types$1._null: case types$1._true: case types$1._false: + node = this.startNode(); + node.value = this.type === types$1._null ? null : this.type === types$1._true; + node.raw = this.type.keyword; + this.next(); + return this.finishNode(node, "Literal") + + case types$1.parenL: + var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow, forInit); + if (refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) + { refDestructuringErrors.parenthesizedAssign = start; } + if (refDestructuringErrors.parenthesizedBind < 0) + { refDestructuringErrors.parenthesizedBind = start; } + } + return expr + + case types$1.bracketL: + node = this.startNode(); + this.next(); + node.elements = this.parseExprList(types$1.bracketR, true, true, refDestructuringErrors); + return this.finishNode(node, "ArrayExpression") + + case types$1.braceL: + this.overrideContext(types.b_expr); + return this.parseObj(false, refDestructuringErrors) + + case types$1._function: + node = this.startNode(); + this.next(); + return this.parseFunction(node, 0) + + case types$1._class: + return this.parseClass(this.startNode(), false) + + case types$1._new: + return this.parseNew() + + case types$1.backQuote: + return this.parseTemplate() + + case types$1._import: + if (this.options.ecmaVersion >= 11) { + return this.parseExprImport(forNew) + } else { + return this.unexpected() + } + + default: + return this.parseExprAtomDefault() + } + }; + + pp$5.parseExprAtomDefault = function() { + this.unexpected(); + }; + + pp$5.parseExprImport = function(forNew) { + var node = this.startNode(); + + // Consume `import` as an identifier for `import.meta`. + // Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`. + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); } + this.next(); + + if (this.type === types$1.parenL && !forNew) { + return this.parseDynamicImport(node) + } else if (this.type === types$1.dot) { + var meta = this.startNodeAt(node.start, node.loc && node.loc.start); + meta.name = "import"; + node.meta = this.finishNode(meta, "Identifier"); + return this.parseImportMeta(node) + } else { + this.unexpected(); + } + }; + + pp$5.parseDynamicImport = function(node) { + this.next(); // skip `(` + + // Parse node.source. + node.source = this.parseMaybeAssign(); + + if (this.options.ecmaVersion >= 16) { + if (!this.eat(types$1.parenR)) { + this.expect(types$1.comma); + if (!this.afterTrailingComma(types$1.parenR)) { + node.options = this.parseMaybeAssign(); + if (!this.eat(types$1.parenR)) { + this.expect(types$1.comma); + if (!this.afterTrailingComma(types$1.parenR)) { + this.unexpected(); + } + } + } else { + node.options = null; + } + } else { + node.options = null; + } + } else { + // Verify ending. + if (!this.eat(types$1.parenR)) { + var errorPos = this.start; + if (this.eat(types$1.comma) && this.eat(types$1.parenR)) { + this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()"); + } else { + this.unexpected(errorPos); + } + } + } + + return this.finishNode(node, "ImportExpression") + }; + + pp$5.parseImportMeta = function(node) { + this.next(); // skip `.` + + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + + if (node.property.name !== "meta") + { this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); } + if (this.options.sourceType !== "module" && !this.options.allowImportExportEverywhere) + { this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); } + + return this.finishNode(node, "MetaProperty") + }; + + pp$5.parseLiteral = function(value) { + var node = this.startNode(); + node.value = value; + node.raw = this.input.slice(this.start, this.end); + if (node.raw.charCodeAt(node.raw.length - 1) === 110) + { node.bigint = node.value != null ? node.value.toString() : node.raw.slice(0, -1).replace(/_/g, ""); } + this.next(); + return this.finishNode(node, "Literal") + }; + + pp$5.parseParenExpression = function() { + this.expect(types$1.parenL); + var val = this.parseExpression(); + this.expect(types$1.parenR); + return val + }; + + pp$5.shouldParseArrow = function(exprList) { + return !this.canInsertSemicolon() + }; + + pp$5.parseParenAndDistinguishExpression = function(canBeArrow, forInit) { + var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8; + if (this.options.ecmaVersion >= 6) { + this.next(); + + var innerStartPos = this.start, innerStartLoc = this.startLoc; + var exprList = [], first = true, lastIsComma = false; + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart; + this.yieldPos = 0; + this.awaitPos = 0; + // Do not save awaitIdentPos to allow checking awaits nested in parameters + while (this.type !== types$1.parenR) { + first ? first = false : this.expect(types$1.comma); + if (allowTrailingComma && this.afterTrailingComma(types$1.parenR, true)) { + lastIsComma = true; + break + } else if (this.type === types$1.ellipsis) { + spreadStart = this.start; + exprList.push(this.parseParenItem(this.parseRestBinding())); + if (this.type === types$1.comma) { + this.raiseRecoverable( + this.start, + "Comma is not permitted after the rest element" + ); + } + break + } else { + exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem)); + } + } + var innerEndPos = this.lastTokEnd, innerEndLoc = this.lastTokEndLoc; + this.expect(types$1.parenR); + + if (canBeArrow && this.shouldParseArrow(exprList) && this.eat(types$1.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false); + this.checkYieldAwaitInDefaultParams(); + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + return this.parseParenArrowList(startPos, startLoc, exprList, forInit) + } + + if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); } + if (spreadStart) { this.unexpected(spreadStart); } + this.checkExpressionErrors(refDestructuringErrors, true); + this.yieldPos = oldYieldPos || this.yieldPos; + this.awaitPos = oldAwaitPos || this.awaitPos; + + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc); + val.expressions = exprList; + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); + } else { + val = exprList[0]; + } + } else { + val = this.parseParenExpression(); + } + + if (this.options.preserveParens) { + var par = this.startNodeAt(startPos, startLoc); + par.expression = val; + return this.finishNode(par, "ParenthesizedExpression") + } else { + return val + } + }; + + pp$5.parseParenItem = function(item) { + return item + }; + + pp$5.parseParenArrowList = function(startPos, startLoc, exprList, forInit) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, false, forInit) + }; + + // New's precedence is slightly tricky. It must allow its argument to + // be a `[]` or dot subscript expression, but not a call — at least, + // not without wrapping it in parentheses. Thus, it uses the noCalls + // argument to parseSubscripts to prevent it from consuming the + // argument list. + + var empty = []; + + pp$5.parseNew = function() { + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); } + var node = this.startNode(); + this.next(); + if (this.options.ecmaVersion >= 6 && this.type === types$1.dot) { + var meta = this.startNodeAt(node.start, node.loc && node.loc.start); + meta.name = "new"; + node.meta = this.finishNode(meta, "Identifier"); + this.next(); + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + if (node.property.name !== "target") + { this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); } + if (!this.allowNewDotTarget) + { this.raiseRecoverable(node.start, "'new.target' can only be used in functions and class static block"); } + return this.finishNode(node, "MetaProperty") + } + var startPos = this.start, startLoc = this.startLoc; + node.callee = this.parseSubscripts(this.parseExprAtom(null, false, true), startPos, startLoc, true, false); + if (this.eat(types$1.parenL)) { node.arguments = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false); } + else { node.arguments = empty; } + return this.finishNode(node, "NewExpression") + }; + + // Parse template expression. + + pp$5.parseTemplateElement = function(ref) { + var isTagged = ref.isTagged; + + var elem = this.startNode(); + if (this.type === types$1.invalidTemplate) { + if (!isTagged) { + this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"); + } + elem.value = { + raw: this.value.replace(/\r\n?/g, "\n"), + cooked: null + }; + } else { + elem.value = { + raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"), + cooked: this.value + }; + } + this.next(); + elem.tail = this.type === types$1.backQuote; + return this.finishNode(elem, "TemplateElement") + }; + + pp$5.parseTemplate = function(ref) { + if ( ref === void 0 ) ref = {}; + var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false; + + var node = this.startNode(); + this.next(); + node.expressions = []; + var curElt = this.parseTemplateElement({isTagged: isTagged}); + node.quasis = [curElt]; + while (!curElt.tail) { + if (this.type === types$1.eof) { this.raise(this.pos, "Unterminated template literal"); } + this.expect(types$1.dollarBraceL); + node.expressions.push(this.parseExpression()); + this.expect(types$1.braceR); + node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged})); + } + this.next(); + return this.finishNode(node, "TemplateLiteral") + }; + + pp$5.isAsyncProp = function(prop) { + return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && + (this.type === types$1.name || this.type === types$1.num || this.type === types$1.string || this.type === types$1.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types$1.star)) && + !lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + }; + + // Parse an object literal or binding pattern. + + pp$5.parseObj = function(isPattern, refDestructuringErrors) { + var node = this.startNode(), first = true, propHash = {}; + node.properties = []; + this.next(); + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } + + var prop = this.parseProperty(isPattern, refDestructuringErrors); + if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); } + node.properties.push(prop); + } + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") + }; + + pp$5.parseProperty = function(isPattern, refDestructuringErrors) { + var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc; + if (this.options.ecmaVersion >= 9 && this.eat(types$1.ellipsis)) { + if (isPattern) { + prop.argument = this.parseIdent(false); + if (this.type === types$1.comma) { + this.raiseRecoverable(this.start, "Comma is not permitted after the rest element"); + } + return this.finishNode(prop, "RestElement") + } + // Parse argument. + prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); + // To disallow trailing comma via `this.toAssignable()`. + if (this.type === types$1.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { + refDestructuringErrors.trailingComma = this.start; + } + // Finish + return this.finishNode(prop, "SpreadElement") + } + if (this.options.ecmaVersion >= 6) { + prop.method = false; + prop.shorthand = false; + if (isPattern || refDestructuringErrors) { + startPos = this.start; + startLoc = this.startLoc; + } + if (!isPattern) + { isGenerator = this.eat(types$1.star); } + } + var containsEsc = this.containsEsc; + this.parsePropertyName(prop); + if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { + isAsync = true; + isGenerator = this.options.ecmaVersion >= 9 && this.eat(types$1.star); + this.parsePropertyName(prop); + } else { + isAsync = false; + } + this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); + return this.finishNode(prop, "Property") + }; + + pp$5.parseGetterSetter = function(prop) { + var kind = prop.key.name; + this.parsePropertyName(prop); + prop.value = this.parseMethod(false); + prop.kind = kind; + var paramCount = prop.kind === "get" ? 0 : 1; + if (prop.value.params.length !== paramCount) { + var start = prop.value.start; + if (prop.kind === "get") + { this.raiseRecoverable(start, "getter should have no params"); } + else + { this.raiseRecoverable(start, "setter should have exactly one param"); } + } else { + if (prop.kind === "set" && prop.value.params[0].type === "RestElement") + { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); } + } + }; + + pp$5.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { + if ((isGenerator || isAsync) && this.type === types$1.colon) + { this.unexpected(); } + + if (this.eat(types$1.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors); + prop.kind = "init"; + } else if (this.options.ecmaVersion >= 6 && this.type === types$1.parenL) { + if (isPattern) { this.unexpected(); } + prop.method = true; + prop.value = this.parseMethod(isGenerator, isAsync); + prop.kind = "init"; + } else if (!isPattern && !containsEsc && + this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && + (prop.key.name === "get" || prop.key.name === "set") && + (this.type !== types$1.comma && this.type !== types$1.braceR && this.type !== types$1.eq)) { + if (isGenerator || isAsync) { this.unexpected(); } + this.parseGetterSetter(prop); + } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { + if (isGenerator || isAsync) { this.unexpected(); } + this.checkUnreserved(prop.key); + if (prop.key.name === "await" && !this.awaitIdentPos) + { this.awaitIdentPos = startPos; } + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key)); + } else if (this.type === types$1.eq && refDestructuringErrors) { + if (refDestructuringErrors.shorthandAssign < 0) + { refDestructuringErrors.shorthandAssign = this.start; } + prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key)); + } else { + prop.value = this.copyNode(prop.key); + } + prop.kind = "init"; + prop.shorthand = true; + } else { this.unexpected(); } + }; + + pp$5.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(types$1.bracketL)) { + prop.computed = true; + prop.key = this.parseMaybeAssign(); + this.expect(types$1.bracketR); + return prop.key + } else { + prop.computed = false; + } + } + return prop.key = this.type === types$1.num || this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never") + }; + + // Initialize empty function node. + + pp$5.initFunction = function(node) { + node.id = null; + if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; } + if (this.options.ecmaVersion >= 8) { node.async = false; } + }; + + // Parse object or class method. + + pp$5.parseMethod = function(isGenerator, isAsync, allowDirectSuper) { + var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + + this.initFunction(node); + if (this.options.ecmaVersion >= 6) + { node.generator = isGenerator; } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0)); + + this.expect(types$1.parenL); + node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + this.parseFunctionBody(node, false, true, false); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, "FunctionExpression") + }; + + // Parse arrow function expression with given parameters. + + pp$5.parseArrowExpression = function(node, params, isAsync, forInit) { + var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + + this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW); + this.initFunction(node); + if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; } + + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + + node.params = this.toAssignableList(params, true); + this.parseFunctionBody(node, true, false, forInit); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, "ArrowFunctionExpression") + }; + + // Parse function body and check parameters. + + pp$5.parseFunctionBody = function(node, isArrowFunction, isMethod, forInit) { + var isExpression = isArrowFunction && this.type !== types$1.braceL; + var oldStrict = this.strict, useStrict = false; + + if (isExpression) { + node.body = this.parseMaybeAssign(forInit); + node.expression = true; + this.checkParams(node, false); + } else { + var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params); + if (!oldStrict || nonSimple) { + useStrict = this.strictDirective(this.end); + // If this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + if (useStrict && nonSimple) + { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); } + } + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + var oldLabels = this.labels; + this.labels = []; + if (useStrict) { this.strict = true; } + + // Add the params to varDeclaredNames to ensure that an error is thrown + // if a let/const declaration in the function clashes with one of the params. + this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params)); + // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' + if (this.strict && node.id) { this.checkLValSimple(node.id, BIND_OUTSIDE); } + node.body = this.parseBlock(false, undefined, useStrict && !oldStrict); + node.expression = false; + this.adaptDirectivePrologue(node.body.body); + this.labels = oldLabels; + } + this.exitScope(); + }; + + pp$5.isSimpleParamList = function(params) { + for (var i = 0, list = params; i < list.length; i += 1) + { + var param = list[i]; + + if (param.type !== "Identifier") { return false + } } + return true + }; + + // Checks function params for various disallowed patterns such as using "eval" + // or "arguments" and duplicate parameters. + + pp$5.checkParams = function(node, allowDuplicates) { + var nameHash = Object.create(null); + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; + + this.checkLValInnerPattern(param, BIND_VAR, allowDuplicates ? null : nameHash); + } + }; + + // Parses a comma-separated list of expressions, and returns them as + // an array. `close` is the token type that ends the list, and + // `allowEmpty` can be turned on to allow subsequent commas with + // nothing in between them to be parsed as `null` (which is needed + // for array literals). + + pp$5.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { + var elts = [], first = true; + while (!this.eat(close)) { + if (!first) { + this.expect(types$1.comma); + if (allowTrailingComma && this.afterTrailingComma(close)) { break } + } else { first = false; } + + var elt = (void 0); + if (allowEmpty && this.type === types$1.comma) + { elt = null; } + else if (this.type === types$1.ellipsis) { + elt = this.parseSpread(refDestructuringErrors); + if (refDestructuringErrors && this.type === types$1.comma && refDestructuringErrors.trailingComma < 0) + { refDestructuringErrors.trailingComma = this.start; } + } else { + elt = this.parseMaybeAssign(false, refDestructuringErrors); + } + elts.push(elt); + } + return elts + }; + + pp$5.checkUnreserved = function(ref) { + var start = ref.start; + var end = ref.end; + var name = ref.name; + + if (this.inGenerator && name === "yield") + { this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); } + if (this.inAsync && name === "await") + { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); } + if (!(this.currentThisScope().flags & SCOPE_VAR) && name === "arguments") + { this.raiseRecoverable(start, "Cannot use 'arguments' in class field initializer"); } + if (this.inClassStaticBlock && (name === "arguments" || name === "await")) + { this.raise(start, ("Cannot use " + name + " in class static initialization block")); } + if (this.keywords.test(name)) + { this.raise(start, ("Unexpected keyword '" + name + "'")); } + if (this.options.ecmaVersion < 6 && + this.input.slice(start, end).indexOf("\\") !== -1) { return } + var re = this.strict ? this.reservedWordsStrict : this.reservedWords; + if (re.test(name)) { + if (!this.inAsync && name === "await") + { this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); } + this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); + } + }; + + // Parse the next token as an identifier. If `liberal` is true (used + // when parsing properties), it will also convert keywords into + // identifiers. + + pp$5.parseIdent = function(liberal) { + var node = this.parseIdentNode(); + this.next(!!liberal); + this.finishNode(node, "Identifier"); + if (!liberal) { + this.checkUnreserved(node); + if (node.name === "await" && !this.awaitIdentPos) + { this.awaitIdentPos = node.start; } + } + return node + }; + + pp$5.parseIdentNode = function() { + var node = this.startNode(); + if (this.type === types$1.name) { + node.name = this.value; + } else if (this.type.keyword) { + node.name = this.type.keyword; + + // To fix https://github.com/acornjs/acorn/issues/575 + // `class` and `function` keywords push new context into this.context. + // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name. + // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword + if ((node.name === "class" || node.name === "function") && + (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { + this.context.pop(); + } + this.type = types$1.name; + } else { + this.unexpected(); + } + return node + }; + + pp$5.parsePrivateIdent = function() { + var node = this.startNode(); + if (this.type === types$1.privateId) { + node.name = this.value; + } else { + this.unexpected(); + } + this.next(); + this.finishNode(node, "PrivateIdentifier"); + + // For validating existence + if (this.options.checkPrivateFields) { + if (this.privateNameStack.length === 0) { + this.raise(node.start, ("Private field '#" + (node.name) + "' must be declared in an enclosing class")); + } else { + this.privateNameStack[this.privateNameStack.length - 1].used.push(node); + } + } + + return node + }; + + // Parses yield expression inside generator. + + pp$5.parseYield = function(forInit) { + if (!this.yieldPos) { this.yieldPos = this.start; } + + var node = this.startNode(); + this.next(); + if (this.type === types$1.semi || this.canInsertSemicolon() || (this.type !== types$1.star && !this.type.startsExpr)) { + node.delegate = false; + node.argument = null; + } else { + node.delegate = this.eat(types$1.star); + node.argument = this.parseMaybeAssign(forInit); + } + return this.finishNode(node, "YieldExpression") + }; + + pp$5.parseAwait = function(forInit) { + if (!this.awaitPos) { this.awaitPos = this.start; } + + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeUnary(null, true, false, forInit); + return this.finishNode(node, "AwaitExpression") + }; + + var pp$4 = Parser.prototype; + + // This function is used to raise exceptions on parse errors. It + // takes an offset integer (into the current `input`) to indicate + // the location of the error, attaches the position to the end + // of the error message, and then raises a `SyntaxError` with that + // message. + + pp$4.raise = function(pos, message) { + var loc = getLineInfo(this.input, pos); + message += " (" + loc.line + ":" + loc.column + ")"; + if (this.sourceFile) { + message += " in " + this.sourceFile; + } + var err = new SyntaxError(message); + err.pos = pos; err.loc = loc; err.raisedAt = this.pos; + throw err + }; + + pp$4.raiseRecoverable = pp$4.raise; + + pp$4.curPosition = function() { + if (this.options.locations) { + return new Position(this.curLine, this.pos - this.lineStart) + } + }; + + var pp$3 = Parser.prototype; + + var Scope = function Scope(flags) { + this.flags = flags; + // A list of var-declared names in the current lexical scope + this.var = []; + // A list of lexically-declared names in the current lexical scope + this.lexical = []; + // A list of lexically-declared FunctionDeclaration names in the current lexical scope + this.functions = []; + }; + + // The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names. + + pp$3.enterScope = function(flags) { + this.scopeStack.push(new Scope(flags)); + }; + + pp$3.exitScope = function() { + this.scopeStack.pop(); + }; + + // The spec says: + // > At the top level of a function, or script, function declarations are + // > treated like var declarations rather than like lexical declarations. + pp$3.treatFunctionsAsVarInScope = function(scope) { + return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP) + }; + + pp$3.declareName = function(name, bindingType, pos) { + var redeclared = false; + if (bindingType === BIND_LEXICAL) { + var scope = this.currentScope(); + redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1; + scope.lexical.push(name); + if (this.inModule && (scope.flags & SCOPE_TOP)) + { delete this.undefinedExports[name]; } + } else if (bindingType === BIND_SIMPLE_CATCH) { + var scope$1 = this.currentScope(); + scope$1.lexical.push(name); + } else if (bindingType === BIND_FUNCTION) { + var scope$2 = this.currentScope(); + if (this.treatFunctionsAsVar) + { redeclared = scope$2.lexical.indexOf(name) > -1; } + else + { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; } + scope$2.functions.push(name); + } else { + for (var i = this.scopeStack.length - 1; i >= 0; --i) { + var scope$3 = this.scopeStack[i]; + if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) || + !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) { + redeclared = true; + break + } + scope$3.var.push(name); + if (this.inModule && (scope$3.flags & SCOPE_TOP)) + { delete this.undefinedExports[name]; } + if (scope$3.flags & SCOPE_VAR) { break } + } + } + if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); } + }; + + pp$3.checkLocalExport = function(id) { + // scope.functions must be empty as Module code is always strict. + if (this.scopeStack[0].lexical.indexOf(id.name) === -1 && + this.scopeStack[0].var.indexOf(id.name) === -1) { + this.undefinedExports[id.name] = id; + } + }; + + pp$3.currentScope = function() { + return this.scopeStack[this.scopeStack.length - 1] + }; + + pp$3.currentVarScope = function() { + for (var i = this.scopeStack.length - 1;; i--) { + var scope = this.scopeStack[i]; + if (scope.flags & (SCOPE_VAR | SCOPE_CLASS_FIELD_INIT | SCOPE_CLASS_STATIC_BLOCK)) { return scope } + } + }; + + // Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`. + pp$3.currentThisScope = function() { + for (var i = this.scopeStack.length - 1;; i--) { + var scope = this.scopeStack[i]; + if (scope.flags & (SCOPE_VAR | SCOPE_CLASS_FIELD_INIT | SCOPE_CLASS_STATIC_BLOCK) && + !(scope.flags & SCOPE_ARROW)) { return scope } + } + }; + + var Node = function Node(parser, pos, loc) { + this.type = ""; + this.start = pos; + this.end = 0; + if (parser.options.locations) + { this.loc = new SourceLocation(parser, loc); } + if (parser.options.directSourceFile) + { this.sourceFile = parser.options.directSourceFile; } + if (parser.options.ranges) + { this.range = [pos, 0]; } + }; + + // Start an AST node, attaching a start offset. + + var pp$2 = Parser.prototype; + + pp$2.startNode = function() { + return new Node(this, this.start, this.startLoc) + }; + + pp$2.startNodeAt = function(pos, loc) { + return new Node(this, pos, loc) + }; + + // Finish an AST node, adding `type` and `end` properties. + + function finishNodeAt(node, type, pos, loc) { + node.type = type; + node.end = pos; + if (this.options.locations) + { node.loc.end = loc; } + if (this.options.ranges) + { node.range[1] = pos; } + return node + } + + pp$2.finishNode = function(node, type) { + return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) + }; + + // Finish node at given position + + pp$2.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) + }; + + pp$2.copyNode = function(node) { + var newNode = new Node(this, node.start, this.startLoc); + for (var prop in node) { newNode[prop] = node[prop]; } + return newNode + }; + + // This file was generated by "bin/generate-unicode-script-values.js". Do not modify manually! + var scriptValuesAddedInUnicode = "Berf Beria_Erfe Gara Garay Gukh Gurung_Khema Hrkt Katakana_Or_Hiragana Kawi Kirat_Rai Krai Nag_Mundari Nagm Ol_Onal Onao Sidetic Sidt Sunu Sunuwar Tai_Yo Tayo Todhri Todr Tolong_Siki Tols Tulu_Tigalari Tutg Unknown Zzzz"; + + // This file contains Unicode properties extracted from the ECMAScript specification. + // The lists are extracted like so: + // $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText) + + // #table-binary-unicode-properties + var ecma9BinaryProperties = "ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS"; + var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic"; + var ecma11BinaryProperties = ecma10BinaryProperties; + var ecma12BinaryProperties = ecma11BinaryProperties + " EBase EComp EMod EPres ExtPict"; + var ecma13BinaryProperties = ecma12BinaryProperties; + var ecma14BinaryProperties = ecma13BinaryProperties; + + var unicodeBinaryProperties = { + 9: ecma9BinaryProperties, + 10: ecma10BinaryProperties, + 11: ecma11BinaryProperties, + 12: ecma12BinaryProperties, + 13: ecma13BinaryProperties, + 14: ecma14BinaryProperties + }; + + // #table-binary-unicode-properties-of-strings + var ecma14BinaryPropertiesOfStrings = "Basic_Emoji Emoji_Keycap_Sequence RGI_Emoji_Modifier_Sequence RGI_Emoji_Flag_Sequence RGI_Emoji_Tag_Sequence RGI_Emoji_ZWJ_Sequence RGI_Emoji"; + + var unicodeBinaryPropertiesOfStrings = { + 9: "", + 10: "", + 11: "", + 12: "", + 13: "", + 14: ecma14BinaryPropertiesOfStrings + }; + + // #table-unicode-general-category-values + var unicodeGeneralCategoryValues = "Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu"; + + // #table-unicode-script-values + var ecma9ScriptValues = "Adlam Adlm Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb"; + var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd"; + var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho"; + var ecma12ScriptValues = ecma11ScriptValues + " Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi"; + var ecma13ScriptValues = ecma12ScriptValues + " Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith"; + var ecma14ScriptValues = ecma13ScriptValues + " " + scriptValuesAddedInUnicode; + + var unicodeScriptValues = { + 9: ecma9ScriptValues, + 10: ecma10ScriptValues, + 11: ecma11ScriptValues, + 12: ecma12ScriptValues, + 13: ecma13ScriptValues, + 14: ecma14ScriptValues + }; + + var data = {}; + function buildUnicodeData(ecmaVersion) { + var d = data[ecmaVersion] = { + binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues), + binaryOfStrings: wordsRegexp(unicodeBinaryPropertiesOfStrings[ecmaVersion]), + nonBinary: { + General_Category: wordsRegexp(unicodeGeneralCategoryValues), + Script: wordsRegexp(unicodeScriptValues[ecmaVersion]) + } + }; + d.nonBinary.Script_Extensions = d.nonBinary.Script; + + d.nonBinary.gc = d.nonBinary.General_Category; + d.nonBinary.sc = d.nonBinary.Script; + d.nonBinary.scx = d.nonBinary.Script_Extensions; + } + + for (var i = 0, list = [9, 10, 11, 12, 13, 14]; i < list.length; i += 1) { + var ecmaVersion = list[i]; + + buildUnicodeData(ecmaVersion); + } + + var pp$1 = Parser.prototype; + + // Track disjunction structure to determine whether a duplicate + // capture group name is allowed because it is in a separate branch. + var BranchID = function BranchID(parent, base) { + // Parent disjunction branch + this.parent = parent; + // Identifies this set of sibling branches + this.base = base || this; + }; + + BranchID.prototype.separatedFrom = function separatedFrom (alt) { + // A branch is separate from another branch if they or any of + // their parents are siblings in a given disjunction + for (var self = this; self; self = self.parent) { + for (var other = alt; other; other = other.parent) { + if (self.base === other.base && self !== other) { return true } + } + } + return false + }; + + BranchID.prototype.sibling = function sibling () { + return new BranchID(this.parent, this.base) + }; + + var RegExpValidationState = function RegExpValidationState(parser) { + this.parser = parser; + this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : "") + (parser.options.ecmaVersion >= 15 ? "v" : ""); + this.unicodeProperties = data[parser.options.ecmaVersion >= 14 ? 14 : parser.options.ecmaVersion]; + this.source = ""; + this.flags = ""; + this.start = 0; + this.switchU = false; + this.switchV = false; + this.switchN = false; + this.pos = 0; + this.lastIntValue = 0; + this.lastStringValue = ""; + this.lastAssertionIsQuantifiable = false; + this.numCapturingParens = 0; + this.maxBackReference = 0; + this.groupNames = Object.create(null); + this.backReferenceNames = []; + this.branchID = null; + }; + + RegExpValidationState.prototype.reset = function reset (start, pattern, flags) { + var unicodeSets = flags.indexOf("v") !== -1; + var unicode = flags.indexOf("u") !== -1; + this.start = start | 0; + this.source = pattern + ""; + this.flags = flags; + if (unicodeSets && this.parser.options.ecmaVersion >= 15) { + this.switchU = true; + this.switchV = true; + this.switchN = true; + } else { + this.switchU = unicode && this.parser.options.ecmaVersion >= 6; + this.switchV = false; + this.switchN = unicode && this.parser.options.ecmaVersion >= 9; + } + }; + + RegExpValidationState.prototype.raise = function raise (message) { + this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message)); + }; + + // If u flag is given, this returns the code point at the index (it combines a surrogate pair). + // Otherwise, this returns the code unit of the index (can be a part of a surrogate pair). + RegExpValidationState.prototype.at = function at (i, forceU) { + if ( forceU === void 0 ) forceU = false; + + var s = this.source; + var l = s.length; + if (i >= l) { + return -1 + } + var c = s.charCodeAt(i); + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { + return c + } + var next = s.charCodeAt(i + 1); + return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c + }; + + RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) { + if ( forceU === void 0 ) forceU = false; + + var s = this.source; + var l = s.length; + if (i >= l) { + return l + } + var c = s.charCodeAt(i), next; + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l || + (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) { + return i + 1 + } + return i + 2 + }; + + RegExpValidationState.prototype.current = function current (forceU) { + if ( forceU === void 0 ) forceU = false; + + return this.at(this.pos, forceU) + }; + + RegExpValidationState.prototype.lookahead = function lookahead (forceU) { + if ( forceU === void 0 ) forceU = false; + + return this.at(this.nextIndex(this.pos, forceU), forceU) + }; + + RegExpValidationState.prototype.advance = function advance (forceU) { + if ( forceU === void 0 ) forceU = false; + + this.pos = this.nextIndex(this.pos, forceU); + }; + + RegExpValidationState.prototype.eat = function eat (ch, forceU) { + if ( forceU === void 0 ) forceU = false; + + if (this.current(forceU) === ch) { + this.advance(forceU); + return true + } + return false + }; + + RegExpValidationState.prototype.eatChars = function eatChars (chs, forceU) { + if ( forceU === void 0 ) forceU = false; + + var pos = this.pos; + for (var i = 0, list = chs; i < list.length; i += 1) { + var ch = list[i]; + + var current = this.at(pos, forceU); + if (current === -1 || current !== ch) { + return false + } + pos = this.nextIndex(pos, forceU); + } + this.pos = pos; + return true + }; + + /** + * Validate the flags part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ + pp$1.validateRegExpFlags = function(state) { + var validFlags = state.validFlags; + var flags = state.flags; + + var u = false; + var v = false; + + for (var i = 0; i < flags.length; i++) { + var flag = flags.charAt(i); + if (validFlags.indexOf(flag) === -1) { + this.raise(state.start, "Invalid regular expression flag"); + } + if (flags.indexOf(flag, i + 1) > -1) { + this.raise(state.start, "Duplicate regular expression flag"); + } + if (flag === "u") { u = true; } + if (flag === "v") { v = true; } + } + if (this.options.ecmaVersion >= 15 && u && v) { + this.raise(state.start, "Invalid regular expression flag"); + } + }; + + function hasProp(obj) { + for (var _ in obj) { return true } + return false + } + + /** + * Validate the pattern part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ + pp$1.validateRegExpPattern = function(state) { + this.regexp_pattern(state); + + // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of + // parsing contains a |GroupName|, reparse with the goal symbol + // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError* + // exception if _P_ did not conform to the grammar, if any elements of _P_ + // were not matched by the parse, or if any Early Error conditions exist. + if (!state.switchN && this.options.ecmaVersion >= 9 && hasProp(state.groupNames)) { + state.switchN = true; + this.regexp_pattern(state); + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern + pp$1.regexp_pattern = function(state) { + state.pos = 0; + state.lastIntValue = 0; + state.lastStringValue = ""; + state.lastAssertionIsQuantifiable = false; + state.numCapturingParens = 0; + state.maxBackReference = 0; + state.groupNames = Object.create(null); + state.backReferenceNames.length = 0; + state.branchID = null; + + this.regexp_disjunction(state); + + if (state.pos !== state.source.length) { + // Make the same messages as V8. + if (state.eat(0x29 /* ) */)) { + state.raise("Unmatched ')'"); + } + if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) { + state.raise("Lone quantifier brackets"); + } + } + if (state.maxBackReference > state.numCapturingParens) { + state.raise("Invalid escape"); + } + for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) { + var name = list[i]; + + if (!state.groupNames[name]) { + state.raise("Invalid named capture referenced"); + } + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction + pp$1.regexp_disjunction = function(state) { + var trackDisjunction = this.options.ecmaVersion >= 16; + if (trackDisjunction) { state.branchID = new BranchID(state.branchID, null); } + this.regexp_alternative(state); + while (state.eat(0x7C /* | */)) { + if (trackDisjunction) { state.branchID = state.branchID.sibling(); } + this.regexp_alternative(state); + } + if (trackDisjunction) { state.branchID = state.branchID.parent; } + + // Make the same message as V8. + if (this.regexp_eatQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + if (state.eat(0x7B /* { */)) { + state.raise("Lone quantifier brackets"); + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative + pp$1.regexp_alternative = function(state) { + while (state.pos < state.source.length && this.regexp_eatTerm(state)) {} + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term + pp$1.regexp_eatTerm = function(state) { + if (this.regexp_eatAssertion(state)) { + // Handle `QuantifiableAssertion Quantifier` alternative. + // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion + // is a QuantifiableAssertion. + if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) { + // Make the same message as V8. + if (state.switchU) { + state.raise("Invalid quantifier"); + } + } + return true + } + + if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) { + this.regexp_eatQuantifier(state); + return true + } + + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion + pp$1.regexp_eatAssertion = function(state) { + var start = state.pos; + state.lastAssertionIsQuantifiable = false; + + // ^, $ + if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) { + return true + } + + // \b \B + if (state.eat(0x5C /* \ */)) { + if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) { + return true + } + state.pos = start; + } + + // Lookahead / Lookbehind + if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) { + var lookbehind = false; + if (this.options.ecmaVersion >= 9) { + lookbehind = state.eat(0x3C /* < */); + } + if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) { + this.regexp_disjunction(state); + if (!state.eat(0x29 /* ) */)) { + state.raise("Unterminated group"); + } + state.lastAssertionIsQuantifiable = !lookbehind; + return true + } + } + + state.pos = start; + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier + pp$1.regexp_eatQuantifier = function(state, noError) { + if ( noError === void 0 ) noError = false; + + if (this.regexp_eatQuantifierPrefix(state, noError)) { + state.eat(0x3F /* ? */); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix + pp$1.regexp_eatQuantifierPrefix = function(state, noError) { + return ( + state.eat(0x2A /* * */) || + state.eat(0x2B /* + */) || + state.eat(0x3F /* ? */) || + this.regexp_eatBracedQuantifier(state, noError) + ) + }; + pp$1.regexp_eatBracedQuantifier = function(state, noError) { + var start = state.pos; + if (state.eat(0x7B /* { */)) { + var min = 0, max = -1; + if (this.regexp_eatDecimalDigits(state)) { + min = state.lastIntValue; + if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) { + max = state.lastIntValue; + } + if (state.eat(0x7D /* } */)) { + // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term + if (max !== -1 && max < min && !noError) { + state.raise("numbers out of order in {} quantifier"); + } + return true + } + } + if (state.switchU && !noError) { + state.raise("Incomplete quantifier"); + } + state.pos = start; + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Atom + pp$1.regexp_eatAtom = function(state) { + return ( + this.regexp_eatPatternCharacters(state) || + state.eat(0x2E /* . */) || + this.regexp_eatReverseSolidusAtomEscape(state) || + this.regexp_eatCharacterClass(state) || + this.regexp_eatUncapturingGroup(state) || + this.regexp_eatCapturingGroup(state) + ) + }; + pp$1.regexp_eatReverseSolidusAtomEscape = function(state) { + var start = state.pos; + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatAtomEscape(state)) { + return true + } + state.pos = start; + } + return false + }; + pp$1.regexp_eatUncapturingGroup = function(state) { + var start = state.pos; + if (state.eat(0x28 /* ( */)) { + if (state.eat(0x3F /* ? */)) { + if (this.options.ecmaVersion >= 16) { + var addModifiers = this.regexp_eatModifiers(state); + var hasHyphen = state.eat(0x2D /* - */); + if (addModifiers || hasHyphen) { + for (var i = 0; i < addModifiers.length; i++) { + var modifier = addModifiers.charAt(i); + if (addModifiers.indexOf(modifier, i + 1) > -1) { + state.raise("Duplicate regular expression modifiers"); + } + } + if (hasHyphen) { + var removeModifiers = this.regexp_eatModifiers(state); + if (!addModifiers && !removeModifiers && state.current() === 0x3A /* : */) { + state.raise("Invalid regular expression modifiers"); + } + for (var i$1 = 0; i$1 < removeModifiers.length; i$1++) { + var modifier$1 = removeModifiers.charAt(i$1); + if ( + removeModifiers.indexOf(modifier$1, i$1 + 1) > -1 || + addModifiers.indexOf(modifier$1) > -1 + ) { + state.raise("Duplicate regular expression modifiers"); + } + } + } + } + } + if (state.eat(0x3A /* : */)) { + this.regexp_disjunction(state); + if (state.eat(0x29 /* ) */)) { + return true + } + state.raise("Unterminated group"); + } + } + state.pos = start; + } + return false + }; + pp$1.regexp_eatCapturingGroup = function(state) { + if (state.eat(0x28 /* ( */)) { + if (this.options.ecmaVersion >= 9) { + this.regexp_groupSpecifier(state); + } else if (state.current() === 0x3F /* ? */) { + state.raise("Invalid group"); + } + this.regexp_disjunction(state); + if (state.eat(0x29 /* ) */)) { + state.numCapturingParens += 1; + return true + } + state.raise("Unterminated group"); + } + return false + }; + // RegularExpressionModifiers :: + // [empty] + // RegularExpressionModifiers RegularExpressionModifier + pp$1.regexp_eatModifiers = function(state) { + var modifiers = ""; + var ch = 0; + while ((ch = state.current()) !== -1 && isRegularExpressionModifier(ch)) { + modifiers += codePointToString(ch); + state.advance(); + } + return modifiers + }; + // RegularExpressionModifier :: one of + // `i` `m` `s` + function isRegularExpressionModifier(ch) { + return ch === 0x69 /* i */ || ch === 0x6d /* m */ || ch === 0x73 /* s */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom + pp$1.regexp_eatExtendedAtom = function(state) { + return ( + state.eat(0x2E /* . */) || + this.regexp_eatReverseSolidusAtomEscape(state) || + this.regexp_eatCharacterClass(state) || + this.regexp_eatUncapturingGroup(state) || + this.regexp_eatCapturingGroup(state) || + this.regexp_eatInvalidBracedQuantifier(state) || + this.regexp_eatExtendedPatternCharacter(state) + ) + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier + pp$1.regexp_eatInvalidBracedQuantifier = function(state) { + if (this.regexp_eatBracedQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter + pp$1.regexp_eatSyntaxCharacter = function(state) { + var ch = state.current(); + if (isSyntaxCharacter(ch)) { + state.lastIntValue = ch; + state.advance(); + return true + } + return false + }; + function isSyntaxCharacter(ch) { + return ( + ch === 0x24 /* $ */ || + ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ || + ch === 0x2E /* . */ || + ch === 0x3F /* ? */ || + ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ || + ch >= 0x7B /* { */ && ch <= 0x7D /* } */ + ) + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter + // But eat eager. + pp$1.regexp_eatPatternCharacters = function(state) { + var start = state.pos; + var ch = 0; + while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) { + state.advance(); + } + return state.pos !== start + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter + pp$1.regexp_eatExtendedPatternCharacter = function(state) { + var ch = state.current(); + if ( + ch !== -1 && + ch !== 0x24 /* $ */ && + !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) && + ch !== 0x2E /* . */ && + ch !== 0x3F /* ? */ && + ch !== 0x5B /* [ */ && + ch !== 0x5E /* ^ */ && + ch !== 0x7C /* | */ + ) { + state.advance(); + return true + } + return false + }; + + // GroupSpecifier :: + // [empty] + // `?` GroupName + pp$1.regexp_groupSpecifier = function(state) { + if (state.eat(0x3F /* ? */)) { + if (!this.regexp_eatGroupName(state)) { state.raise("Invalid group"); } + var trackDisjunction = this.options.ecmaVersion >= 16; + var known = state.groupNames[state.lastStringValue]; + if (known) { + if (trackDisjunction) { + for (var i = 0, list = known; i < list.length; i += 1) { + var altID = list[i]; + + if (!altID.separatedFrom(state.branchID)) + { state.raise("Duplicate capture group name"); } + } + } else { + state.raise("Duplicate capture group name"); + } + } + if (trackDisjunction) { + (known || (state.groupNames[state.lastStringValue] = [])).push(state.branchID); + } else { + state.groupNames[state.lastStringValue] = true; + } + } + }; + + // GroupName :: + // `<` RegExpIdentifierName `>` + // Note: this updates `state.lastStringValue` property with the eaten name. + pp$1.regexp_eatGroupName = function(state) { + state.lastStringValue = ""; + if (state.eat(0x3C /* < */)) { + if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) { + return true + } + state.raise("Invalid capture group name"); + } + return false + }; + + // RegExpIdentifierName :: + // RegExpIdentifierStart + // RegExpIdentifierName RegExpIdentifierPart + // Note: this updates `state.lastStringValue` property with the eaten name. + pp$1.regexp_eatRegExpIdentifierName = function(state) { + state.lastStringValue = ""; + if (this.regexp_eatRegExpIdentifierStart(state)) { + state.lastStringValue += codePointToString(state.lastIntValue); + while (this.regexp_eatRegExpIdentifierPart(state)) { + state.lastStringValue += codePointToString(state.lastIntValue); + } + return true + } + return false + }; + + // RegExpIdentifierStart :: + // UnicodeIDStart + // `$` + // `_` + // `\` RegExpUnicodeEscapeSequence[+U] + pp$1.regexp_eatRegExpIdentifierStart = function(state) { + var start = state.pos; + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); + + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { + ch = state.lastIntValue; + } + if (isRegExpIdentifierStart(ch)) { + state.lastIntValue = ch; + return true + } + + state.pos = start; + return false + }; + function isRegExpIdentifierStart(ch) { + return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ + } + + // RegExpIdentifierPart :: + // UnicodeIDContinue + // `$` + // `_` + // `\` RegExpUnicodeEscapeSequence[+U] + // + // + pp$1.regexp_eatRegExpIdentifierPart = function(state) { + var start = state.pos; + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); + + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { + ch = state.lastIntValue; + } + if (isRegExpIdentifierPart(ch)) { + state.lastIntValue = ch; + return true + } + + state.pos = start; + return false + }; + function isRegExpIdentifierPart(ch) { + return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* */ || ch === 0x200D /* */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape + pp$1.regexp_eatAtomEscape = function(state) { + if ( + this.regexp_eatBackReference(state) || + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) || + (state.switchN && this.regexp_eatKGroupName(state)) + ) { + return true + } + if (state.switchU) { + // Make the same message as V8. + if (state.current() === 0x63 /* c */) { + state.raise("Invalid unicode escape"); + } + state.raise("Invalid escape"); + } + return false + }; + pp$1.regexp_eatBackReference = function(state) { + var start = state.pos; + if (this.regexp_eatDecimalEscape(state)) { + var n = state.lastIntValue; + if (state.switchU) { + // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape + if (n > state.maxBackReference) { + state.maxBackReference = n; + } + return true + } + if (n <= state.numCapturingParens) { + return true + } + state.pos = start; + } + return false + }; + pp$1.regexp_eatKGroupName = function(state) { + if (state.eat(0x6B /* k */)) { + if (this.regexp_eatGroupName(state)) { + state.backReferenceNames.push(state.lastStringValue); + return true + } + state.raise("Invalid named reference"); + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape + pp$1.regexp_eatCharacterEscape = function(state) { + return ( + this.regexp_eatControlEscape(state) || + this.regexp_eatCControlLetter(state) || + this.regexp_eatZero(state) || + this.regexp_eatHexEscapeSequence(state) || + this.regexp_eatRegExpUnicodeEscapeSequence(state, false) || + (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) || + this.regexp_eatIdentityEscape(state) + ) + }; + pp$1.regexp_eatCControlLetter = function(state) { + var start = state.pos; + if (state.eat(0x63 /* c */)) { + if (this.regexp_eatControlLetter(state)) { + return true + } + state.pos = start; + } + return false + }; + pp$1.regexp_eatZero = function(state) { + if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) { + state.lastIntValue = 0; + state.advance(); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape + pp$1.regexp_eatControlEscape = function(state) { + var ch = state.current(); + if (ch === 0x74 /* t */) { + state.lastIntValue = 0x09; /* \t */ + state.advance(); + return true + } + if (ch === 0x6E /* n */) { + state.lastIntValue = 0x0A; /* \n */ + state.advance(); + return true + } + if (ch === 0x76 /* v */) { + state.lastIntValue = 0x0B; /* \v */ + state.advance(); + return true + } + if (ch === 0x66 /* f */) { + state.lastIntValue = 0x0C; /* \f */ + state.advance(); + return true + } + if (ch === 0x72 /* r */) { + state.lastIntValue = 0x0D; /* \r */ + state.advance(); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter + pp$1.regexp_eatControlLetter = function(state) { + var ch = state.current(); + if (isControlLetter(ch)) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false + }; + function isControlLetter(ch) { + return ( + (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) || + (ch >= 0x61 /* a */ && ch <= 0x7A /* z */) + ) + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence + pp$1.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) { + if ( forceU === void 0 ) forceU = false; + + var start = state.pos; + var switchU = forceU || state.switchU; + + if (state.eat(0x75 /* u */)) { + if (this.regexp_eatFixedHexDigits(state, 4)) { + var lead = state.lastIntValue; + if (switchU && lead >= 0xD800 && lead <= 0xDBFF) { + var leadSurrogateEnd = state.pos; + if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) { + var trail = state.lastIntValue; + if (trail >= 0xDC00 && trail <= 0xDFFF) { + state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000; + return true + } + } + state.pos = leadSurrogateEnd; + state.lastIntValue = lead; + } + return true + } + if ( + switchU && + state.eat(0x7B /* { */) && + this.regexp_eatHexDigits(state) && + state.eat(0x7D /* } */) && + isValidUnicode(state.lastIntValue) + ) { + return true + } + if (switchU) { + state.raise("Invalid unicode escape"); + } + state.pos = start; + } + + return false + }; + function isValidUnicode(ch) { + return ch >= 0 && ch <= 0x10FFFF + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape + pp$1.regexp_eatIdentityEscape = function(state) { + if (state.switchU) { + if (this.regexp_eatSyntaxCharacter(state)) { + return true + } + if (state.eat(0x2F /* / */)) { + state.lastIntValue = 0x2F; /* / */ + return true + } + return false + } + + var ch = state.current(); + if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) { + state.lastIntValue = ch; + state.advance(); + return true + } + + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape + pp$1.regexp_eatDecimalEscape = function(state) { + state.lastIntValue = 0; + var ch = state.current(); + if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) { + do { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); + state.advance(); + } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) + return true + } + return false + }; + + // Return values used by character set parsing methods, needed to + // forbid negation of sets that can match strings. + var CharSetNone = 0; // Nothing parsed + var CharSetOk = 1; // Construct parsed, cannot contain strings + var CharSetString = 2; // Construct parsed, can contain strings + + // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape + pp$1.regexp_eatCharacterClassEscape = function(state) { + var ch = state.current(); + + if (isCharacterClassEscape(ch)) { + state.lastIntValue = -1; + state.advance(); + return CharSetOk + } + + var negate = false; + if ( + state.switchU && + this.options.ecmaVersion >= 9 && + ((negate = ch === 0x50 /* P */) || ch === 0x70 /* p */) + ) { + state.lastIntValue = -1; + state.advance(); + var result; + if ( + state.eat(0x7B /* { */) && + (result = this.regexp_eatUnicodePropertyValueExpression(state)) && + state.eat(0x7D /* } */) + ) { + if (negate && result === CharSetString) { state.raise("Invalid property name"); } + return result + } + state.raise("Invalid property name"); + } + + return CharSetNone + }; + + function isCharacterClassEscape(ch) { + return ( + ch === 0x64 /* d */ || + ch === 0x44 /* D */ || + ch === 0x73 /* s */ || + ch === 0x53 /* S */ || + ch === 0x77 /* w */ || + ch === 0x57 /* W */ + ) + } + + // UnicodePropertyValueExpression :: + // UnicodePropertyName `=` UnicodePropertyValue + // LoneUnicodePropertyNameOrValue + pp$1.regexp_eatUnicodePropertyValueExpression = function(state) { + var start = state.pos; + + // UnicodePropertyName `=` UnicodePropertyValue + if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) { + var name = state.lastStringValue; + if (this.regexp_eatUnicodePropertyValue(state)) { + var value = state.lastStringValue; + this.regexp_validateUnicodePropertyNameAndValue(state, name, value); + return CharSetOk + } + } + state.pos = start; + + // LoneUnicodePropertyNameOrValue + if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) { + var nameOrValue = state.lastStringValue; + return this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue) + } + return CharSetNone + }; + + pp$1.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) { + if (!hasOwn(state.unicodeProperties.nonBinary, name)) + { state.raise("Invalid property name"); } + if (!state.unicodeProperties.nonBinary[name].test(value)) + { state.raise("Invalid property value"); } + }; + + pp$1.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) { + if (state.unicodeProperties.binary.test(nameOrValue)) { return CharSetOk } + if (state.switchV && state.unicodeProperties.binaryOfStrings.test(nameOrValue)) { return CharSetString } + state.raise("Invalid property name"); + }; + + // UnicodePropertyName :: + // UnicodePropertyNameCharacters + pp$1.regexp_eatUnicodePropertyName = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyNameCharacter(ch = state.current())) { + state.lastStringValue += codePointToString(ch); + state.advance(); + } + return state.lastStringValue !== "" + }; + + function isUnicodePropertyNameCharacter(ch) { + return isControlLetter(ch) || ch === 0x5F /* _ */ + } + + // UnicodePropertyValue :: + // UnicodePropertyValueCharacters + pp$1.regexp_eatUnicodePropertyValue = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyValueCharacter(ch = state.current())) { + state.lastStringValue += codePointToString(ch); + state.advance(); + } + return state.lastStringValue !== "" + }; + function isUnicodePropertyValueCharacter(ch) { + return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch) + } + + // LoneUnicodePropertyNameOrValue :: + // UnicodePropertyValueCharacters + pp$1.regexp_eatLoneUnicodePropertyNameOrValue = function(state) { + return this.regexp_eatUnicodePropertyValue(state) + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass + pp$1.regexp_eatCharacterClass = function(state) { + if (state.eat(0x5B /* [ */)) { + var negate = state.eat(0x5E /* ^ */); + var result = this.regexp_classContents(state); + if (!state.eat(0x5D /* ] */)) + { state.raise("Unterminated character class"); } + if (negate && result === CharSetString) + { state.raise("Negated character class may contain strings"); } + return true + } + return false + }; + + // https://tc39.es/ecma262/#prod-ClassContents + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges + pp$1.regexp_classContents = function(state) { + if (state.current() === 0x5D /* ] */) { return CharSetOk } + if (state.switchV) { return this.regexp_classSetExpression(state) } + this.regexp_nonEmptyClassRanges(state); + return CharSetOk + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges + // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash + pp$1.regexp_nonEmptyClassRanges = function(state) { + while (this.regexp_eatClassAtom(state)) { + var left = state.lastIntValue; + if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) { + var right = state.lastIntValue; + if (state.switchU && (left === -1 || right === -1)) { + state.raise("Invalid character class"); + } + if (left !== -1 && right !== -1 && left > right) { + state.raise("Range out of order in character class"); + } + } + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash + pp$1.regexp_eatClassAtom = function(state) { + var start = state.pos; + + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatClassEscape(state)) { + return true + } + if (state.switchU) { + // Make the same message as V8. + var ch$1 = state.current(); + if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) { + state.raise("Invalid class escape"); + } + state.raise("Invalid escape"); + } + state.pos = start; + } + + var ch = state.current(); + if (ch !== 0x5D /* ] */) { + state.lastIntValue = ch; + state.advance(); + return true + } + + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape + pp$1.regexp_eatClassEscape = function(state) { + var start = state.pos; + + if (state.eat(0x62 /* b */)) { + state.lastIntValue = 0x08; /* */ + return true + } + + if (state.switchU && state.eat(0x2D /* - */)) { + state.lastIntValue = 0x2D; /* - */ + return true + } + + if (!state.switchU && state.eat(0x63 /* c */)) { + if (this.regexp_eatClassControlLetter(state)) { + return true + } + state.pos = start; + } + + return ( + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) + ) + }; + + // https://tc39.es/ecma262/#prod-ClassSetExpression + // https://tc39.es/ecma262/#prod-ClassUnion + // https://tc39.es/ecma262/#prod-ClassIntersection + // https://tc39.es/ecma262/#prod-ClassSubtraction + pp$1.regexp_classSetExpression = function(state) { + var result = CharSetOk, subResult; + if (this.regexp_eatClassSetRange(state)) ; else if (subResult = this.regexp_eatClassSetOperand(state)) { + if (subResult === CharSetString) { result = CharSetString; } + // https://tc39.es/ecma262/#prod-ClassIntersection + var start = state.pos; + while (state.eatChars([0x26, 0x26] /* && */)) { + if ( + state.current() !== 0x26 /* & */ && + (subResult = this.regexp_eatClassSetOperand(state)) + ) { + if (subResult !== CharSetString) { result = CharSetOk; } + continue + } + state.raise("Invalid character in character class"); + } + if (start !== state.pos) { return result } + // https://tc39.es/ecma262/#prod-ClassSubtraction + while (state.eatChars([0x2D, 0x2D] /* -- */)) { + if (this.regexp_eatClassSetOperand(state)) { continue } + state.raise("Invalid character in character class"); + } + if (start !== state.pos) { return result } + } else { + state.raise("Invalid character in character class"); + } + // https://tc39.es/ecma262/#prod-ClassUnion + for (;;) { + if (this.regexp_eatClassSetRange(state)) { continue } + subResult = this.regexp_eatClassSetOperand(state); + if (!subResult) { return result } + if (subResult === CharSetString) { result = CharSetString; } + } + }; + + // https://tc39.es/ecma262/#prod-ClassSetRange + pp$1.regexp_eatClassSetRange = function(state) { + var start = state.pos; + if (this.regexp_eatClassSetCharacter(state)) { + var left = state.lastIntValue; + if (state.eat(0x2D /* - */) && this.regexp_eatClassSetCharacter(state)) { + var right = state.lastIntValue; + if (left !== -1 && right !== -1 && left > right) { + state.raise("Range out of order in character class"); + } + return true + } + state.pos = start; + } + return false + }; + + // https://tc39.es/ecma262/#prod-ClassSetOperand + pp$1.regexp_eatClassSetOperand = function(state) { + if (this.regexp_eatClassSetCharacter(state)) { return CharSetOk } + return this.regexp_eatClassStringDisjunction(state) || this.regexp_eatNestedClass(state) + }; + + // https://tc39.es/ecma262/#prod-NestedClass + pp$1.regexp_eatNestedClass = function(state) { + var start = state.pos; + if (state.eat(0x5B /* [ */)) { + var negate = state.eat(0x5E /* ^ */); + var result = this.regexp_classContents(state); + if (state.eat(0x5D /* ] */)) { + if (negate && result === CharSetString) { + state.raise("Negated character class may contain strings"); + } + return result + } + state.pos = start; + } + if (state.eat(0x5C /* \ */)) { + var result$1 = this.regexp_eatCharacterClassEscape(state); + if (result$1) { + return result$1 + } + state.pos = start; + } + return null + }; + + // https://tc39.es/ecma262/#prod-ClassStringDisjunction + pp$1.regexp_eatClassStringDisjunction = function(state) { + var start = state.pos; + if (state.eatChars([0x5C, 0x71] /* \q */)) { + if (state.eat(0x7B /* { */)) { + var result = this.regexp_classStringDisjunctionContents(state); + if (state.eat(0x7D /* } */)) { + return result + } + } else { + // Make the same message as V8. + state.raise("Invalid escape"); + } + state.pos = start; + } + return null + }; + + // https://tc39.es/ecma262/#prod-ClassStringDisjunctionContents + pp$1.regexp_classStringDisjunctionContents = function(state) { + var result = this.regexp_classString(state); + while (state.eat(0x7C /* | */)) { + if (this.regexp_classString(state) === CharSetString) { result = CharSetString; } + } + return result + }; + + // https://tc39.es/ecma262/#prod-ClassString + // https://tc39.es/ecma262/#prod-NonEmptyClassString + pp$1.regexp_classString = function(state) { + var count = 0; + while (this.regexp_eatClassSetCharacter(state)) { count++; } + return count === 1 ? CharSetOk : CharSetString + }; + + // https://tc39.es/ecma262/#prod-ClassSetCharacter + pp$1.regexp_eatClassSetCharacter = function(state) { + var start = state.pos; + if (state.eat(0x5C /* \ */)) { + if ( + this.regexp_eatCharacterEscape(state) || + this.regexp_eatClassSetReservedPunctuator(state) + ) { + return true + } + if (state.eat(0x62 /* b */)) { + state.lastIntValue = 0x08; /* */ + return true + } + state.pos = start; + return false + } + var ch = state.current(); + if (ch < 0 || ch === state.lookahead() && isClassSetReservedDoublePunctuatorCharacter(ch)) { return false } + if (isClassSetSyntaxCharacter(ch)) { return false } + state.advance(); + state.lastIntValue = ch; + return true + }; + + // https://tc39.es/ecma262/#prod-ClassSetReservedDoublePunctuator + function isClassSetReservedDoublePunctuatorCharacter(ch) { + return ( + ch === 0x21 /* ! */ || + ch >= 0x23 /* # */ && ch <= 0x26 /* & */ || + ch >= 0x2A /* * */ && ch <= 0x2C /* , */ || + ch === 0x2E /* . */ || + ch >= 0x3A /* : */ && ch <= 0x40 /* @ */ || + ch === 0x5E /* ^ */ || + ch === 0x60 /* ` */ || + ch === 0x7E /* ~ */ + ) + } + + // https://tc39.es/ecma262/#prod-ClassSetSyntaxCharacter + function isClassSetSyntaxCharacter(ch) { + return ( + ch === 0x28 /* ( */ || + ch === 0x29 /* ) */ || + ch === 0x2D /* - */ || + ch === 0x2F /* / */ || + ch >= 0x5B /* [ */ && ch <= 0x5D /* ] */ || + ch >= 0x7B /* { */ && ch <= 0x7D /* } */ + ) + } + + // https://tc39.es/ecma262/#prod-ClassSetReservedPunctuator + pp$1.regexp_eatClassSetReservedPunctuator = function(state) { + var ch = state.current(); + if (isClassSetReservedPunctuator(ch)) { + state.lastIntValue = ch; + state.advance(); + return true + } + return false + }; + + // https://tc39.es/ecma262/#prod-ClassSetReservedPunctuator + function isClassSetReservedPunctuator(ch) { + return ( + ch === 0x21 /* ! */ || + ch === 0x23 /* # */ || + ch === 0x25 /* % */ || + ch === 0x26 /* & */ || + ch === 0x2C /* , */ || + ch === 0x2D /* - */ || + ch >= 0x3A /* : */ && ch <= 0x3E /* > */ || + ch === 0x40 /* @ */ || + ch === 0x60 /* ` */ || + ch === 0x7E /* ~ */ + ) + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter + pp$1.regexp_eatClassControlLetter = function(state) { + var ch = state.current(); + if (isDecimalDigit(ch) || ch === 0x5F /* _ */) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence + pp$1.regexp_eatHexEscapeSequence = function(state) { + var start = state.pos; + if (state.eat(0x78 /* x */)) { + if (this.regexp_eatFixedHexDigits(state, 2)) { + return true + } + if (state.switchU) { + state.raise("Invalid escape"); + } + state.pos = start; + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits + pp$1.regexp_eatDecimalDigits = function(state) { + var start = state.pos; + var ch = 0; + state.lastIntValue = 0; + while (isDecimalDigit(ch = state.current())) { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); + state.advance(); + } + return state.pos !== start + }; + function isDecimalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits + pp$1.regexp_eatHexDigits = function(state) { + var start = state.pos; + var ch = 0; + state.lastIntValue = 0; + while (isHexDigit(ch = state.current())) { + state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); + state.advance(); + } + return state.pos !== start + }; + function isHexDigit(ch) { + return ( + (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) || + (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) || + (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) + ) + } + function hexToInt(ch) { + if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) { + return 10 + (ch - 0x41 /* A */) + } + if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) { + return 10 + (ch - 0x61 /* a */) + } + return ch - 0x30 /* 0 */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence + // Allows only 0-377(octal) i.e. 0-255(decimal). + pp$1.regexp_eatLegacyOctalEscapeSequence = function(state) { + if (this.regexp_eatOctalDigit(state)) { + var n1 = state.lastIntValue; + if (this.regexp_eatOctalDigit(state)) { + var n2 = state.lastIntValue; + if (n1 <= 3 && this.regexp_eatOctalDigit(state)) { + state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue; + } else { + state.lastIntValue = n1 * 8 + n2; + } + } else { + state.lastIntValue = n1; + } + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit + pp$1.regexp_eatOctalDigit = function(state) { + var ch = state.current(); + if (isOctalDigit(ch)) { + state.lastIntValue = ch - 0x30; /* 0 */ + state.advance(); + return true + } + state.lastIntValue = 0; + return false + }; + function isOctalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit + // And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence + pp$1.regexp_eatFixedHexDigits = function(state, length) { + var start = state.pos; + state.lastIntValue = 0; + for (var i = 0; i < length; ++i) { + var ch = state.current(); + if (!isHexDigit(ch)) { + state.pos = start; + return false + } + state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); + state.advance(); + } + return true + }; + + // Object type used to represent tokens. Note that normally, tokens + // simply exist as properties on the parser object. This is only + // used for the onToken callback and the external tokenizer. + + var Token = function Token(p) { + this.type = p.type; + this.value = p.value; + this.start = p.start; + this.end = p.end; + if (p.options.locations) + { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); } + if (p.options.ranges) + { this.range = [p.start, p.end]; } + }; + + // ## Tokenizer + + var pp = Parser.prototype; + + // Move to the next token + + pp.next = function(ignoreEscapeSequenceInKeyword) { + if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc) + { this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword); } + if (this.options.onToken) + { this.options.onToken(new Token(this)); } + + this.lastTokEnd = this.end; + this.lastTokStart = this.start; + this.lastTokEndLoc = this.endLoc; + this.lastTokStartLoc = this.startLoc; + this.nextToken(); + }; + + pp.getToken = function() { + this.next(); + return new Token(this) + }; + + // If we're in an ES6 environment, make parsers iterable + if (typeof Symbol !== "undefined") + { pp[Symbol.iterator] = function() { + var this$1$1 = this; + + return { + next: function () { + var token = this$1$1.getToken(); + return { + done: token.type === types$1.eof, + value: token + } + } + } + }; } + + // Toggle strict mode. Re-reads the next number or string to please + // pedantic tests (`"use strict"; 010;` should fail). + + // Read a single token, updating the parser object's token-related + // properties. + + pp.nextToken = function() { + var curContext = this.curContext(); + if (!curContext || !curContext.preserveSpace) { this.skipSpace(); } + + this.start = this.pos; + if (this.options.locations) { this.startLoc = this.curPosition(); } + if (this.pos >= this.input.length) { return this.finishToken(types$1.eof) } + + if (curContext.override) { return curContext.override(this) } + else { this.readToken(this.fullCharCodeAtPos()); } + }; + + pp.readToken = function(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) + { return this.readWord() } + + return this.getTokenFromCode(code) + }; + + pp.fullCharCodeAt = function(pos) { + var code = this.input.charCodeAt(pos); + if (code <= 0xd7ff || code >= 0xdc00) { return code } + var next = this.input.charCodeAt(pos + 1); + return next <= 0xdbff || next >= 0xe000 ? code : (code << 10) + next - 0x35fdc00 + }; + + pp.fullCharCodeAtPos = function() { + return this.fullCharCodeAt(this.pos) + }; + + pp.skipBlockComment = function() { + var startLoc = this.options.onComment && this.curPosition(); + var start = this.pos, end = this.input.indexOf("*/", this.pos += 2); + if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); } + this.pos = end + 2; + if (this.options.locations) { + for (var nextBreak = (void 0), pos = start; (nextBreak = nextLineBreak(this.input, pos, this.pos)) > -1;) { + ++this.curLine; + pos = this.lineStart = nextBreak; + } + } + if (this.options.onComment) + { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, + startLoc, this.curPosition()); } + }; + + pp.skipLineComment = function(startSkip) { + var start = this.pos; + var startLoc = this.options.onComment && this.curPosition(); + var ch = this.input.charCodeAt(this.pos += startSkip); + while (this.pos < this.input.length && !isNewLine(ch)) { + ch = this.input.charCodeAt(++this.pos); + } + if (this.options.onComment) + { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()); } + }; + + // Called at the start of the parse and after every token. Skips + // whitespace and comments, and. + + pp.skipSpace = function() { + loop: while (this.pos < this.input.length) { + var ch = this.input.charCodeAt(this.pos); + switch (ch) { + case 32: case 160: // ' ' + ++this.pos; + break + case 13: + if (this.input.charCodeAt(this.pos + 1) === 10) { + ++this.pos; + } + case 10: case 8232: case 8233: + ++this.pos; + if (this.options.locations) { + ++this.curLine; + this.lineStart = this.pos; + } + break + case 47: // '/' + switch (this.input.charCodeAt(this.pos + 1)) { + case 42: // '*' + this.skipBlockComment(); + break + case 47: + this.skipLineComment(2); + break + default: + break loop + } + break + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this.pos; + } else { + break loop + } + } + } + }; + + // Called at the end of every token. Sets `end`, `val`, and + // maintains `context` and `exprAllowed`, and skips the space after + // the token, so that the next one's `start` will point at the + // right position. + + pp.finishToken = function(type, val) { + this.end = this.pos; + if (this.options.locations) { this.endLoc = this.curPosition(); } + var prevType = this.type; + this.type = type; + this.value = val; + + this.updateContext(prevType); + }; + + // ### Token reading + + // This is the function that is called to fetch the next token. It + // is somewhat obscure, because it works in character codes rather + // than characters, and because operator parsing has been inlined + // into it. + // + // All in the name of speed. + // + pp.readToken_dot = function() { + var next = this.input.charCodeAt(this.pos + 1); + if (next >= 48 && next <= 57) { return this.readNumber(true) } + var next2 = this.input.charCodeAt(this.pos + 2); + if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' + this.pos += 3; + return this.finishToken(types$1.ellipsis) + } else { + ++this.pos; + return this.finishToken(types$1.dot) + } + }; + + pp.readToken_slash = function() { // '/' + var next = this.input.charCodeAt(this.pos + 1); + if (this.exprAllowed) { ++this.pos; return this.readRegexp() } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.slash, 1) + }; + + pp.readToken_mult_modulo_exp = function(code) { // '%*' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + var tokentype = code === 42 ? types$1.star : types$1.modulo; + + // exponentiation operator ** and **= + if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) { + ++size; + tokentype = types$1.starstar; + next = this.input.charCodeAt(this.pos + 2); + } + + if (next === 61) { return this.finishOp(types$1.assign, size + 1) } + return this.finishOp(tokentype, size) + }; + + pp.readToken_pipe_amp = function(code) { // '|&' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { + if (this.options.ecmaVersion >= 12) { + var next2 = this.input.charCodeAt(this.pos + 2); + if (next2 === 61) { return this.finishOp(types$1.assign, 3) } + } + return this.finishOp(code === 124 ? types$1.logicalOR : types$1.logicalAND, 2) + } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(code === 124 ? types$1.bitwiseOR : types$1.bitwiseAND, 1) + }; + + pp.readToken_caret = function() { // '^' + var next = this.input.charCodeAt(this.pos + 1); + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.bitwiseXOR, 1) + }; + + pp.readToken_plus_min = function(code) { // '+-' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { + if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 && + (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) { + // A `-->` line comment + this.skipLineComment(3); + this.skipSpace(); + return this.nextToken() + } + return this.finishOp(types$1.incDec, 2) + } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.plusMin, 1) + }; + + pp.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; + if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) } + return this.finishOp(types$1.bitShift, size) + } + if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && + this.input.charCodeAt(this.pos + 3) === 45) { + // `` line comment + this.skipLineComment(3); + this.skipSpace(); + return this.nextToken() + } + return this.finishOp(types$1.incDec, 2) + } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.plusMin, 1) +}; + +pp.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; + if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) } + return this.finishOp(types$1.bitShift, size) + } + if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && + this.input.charCodeAt(this.pos + 3) === 45) { + // `)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/node_modules/istanbul-reports/lib/html/index.js b/node_modules/istanbul-reports/lib/html/index.js new file mode 100644 index 0000000..2d7f7be --- /dev/null +++ b/node_modules/istanbul-reports/lib/html/index.js @@ -0,0 +1,421 @@ +'use strict'; +/* + Copyright 2012-2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +const fs = require('fs'); +const path = require('path'); +const html = require('html-escaper'); +const { ReportBase } = require('istanbul-lib-report'); +const annotator = require('./annotator'); + +function htmlHead(details) { + return ` + + Code coverage report for ${html.escape(details.entity)} + + + + + + + + `; +} + +function headerTemplate(details) { + function metricsTemplate({ pct, covered, total }, kind) { + return ` +
+ ${pct}% + ${kind} + ${covered}/${total} +
+ `; + } + + function skipTemplate(metrics) { + const statements = metrics.statements.skipped; + const branches = metrics.branches.skipped; + const functions = metrics.functions.skipped; + + const countLabel = (c, label, plural) => + c === 0 ? [] : `${c} ${label}${c === 1 ? '' : plural}`; + const skips = [].concat( + countLabel(statements, 'statement', 's'), + countLabel(functions, 'function', 's'), + countLabel(branches, 'branch', 'es') + ); + + if (skips.length === 0) { + return ''; + } + + return ` +
+ ${skips.join(', ')} + Ignored      +
+ `; + } + + return ` + + +${htmlHead(details)} + +
+
+

${details.pathHtml}

+
+ ${metricsTemplate(details.metrics.statements, 'Statements')} + ${metricsTemplate(details.metrics.branches, 'Branches')} + ${metricsTemplate(details.metrics.functions, 'Functions')} + ${metricsTemplate(details.metrics.lines, 'Lines')} + ${skipTemplate(details.metrics)} +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+ `; +} + +function footerTemplate(details) { + return ` +
+
+ + + + + + + + `; +} + +function detailTemplate(data) { + const lineNumbers = new Array(data.maxLines).fill().map((_, i) => i + 1); + const lineLink = num => + `${num}`; + const lineCount = line => + `${line.hits}`; + + /* This is rendered in a `
`, need control of all whitespace. */
+    return [
+        '',
+        `${lineNumbers
+            .map(lineLink)
+            .join('\n')}`,
+        `${data.lineCoverage
+            .map(lineCount)
+            .join('\n')}`,
+        `
${data.annotatedCode.join(
+            '\n'
+        )}
`, + '' + ].join(''); +} +const summaryTableHeader = [ + '
', + '', + '', + '', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + '', + '', + '' +].join('\n'); + +function summaryLineTemplate(details) { + const { reportClasses, metrics, file, output } = details; + const percentGraph = pct => { + if (!isFinite(pct)) { + return ''; + } + + const cls = ['cover-fill']; + if (pct === 100) { + cls.push('cover-full'); + } + + pct = Math.floor(pct); + return [ + `
`, + `
` + ].join(''); + }; + const summaryType = (type, showGraph = false) => { + const info = metrics[type]; + const reportClass = reportClasses[type]; + const result = [ + ``, + `` + ]; + if (showGraph) { + result.unshift( + `` + ); + } + + return result; + }; + + return [] + .concat( + '', + ``, + summaryType('statements', true), + summaryType('branches'), + summaryType('functions'), + summaryType('lines'), + '\n' + ) + .join('\n\t'); +} + +const summaryTableFooter = ['', '
FileStatementsBranchesFunctionsLines
${info.pct}%${info.covered}/${info.total}`, + `
${percentGraph(info.pct)}
`, + `
${html.escape(file)}
', '
'].join('\n'); +const emptyClasses = { + statements: 'empty', + lines: 'empty', + functions: 'empty', + branches: 'empty' +}; + +const standardLinkMapper = { + getPath(node) { + if (typeof node === 'string') { + return node; + } + let filePath = node.getQualifiedName(); + if (node.isSummary()) { + if (filePath !== '') { + filePath += '/index.html'; + } else { + filePath = 'index.html'; + } + } else { + filePath += '.html'; + } + return filePath; + }, + + relativePath(source, target) { + const targetPath = this.getPath(target); + const sourcePath = path.dirname(this.getPath(source)); + return path.posix.relative(sourcePath, targetPath); + }, + + assetPath(node, name) { + return this.relativePath(this.getPath(node), name); + } +}; + +function fixPct(metrics) { + Object.keys(emptyClasses).forEach(key => { + metrics[key].pct = 0; + }); + return metrics; +} + +class HtmlReport extends ReportBase { + constructor(opts) { + super(); + + this.verbose = opts.verbose; + this.linkMapper = opts.linkMapper || standardLinkMapper; + this.subdir = opts.subdir || ''; + this.date = new Date().toISOString(); + this.skipEmpty = opts.skipEmpty; + } + + getBreadcrumbHtml(node) { + let parent = node.getParent(); + const nodePath = []; + + while (parent) { + nodePath.push(parent); + parent = parent.getParent(); + } + + const linkPath = nodePath.map(ancestor => { + const target = this.linkMapper.relativePath(node, ancestor); + const name = ancestor.getRelativeName() || 'All files'; + return '' + name + ''; + }); + + linkPath.reverse(); + return linkPath.length > 0 + ? linkPath.join(' / ') + ' ' + node.getRelativeName() + : 'All files'; + } + + fillTemplate(node, templateData, context) { + const linkMapper = this.linkMapper; + const summary = node.getCoverageSummary(); + templateData.entity = node.getQualifiedName() || 'All files'; + templateData.metrics = summary; + templateData.reportClass = context.classForPercent( + 'statements', + summary.statements.pct + ); + templateData.pathHtml = this.getBreadcrumbHtml(node); + templateData.base = { + css: linkMapper.assetPath(node, 'base.css') + }; + templateData.sorter = { + js: linkMapper.assetPath(node, 'sorter.js'), + image: linkMapper.assetPath(node, 'sort-arrow-sprite.png') + }; + templateData.blockNavigation = { + js: linkMapper.assetPath(node, 'block-navigation.js') + }; + templateData.prettify = { + js: linkMapper.assetPath(node, 'prettify.js'), + css: linkMapper.assetPath(node, 'prettify.css') + }; + templateData.favicon = linkMapper.assetPath(node, 'favicon.png'); + } + + getTemplateData() { + return { datetime: this.date }; + } + + getWriter(context) { + if (!this.subdir) { + return context.writer; + } + return context.writer.writerForDir(this.subdir); + } + + onStart(root, context) { + const assetHeaders = { + '.js': '/* eslint-disable */\n' + }; + + ['.', 'vendor'].forEach(subdir => { + const writer = this.getWriter(context); + const srcDir = path.resolve(__dirname, 'assets', subdir); + fs.readdirSync(srcDir).forEach(f => { + const resolvedSource = path.resolve(srcDir, f); + const resolvedDestination = '.'; + const stat = fs.statSync(resolvedSource); + let dest; + + if (stat.isFile()) { + dest = resolvedDestination + '/' + f; + if (this.verbose) { + console.log('Write asset: ' + dest); + } + writer.copyFile( + resolvedSource, + dest, + assetHeaders[path.extname(f)] + ); + } + }); + }); + } + + onSummary(node, context) { + const linkMapper = this.linkMapper; + const templateData = this.getTemplateData(); + const children = node.getChildren(); + const skipEmpty = this.skipEmpty; + + this.fillTemplate(node, templateData, context); + const cw = this.getWriter(context).writeFile(linkMapper.getPath(node)); + cw.write(headerTemplate(templateData)); + cw.write(summaryTableHeader); + children.forEach(child => { + const metrics = child.getCoverageSummary(); + const isEmpty = metrics.isEmpty(); + if (skipEmpty && isEmpty) { + return; + } + const reportClasses = isEmpty + ? emptyClasses + : { + statements: context.classForPercent( + 'statements', + metrics.statements.pct + ), + lines: context.classForPercent( + 'lines', + metrics.lines.pct + ), + functions: context.classForPercent( + 'functions', + metrics.functions.pct + ), + branches: context.classForPercent( + 'branches', + metrics.branches.pct + ) + }; + const data = { + metrics: isEmpty ? fixPct(metrics) : metrics, + reportClasses, + file: child.getRelativeName(), + output: linkMapper.relativePath(node, child) + }; + cw.write(summaryLineTemplate(data) + '\n'); + }); + cw.write(summaryTableFooter); + cw.write(footerTemplate(templateData)); + cw.close(); + } + + onDetail(node, context) { + const linkMapper = this.linkMapper; + const templateData = this.getTemplateData(); + + this.fillTemplate(node, templateData, context); + const cw = this.getWriter(context).writeFile(linkMapper.getPath(node)); + cw.write(headerTemplate(templateData)); + cw.write('
\n');
+        cw.write(detailTemplate(annotator(node.getFileCoverage(), context)));
+        cw.write('
\n'); + cw.write(footerTemplate(templateData)); + cw.close(); + } +} + +module.exports = HtmlReport; diff --git a/node_modules/istanbul-reports/lib/html/insertion-text.js b/node_modules/istanbul-reports/lib/html/insertion-text.js new file mode 100644 index 0000000..6f80642 --- /dev/null +++ b/node_modules/istanbul-reports/lib/html/insertion-text.js @@ -0,0 +1,114 @@ +'use strict'; +/* + Copyright 2012-2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +function InsertionText(text, consumeBlanks) { + this.text = text; + this.origLength = text.length; + this.offsets = []; + this.consumeBlanks = consumeBlanks; + this.startPos = this.findFirstNonBlank(); + this.endPos = this.findLastNonBlank(); +} + +const WHITE_RE = /[ \f\n\r\t\v\u00A0\u2028\u2029]/; + +InsertionText.prototype = { + findFirstNonBlank() { + let pos = -1; + const text = this.text; + const len = text.length; + let i; + for (i = 0; i < len; i += 1) { + if (!text.charAt(i).match(WHITE_RE)) { + pos = i; + break; + } + } + return pos; + }, + findLastNonBlank() { + const text = this.text; + const len = text.length; + let pos = text.length + 1; + let i; + for (i = len - 1; i >= 0; i -= 1) { + if (!text.charAt(i).match(WHITE_RE)) { + pos = i; + break; + } + } + return pos; + }, + originalLength() { + return this.origLength; + }, + + insertAt(col, str, insertBefore, consumeBlanks) { + consumeBlanks = + typeof consumeBlanks === 'undefined' + ? this.consumeBlanks + : consumeBlanks; + col = col > this.originalLength() ? this.originalLength() : col; + col = col < 0 ? 0 : col; + + if (consumeBlanks) { + if (col <= this.startPos) { + col = 0; + } + if (col > this.endPos) { + col = this.origLength; + } + } + + const len = str.length; + const offset = this.findOffset(col, len, insertBefore); + const realPos = col + offset; + const text = this.text; + this.text = text.substring(0, realPos) + str + text.substring(realPos); + return this; + }, + + findOffset(pos, len, insertBefore) { + const offsets = this.offsets; + let offsetObj; + let cumulativeOffset = 0; + let i; + + for (i = 0; i < offsets.length; i += 1) { + offsetObj = offsets[i]; + if ( + offsetObj.pos < pos || + (offsetObj.pos === pos && !insertBefore) + ) { + cumulativeOffset += offsetObj.len; + } + if (offsetObj.pos >= pos) { + break; + } + } + if (offsetObj && offsetObj.pos === pos) { + offsetObj.len += len; + } else { + offsets.splice(i, 0, { pos, len }); + } + return cumulativeOffset; + }, + + wrap(startPos, startText, endPos, endText, consumeBlanks) { + this.insertAt(startPos, startText, true, consumeBlanks); + this.insertAt(endPos, endText, false, consumeBlanks); + return this; + }, + + wrapLine(startText, endText) { + this.wrap(0, startText, this.originalLength(), endText); + }, + + toString() { + return this.text; + } +}; + +module.exports = InsertionText; diff --git a/node_modules/istanbul-reports/lib/json-summary/index.js b/node_modules/istanbul-reports/lib/json-summary/index.js new file mode 100644 index 0000000..318a47f --- /dev/null +++ b/node_modules/istanbul-reports/lib/json-summary/index.js @@ -0,0 +1,56 @@ +/* + Copyright 2012-2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +'use strict'; +const { ReportBase } = require('istanbul-lib-report'); + +class JsonSummaryReport extends ReportBase { + constructor(opts) { + super(); + + this.file = opts.file || 'coverage-summary.json'; + this.contentWriter = null; + this.first = true; + } + + onStart(root, context) { + this.contentWriter = context.writer.writeFile(this.file); + this.contentWriter.write('{'); + } + + writeSummary(filePath, sc) { + const cw = this.contentWriter; + if (this.first) { + this.first = false; + } else { + cw.write(','); + } + cw.write(JSON.stringify(filePath)); + cw.write(': '); + cw.write(JSON.stringify(sc)); + cw.println(''); + } + + onSummary(node) { + if (!node.isRoot()) { + return; + } + this.writeSummary('total', node.getCoverageSummary()); + } + + onDetail(node) { + this.writeSummary( + node.getFileCoverage().path, + node.getCoverageSummary() + ); + } + + onEnd() { + const cw = this.contentWriter; + cw.println('}'); + cw.close(); + } +} + +module.exports = JsonSummaryReport; diff --git a/node_modules/istanbul-reports/lib/json/index.js b/node_modules/istanbul-reports/lib/json/index.js new file mode 100644 index 0000000..bcae6ae --- /dev/null +++ b/node_modules/istanbul-reports/lib/json/index.js @@ -0,0 +1,44 @@ +/* + Copyright 2012-2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +'use strict'; +const { ReportBase } = require('istanbul-lib-report'); + +class JsonReport extends ReportBase { + constructor(opts) { + super(); + + this.file = opts.file || 'coverage-final.json'; + this.first = true; + } + + onStart(root, context) { + this.contentWriter = context.writer.writeFile(this.file); + this.contentWriter.write('{'); + } + + onDetail(node) { + const fc = node.getFileCoverage(); + const key = fc.path; + const cw = this.contentWriter; + + if (this.first) { + this.first = false; + } else { + cw.write(','); + } + cw.write(JSON.stringify(key)); + cw.write(': '); + cw.write(JSON.stringify(fc)); + cw.println(''); + } + + onEnd() { + const cw = this.contentWriter; + cw.println('}'); + cw.close(); + } +} + +module.exports = JsonReport; diff --git a/node_modules/istanbul-reports/lib/lcov/index.js b/node_modules/istanbul-reports/lib/lcov/index.js new file mode 100644 index 0000000..383c202 --- /dev/null +++ b/node_modules/istanbul-reports/lib/lcov/index.js @@ -0,0 +1,33 @@ +'use strict'; +/* + Copyright 2012-2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +const { ReportBase } = require('istanbul-lib-report'); +const LcovOnlyReport = require('../lcovonly'); +const HtmlReport = require('../html'); + +class LcovReport extends ReportBase { + constructor(opts) { + super(); + this.lcov = new LcovOnlyReport({ file: 'lcov.info', ...opts }); + this.html = new HtmlReport({ subdir: 'lcov-report' }); + } +} + +['Start', 'End', 'Summary', 'SummaryEnd', 'Detail'].forEach(what => { + const meth = 'on' + what; + LcovReport.prototype[meth] = function(...args) { + const lcov = this.lcov; + const html = this.html; + + if (lcov[meth]) { + lcov[meth](...args); + } + if (html[meth]) { + html[meth](...args); + } + }; +}); + +module.exports = LcovReport; diff --git a/node_modules/istanbul-reports/lib/lcovonly/index.js b/node_modules/istanbul-reports/lib/lcovonly/index.js new file mode 100644 index 0000000..0720e46 --- /dev/null +++ b/node_modules/istanbul-reports/lib/lcovonly/index.js @@ -0,0 +1,77 @@ +/* + Copyright 2012-2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +'use strict'; +const { ReportBase } = require('istanbul-lib-report'); + +class LcovOnlyReport extends ReportBase { + constructor(opts) { + super(); + opts = opts || {}; + this.file = opts.file || 'lcov.info'; + this.projectRoot = opts.projectRoot || process.cwd(); + this.contentWriter = null; + } + + onStart(root, context) { + this.contentWriter = context.writer.writeFile(this.file); + } + + onDetail(node) { + const fc = node.getFileCoverage(); + const writer = this.contentWriter; + const functions = fc.f; + const functionMap = fc.fnMap; + const lines = fc.getLineCoverage(); + const branches = fc.b; + const branchMap = fc.branchMap; + const summary = node.getCoverageSummary(); + const path = require('path'); + + writer.println('TN:'); + const fileName = path.relative(this.projectRoot, fc.path); + writer.println('SF:' + fileName); + + Object.values(functionMap).forEach(meta => { + // Some versions of the instrumenter in the wild populate 'loc' + // but not 'decl': + const decl = meta.decl || meta.loc; + writer.println('FN:' + [decl.start.line, meta.name].join(',')); + }); + writer.println('FNF:' + summary.functions.total); + writer.println('FNH:' + summary.functions.covered); + + Object.entries(functionMap).forEach(([key, meta]) => { + const stats = functions[key]; + writer.println('FNDA:' + [stats, meta.name].join(',')); + }); + + Object.entries(lines).forEach(entry => { + writer.println('DA:' + entry.join(',')); + }); + writer.println('LF:' + summary.lines.total); + writer.println('LH:' + summary.lines.covered); + + Object.entries(branches).forEach(([key, branchArray]) => { + const meta = branchMap[key]; + if (meta) { + const { line } = meta.loc.start; + branchArray.forEach((b, i) => { + writer.println('BRDA:' + [line, key, i, b].join(',')); + }); + } else { + console.warn('Missing coverage entries in', fileName, key); + } + }); + writer.println('BRF:' + summary.branches.total); + writer.println('BRH:' + summary.branches.covered); + writer.println('end_of_record'); + } + + onEnd() { + this.contentWriter.close(); + } +} + +module.exports = LcovOnlyReport; diff --git a/node_modules/istanbul-reports/lib/none/index.js b/node_modules/istanbul-reports/lib/none/index.js new file mode 100644 index 0000000..81c1408 --- /dev/null +++ b/node_modules/istanbul-reports/lib/none/index.js @@ -0,0 +1,10 @@ +'use strict'; +/* + Copyright 2012-2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +const { ReportBase } = require('istanbul-lib-report'); + +class NoneReport extends ReportBase {} + +module.exports = NoneReport; diff --git a/node_modules/istanbul-reports/lib/teamcity/index.js b/node_modules/istanbul-reports/lib/teamcity/index.js new file mode 100644 index 0000000..2bca26a --- /dev/null +++ b/node_modules/istanbul-reports/lib/teamcity/index.js @@ -0,0 +1,67 @@ +/* + Copyright 2012-2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +'use strict'; +const { ReportBase } = require('istanbul-lib-report'); + +class TeamcityReport extends ReportBase { + constructor(opts) { + super(); + + opts = opts || {}; + this.file = opts.file || null; + this.blockName = opts.blockName || 'Code Coverage Summary'; + } + + onStart(node, context) { + const metrics = node.getCoverageSummary(); + const cw = context.writer.writeFile(this.file); + + cw.println(''); + cw.println("##teamcity[blockOpened name='" + this.blockName + "']"); + + //Statements Covered + cw.println( + lineForKey(metrics.statements.covered, 'CodeCoverageAbsBCovered') + ); + cw.println( + lineForKey(metrics.statements.total, 'CodeCoverageAbsBTotal') + ); + + //Branches Covered + cw.println( + lineForKey(metrics.branches.covered, 'CodeCoverageAbsRCovered') + ); + cw.println(lineForKey(metrics.branches.total, 'CodeCoverageAbsRTotal')); + + //Functions Covered + cw.println( + lineForKey(metrics.functions.covered, 'CodeCoverageAbsMCovered') + ); + cw.println( + lineForKey(metrics.functions.total, 'CodeCoverageAbsMTotal') + ); + + //Lines Covered + cw.println( + lineForKey(metrics.lines.covered, 'CodeCoverageAbsLCovered') + ); + cw.println(lineForKey(metrics.lines.total, 'CodeCoverageAbsLTotal')); + + cw.println("##teamcity[blockClosed name='" + this.blockName + "']"); + cw.close(); + } +} + +function lineForKey(value, teamcityVar) { + return ( + "##teamcity[buildStatisticValue key='" + + teamcityVar + + "' value='" + + value + + "']" + ); +} + +module.exports = TeamcityReport; diff --git a/node_modules/istanbul-reports/lib/text-lcov/index.js b/node_modules/istanbul-reports/lib/text-lcov/index.js new file mode 100644 index 0000000..847aedf --- /dev/null +++ b/node_modules/istanbul-reports/lib/text-lcov/index.js @@ -0,0 +1,17 @@ +'use strict'; +/* + Copyright 2012-2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +const LcovOnly = require('../lcovonly'); + +class TextLcov extends LcovOnly { + constructor(opts) { + super({ + ...opts, + file: '-' + }); + } +} + +module.exports = TextLcov; diff --git a/node_modules/istanbul-reports/lib/text-summary/index.js b/node_modules/istanbul-reports/lib/text-summary/index.js new file mode 100644 index 0000000..a9e6eab --- /dev/null +++ b/node_modules/istanbul-reports/lib/text-summary/index.js @@ -0,0 +1,62 @@ +/* + Copyright 2012-2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ +'use strict'; +const { ReportBase } = require('istanbul-lib-report'); + +class TextSummaryReport extends ReportBase { + constructor(opts) { + super(); + + opts = opts || {}; + this.file = opts.file || null; + } + + onStart(node, context) { + const summary = node.getCoverageSummary(); + const cw = context.writer.writeFile(this.file); + const printLine = function(key) { + const str = lineForKey(summary, key); + const clazz = context.classForPercent(key, summary[key].pct); + cw.println(cw.colorize(str, clazz)); + }; + + cw.println(''); + cw.println( + '=============================== Coverage summary ===============================' + ); + printLine('statements'); + printLine('branches'); + printLine('functions'); + printLine('lines'); + cw.println( + '================================================================================' + ); + cw.close(); + } +} + +function lineForKey(summary, key) { + const metrics = summary[key]; + + key = key.substring(0, 1).toUpperCase() + key.substring(1); + if (key.length < 12) { + key += ' '.substring(0, 12 - key.length); + } + const result = [ + key, + ':', + metrics.pct + '%', + '(', + metrics.covered + '/' + metrics.total, + ')' + ].join(' '); + const skipped = metrics.skipped; + if (skipped > 0) { + return result + ', ' + skipped + ' ignored'; + } + return result; +} + +module.exports = TextSummaryReport; diff --git a/node_modules/istanbul-reports/lib/text/index.js b/node_modules/istanbul-reports/lib/text/index.js new file mode 100644 index 0000000..c28cedb --- /dev/null +++ b/node_modules/istanbul-reports/lib/text/index.js @@ -0,0 +1,298 @@ +/* + Copyright 2012-2015, Yahoo Inc. + Copyrights licensed under the New BSD License. See the accompanying LICENSE + file for terms. + */ +'use strict'; +const { ReportBase } = require('istanbul-lib-report'); + +const NAME_COL = 4; +const PCT_COLS = 7; +const MISSING_COL = 17; +const TAB_SIZE = 1; +const DELIM = ' | '; + +function padding(num, ch) { + let str = ''; + let i; + ch = ch || ' '; + for (i = 0; i < num; i += 1) { + str += ch; + } + return str; +} + +function fill(str, width, right, tabs) { + tabs = tabs || 0; + str = String(str); + + const leadingSpaces = tabs * TAB_SIZE; + const remaining = width - leadingSpaces; + const leader = padding(leadingSpaces); + let fmtStr = ''; + + if (remaining > 0) { + const strlen = str.length; + let fillStr; + + if (remaining >= strlen) { + fillStr = padding(remaining - strlen); + } else { + fillStr = '...'; + const length = remaining - fillStr.length; + + str = str.substring(strlen - length); + right = true; + } + fmtStr = right ? fillStr + str : str + fillStr; + } + + return leader + fmtStr; +} + +function formatName(name, maxCols, level) { + return fill(name, maxCols, false, level); +} + +function formatPct(pct, width) { + return fill(pct, width || PCT_COLS, true, 0); +} + +function nodeMissing(node) { + if (node.isSummary()) { + return ''; + } + + const metrics = node.getCoverageSummary(); + const isEmpty = metrics.isEmpty(); + const lines = isEmpty ? 0 : metrics.lines.pct; + + let coveredLines; + + const fileCoverage = node.getFileCoverage(); + if (lines === 100) { + const branches = fileCoverage.getBranchCoverageByLine(); + coveredLines = Object.entries(branches).map(([key, { coverage }]) => [ + key, + coverage === 100 + ]); + } else { + coveredLines = Object.entries(fileCoverage.getLineCoverage()); + } + + let newRange = true; + const ranges = coveredLines + .reduce((acum, [line, hit]) => { + if (hit) newRange = true; + else { + line = parseInt(line); + if (newRange) { + acum.push([line]); + newRange = false; + } else acum[acum.length - 1][1] = line; + } + + return acum; + }, []) + .map(range => { + const { length } = range; + + if (length === 1) return range[0]; + + return `${range[0]}-${range[1]}`; + }); + + return [].concat(...ranges).join(','); +} + +function nodeName(node) { + return node.getRelativeName() || 'All files'; +} + +function depthFor(node) { + let ret = 0; + node = node.getParent(); + while (node) { + ret += 1; + node = node.getParent(); + } + return ret; +} + +function nullDepthFor() { + return 0; +} + +function findWidth(node, context, nodeExtractor, depthFor = nullDepthFor) { + let last = 0; + function compareWidth(node) { + last = Math.max( + last, + TAB_SIZE * depthFor(node) + nodeExtractor(node).length + ); + } + const visitor = { + onSummary: compareWidth, + onDetail: compareWidth + }; + node.visit(context.getVisitor(visitor)); + return last; +} + +function makeLine(nameWidth, missingWidth) { + const name = padding(nameWidth, '-'); + const pct = padding(PCT_COLS, '-'); + const elements = []; + + elements.push(name); + elements.push(pct); + elements.push(padding(PCT_COLS + 1, '-')); + elements.push(pct); + elements.push(pct); + elements.push(padding(missingWidth, '-')); + return elements.join(DELIM.replace(/ /g, '-')) + '-'; +} + +function tableHeader(maxNameCols, missingWidth) { + const elements = []; + elements.push(formatName('File', maxNameCols, 0)); + elements.push(formatPct('% Stmts')); + elements.push(formatPct('% Branch', PCT_COLS + 1)); + elements.push(formatPct('% Funcs')); + elements.push(formatPct('% Lines')); + elements.push(formatName('Uncovered Line #s', missingWidth)); + return elements.join(DELIM) + ' '; +} + +function isFull(metrics) { + return ( + metrics.statements.pct === 100 && + metrics.branches.pct === 100 && + metrics.functions.pct === 100 && + metrics.lines.pct === 100 + ); +} + +function tableRow( + node, + context, + colorizer, + maxNameCols, + level, + skipEmpty, + skipFull, + missingWidth +) { + const name = nodeName(node); + const metrics = node.getCoverageSummary(); + const isEmpty = metrics.isEmpty(); + if (skipEmpty && isEmpty) { + return ''; + } + if (skipFull && isFull(metrics)) { + return ''; + } + + const mm = { + statements: isEmpty ? 0 : metrics.statements.pct, + branches: isEmpty ? 0 : metrics.branches.pct, + functions: isEmpty ? 0 : metrics.functions.pct, + lines: isEmpty ? 0 : metrics.lines.pct + }; + const colorize = isEmpty + ? function(str) { + return str; + } + : function(str, key) { + return colorizer(str, context.classForPercent(key, mm[key])); + }; + const elements = []; + + elements.push(colorize(formatName(name, maxNameCols, level), 'statements')); + elements.push(colorize(formatPct(mm.statements), 'statements')); + elements.push(colorize(formatPct(mm.branches, PCT_COLS + 1), 'branches')); + elements.push(colorize(formatPct(mm.functions), 'functions')); + elements.push(colorize(formatPct(mm.lines), 'lines')); + elements.push( + colorizer( + formatName(nodeMissing(node), missingWidth), + mm.lines === 100 ? 'medium' : 'low' + ) + ); + + return elements.join(DELIM) + ' '; +} + +class TextReport extends ReportBase { + constructor(opts) { + super(opts); + + opts = opts || {}; + const { maxCols } = opts; + + this.file = opts.file || null; + this.maxCols = maxCols != null ? maxCols : process.stdout.columns || 80; + this.cw = null; + this.skipEmpty = opts.skipEmpty; + this.skipFull = opts.skipFull; + } + + onStart(root, context) { + this.cw = context.writer.writeFile(this.file); + this.nameWidth = Math.max( + NAME_COL, + findWidth(root, context, nodeName, depthFor) + ); + this.missingWidth = Math.max( + MISSING_COL, + findWidth(root, context, nodeMissing) + ); + + if (this.maxCols > 0) { + const pct_cols = DELIM.length + 4 * (PCT_COLS + DELIM.length) + 2; + + const maxRemaining = this.maxCols - (pct_cols + MISSING_COL); + if (this.nameWidth > maxRemaining) { + this.nameWidth = maxRemaining; + this.missingWidth = MISSING_COL; + } else if (this.nameWidth < maxRemaining) { + const maxRemaining = this.maxCols - (this.nameWidth + pct_cols); + if (this.missingWidth > maxRemaining) { + this.missingWidth = maxRemaining; + } + } + } + const line = makeLine(this.nameWidth, this.missingWidth); + this.cw.println(line); + this.cw.println(tableHeader(this.nameWidth, this.missingWidth)); + this.cw.println(line); + } + + onSummary(node, context) { + const nodeDepth = depthFor(node); + const row = tableRow( + node, + context, + this.cw.colorize.bind(this.cw), + this.nameWidth, + nodeDepth, + this.skipEmpty, + this.skipFull, + this.missingWidth + ); + if (row) { + this.cw.println(row); + } + } + + onDetail(node, context) { + return this.onSummary(node, context); + } + + onEnd() { + this.cw.println(makeLine(this.nameWidth, this.missingWidth)); + this.cw.close(); + } +} + +module.exports = TextReport; diff --git a/node_modules/istanbul-reports/package.json b/node_modules/istanbul-reports/package.json new file mode 100644 index 0000000..cc668dd --- /dev/null +++ b/node_modules/istanbul-reports/package.json @@ -0,0 +1,60 @@ +{ + "name": "istanbul-reports", + "version": "3.2.0", + "description": "istanbul reports", + "author": "Krishnan Anantheswaran ", + "main": "index.js", + "files": [ + "index.js", + "lib" + ], + "scripts": { + "test": "nyc mocha --recursive", + "prepare": "webpack --config lib/html-spa/webpack.config.js --mode production", + "prepare:watch": "webpack --config lib/html-spa/webpack.config.js --watch --mode development" + }, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "devDependencies": { + "@babel/core": "^7.7.5", + "@babel/preset-env": "^7.7.5", + "@babel/preset-react": "^7.7.4", + "babel-loader": "^8.0.6", + "chai": "^4.2.0", + "is-windows": "^1.0.2", + "istanbul-lib-coverage": "^3.0.0", + "mocha": "^6.2.2", + "nyc": "^15.0.0-beta.2", + "react": "^16.12.0", + "react-dom": "^16.12.0", + "webpack": "^4.41.2", + "webpack-cli": "^3.3.10" + }, + "license": "BSD-3-Clause", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/istanbuljs/istanbuljs.git", + "directory": "packages/istanbul-reports" + }, + "keywords": [ + "istanbul", + "reports" + ], + "bugs": { + "url": "https://github.com/istanbuljs/istanbuljs/issues" + }, + "homepage": "https://istanbul.js.org/", + "nyc": { + "exclude": [ + "lib/html/assets/**", + "lib/html-spa/assets/**", + "lib/html-spa/rollup.config.js", + "test/**" + ] + }, + "engines": { + "node": ">=8" + } +} diff --git a/node_modules/lz-utils/LICENSE b/node_modules/lz-utils/LICENSE new file mode 100644 index 0000000..9139430 --- /dev/null +++ b/node_modules/lz-utils/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 cenfun + +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/node_modules/lz-utils/README.md b/node_modules/lz-utils/README.md new file mode 100644 index 0000000..c5c9c7e --- /dev/null +++ b/node_modules/lz-utils/README.md @@ -0,0 +1,82 @@ +# lz-utils - Utils for string compression + +[![](https://img.shields.io/npm/v/lz-utils)](https://www.npmjs.com/package/lz-utils) +![](https://img.shields.io/librariesio/github/cenfun/lz-utils) +![](https://img.shields.io/librariesio/dependents/npm/lz-utils) +[![](https://badgen.net/npm/dw/lz-utils)](https://www.npmjs.com/package/lz-utils) +![](https://img.shields.io/github/license/cenfun/lz-utils) + +* `deflateSync` and `deflate` + - Compress raw string and encode in base64 + - Node.js only + - The highest performance (Using native `zlib`) + - Synchronous and Asynchronous + - The smallest size (minified) `0.13KB` / `0.17KB` +* `inflateSync` and `inflate` + - Decompress base64 string to raw string + - Browser only (Using `Uint8Array` and `TextDecoder`) + - Higher performance (Using [tiny-inflate](https://github.com/foliojs/tiny-inflate)) + - Synchronous and Asynchronous/Multi-thread (Using Worker) + - Smaller size (minified) `3.16KB` / `3.62KB` +* `compress` / `decompress` + - Using [lz-string](https://github.com/pieroxy/lz-string) compress/decompress in base64 only + - Both browser and Node.js + - Normal performance + - Synchronous only + - The smallest size (minified) `1.75KB` / `1.67KB` +* `createScriptLoader` + - create script loader + + +## Install +```sh +npm install lz-utils +``` +## Usage +```js +import { + compress, decompress, + deflateSync, deflate, + inflateSync, inflate +} from 'lz-utils'; + +const raw = "this is string"; +const cs = compress(raw); +const ds = decompress(cs); + +``` + +## Examples +- [test.js](/scripts/test.js) +- [test.html](/test/test.html) + +## Business Requirements and Why lz-utils? +- The business here is to generate a lot of `html reports` to users or customers, so the report needs to be generated as `fast` as possible and the file size should be as `small` as possible. +- The possible process is to compress the report data and bundle it with the html file. When the user opens the html file in the browser, the report data will be `self-decompressed` and rendered in the browser. So that's why `inflate` browser only. +- Why `base64`? First of all, the data is stored in `JSON` format, which is easily serialized and compressed. At this time, we get `binary` data. Although its size is the smallest, it has many problems, such as `security issues` (CORS) because it is not JS type or object, so we need to convert binary data into JS string, and `base64` is a good choice. + + +## String Compression Benchmark +- [string-compression](https://github.com/cenfun/string-compression) lz-string, pako, uzip.js, fflate, tiny-inflate + + +## Link +* [https://github.com/pieroxy/lz-string](https://github.com/pieroxy/lz-string) +* [https://github.com/foliojs/tiny-inflate](https://github.com/foliojs/tiny-inflate) + +## Changelog + +* 2.1.0 + - added `createScriptLoader` + +* 2.0.2 + - added types + +* 2.0.0 + - added tiny-inflate + +* 1.0.7 + - added ESM supported + +* 1.0.5 + - added browser version \ No newline at end of file diff --git a/node_modules/lz-utils/dist/browser.js b/node_modules/lz-utils/dist/browser.js new file mode 100644 index 0000000..f477940 --- /dev/null +++ b/node_modules/lz-utils/dist/browser.js @@ -0,0 +1,2 @@ +(()=>{var _=(e,o)=>()=>(o||e((o={exports:{}}).exports,o),o.exports);var T=_((de,O)=>{var N=function(e,o,t){let n,r,c={},w={},l="",d="",b="",h=2,p=3,f=2,u=[],i=0,a=0,s;for(s=0;s>=1}else{for(r=1,n=0;n>=1}h--,h===0&&(h=Math.pow(2,f),f++),delete w[b]}else for(r=c[b],n=0;n>=1;h--,h===0&&(h=Math.pow(2,f),f++),c[d]=p++,b=String(l)}if(b!==""){if(Object.prototype.hasOwnProperty.call(w,b)){if(b.charCodeAt(0)<256){for(n=0;n>=1}else{for(r=1,n=0;n>=1}h--,h===0&&(h=Math.pow(2,f),f++),delete w[b]}else for(r=c[b],n=0;n>=1;h--,h===0&&(h=Math.pow(2,f),f++)}for(r=2,n=0;n>=1;for(;;)if(i<<=1,a===o-1){u.push(t(i));break}else a++;return u.join("")},P="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",F=function(e){let o=N(e,6,function(t){return P.charAt(t)});switch(o.length%4){case 0:return o;case 1:return`${o}===`;case 2:return`${o}==`;case 3:return`${o}=`;default:}};O.exports=function(e){return e===null||e===""||typeof e>"u"?"":F(e)}});var B=_((ve,S)=>{var A=String.fromCharCode,C="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",k={};function V(e,o){if(!k[e]){k[e]={};for(let t=0;t>=1,s.position===0&&(s.position=o,s.val=t(s.index++)),p|=(f>0?1:0)*i,i<<=1;switch(p){case 0:for(p=0,u=Math.pow(2,8),i=1;i!==u;)f=s.val&s.position,s.position>>=1,s.position===0&&(s.position=o,s.val=t(s.index++)),p|=(f>0?1:0)*i,i<<=1;a=A(p);break;case 1:for(p=0,u=Math.pow(2,16),i=1;i!==u;)f=s.val&s.position,s.position>>=1,s.position===0&&(s.position=o,s.val=t(s.index++)),p|=(f>0?1:0)*i,i<<=1;a=A(p);break;case 2:return"";default:}for(n[3]=a,h=a,d.push(a);;){if(s.index>e)return"";for(p=0,u=Math.pow(2,w),i=1;i!==u;)f=s.val&s.position,s.position>>=1,s.position===0&&(s.position=o,s.val=t(s.index++)),p|=(f>0?1:0)*i,i<<=1;switch(a=p){case 0:for(p=0,u=Math.pow(2,8),i=1;i!==u;)f=s.val&s.position,s.position>>=1,s.position===0&&(s.position=o,s.val=t(s.index++)),p|=(f>0?1:0)*i,i<<=1;n[c++]=A(p),a=c-1,r--;break;case 1:for(p=0,u=Math.pow(2,16),i=1;i!==u;)f=s.val&s.position,s.position>>=1,s.position===0&&(s.position=o,s.val=t(s.index++)),p|=(f>0?1:0)*i,i<<=1;n[c++]=A(p),a=c-1,r--;break;case 2:return d.join("");default:}if(r===0&&(r=Math.pow(2,w),w++),n[a])l=n[a];else if(a===c)l=h+h.charAt(0);else return null;d.push(l),n[c++]=h+l.charAt(0),r--,h=l,r===0&&(r=Math.pow(2,w),w++)}},te=function(e){return ee(e.length,32,function(o){return V(C,e.charAt(o))})};S.exports=function(e){return e===null||e===""||typeof e>"u"?"":te(e)}});var j=_((xe,D)=>{D.exports=`(()=>{var x=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports);var S=x((V,R)=>{var _=0,p=-3;function b(){this.table=new Uint16Array(16),this.trans=new Uint16Array(288)}function N(e,n){this.source=e,this.sourceIndex=0,this.tag=0,this.bitcount=0,this.dest=n,this.destLen=0,this.ltree=new b,this.dtree=new b}var y=new b,k=new b,w=new Uint8Array(30),h=new Uint16Array(30),L=new Uint8Array(30),T=new Uint16Array(30),O=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),A=new b,c=new Uint8Array(320);function D(e,n,r,a){var t,i;for(t=0;t>>=1,n}function u(e,n,r){if(!n)return r;for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>16-n;return e.tag>>>=n,e.bitcount-=n,a+r}function v(e,n){for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>=1,++t,r+=n.table[t],a-=n.table[t];while(a>=0);return e.tag=i,e.bitcount-=t,n.trans[r+a]}function C(e,n,r){var a,t,i,o,s,f;for(a=u(e,5,257),t=u(e,5,1),i=u(e,4,4),o=0;o<19;++o)c[o]=0;for(o=0;o8;)e.sourceIndex--,e.bitcount-=8;if(n=e.source[e.sourceIndex+1],n=256*n+e.source[e.sourceIndex],r=e.source[e.sourceIndex+3],r=256*r+e.source[e.sourceIndex+2],n!==(~r&65535))return p;for(e.sourceIndex+=4,a=n;a;--a)e.dest[e.destLen++]=e.source[e.sourceIndex++];return e.bitcount=0,_}function j(e,n){var r=new N(e,n),a,t,i;do{switch(a=B(r),t=u(r,2,0),t){case 0:i=K(r);break;case 1:i=U(r,y,k);break;case 2:C(r,r.ltree,r.dtree),i=U(r,r.ltree,r.dtree);break;default:i=p}if(i!==_)throw new Error("Data error")}while(!a);return r.destLen{var G=S(),H=e=>Uint8Array.from(atob(e),n=>n.charCodeAt(0)),J=e=>new TextDecoder().decode(e);q.exports=function(e){if(e){let[n,r]=e.split(".");if(n&&r){let a=H(n),t=new Uint8Array(parseInt(r));return G(a,t),J(t)}}}});var P=E();onmessage=function(e){postMessage(P(e.data))};postMessage("workerReady");})(); +`});var q=_((_e,R)=>{var re=j();R.exports=e=>new Promise(o=>{let t=new Worker(URL.createObjectURL(new Blob([re],{type:"application/javascript"})));t.onmessage=n=>{if(n.data==="workerReady"){t.postMessage(e);return}o(n.data),t.terminate()},t.onerror=n=>{o({error:n}),t.terminate()}})});var X=_((ye,Q)=>{var L=0,K=-3;function y(){this.table=new Uint16Array(16),this.trans=new Uint16Array(288)}function ne(e,o){this.source=e,this.sourceIndex=0,this.tag=0,this.bitcount=0,this.dest=o,this.destLen=0,this.ltree=new y,this.dtree=new y}var G=new y,H=new y,I=new Uint8Array(30),M=new Uint16Array(30),J=new Uint8Array(30),W=new Uint16Array(30),oe=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),z=new y,v=new Uint8Array(320);function $(e,o,t,n){var r,c;for(r=0;r>>=1,o}function x(e,o,t){if(!o)return t;for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>16-o;return e.tag>>>=o,e.bitcount-=o,n+t}function U(e,o){for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>=1,++r,t+=o.table[r],n-=o.table[r];while(n>=0);return e.tag=c,e.bitcount-=r,o.trans[t+n]}function ae(e,o,t){var n,r,c,w,l,d;for(n=x(e,5,257),r=x(e,5,1),c=x(e,4,4),w=0;w<19;++w)v[w]=0;for(w=0;w8;)e.sourceIndex--,e.bitcount-=8;if(o=e.source[e.sourceIndex+1],o=256*o+e.source[e.sourceIndex],t=e.source[e.sourceIndex+3],t=256*t+e.source[e.sourceIndex+2],o!==(~t&65535))return K;for(e.sourceIndex+=4,n=o;n;--n)e.dest[e.destLen++]=e.source[e.sourceIndex++];return e.bitcount=0,L}function fe(e,o){var t=new ne(e,o),n,r,c;do{switch(n=se(t),r=x(t,2,0),r){case 0:c=ce(t);break;case 1:c=m(t,G,H);break;case 2:ae(t,t.ltree,t.dtree),c=m(t,t.ltree,t.dtree);break;default:c=K}if(c!==L)throw new Error("Data error")}while(!n);return t.destLen{var ue=X(),le=e=>Uint8Array.from(atob(e),o=>o.charCodeAt(0)),we=e=>new TextDecoder().decode(e);Y.exports=function(e){if(e){let[o,t]=e.split(".");if(o&&t){let n=le(o),r=new Uint8Array(parseInt(t));return ue(n,r),we(r)}}}});var be=self||window;be["lz-utils"]={compress:T(),decompress:B(),inflate:q(),inflateSync:Z()};})(); diff --git a/node_modules/lz-utils/dist/compress.js b/node_modules/lz-utils/dist/compress.js new file mode 100644 index 0000000..dad219e --- /dev/null +++ b/node_modules/lz-utils/dist/compress.js @@ -0,0 +1 @@ +var y=function(u,l,n){let o,c,a={},r={},d="",_="",f="",p=2,x=3,s=2,i=[],e=0,t=0,w;for(w=0;w>=1}else{for(c=1,o=0;o>=1}p--,p===0&&(p=Math.pow(2,s),s++),delete r[f]}else for(c=a[f],o=0;o>=1;p--,p===0&&(p=Math.pow(2,s),s++),a[_]=x++,f=String(d)}if(f!==""){if(Object.prototype.hasOwnProperty.call(r,f)){if(f.charCodeAt(0)<256){for(o=0;o>=1}else{for(c=1,o=0;o>=1}p--,p===0&&(p=Math.pow(2,s),s++),delete r[f]}else for(c=a[f],o=0;o>=1;p--,p===0&&(p=Math.pow(2,s),s++)}for(c=2,o=0;o>=1;for(;;)if(e<<=1,t===l-1){i.push(n(e));break}else t++;return i.join("")},h="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",A=function(u){let l=y(u,6,function(n){return h.charAt(n)});switch(l.length%4){case 0:return l;case 1:return`${l}===`;case 2:return`${l}==`;case 3:return`${l}=`;default:}};module.exports=function(u){return u===null||u===""||typeof u>"u"?"":A(u)}; diff --git a/node_modules/lz-utils/dist/create-script-loader.js b/node_modules/lz-utils/dist/create-script-loader.js new file mode 100644 index 0000000..56ff7aa --- /dev/null +++ b/node_modules/lz-utils/dist/create-script-loader.js @@ -0,0 +1 @@ +var t=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var a=t((p,n)=>{n.exports='var a=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var s=a((b,o)=>{o.exports=`(()=>{var x=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports);var S=x((V,R)=>{var _=0,p=-3;function b(){this.table=new Uint16Array(16),this.trans=new Uint16Array(288)}function N(e,n){this.source=e,this.sourceIndex=0,this.tag=0,this.bitcount=0,this.dest=n,this.destLen=0,this.ltree=new b,this.dtree=new b}var y=new b,k=new b,w=new Uint8Array(30),h=new Uint16Array(30),L=new Uint8Array(30),T=new Uint16Array(30),O=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),A=new b,c=new Uint8Array(320);function D(e,n,r,a){var t,i;for(t=0;t>>=1,n}function u(e,n,r){if(!n)return r;for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>16-n;return e.tag>>>=n,e.bitcount-=n,a+r}function v(e,n){for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>=1,++t,r+=n.table[t],a-=n.table[t];while(a>=0);return e.tag=i,e.bitcount-=t,n.trans[r+a]}function C(e,n,r){var a,t,i,o,s,f;for(a=u(e,5,257),t=u(e,5,1),i=u(e,4,4),o=0;o<19;++o)c[o]=0;for(o=0;o8;)e.sourceIndex--,e.bitcount-=8;if(n=e.source[e.sourceIndex+1],n=256*n+e.source[e.sourceIndex],r=e.source[e.sourceIndex+3],r=256*r+e.source[e.sourceIndex+2],n!==(~r&65535))return p;for(e.sourceIndex+=4,a=n;a;--a)e.dest[e.destLen++]=e.source[e.sourceIndex++];return e.bitcount=0,_}function j(e,n){var r=new N(e,n),a,t,i;do{switch(a=B(r),t=u(r,2,0),t){case 0:i=K(r);break;case 1:i=U(r,y,k);break;case 2:C(r,r.ltree,r.dtree),i=U(r,r.ltree,r.dtree);break;default:i=p}if(i!==_)throw new Error("Data error")}while(!a);return r.destLen{var G=S(),H=e=>Uint8Array.from(atob(e),n=>n.charCodeAt(0)),J=e=>new TextDecoder().decode(e);q.exports=function(e){if(e){let[n,r]=e.split(".");if(n&&r){let a=H(n),t=new Uint8Array(parseInt(r));return G(a,t),J(t)}}}});var P=E();onmessage=function(e){postMessage(P(e.data))};postMessage("workerReady");})();\n`});var c=a((l,i)=>{var u=s();i.exports=r=>new Promise(e=>{let t=new Worker(URL.createObjectURL(new Blob([u],{type:"application/javascript"})));t.onmessage=n=>{if(n.data==="workerReady"){t.postMessage(r);return}e(n.data),t.terminate()},t.onerror=n=>{e({error:n}),t.terminate()}})});var f=c();f("{placeholder}").then(r=>{let e=document.createElement("script");e.innerHTML=r,document.body.appendChild(e)});\n'});var s=t((v,o)=>{var c=require("zlib");o.exports=r=>{let e=Buffer.from(r),i=e.length;return`${c.deflateRawSync(e).toString("base64")}.${i}`}});var u=a(),f=s();module.exports=r=>u.replace("{placeholder}",f(r)); diff --git a/node_modules/lz-utils/dist/decompress.js b/node_modules/lz-utils/dist/decompress.js new file mode 100644 index 0000000..fbf647a --- /dev/null +++ b/node_modules/lz-utils/dist/decompress.js @@ -0,0 +1 @@ +var u=String.fromCharCode,x="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",M={};function k(t,c){if(!M[t]){M[t]={};for(let s=0;s>=1,i.position===0&&(i.position=c,i.val=s(i.index++)),n|=(e>0?1:0)*o,o<<=1;switch(n){case 0:for(n=0,r=Math.pow(2,8),o=1;o!==r;)e=i.val&i.position,i.position>>=1,i.position===0&&(i.position=c,i.val=s(i.index++)),n|=(e>0?1:0)*o,o<<=1;p=u(n);break;case 1:for(n=0,r=Math.pow(2,16),o=1;o!==r;)e=i.val&i.position,i.position>>=1,i.position===0&&(i.position=c,i.val=s(i.index++)),n|=(e>0?1:0)*o,o<<=1;p=u(n);break;case 2:return"";default:}for(l[3]=p,v=p,m.push(p);;){if(i.index>t)return"";for(n=0,r=Math.pow(2,h),o=1;o!==r;)e=i.val&i.position,i.position>>=1,i.position===0&&(i.position=c,i.val=s(i.index++)),n|=(e>0?1:0)*o,o<<=1;switch(p=n){case 0:for(n=0,r=Math.pow(2,8),o=1;o!==r;)e=i.val&i.position,i.position>>=1,i.position===0&&(i.position=c,i.val=s(i.index++)),n|=(e>0?1:0)*o,o<<=1;l[f++]=u(n),p=f-1,a--;break;case 1:for(n=0,r=Math.pow(2,16),o=1;o!==r;)e=i.val&i.position,i.position>>=1,i.position===0&&(i.position=c,i.val=s(i.index++)),n|=(e>0?1:0)*o,o<<=1;l[f++]=u(n),p=f-1,a--;break;case 2:return m.join("");default:}if(a===0&&(a=Math.pow(2,h),h++),l[p])w=l[p];else if(p===f)w=v+v.charAt(0);else return null;m.push(w),l[f++]=v+w.charAt(0),a--,v=w,a===0&&(a=Math.pow(2,h),h++)}},A=function(t){return y(t.length,32,function(c){return k(x,t.charAt(c))})};module.exports=function(t){return t===null||t===""||typeof t>"u"?"":A(t)}; diff --git a/node_modules/lz-utils/dist/deflate-sync.js b/node_modules/lz-utils/dist/deflate-sync.js new file mode 100644 index 0000000..6b9b095 --- /dev/null +++ b/node_modules/lz-utils/dist/deflate-sync.js @@ -0,0 +1 @@ +var n=require("zlib");module.exports=e=>{let t=Buffer.from(e),r=t.length;return`${n.deflateRawSync(t).toString("base64")}.${r}`}; diff --git a/node_modules/lz-utils/dist/deflate.js b/node_modules/lz-utils/dist/deflate.js new file mode 100644 index 0000000..0f98258 --- /dev/null +++ b/node_modules/lz-utils/dist/deflate.js @@ -0,0 +1 @@ +var u=require("zlib");module.exports=n=>new Promise(t=>{let e=Buffer.from(n),r=e.length;u.deflateRaw(e,(o,s)=>{if(o){t();return}let f=`${s.toString("base64")}.${r}`;t(f)})}); diff --git a/node_modules/lz-utils/dist/index.js b/node_modules/lz-utils/dist/index.js new file mode 100644 index 0000000..c1eb63c --- /dev/null +++ b/node_modules/lz-utils/dist/index.js @@ -0,0 +1,9 @@ +module.exports = { + compress: require('./compress.js'), + decompress: require('./decompress.js'), + deflate: require('./deflate.js'), + inflate: require('./inflate.js'), + deflateSync: require('./deflate-sync.js'), + inflateSync: require('./inflate-sync.js'), + createScriptLoader: require('./create-script-loader.js') +}; diff --git a/node_modules/lz-utils/dist/index.mjs b/node_modules/lz-utils/dist/index.mjs new file mode 100644 index 0000000..eca2d8a --- /dev/null +++ b/node_modules/lz-utils/dist/index.mjs @@ -0,0 +1,19 @@ +import compress from './compress.js'; +import decompress from './decompress.js'; + +import deflate from './deflate.js'; +import inflate from './inflate.js'; + +import deflateSync from './deflate-sync.js'; +import inflateSync from './inflate-sync.js'; + +export { + compress, + decompress, + + deflate, + inflate, + + deflateSync, + inflateSync +}; diff --git a/node_modules/lz-utils/dist/inflate-sync.js b/node_modules/lz-utils/dist/inflate-sync.js new file mode 100644 index 0000000..64a0cad --- /dev/null +++ b/node_modules/lz-utils/dist/inflate-sync.js @@ -0,0 +1 @@ +var F=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports);var R=F((M,D)=>{var _=0,U=-3;function b(){this.table=new Uint16Array(16),this.trans=new Uint16Array(288)}function N(e,n){this.source=e,this.sourceIndex=0,this.tag=0,this.bitcount=0,this.dest=n,this.destLen=0,this.ltree=new b,this.dtree=new b}var k=new b,p=new b,h=new Uint8Array(30),w=new Uint16Array(30),y=new Uint8Array(30),L=new Uint16Array(30),O=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),g=new b,c=new Uint8Array(320);function T(e,n,r,a){var t,i;for(t=0;t>>=1,n}function u(e,n,r){if(!n)return r;for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>16-n;return e.tag>>>=n,e.bitcount-=n,a+r}function v(e,n){for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>=1,++t,r+=n.table[t],a-=n.table[t];while(a>=0);return e.tag=i,e.bitcount-=t,n.trans[r+a]}function B(e,n,r){var a,t,i,o,s,f;for(a=u(e,5,257),t=u(e,5,1),i=u(e,4,4),o=0;o<19;++o)c[o]=0;for(o=0;o8;)e.sourceIndex--,e.bitcount-=8;if(n=e.source[e.sourceIndex+1],n=256*n+e.source[e.sourceIndex],r=e.source[e.sourceIndex+3],r=256*r+e.source[e.sourceIndex+2],n!==(~r&65535))return U;for(e.sourceIndex+=4,a=n;a;--a)e.dest[e.destLen++]=e.source[e.sourceIndex++];return e.bitcount=0,_}function K(e,n){var r=new N(e,n),a,t,i;do{switch(a=z(r),t=u(r,2,0),t){case 0:i=C(r);break;case 1:i=I(r,k,p);break;case 2:B(r,r.ltree,r.dtree),i=I(r,r.ltree,r.dtree);break;default:i=U}if(i!==_)throw new Error("Data error")}while(!a);return r.destLenUint8Array.from(atob(e),n=>n.charCodeAt(0)),H=e=>new TextDecoder().decode(e);module.exports=function(e){if(e){let[n,r]=e.split(".");if(n&&r){let a=G(n),t=new Uint8Array(parseInt(r));return j(a,t),H(t)}}}; diff --git a/node_modules/lz-utils/dist/inflate-worker-data.js b/node_modules/lz-utils/dist/inflate-worker-data.js new file mode 100644 index 0000000..2370764 --- /dev/null +++ b/node_modules/lz-utils/dist/inflate-worker-data.js @@ -0,0 +1 @@ +module.exports = "(()=>{var x=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports);var S=x((V,R)=>{var _=0,p=-3;function b(){this.table=new Uint16Array(16),this.trans=new Uint16Array(288)}function N(e,n){this.source=e,this.sourceIndex=0,this.tag=0,this.bitcount=0,this.dest=n,this.destLen=0,this.ltree=new b,this.dtree=new b}var y=new b,k=new b,w=new Uint8Array(30),h=new Uint16Array(30),L=new Uint8Array(30),T=new Uint16Array(30),O=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),A=new b,c=new Uint8Array(320);function D(e,n,r,a){var t,i;for(t=0;t>>=1,n}function u(e,n,r){if(!n)return r;for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>16-n;return e.tag>>>=n,e.bitcount-=n,a+r}function v(e,n){for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>=1,++t,r+=n.table[t],a-=n.table[t];while(a>=0);return e.tag=i,e.bitcount-=t,n.trans[r+a]}function C(e,n,r){var a,t,i,o,s,f;for(a=u(e,5,257),t=u(e,5,1),i=u(e,4,4),o=0;o<19;++o)c[o]=0;for(o=0;o8;)e.sourceIndex--,e.bitcount-=8;if(n=e.source[e.sourceIndex+1],n=256*n+e.source[e.sourceIndex],r=e.source[e.sourceIndex+3],r=256*r+e.source[e.sourceIndex+2],n!==(~r&65535))return p;for(e.sourceIndex+=4,a=n;a;--a)e.dest[e.destLen++]=e.source[e.sourceIndex++];return e.bitcount=0,_}function j(e,n){var r=new N(e,n),a,t,i;do{switch(a=B(r),t=u(r,2,0),t){case 0:i=K(r);break;case 1:i=U(r,y,k);break;case 2:C(r,r.ltree,r.dtree),i=U(r,r.ltree,r.dtree);break;default:i=p}if(i!==_)throw new Error(\"Data error\")}while(!a);return r.destLen{var G=S(),H=e=>Uint8Array.from(atob(e),n=>n.charCodeAt(0)),J=e=>new TextDecoder().decode(e);q.exports=function(e){if(e){let[n,r]=e.split(\".\");if(n&&r){let a=H(n),t=new Uint8Array(parseInt(r));return G(a,t),J(t)}}}});var P=E();onmessage=function(e){postMessage(P(e.data))};postMessage(\"workerReady\");})();\n"; \ No newline at end of file diff --git a/node_modules/lz-utils/dist/inflate-worker.js b/node_modules/lz-utils/dist/inflate-worker.js new file mode 100644 index 0000000..ed7019e --- /dev/null +++ b/node_modules/lz-utils/dist/inflate-worker.js @@ -0,0 +1 @@ +(()=>{var x=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports);var S=x((V,R)=>{var _=0,p=-3;function b(){this.table=new Uint16Array(16),this.trans=new Uint16Array(288)}function N(e,n){this.source=e,this.sourceIndex=0,this.tag=0,this.bitcount=0,this.dest=n,this.destLen=0,this.ltree=new b,this.dtree=new b}var y=new b,k=new b,w=new Uint8Array(30),h=new Uint16Array(30),L=new Uint8Array(30),T=new Uint16Array(30),O=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),A=new b,c=new Uint8Array(320);function D(e,n,r,a){var t,i;for(t=0;t>>=1,n}function u(e,n,r){if(!n)return r;for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>16-n;return e.tag>>>=n,e.bitcount-=n,a+r}function v(e,n){for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>=1,++t,r+=n.table[t],a-=n.table[t];while(a>=0);return e.tag=i,e.bitcount-=t,n.trans[r+a]}function C(e,n,r){var a,t,i,o,s,f;for(a=u(e,5,257),t=u(e,5,1),i=u(e,4,4),o=0;o<19;++o)c[o]=0;for(o=0;o8;)e.sourceIndex--,e.bitcount-=8;if(n=e.source[e.sourceIndex+1],n=256*n+e.source[e.sourceIndex],r=e.source[e.sourceIndex+3],r=256*r+e.source[e.sourceIndex+2],n!==(~r&65535))return p;for(e.sourceIndex+=4,a=n;a;--a)e.dest[e.destLen++]=e.source[e.sourceIndex++];return e.bitcount=0,_}function j(e,n){var r=new N(e,n),a,t,i;do{switch(a=B(r),t=u(r,2,0),t){case 0:i=K(r);break;case 1:i=U(r,y,k);break;case 2:C(r,r.ltree,r.dtree),i=U(r,r.ltree,r.dtree);break;default:i=p}if(i!==_)throw new Error("Data error")}while(!a);return r.destLen{var G=S(),H=e=>Uint8Array.from(atob(e),n=>n.charCodeAt(0)),J=e=>new TextDecoder().decode(e);q.exports=function(e){if(e){let[n,r]=e.split(".");if(n&&r){let a=H(n),t=new Uint8Array(parseInt(r));return G(a,t),J(t)}}}});var P=E();onmessage=function(e){postMessage(P(e.data))};postMessage("workerReady");})(); diff --git a/node_modules/lz-utils/dist/inflate.js b/node_modules/lz-utils/dist/inflate.js new file mode 100644 index 0000000..8430083 --- /dev/null +++ b/node_modules/lz-utils/dist/inflate.js @@ -0,0 +1,2 @@ +var s=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports);var o=s((u,a)=>{a.exports=`(()=>{var x=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports);var S=x((V,R)=>{var _=0,p=-3;function b(){this.table=new Uint16Array(16),this.trans=new Uint16Array(288)}function N(e,n){this.source=e,this.sourceIndex=0,this.tag=0,this.bitcount=0,this.dest=n,this.destLen=0,this.ltree=new b,this.dtree=new b}var y=new b,k=new b,w=new Uint8Array(30),h=new Uint16Array(30),L=new Uint8Array(30),T=new Uint16Array(30),O=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),A=new b,c=new Uint8Array(320);function D(e,n,r,a){var t,i;for(t=0;t>>=1,n}function u(e,n,r){if(!n)return r;for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>16-n;return e.tag>>>=n,e.bitcount-=n,a+r}function v(e,n){for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>=1,++t,r+=n.table[t],a-=n.table[t];while(a>=0);return e.tag=i,e.bitcount-=t,n.trans[r+a]}function C(e,n,r){var a,t,i,o,s,f;for(a=u(e,5,257),t=u(e,5,1),i=u(e,4,4),o=0;o<19;++o)c[o]=0;for(o=0;o8;)e.sourceIndex--,e.bitcount-=8;if(n=e.source[e.sourceIndex+1],n=256*n+e.source[e.sourceIndex],r=e.source[e.sourceIndex+3],r=256*r+e.source[e.sourceIndex+2],n!==(~r&65535))return p;for(e.sourceIndex+=4,a=n;a;--a)e.dest[e.destLen++]=e.source[e.sourceIndex++];return e.bitcount=0,_}function j(e,n){var r=new N(e,n),a,t,i;do{switch(a=B(r),t=u(r,2,0),t){case 0:i=K(r);break;case 1:i=U(r,y,k);break;case 2:C(r,r.ltree,r.dtree),i=U(r,r.ltree,r.dtree);break;default:i=p}if(i!==_)throw new Error("Data error")}while(!a);return r.destLen{var G=S(),H=e=>Uint8Array.from(atob(e),n=>n.charCodeAt(0)),J=e=>new TextDecoder().decode(e);q.exports=function(e){if(e){let[n,r]=e.split(".");if(n&&r){let a=H(n),t=new Uint8Array(parseInt(r));return G(a,t),J(t)}}}});var P=E();onmessage=function(e){postMessage(P(e.data))};postMessage("workerReady");})(); +`});var i=o();module.exports=n=>new Promise(e=>{let r=new Worker(URL.createObjectURL(new Blob([i],{type:"application/javascript"})));r.onmessage=t=>{if(t.data==="workerReady"){r.postMessage(n);return}e(t.data),r.terminate()},r.onerror=t=>{e({error:t}),r.terminate()}}); diff --git a/node_modules/lz-utils/dist/script-loader-data.js b/node_modules/lz-utils/dist/script-loader-data.js new file mode 100644 index 0000000..6fa54ad --- /dev/null +++ b/node_modules/lz-utils/dist/script-loader-data.js @@ -0,0 +1 @@ +module.exports = "var a=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var s=a((b,o)=>{o.exports=`(()=>{var x=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports);var S=x((V,R)=>{var _=0,p=-3;function b(){this.table=new Uint16Array(16),this.trans=new Uint16Array(288)}function N(e,n){this.source=e,this.sourceIndex=0,this.tag=0,this.bitcount=0,this.dest=n,this.destLen=0,this.ltree=new b,this.dtree=new b}var y=new b,k=new b,w=new Uint8Array(30),h=new Uint16Array(30),L=new Uint8Array(30),T=new Uint16Array(30),O=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),A=new b,c=new Uint8Array(320);function D(e,n,r,a){var t,i;for(t=0;t>>=1,n}function u(e,n,r){if(!n)return r;for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>16-n;return e.tag>>>=n,e.bitcount-=n,a+r}function v(e,n){for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>=1,++t,r+=n.table[t],a-=n.table[t];while(a>=0);return e.tag=i,e.bitcount-=t,n.trans[r+a]}function C(e,n,r){var a,t,i,o,s,f;for(a=u(e,5,257),t=u(e,5,1),i=u(e,4,4),o=0;o<19;++o)c[o]=0;for(o=0;o8;)e.sourceIndex--,e.bitcount-=8;if(n=e.source[e.sourceIndex+1],n=256*n+e.source[e.sourceIndex],r=e.source[e.sourceIndex+3],r=256*r+e.source[e.sourceIndex+2],n!==(~r&65535))return p;for(e.sourceIndex+=4,a=n;a;--a)e.dest[e.destLen++]=e.source[e.sourceIndex++];return e.bitcount=0,_}function j(e,n){var r=new N(e,n),a,t,i;do{switch(a=B(r),t=u(r,2,0),t){case 0:i=K(r);break;case 1:i=U(r,y,k);break;case 2:C(r,r.ltree,r.dtree),i=U(r,r.ltree,r.dtree);break;default:i=p}if(i!==_)throw new Error(\"Data error\")}while(!a);return r.destLen{var G=S(),H=e=>Uint8Array.from(atob(e),n=>n.charCodeAt(0)),J=e=>new TextDecoder().decode(e);q.exports=function(e){if(e){let[n,r]=e.split(\".\");if(n&&r){let a=H(n),t=new Uint8Array(parseInt(r));return G(a,t),J(t)}}}});var P=E();onmessage=function(e){postMessage(P(e.data))};postMessage(\"workerReady\");})();\n`});var c=a((l,i)=>{var u=s();i.exports=r=>new Promise(e=>{let t=new Worker(URL.createObjectURL(new Blob([u],{type:\"application/javascript\"})));t.onmessage=n=>{if(n.data===\"workerReady\"){t.postMessage(r);return}e(n.data),t.terminate()},t.onerror=n=>{e({error:n}),t.terminate()}})});var f=c();f(\"{placeholder}\").then(r=>{let e=document.createElement(\"script\");e.innerHTML=r,document.body.appendChild(e)});\n"; \ No newline at end of file diff --git a/node_modules/lz-utils/dist/script-loader.js b/node_modules/lz-utils/dist/script-loader.js new file mode 100644 index 0000000..2e116ad --- /dev/null +++ b/node_modules/lz-utils/dist/script-loader.js @@ -0,0 +1,2 @@ +var a=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var s=a((b,o)=>{o.exports=`(()=>{var x=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports);var S=x((V,R)=>{var _=0,p=-3;function b(){this.table=new Uint16Array(16),this.trans=new Uint16Array(288)}function N(e,n){this.source=e,this.sourceIndex=0,this.tag=0,this.bitcount=0,this.dest=n,this.destLen=0,this.ltree=new b,this.dtree=new b}var y=new b,k=new b,w=new Uint8Array(30),h=new Uint16Array(30),L=new Uint8Array(30),T=new Uint16Array(30),O=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),A=new b,c=new Uint8Array(320);function D(e,n,r,a){var t,i;for(t=0;t>>=1,n}function u(e,n,r){if(!n)return r;for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>16-n;return e.tag>>>=n,e.bitcount-=n,a+r}function v(e,n){for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>=1,++t,r+=n.table[t],a-=n.table[t];while(a>=0);return e.tag=i,e.bitcount-=t,n.trans[r+a]}function C(e,n,r){var a,t,i,o,s,f;for(a=u(e,5,257),t=u(e,5,1),i=u(e,4,4),o=0;o<19;++o)c[o]=0;for(o=0;o8;)e.sourceIndex--,e.bitcount-=8;if(n=e.source[e.sourceIndex+1],n=256*n+e.source[e.sourceIndex],r=e.source[e.sourceIndex+3],r=256*r+e.source[e.sourceIndex+2],n!==(~r&65535))return p;for(e.sourceIndex+=4,a=n;a;--a)e.dest[e.destLen++]=e.source[e.sourceIndex++];return e.bitcount=0,_}function j(e,n){var r=new N(e,n),a,t,i;do{switch(a=B(r),t=u(r,2,0),t){case 0:i=K(r);break;case 1:i=U(r,y,k);break;case 2:C(r,r.ltree,r.dtree),i=U(r,r.ltree,r.dtree);break;default:i=p}if(i!==_)throw new Error("Data error")}while(!a);return r.destLen{var G=S(),H=e=>Uint8Array.from(atob(e),n=>n.charCodeAt(0)),J=e=>new TextDecoder().decode(e);q.exports=function(e){if(e){let[n,r]=e.split(".");if(n&&r){let a=H(n),t=new Uint8Array(parseInt(r));return G(a,t),J(t)}}}});var P=E();onmessage=function(e){postMessage(P(e.data))};postMessage("workerReady");})(); +`});var c=a((l,i)=>{var u=s();i.exports=r=>new Promise(e=>{let t=new Worker(URL.createObjectURL(new Blob([u],{type:"application/javascript"})));t.onmessage=n=>{if(n.data==="workerReady"){t.postMessage(r);return}e(n.data),t.terminate()},t.onerror=n=>{e({error:n}),t.terminate()}})});var f=c();f("{placeholder}").then(r=>{let e=document.createElement("script");e.innerHTML=r,document.body.appendChild(e)}); diff --git a/node_modules/lz-utils/lib/browser.js b/node_modules/lz-utils/lib/browser.js new file mode 100644 index 0000000..fb0dded --- /dev/null +++ b/node_modules/lz-utils/lib/browser.js @@ -0,0 +1,7 @@ +const root = self || window; +root['lz-utils'] = { + compress: require('./compress.js'), + decompress: require('./decompress.js'), + inflate: require('./inflate.js'), + inflateSync: require('./inflate-sync.js') +}; diff --git a/node_modules/lz-utils/lib/compress.js b/node_modules/lz-utils/lib/compress.js new file mode 100644 index 0000000..8b341de --- /dev/null +++ b/node_modules/lz-utils/lib/compress.js @@ -0,0 +1,244 @@ + +// https://github.com/pieroxy/lz-string +// https://pieroxy.net/blog/pages/lz-string/index.html +/* eslint-disable max-statements,complexity,no-constant-condition,max-depth */ + +const _compress = function(uncompressed, bitsPerChar, getCharFromInt) { + let i; + let value; + const context_dictionary = {}; + const context_dictionaryToCreate = {}; + let context_c = ''; + let context_wc = ''; + let context_w = ''; + let context_enlargeIn = 2; + let context_dictSize = 3; + let context_numBits = 2; + const context_data = []; + let context_data_val = 0; + let context_data_position = 0; + let ii; + + for (ii = 0; ii < uncompressed.length; ii += 1) { + context_c = uncompressed.charAt(ii); + if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) { + context_dictionary[context_c] = context_dictSize++; + context_dictionaryToCreate[context_c] = true; + } + + context_wc = context_w + context_c; + if (Object.prototype.hasOwnProperty.call(context_dictionary, context_wc)) { + context_w = context_wc; + } else { + if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) { + if (context_w.charCodeAt(0) < 256) { + for (i = 0; i < context_numBits; i++) { + context_data_val <<= 1; + if (context_data_position === bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + } + value = context_w.charCodeAt(0); + for (i = 0; i < 8; i++) { + context_data_val = (context_data_val << 1) | (value & 1); + if (context_data_position === bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value >>= 1; + } + } else { + value = 1; + for (i = 0; i < context_numBits; i++) { + context_data_val = (context_data_val << 1) | value; + if (context_data_position === bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value = 0; + } + value = context_w.charCodeAt(0); + for (i = 0; i < 16; i++) { + context_data_val = (context_data_val << 1) | (value & 1); + if (context_data_position === bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value >>= 1; + } + } + context_enlargeIn--; + if (context_enlargeIn === 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + delete context_dictionaryToCreate[context_w]; + } else { + value = context_dictionary[context_w]; + for (i = 0; i < context_numBits; i++) { + context_data_val = (context_data_val << 1) | (value & 1); + if (context_data_position === bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value >>= 1; + } + + + } + context_enlargeIn--; + if (context_enlargeIn === 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + // Add wc to the dictionary. + context_dictionary[context_wc] = context_dictSize++; + context_w = String(context_c); + } + } + + // Output the code for w. + if (context_w !== '') { + if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) { + if (context_w.charCodeAt(0) < 256) { + for (i = 0; i < context_numBits; i++) { + context_data_val <<= 1; + if (context_data_position === bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + } + value = context_w.charCodeAt(0); + for (i = 0; i < 8; i++) { + context_data_val = (context_data_val << 1) | (value & 1); + if (context_data_position === bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value >>= 1; + } + } else { + value = 1; + for (i = 0; i < context_numBits; i++) { + context_data_val = (context_data_val << 1) | value; + if (context_data_position === bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value = 0; + } + value = context_w.charCodeAt(0); + for (i = 0; i < 16; i++) { + context_data_val = (context_data_val << 1) | (value & 1); + if (context_data_position === bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value >>= 1; + } + } + context_enlargeIn--; + if (context_enlargeIn === 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + delete context_dictionaryToCreate[context_w]; + } else { + value = context_dictionary[context_w]; + for (i = 0; i < context_numBits; i++) { + context_data_val = (context_data_val << 1) | (value & 1); + if (context_data_position === bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value >>= 1; + } + + + } + context_enlargeIn--; + if (context_enlargeIn === 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + } + + // Mark the end of the stream + value = 2; + for (i = 0; i < context_numBits; i++) { + context_data_val = (context_data_val << 1) | (value & 1); + if (context_data_position === bitsPerChar - 1) { + context_data_position = 0; + context_data.push(getCharFromInt(context_data_val)); + context_data_val = 0; + } else { + context_data_position++; + } + value >>= 1; + } + + // Flush the last char + while (true) { + context_data_val <<= 1; + if (context_data_position === bitsPerChar - 1) { + context_data.push(getCharFromInt(context_data_val)); + break; + } else { + context_data_position++; + } + } + return context_data.join(''); +}; + +const keyStrBase64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; +const compressToBase64 = function(input) { + const res = _compress(input, 6, function(a) { + return keyStrBase64.charAt(a); + }); + switch (res.length % 4) { + case 0: return res; + case 1: return `${res}===`; + case 2: return `${res}==`; + case 3: return `${res}=`; + default: + } +}; + +module.exports = function(input) { + if (input === null || input === '' || typeof input === 'undefined') { + return ''; + } + // 166% bigger + return compressToBase64(input); +}; diff --git a/node_modules/lz-utils/lib/create-script-loader.js b/node_modules/lz-utils/lib/create-script-loader.js new file mode 100644 index 0000000..3311807 --- /dev/null +++ b/node_modules/lz-utils/lib/create-script-loader.js @@ -0,0 +1,5 @@ +const loader = require('../dist/script-loader-data.js'); +const deflateSync = require('./deflate-sync.js'); +module.exports = (str) => { + return loader.replace('{placeholder}', deflateSync(str)); +}; diff --git a/node_modules/lz-utils/lib/decompress.js b/node_modules/lz-utils/lib/decompress.js new file mode 100644 index 0000000..91cf34d --- /dev/null +++ b/node_modules/lz-utils/lib/decompress.js @@ -0,0 +1,201 @@ + +// https://github.com/pieroxy/lz-string +// https://pieroxy.net/blog/pages/lz-string/index.html +/* eslint-disable max-statements,complexity,no-constant-condition */ + +const fcc = String.fromCharCode; +const keyStrBase64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; +const baseReverseDic = {}; + +function getBaseValue(alphabet, character) { + if (!baseReverseDic[alphabet]) { + baseReverseDic[alphabet] = {}; + for (let i = 0; i < alphabet.length; i++) { + baseReverseDic[alphabet][alphabet.charAt(i)] = i; + } + } + return baseReverseDic[alphabet][character]; +} + +const _decompress = function(length, resetValue, getNextValue) { + const dictionary = []; + + let enlargeIn = 4; + let dictSize = 4; + let numBits = 3; + let entry = ''; + const result = []; + let i; + let w; + let bits; + let resb; + let maxpower; + let power; + let c; + const data = { + val: getNextValue(0), position: resetValue, index: 1 + }; + + for (i = 0; i < 3; i += 1) { + dictionary[i] = i; + } + + bits = 0; + maxpower = Math.pow(2, 2); + power = 1; + while (power !== maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position === 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb > 0 ? 1 : 0) * power; + power <<= 1; + } + + const next = bits; + switch (next) { + case 0: + bits = 0; + maxpower = Math.pow(2, 8); + power = 1; + while (power !== maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position === 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb > 0 ? 1 : 0) * power; + power <<= 1; + } + c = fcc(bits); + break; + case 1: + bits = 0; + maxpower = Math.pow(2, 16); + power = 1; + while (power !== maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position === 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb > 0 ? 1 : 0) * power; + power <<= 1; + } + c = fcc(bits); + break; + case 2: + return ''; + default: + } + dictionary[3] = c; + w = c; + result.push(c); + while (true) { + if (data.index > length) { + return ''; + } + + bits = 0; + maxpower = Math.pow(2, numBits); + power = 1; + while (power !== maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position === 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb > 0 ? 1 : 0) * power; + power <<= 1; + } + + switch (c = bits) { + case 0: + bits = 0; + maxpower = Math.pow(2, 8); + power = 1; + while (power !== maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position === 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb > 0 ? 1 : 0) * power; + power <<= 1; + } + + dictionary[dictSize++] = fcc(bits); + c = dictSize - 1; + enlargeIn--; + break; + case 1: + bits = 0; + maxpower = Math.pow(2, 16); + power = 1; + while (power !== maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position === 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb > 0 ? 1 : 0) * power; + power <<= 1; + } + dictionary[dictSize++] = fcc(bits); + c = dictSize - 1; + enlargeIn--; + break; + case 2: + return result.join(''); + default: + } + + if (enlargeIn === 0) { + enlargeIn = Math.pow(2, numBits); + numBits++; + } + + if (dictionary[c]) { + entry = dictionary[c]; + } else { + if (c === dictSize) { + entry = w + w.charAt(0); + } else { + return null; + } + } + result.push(entry); + + // Add w+entry[0] to the dictionary. + dictionary[dictSize++] = w + entry.charAt(0); + enlargeIn--; + + w = entry; + + if (enlargeIn === 0) { + enlargeIn = Math.pow(2, numBits); + numBits++; + } + + } +}; + +const decompressFromBase64 = function(input) { + return _decompress(input.length, 32, function(index) { + return getBaseValue(keyStrBase64, input.charAt(index)); + }); +}; + +module.exports = function(input) { + if (input === null || input === '' || typeof input === 'undefined') { + return ''; + } + return decompressFromBase64(input); +}; diff --git a/node_modules/lz-utils/lib/deflate-sync.js b/node_modules/lz-utils/lib/deflate-sync.js new file mode 100644 index 0000000..d962e41 --- /dev/null +++ b/node_modules/lz-utils/lib/deflate-sync.js @@ -0,0 +1,9 @@ +const zlib = require('zlib'); +module.exports = (str) => { + const buf = Buffer.from(str); + const length = buf.length; + const buffer = zlib.deflateRawSync(buf); + const b64 = buffer.toString('base64'); + const result = `${b64}.${length}`; + return result; +}; diff --git a/node_modules/lz-utils/lib/deflate.js b/node_modules/lz-utils/lib/deflate.js new file mode 100644 index 0000000..1a0f32d --- /dev/null +++ b/node_modules/lz-utils/lib/deflate.js @@ -0,0 +1,16 @@ +const zlib = require('zlib'); +module.exports = (str) => { + return new Promise((resolve) => { + const buf = Buffer.from(str); + const length = buf.length; + zlib.deflateRaw(buf, (err, buffer) => { + if (err) { + resolve(); + return; + } + const b64 = buffer.toString('base64'); + const result = `${b64}.${length}`; + resolve(result); + }); + }); +}; diff --git a/node_modules/lz-utils/lib/index.d.ts b/node_modules/lz-utils/lib/index.d.ts new file mode 100644 index 0000000..c9f4f93 --- /dev/null +++ b/node_modules/lz-utils/lib/index.d.ts @@ -0,0 +1,14 @@ +declare namespace LZ { + function compress(input: string): string; + function decompress(input: string): string; + + function deflateSync(input: string): string; + function deflate(input: string): Promise; + + function inflateSync(input: string): string; + function inflate(input: string): Promise; + + function createScriptLoader(input: string): string; +} + +export = LZ \ No newline at end of file diff --git a/node_modules/lz-utils/lib/index.js b/node_modules/lz-utils/lib/index.js new file mode 100644 index 0000000..c1eb63c --- /dev/null +++ b/node_modules/lz-utils/lib/index.js @@ -0,0 +1,9 @@ +module.exports = { + compress: require('./compress.js'), + decompress: require('./decompress.js'), + deflate: require('./deflate.js'), + inflate: require('./inflate.js'), + deflateSync: require('./deflate-sync.js'), + inflateSync: require('./inflate-sync.js'), + createScriptLoader: require('./create-script-loader.js') +}; diff --git a/node_modules/lz-utils/lib/index.mjs b/node_modules/lz-utils/lib/index.mjs new file mode 100644 index 0000000..eca2d8a --- /dev/null +++ b/node_modules/lz-utils/lib/index.mjs @@ -0,0 +1,19 @@ +import compress from './compress.js'; +import decompress from './decompress.js'; + +import deflate from './deflate.js'; +import inflate from './inflate.js'; + +import deflateSync from './deflate-sync.js'; +import inflateSync from './inflate-sync.js'; + +export { + compress, + decompress, + + deflate, + inflate, + + deflateSync, + inflateSync +}; diff --git a/node_modules/lz-utils/lib/inflate-sync.js b/node_modules/lz-utils/lib/inflate-sync.js new file mode 100644 index 0000000..04b14ce --- /dev/null +++ b/node_modules/lz-utils/lib/inflate-sync.js @@ -0,0 +1,18 @@ +const inflate = require('tiny-inflate'); + +const base64ToUint8 = (str) => Uint8Array.from(atob(str), (c) => c.charCodeAt(0)); + +const uint8ArrToString = (uint8arr) => new TextDecoder().decode(uint8arr); + +module.exports = function(compressedB64) { + if (compressedB64) { + const [b64Str, sizeStr] = compressedB64.split('.'); + if (b64Str && sizeStr) { + const compressedBuffer = base64ToUint8(b64Str); + const outputBuffer = new Uint8Array(parseInt(sizeStr)); + inflate(compressedBuffer, outputBuffer); + return uint8ArrToString(outputBuffer); + } + } +}; + diff --git a/node_modules/lz-utils/lib/inflate-worker.js b/node_modules/lz-utils/lib/inflate-worker.js new file mode 100644 index 0000000..9d27bde --- /dev/null +++ b/node_modules/lz-utils/lib/inflate-worker.js @@ -0,0 +1,5 @@ +const inflateSync = require('./inflate-sync.js'); +onmessage = function(e) { + postMessage(inflateSync(e.data)); +}; +postMessage('workerReady'); diff --git a/node_modules/lz-utils/lib/inflate.js b/node_modules/lz-utils/lib/inflate.js new file mode 100644 index 0000000..9493797 --- /dev/null +++ b/node_modules/lz-utils/lib/inflate.js @@ -0,0 +1,22 @@ +const workerData = require('../dist/inflate-worker-data.js'); +module.exports = (compressedB64) => { + return new Promise((resolve) => { + const worker = new Worker(URL.createObjectURL(new Blob([workerData], { + type: 'application/javascript' + }))); + worker.onmessage = (e) => { + if (e.data === 'workerReady') { + worker.postMessage(compressedB64); + return; + } + resolve(e.data); + worker.terminate(); + }; + worker.onerror = (err) => { + resolve({ + error: err + }); + worker.terminate(); + }; + }); +}; diff --git a/node_modules/lz-utils/lib/script-loader.js b/node_modules/lz-utils/lib/script-loader.js new file mode 100644 index 0000000..6144283 --- /dev/null +++ b/node_modules/lz-utils/lib/script-loader.js @@ -0,0 +1,6 @@ +const inflate = require('./inflate.js'); +inflate('{placeholder}').then((res) => { + const script = document.createElement('script'); + script.innerHTML = res; + document.body.appendChild(script); +}); diff --git a/node_modules/lz-utils/package.json b/node_modules/lz-utils/package.json new file mode 100644 index 0000000..8ecfd62 --- /dev/null +++ b/node_modules/lz-utils/package.json @@ -0,0 +1,51 @@ +{ + "name": "lz-utils", + "version": "2.1.0", + "description": "lz-utils", + "main": "./dist/index.js", + "browser": { + "lz-utils": "./dist/browser.js" + }, + "exports": { + ".": { + "types": "./lib/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js", + "default": "./dist/index.js" + }, + "./compress": "./dist/compress.js", + "./decompress": "./dist/decompress.js", + "./deflate": "./dist/deflate.js", + "./deflate-sync": "./dist/deflate-sync.js", + "./inflate": "./dist/inflate.js", + "./inflate-sync": "./dist/inflate-sync.js", + "./create-script-loader": "./dist/create-script-loader.js", + "./dist/*": "./dist/*", + "./lib/*": "./lib/*", + "./package.json": "./package.json" + }, + "types": "./lib/index.d.ts", + "scripts": { + "build": "node ./scripts/build.js", + "test": "node ./scripts/test.js", + "patch": "npm run build && sf publish patch -r" + }, + "files": [ + "dist", + "lib" + ], + "keywords": [ + "lz-utils" + ], + "license": "MIT", + "dependencies": {}, + "devDependencies": { + "babel-loader": "^9.1.3", + "eight-colors": "^1.3.0", + "esbuild": "^0.23.0", + "eslint": "^9.7.0", + "eslint-config-plus": "^2.0.2", + "eslint-plugin-html": "^8.1.1", + "tiny-inflate": "^1.0.3" + } +} diff --git a/node_modules/make-dir/index.d.ts b/node_modules/make-dir/index.d.ts new file mode 100644 index 0000000..3a78251 --- /dev/null +++ b/node_modules/make-dir/index.d.ts @@ -0,0 +1,66 @@ +/// +import * as fs from 'fs'; + +declare namespace makeDir { + interface Options { + /** + Directory [permissions](https://x-team.com/blog/file-system-permissions-umask-node-js/). + + @default 0o777 + */ + readonly mode?: number; + + /** + Use a custom `fs` implementation. For example [`graceful-fs`](https://github.com/isaacs/node-graceful-fs). + + Using a custom `fs` implementation will block the use of the native `recursive` option if `fs.mkdir` or `fs.mkdirSync` is not the native function. + + @default require('fs') + */ + readonly fs?: typeof fs; + } +} + +declare const makeDir: { + /** + Make a directory and its parents if needed - Think `mkdir -p`. + + @param path - Directory to create. + @returns The path to the created directory. + + @example + ``` + import makeDir = require('make-dir'); + + (async () => { + const path = await makeDir('unicorn/rainbow/cake'); + + console.log(path); + //=> '/Users/sindresorhus/fun/unicorn/rainbow/cake' + + // Multiple directories: + const paths = await Promise.all([ + makeDir('unicorn/rainbow'), + makeDir('foo/bar') + ]); + + console.log(paths); + // [ + // '/Users/sindresorhus/fun/unicorn/rainbow', + // '/Users/sindresorhus/fun/foo/bar' + // ] + })(); + ``` + */ + (path: string, options?: makeDir.Options): Promise; + + /** + Synchronously make a directory and its parents if needed - Think `mkdir -p`. + + @param path - Directory to create. + @returns The path to the created directory. + */ + sync(path: string, options?: makeDir.Options): string; +}; + +export = makeDir; diff --git a/node_modules/make-dir/index.js b/node_modules/make-dir/index.js new file mode 100644 index 0000000..2c0814e --- /dev/null +++ b/node_modules/make-dir/index.js @@ -0,0 +1,155 @@ +'use strict'; +const fs = require('fs'); +const path = require('path'); +const {promisify} = require('util'); +const semverGte = require('semver/functions/gte'); + +const useNativeRecursiveOption = semverGte(process.version, '10.12.0'); + +// https://github.com/nodejs/node/issues/8987 +// https://github.com/libuv/libuv/pull/1088 +const checkPath = pth => { + if (process.platform === 'win32') { + const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path.parse(pth).root, '')); + + if (pathHasInvalidWinCharacters) { + const error = new Error(`Path contains invalid characters: ${pth}`); + error.code = 'EINVAL'; + throw error; + } + } +}; + +const processOptions = options => { + const defaults = { + mode: 0o777, + fs + }; + + return { + ...defaults, + ...options + }; +}; + +const permissionError = pth => { + // This replicates the exception of `fs.mkdir` with native the + // `recusive` option when run on an invalid drive under Windows. + const error = new Error(`operation not permitted, mkdir '${pth}'`); + error.code = 'EPERM'; + error.errno = -4048; + error.path = pth; + error.syscall = 'mkdir'; + return error; +}; + +const makeDir = async (input, options) => { + checkPath(input); + options = processOptions(options); + + const mkdir = promisify(options.fs.mkdir); + const stat = promisify(options.fs.stat); + + if (useNativeRecursiveOption && options.fs.mkdir === fs.mkdir) { + const pth = path.resolve(input); + + await mkdir(pth, { + mode: options.mode, + recursive: true + }); + + return pth; + } + + const make = async pth => { + try { + await mkdir(pth, options.mode); + + return pth; + } catch (error) { + if (error.code === 'EPERM') { + throw error; + } + + if (error.code === 'ENOENT') { + if (path.dirname(pth) === pth) { + throw permissionError(pth); + } + + if (error.message.includes('null bytes')) { + throw error; + } + + await make(path.dirname(pth)); + + return make(pth); + } + + try { + const stats = await stat(pth); + if (!stats.isDirectory()) { + throw new Error('The path is not a directory'); + } + } catch { + throw error; + } + + return pth; + } + }; + + return make(path.resolve(input)); +}; + +module.exports = makeDir; + +module.exports.sync = (input, options) => { + checkPath(input); + options = processOptions(options); + + if (useNativeRecursiveOption && options.fs.mkdirSync === fs.mkdirSync) { + const pth = path.resolve(input); + + fs.mkdirSync(pth, { + mode: options.mode, + recursive: true + }); + + return pth; + } + + const make = pth => { + try { + options.fs.mkdirSync(pth, options.mode); + } catch (error) { + if (error.code === 'EPERM') { + throw error; + } + + if (error.code === 'ENOENT') { + if (path.dirname(pth) === pth) { + throw permissionError(pth); + } + + if (error.message.includes('null bytes')) { + throw error; + } + + make(path.dirname(pth)); + return make(pth); + } + + try { + if (!options.fs.statSync(pth).isDirectory()) { + throw new Error('The path is not a directory'); + } + } catch { + throw error; + } + } + + return pth; + }; + + return make(path.resolve(input)); +}; diff --git a/node_modules/make-dir/license b/node_modules/make-dir/license new file mode 100644 index 0000000..fa7ceba --- /dev/null +++ b/node_modules/make-dir/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +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/node_modules/make-dir/package.json b/node_modules/make-dir/package.json new file mode 100644 index 0000000..db305b1 --- /dev/null +++ b/node_modules/make-dir/package.json @@ -0,0 +1,63 @@ +{ + "name": "make-dir", + "version": "4.0.0", + "description": "Make a directory and its parents if needed - Think `mkdir -p`", + "license": "MIT", + "repository": "sindresorhus/make-dir", + "funding": "https://github.com/sponsors/sindresorhus", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://sindresorhus.com" + }, + "engines": { + "node": ">=10" + }, + "scripts": { + "test": "xo && nyc ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "mkdir", + "mkdirp", + "make", + "directories", + "folders", + "directory", + "folder", + "path", + "parent", + "parents", + "intermediate", + "recursively", + "recursive", + "create", + "fs", + "filesystem", + "file-system" + ], + "dependencies": { + "semver": "^7.5.3" + }, + "devDependencies": { + "@types/graceful-fs": "^4.1.3", + "@types/node": "^14.14.6", + "ava": "^2.4.0", + "codecov": "^3.2.0", + "graceful-fs": "^4.1.15", + "nyc": "^15.0.0", + "path-type": "^4.0.0", + "tempy": "^1.0.0", + "tsd": "^0.13.1", + "xo": "^0.34.2" + }, + "nyc": { + "reporter": [ + "text", + "lcov" + ] + } +} diff --git a/node_modules/make-dir/readme.md b/node_modules/make-dir/readme.md new file mode 100644 index 0000000..13fa8fd --- /dev/null +++ b/node_modules/make-dir/readme.md @@ -0,0 +1,125 @@ +# make-dir [![codecov](https://codecov.io/gh/sindresorhus/make-dir/branch/main/graph/badge.svg)](https://codecov.io/gh/sindresorhus/make-dir) + +> Make a directory and its parents if needed - Think `mkdir -p` + +## Advantages over [`mkdirp`](https://github.com/substack/node-mkdirp) + +- Promise API *(Async/await ready!)* +- Fixes many `mkdirp` issues: [#96](https://github.com/substack/node-mkdirp/pull/96) [#70](https://github.com/substack/node-mkdirp/issues/70) [#66](https://github.com/substack/node-mkdirp/issues/66) +- 100% test coverage +- CI-tested on macOS, Linux, and Windows +- Actively maintained +- Doesn't bundle a CLI +- Uses the native `fs.mkdir/mkdirSync` [`recursive` option](https://nodejs.org/dist/latest/docs/api/fs.html#fs_fs_mkdir_path_options_callback) in Node.js >=10.12.0 unless [overridden](#fs) + +## Install + +``` +$ npm install make-dir +``` + +## Usage + +``` +$ pwd +/Users/sindresorhus/fun +$ tree +. +``` + +```js +const makeDir = require('make-dir'); + +(async () => { + const path = await makeDir('unicorn/rainbow/cake'); + + console.log(path); + //=> '/Users/sindresorhus/fun/unicorn/rainbow/cake' +})(); +``` + +``` +$ tree +. +└── unicorn + └── rainbow + └── cake +``` + +Multiple directories: + +```js +const makeDir = require('make-dir'); + +(async () => { + const paths = await Promise.all([ + makeDir('unicorn/rainbow'), + makeDir('foo/bar') + ]); + + console.log(paths); + /* + [ + '/Users/sindresorhus/fun/unicorn/rainbow', + '/Users/sindresorhus/fun/foo/bar' + ] + */ +})(); +``` + +## API + +### makeDir(path, options?) + +Returns a `Promise` for the path to the created directory. + +### makeDir.sync(path, options?) + +Returns the path to the created directory. + +#### path + +Type: `string` + +Directory to create. + +#### options + +Type: `object` + +##### mode + +Type: `integer`\ +Default: `0o777` + +Directory [permissions](https://x-team.com/blog/file-system-permissions-umask-node-js/). + +##### fs + +Type: `object`\ +Default: `require('fs')` + +Use a custom `fs` implementation. For example [`graceful-fs`](https://github.com/isaacs/node-graceful-fs). + +Using a custom `fs` implementation will block the use of the native `recursive` option if `fs.mkdir` or `fs.mkdirSync` is not the native function. + +## Related + +- [make-dir-cli](https://github.com/sindresorhus/make-dir-cli) - CLI for this module +- [del](https://github.com/sindresorhus/del) - Delete files and directories +- [globby](https://github.com/sindresorhus/globby) - User-friendly glob matching +- [cpy](https://github.com/sindresorhus/cpy) - Copy files +- [cpy-cli](https://github.com/sindresorhus/cpy-cli) - Copy files on the command-line +- [move-file](https://github.com/sindresorhus/move-file) - Move a file + +--- + +
+ + Get professional support for this package with a Tidelift subscription + +
+ + Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. +
+
diff --git a/node_modules/monocart-coverage-reports/LICENSE b/node_modules/monocart-coverage-reports/LICENSE new file mode 100644 index 0000000..513af51 --- /dev/null +++ b/node_modules/monocart-coverage-reports/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 cenfun + +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/node_modules/monocart-coverage-reports/README.md b/node_modules/monocart-coverage-reports/README.md new file mode 100644 index 0000000..be9db15 --- /dev/null +++ b/node_modules/monocart-coverage-reports/README.md @@ -0,0 +1,1186 @@ +# Monocart Coverage Reports + +[![npm](https://img.shields.io/npm/v/monocart-coverage-reports)](https://www.npmjs.com/package/monocart-coverage-reports) +![license](https://img.shields.io/github/license/cenfun/monocart-coverage-reports) +![build](https://img.shields.io/github/actions/workflow/status/cenfun/monocart-coverage-reports/ci.yml) +[![install size](https://packagephobia.com/badge?p=monocart-coverage-reports)](https://packagephobia.com/result?p=monocart-coverage-reports) +[![npm graph](https://img.shields.io/badge/npm-graph-blue)](https://npmgraph.js.org/?q=monocart-coverage-reports) +![dependencies](https://img.shields.io/librariesio/github/cenfun/monocart-coverage-reports) +[![downloads](https://devimg.vercel.app/npm/downloads/monocart-coverage-reports?label={total}%20downloads/month)](https://www.npmjs.com/package/monocart-coverage-reports) + +🌐 English | [简体中文](README.zh-Hans.md) + +> A JavaScript code coverage tool to generate native [V8](https://v8.dev/blog/javascript-code-coverage) reports or [Istanbul](https://istanbul.js.org/) reports. + +* [Usage](#usage) +* [Options](#options) +* [Available Reports](#available-reports) +* [Compare Reports](#compare-reports) +* [Collecting Istanbul Coverage Data](#collecting-istanbul-coverage-data) +* [Collecting V8 Coverage Data](#collecting-v8-coverage-data) + - [Collecting V8 Coverage Data with Playwright](#collecting-v8-coverage-data-with-playwright) + - [Collecting Raw V8 Coverage Data with Puppeteer](#collecting-raw-v8-coverage-data-with-puppeteer) + - [Collecting V8 Coverage Data from Node.js](#collecting-v8-coverage-data-from-nodejs) + - [Collecting V8 Coverage Data with `CDPClient` API](#collecting-v8-coverage-data-with-cdpclient-api) + - [V8 Coverage Data API](#v8-coverage-data-api) +* [Filtering Results](#filtering-results) +* [Resolve `sourcePath` for the Source Files](#resolve-sourcepath-for-the-source-files) +* [Adding Empty Coverage for Untested Files](#adding-empty-coverage-for-untested-files) +* [onEnd Hook](#onend-hook) +* [Ignoring Uncovered Codes](#ignoring-uncovered-codes) +* [Multiprocessing Support](#multiprocessing-support) +* [Command Line](#command-line) +* [Config File](#config-file) +* [Merge Coverage Reports](#merge-coverage-reports) + - [Automatic Merging](#automatic-merging) + - [Manual Merging](#manual-merging) +* [Common issues](#common-issues) + - [Unexpected coverage](#unexpected-coverage) + - [Unparsable source](#unparsable-source) + - [JavaScript heap out of memory](#javascript-heap-out-of-memory) +* [Debug for Coverage and Sourcemap](#debug-for-coverage-and-sourcemap) +* [Integration with Any Testing Framework](#integration-with-any-testing-framework) +* [Integration Examples](#integration-examples) + - [Playwright](#playwright) + - [c8](#c8) + - [CodeceptJS](#codeceptjs) + - [VSCode](#vscode) + - [Jest](#jest) + - [Vitest](#vitest) + - [Node Test Runner](#node-test-runner) + - [Puppeteer](#puppeteer) + - [Cypress](#cypress) + - [WebdriverIO](#webdriverio) + - [Storybook Test Runner](#storybook-test-runner) + - [TestCafe](#testcafe) + - [Selenium Webdriver](#selenium-webdriver) + - [Mocha](#mocha) + - [TypeScript](#typescript) + - [AVA](#ava) + - [Codecov](#codecov) + - [Codacy](#codacy) + - [Coveralls](#coveralls) + - [Sonar Cloud](#sonar-cloud) +* [Contributing](#contributing) +* [Changelog](CHANGELOG.md) +* [Thanks](#thanks) + +## Usage +> It's recommended to use [Node.js 20+](https://nodejs.org/). +- Install +```sh +npm install monocart-coverage-reports +``` +- API +```js +const MCR = require('monocart-coverage-reports'); +const mcr = MCR({ + name: 'My Coverage Report - 2024-02-28', + outputDir: './coverage-reports', + reports: ["v8", "console-details"], + cleanCache: true +}); +await mcr.add(coverageData); +await mcr.generate(); +``` +Using `import` and load options from [config file](#config-file) +```js +import { CoverageReport } from 'monocart-coverage-reports'; +const mcr = new CoverageReport(); +await mcr.loadConfig(); +``` +For more information, see [Multiprocessing Support](#multiprocessing-support) + +- CLI +```sh +mcr node my-app.js -r v8,console-details +``` +For more information, see [Command Line](#command-line) + +## Options +- Default options: [lib/default/options.js](./lib/default/options.js) +- Options declaration see `CoverageReportOptions` [lib/index.d.ts](./lib/index.d.ts) +- [Config file](#config-file) + +## Available Reports + +> V8 build-in reports (V8 data only): + +- `v8` + - Features: + - A Brand-New V8 Coverage Report User Interface + - Support for Native Byte Statistics + - Support processing big data with high performance + - Coverage for Any Runtime Code + - CSS Coverage Support + - Better Support for Sourcemap Conversion + - Demos: [V8](https://cenfun.github.io/monocart-coverage-reports/v8) and [more](https://cenfun.github.io/monocart-coverage-reports/) + +![](./assets/v8.gif) + +- `v8-json` + - Save `CoverageResults` to a json file (defaults to [`coverage-report.json`](https://cenfun.github.io/monocart-coverage-reports/v8-and-istanbul/coverage-report.json)). + - Shows native V8 code coverage with VSCode extension: [Monocart Coverage for VSCode](https://github.com/cenfun/monocart-coverage-vscode) + +![](./assets/mcv.gif) + +> Istanbul build-in reports (both V8 and Istanbul data): + +- `clover` +- `cobertura` +- `html` + - [Istanbul html](https://cenfun.github.io/monocart-coverage-reports/istanbul/) + - [V8 to Istanbul](https://cenfun.github.io/monocart-coverage-reports/v8-and-istanbul/istanbul) +- `html-spa` +- `json` +- `json-summary` +- `lcov` +- `lcovonly` + - [V8 lcov.info](https://cenfun.github.io/monocart-coverage-reports/v8/lcov.info) + - [Istanbul lcov.info](https://cenfun.github.io/monocart-coverage-reports/istanbul/lcov.info) +- `none` +- `teamcity` +- `text` +- `text-lcov` +- `text-summary` + +> Other build-in reports (both V8 and Istanbul data): + +- `codecov` Save coverage data to a json file with [Codecov](https://docs.codecov.com/docs/codecov-custom-coverage-format) format (defaults to `codecov.json`), see [example](https://app.codecov.io/github/cenfun/monocart-coverage-reports). + +- `codacy` Save coverage data to a json file with [Codacy API](https://api.codacy.com/swagger#tocscoveragereport) format (defaults to `codacy.json`). + +- `console-summary` shows coverage summary in the console. + +![](./assets/console-summary.png) + +- `console-details` Show coverage details in the console. Like `text`, but for V8. For Github actions, we can enforce color with env: `FORCE_COLOR: true`. + +![](./assets/console-details.png) + +- `markdown-summary` Save coverage summary to a markdown file (defaults to `coverage-summary.md`). For Github actions, we can show the markdown content to [a job summary](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary) +```sh +cat path-to/coverage-summary.md >> $GITHUB_STEP_SUMMARY +``` +![](./assets/markdown-summary.png) + +- `markdown-details` Save coverage details to a markdown file (defaults to `coverage-details.md`). + - Preview in [runs](https://github.com/cenfun/monocart-coverage-reports/actions/workflows/ci.yml) + +- `raw` only keep all original data, which can be used for other reports input with `inputDir`. see [Merge Coverage Reports](#merge-coverage-reports) + +- Custom Reporter + ```js + { + reports: [ + [path.resolve('./test/custom-istanbul-reporter.js'), { + type: 'istanbul', + file: 'custom-istanbul-coverage.text' + }], + [path.resolve('./test/custom-v8-reporter.js'), { + type: 'v8', + outputFile: 'custom-v8-coverage.json' + }], + [path.resolve('./test/custom-v8-reporter.mjs'), { + type: 'both' + }] + ] + } + ``` + - Istanbul custom reporter + > example: [./test/custom-istanbul-reporter.js](./test/custom-istanbul-reporter.js), see [istanbul built-in reporters' implementation](https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-reports/lib) for reference. + - V8 custom reporter + > example: [./test/custom-v8-reporter.js](./test/custom-v8-reporter.js) + +### Multiple Reports: +```js +const MCR = require('monocart-coverage-reports'); +const coverageOptions = { + outputDir: './coverage-reports', + reports: [ + // build-in reports + ['console-summary'], + ['v8'], + ['html', { + subdir: 'istanbul' + }], + ['json', { + file: 'my-json-file.json' + }], + 'lcovonly', + + // custom reports + // Specify reporter name with the NPM package + ["custom-reporter-1"], + ["custom-reporter-2", { + type: "istanbul", + key: "value" + }], + // Specify reporter name with local path + ['/absolute/path/to/custom-reporter.js'] + ] +} +const mcr = MCR(coverageOptions); +``` + +## Compare Reports +> If the V8 data format is used for Istanbul reports, it will be automatically converted from V8 to Istanbul. + +| | Istanbul | V8 | V8 to Istanbul | +| :--------------| :------ | :------ | :---------------------- | +| Coverage data | [Istanbul](https://github.com/gotwarlost/istanbul/blob/master/coverage.json.md) (Object) | [V8](#v8-coverage-data-format) (Array) | [V8](#v8-coverage-data-format) (Array) | +| Output | [Istanbul reports](#available-reports) | [V8 reports](#available-reports) | [Istanbul reports](#available-reports) | +| - Bytes | ❌ | ✅ | ❌ | +| - Statements | ✅ | ✅ | ✅ | +| - Branches | ✅ | ✅ | ✅ | +| - Functions | ✅ | ✅ | ✅ | +| - Lines | ✅ | ✅ | ✅ | +| - Execution counts | ✅ | ✅ | ✅ | +| CSS coverage | ❌ | ✅ | ✅ | +| Minified code | ❌ | ✅ | ❌ | + +## Collecting Istanbul Coverage Data +- Before coverage collection: Instrumenting source code with Istanbul + - webpack with babel loader: [babel-plugin-istanbul](https://github.com/istanbuljs/babel-plugin-istanbul), see example: [webpack.config-istanbul.js](./test/build/webpack.config-istanbul.js) + - CLI: [nyc instrument](https://github.com/istanbuljs/nyc/blob/master/docs/instrument.md) or API: [istanbul-lib-instrument](https://github.com/istanbuljs/istanbuljs/blob/main/packages/istanbul-lib-instrument/api.md) + - vite: [vite-plugin-istanbul](https://github.com/ifaxity/vite-plugin-istanbul) + - rollup: [rollup-plugin-istanbul](https://github.com/artberri/rollup-plugin-istanbul) + - swc: [swc-plugin-coverage-instrument](https://github.com/kwonoj/swc-plugin-coverage-instrument) + +- Browser + - Collecting coverage data from `window.__coverage__`, example: [test-istanbul.js](./test/test-istanbul.js) + +- Node.js + - Collecting coverage data from `global.__coverage__` + +- CDP + - `getIstanbulCoverage()` see [`CDPClient` API](#collecting-v8-coverage-data-with-cdpclient-api) + +## Collecting V8 Coverage Data +- Before coverage collection: Enabling `sourcemap` for source code + - [webpack](https://webpack.js.org/configuration/): `devtool: source-map` and `mode: development`, example [webpack.config-v8.js](./test/build/webpack.config-v8.js) + - [rollup](https://rollupjs.org/configuration-options/): `sourcemap: true` and `treeshake: false` + - [esbuild](https://esbuild.github.io/api/): `sourcemap: true`, `treeShaking: false` and `minify: false` + - [vite](https://vitejs.dev/config/build-options.html): `sourcemap: true` and `minify: false` + +- Browser (Chromium-based Only) + - [Collecting V8 Coverage Data with Playwright](#collecting-v8-coverage-data-with-playwright) + - [Collecting Raw V8 Coverage Data with Puppeteer](#collecting-raw-v8-coverage-data-with-puppeteer) + +- Node.js + - [Collecting V8 Coverage Data from Node.js](#collecting-v8-coverage-data-from-nodejs) + +- CDP + - [Collecting V8 Coverage Data with `CDPClient` API](#collecting-v8-coverage-data-with-cdpclient-api) + +### Collecting V8 Coverage Data with Playwright +```js +await Promise.all([ + page.coverage.startJSCoverage({ + // reportAnonymousScripts: true, + resetOnNavigation: false + }), + page.coverage.startCSSCoverage({ + // Note, anonymous styles (without sourceURLs) are not supported, alternatively, you can use CDPClient + resetOnNavigation: false + }) +]); + +await page.goto("your page url"); + +const [jsCoverage, cssCoverage] = await Promise.all([ + page.coverage.stopJSCoverage(), + page.coverage.stopCSSCoverage() +]); + +const coverageData = [... jsCoverage, ... cssCoverage]; + +``` +Collect coverage with `@playwright/test` [`Automatic fixtures`](https://playwright.dev/docs/test-fixtures#automatic-fixtures), see example: [fixtures.ts](https://github.com/cenfun/playwright-coverage/blob/main/fixtures.ts) +For more examples, see [./test/test-v8.js](./test/test-v8.js), [css](./test/test-css.js) + + +### Collecting Raw V8 Coverage Data with Puppeteer +```js +await Promise.all([ + page.coverage.startJSCoverage({ + // reportAnonymousScripts: true, + resetOnNavigation: false, + // provide raw v8 coverage data + includeRawScriptCoverage: true + }), + page.coverage.startCSSCoverage({ + resetOnNavigation: false + }) +]); + +await page.goto("your page url"); + +const [jsCoverage, cssCoverage] = await Promise.all([ + page.coverage.stopJSCoverage(), + page.coverage.stopCSSCoverage() +]); + +// to raw V8 script coverage +const coverageData = [... jsCoverage.map((it) => { + return { + source: it.text, + ... it.rawScriptCoverage + }; +}), ... cssCoverage]; +``` +Example: [./test/test-puppeteer.js](./test/test-puppeteer.js) + +### Collecting V8 Coverage Data from Node.js +Possible solutions: +- [NODE_V8_COVERAGE](https://nodejs.org/docs/latest/api/cli.html#node_v8_coveragedir)=`dir` + - Sets Node.js env `NODE_V8_COVERAGE`=`dir` before the program running, the coverage data will be saved to the `dir` after the program exits gracefully. + - Read the JSON file(s) from the `dir` and generate coverage report. + - Example: + > cross-env NODE_V8_COVERAGE=`.temp/v8-coverage-env` node [./test/test-node-env.js](./test/test-node-env.js) && node [./test/generate-report.js](./test/generate-report.js) + +- [V8](https://nodejs.org/docs/latest/api/v8.html#v8takecoverage) API + NODE_V8_COVERAGE + - Writing the coverage started by NODE_V8_COVERAGE to disk on demand with `v8.takeCoverage()`, it does not require waiting until the program exits gracefully. + - Example: + > cross-env NODE_V8_COVERAGE=`.temp/v8-coverage-api` node [./test/test-node-api.js](./test/test-node-api.js) + +- [Inspector](https://nodejs.org/docs/latest/api/inspector.html) API + - Connecting to the V8 inspector and enable V8 coverage. + - Taking coverage data and adding it to the report. + - Example: + > node [./test/test-node-ins.js](./test/test-node-ins.js) + - vm Example (scriptOffset): + > node [./test/test-node-vm.js](./test/test-node-vm.js) + +- [CDP](https://chromedevtools.github.io/devtools-protocol/) API + - Enabling [Node Debugging](https://nodejs.org/en/guides/debugging-getting-started/). + - Collecting coverage data with CDP API. + - Example: + > node --inspect=9229 [./test/test-node-cdp.js](./test/test-node-cdp.js) + +- [Node Debugging](https://nodejs.org/en/guides/debugging-getting-started) + CDP + NODE_V8_COVERAGE + V8 API + - When the program starts a server, it will not exit on its own, thus requiring a manual invocation of the `v8.takeCoverage()` interface to manually collect coverage data. Remote invocation of the `v8.takeCoverage()` interface can be accomplished through the `Runtime.evaluate` of the CDP. + - Example for [koa](https://github.com/koajs/koa) web server: + > node [./test/test-node-koa.js](./test/test-node-koa.js) + +- [Child Process](https://nodejs.org/docs/latest/api/child_process.html) + NODE_V8_COVERAGE + - see [Command Line](#command-line) + +### Collecting V8 Coverage Data with `CDPClient` API +- `CDPClient` available APIs +```js +startJSCoverage: () => Promise; +stopJSCoverage: () => Promise; + +startCSSCoverage: () => Promise; +stopCSSCoverage: () => Promise; + +/** start both js and css coverage */ +startCoverage: () => Promise; +/** stop and return both js and css coverage */ +stopCoverage: () => Promise; + +/** write the coverage started by NODE_V8_COVERAGE to disk on demand, returns v8 coverage dir */ +writeCoverage: () => Promise; + +/** get istanbul coverage data */ +getIstanbulCoverage: (coverageKey?: string) => Promise; +``` + +- Work with node debugger port `--inspect=9229` or browser debugging port `--remote-debugging-port=9229` +```js +const MCR = require('monocart-coverage-reports'); +const client = await MCR.CDPClient({ + port: 9229 +}); +await client.startJSCoverage(); +// run your test here +const coverageData = await client.stopJSCoverage(); +``` + +- Work with [Playwright CDPSession](https://playwright.dev/docs/api/class-cdpsession) +```js +const { chromium } = require('playwright'); +const MCR = require('monocart-coverage-reports'); +const browser = await chromium.launch(); +const page = await browser.newPage(); +const session = await page.context().newCDPSession(page); +const client = await MCR.CDPClient({ + session +}); +// both js and css coverage +await client.startCoverage(); +// run your test page here +await page.goto("your page url"); +const coverageData = await client.stopCoverage(); +``` + +- Work with [Puppeteer CDPSession](https://pptr.dev/api/puppeteer.cdpsession) +```js +const puppeteer = require('puppeteer'); +const MCR = require('monocart-coverage-reports'); +const browser = await puppeteer.launch({}); +const page = await browser.newPage(); +const session = await page.target().createCDPSession(); +const client = await MCR.CDPClient({ + session +}); +// both js and css coverage +await client.startCoverage(); +// run your test page here +await page.goto("your page url"); +const coverageData = await client.stopCoverage(); +``` + +- Work with [Selenium Webdriver](https://www.selenium.dev/documentation/webdriver/) WebSocket (Chrome/Edge Browser) +```js +const { Builder, Browser } = require('selenium-webdriver'); +const MCR = require('monocart-coverage-reports'); +const driver = await new Builder().forBrowser(Browser.CHROME).build(); +const pageCdpConnection = await driver.createCDPConnection('page'); +const session = new MCR.WSSession(pageCdpConnection._wsConnection); +const client = await MCR.CDPClient({ + session +}) +``` + +### V8 Coverage Data API +- [JavaScript code coverage in V8](https://v8.dev/blog/javascript-code-coverage) +- [Playwright Coverage Class](https://playwright.dev/docs/api/class-coverage) +- [Puppeteer Coverage Class](https://pptr.dev/api/puppeteer.coverage) +- [DevTools Protocol for Coverage](https://chromedevtools.github.io/devtools-protocol/tot/Profiler/#method-startPreciseCoverage) see [ScriptCoverage](https://chromedevtools.github.io/devtools-protocol/tot/Profiler/#type-ScriptCoverage) and [v8-coverage](https://github.com/bcoe/v8-coverage) +```js +// Coverage data for a source range. +export interface CoverageRange { + // JavaScript script source offset for the range start. + startOffset: integer; + // JavaScript script source offset for the range end. + endOffset: integer; + // Collected execution count of the source range. + count: integer; +} +// Coverage data for a JavaScript function. +/** + * @functionName can be an empty string. + * @ranges is always non-empty. The first range is called the "root range". + * @isBlockCoverage indicates if the function has block coverage information. + If this is false, it usually means that the functions was never called. + It seems to be equivalent to ranges.length === 1 && ranges[0].count === 0. +*/ +export interface FunctionCoverage { + // JavaScript function name. + functionName: string; + // Source ranges inside the function with coverage data. + ranges: CoverageRange[]; + // Whether coverage data for this function has block granularity. + isBlockCoverage: boolean; +} +// Coverage data for a JavaScript script. +export interface ScriptCoverage { + // JavaScript script id. + scriptId: Runtime.ScriptId; + // JavaScript script name or url. + url: string; + // Functions contained in the script that has coverage data. + functions: FunctionCoverage[]; +} +export type V8CoverageData = ScriptCoverage[]; +``` + +| JavaScript Runtime | V8 Coverage | | +| :--------------| :----: | :---------------------- | +| Chrome (65%) | ✅ | Chromium-based | +| Safari (18%) | ❌ | | +| Edge (5%) | ✅ | Chromium-based | +| Firefox (2%) | ❌ | | +| Node.js | ✅ | | +| Deno | ❌ | [issue](https://github.com/denoland/deno/issues/23359) | +| Bun | ❌ | | + +## Filtering Results +### Using `entryFilter` and `sourceFilter` to filter the results for V8 report +When V8 coverage data collected, it actually contains the data of all entry files, for example: + +- *dist/main.js* +- *dist/vendor.js* +- *dist/something-else.js* + +We can use `entryFilter` to filter the entry files. For example, we should remove `vendor.js` and `something-else.js` if they are not in our coverage scope. + +- *dist/main.js* + +When inline or linked sourcemap exists to the entry file, the source files will be extracted from the sourcemap for the entry file, and the entry file will be removed if `logging` is not `debug`. + +- *src/index.js* +- *src/components/app.js* +- *node_modules/dependency/dist/dependency.js* + +We can use `sourceFilter` to filter the source files. For example, we should remove `dependency.js` if it is not in our coverage scope. + +- *src/index.js* +- *src/components/app.js* + +For example: +```js +const coverageOptions = { + entryFilter: (entry) => entry.url.indexOf("main.js") !== -1, + sourceFilter: (sourcePath) => sourcePath.search(/src\//) !== -1 +}; +``` +Or using [`minimatch`](https://github.com/isaacs/minimatch) pattern: +```js +const coverageOptions = { + entryFilter: "**/main.js", + sourceFilter: "**/src/**" +}; +``` +Support multiple patterns: +```js +const coverageOptions = { + entryFilter: { + '**/node_modules/**': false, + '**/vendor.js': false, + '**/src/**': true + }, + sourceFilter: { + '**/node_modules/**': false, + '**/**': true + } +}; +``` +As CLI args (JSON-like string. Added in: v2.8): +```sh +mcr --sourceFilter "{'**/node_modules/**':false,'**/**':true}" +``` +Note, those patterns will be transformed to a function, and the order of the patterns will impact the results: +```js +const coverageOptions = { + entryFilter: (entry) => { + if (minimatch(entry.url, '**/node_modules/**')) { return false; } + if (minimatch(entry.url, '**/vendor.js')) { return false; } + if (minimatch(entry.url, '**/src/**')) { return true; } + return false; // else unmatched + } +}; +``` + +### Using `filter` instead of `entryFilter` and `sourceFilter` +If you don't want to define both `entryFilter` and `sourceFilter`, you can use `filter` instead. (Added in: v2.8) +```js +const coverageOptions = { + // combined patterns + filter: { + '**/node_modules/**': false, + '**/vendor.js': false, + '**/src/**': true + '**/**': true + } +}; +``` + +## Resolve `sourcePath` for the Source Files +If the source file comes from the sourcemap, then its path is a virtual path. Using the `sourcePath` option to resolve a custom path. +For example, we have tested multiple dist files, which contain some common files. We hope to merge the coverage of the same files, so we need to unify the `sourcePath` in order to be able to merge the coverage data. +```js +const coverageOptions = { + sourcePath: (filePath) => { + // Remove the virtual prefix + const list = ['my-dist-file1/', 'my-dist-file2/']; + for (const str of list) { + if (filePath.startsWith(str)) { + return filePath.slice(str.length); + } + } + return filePath; + } +}; +``` +It also supports simple key/value replacement: +```js +const coverageOptions = { + sourcePath: { + 'my-dist-file1/': '', + 'my-dist-file2/': '' + } +}; +``` +Normalize the full path of the file: +```js +const path = require("path") + +// MCR coverage options +const coverageOptions = { + sourcePath: (filePath, info)=> { + if (!filePath.includes('/') && info.distFile) { + return `${path.dirname(info.distFile)}/${filePath}`; + } + return filePath; + } +} +``` + +## Adding Empty Coverage for Untested Files +By default the untested files will not be included in the coverage report, we can add empty coverage for untested files with option `all`, the untested files will show 0% coverage. +```js +const coverageOptions = { + all: './src', + + // or multiple dirs + all: ['./src', './lib'], +}; +``` +The untested files will apply to the `sourceFilter`. And it also supports additional `filter` (return the file type for js or css coverage): +```js +const coverageOptions = { + all: { + dir: ['./src'], + filter: { + // exclude files + '**/ignored-*.js': false, + '**/*.html': false, + // empty css coverage + '**/*.scss': "css", + '**/*': true + } + } +}; +``` +We can also compile these untested files, such as .ts, .jsx, or .vue, etc., so that they can be analyzed by the default AST parser, thus get more coverage metric data. +```js +const path = require("path"); +const swc = require("@swc/core"); +const coverageOptions = { + all: { + dir: ['./src'], + transformer: async (entry) => { + const { code, map } = await swc.transform(entry.source, { + filename: path.basename(entry.url), + sourceMaps: true, + isModule: true, + jsc: { + parser: { + syntax: "typescript", + jsx: true + }, + transform: {} + } + }); + entry.source = code; + entry.sourceMap = JSON.parse(map); + } + } +}; +``` + +## onEnd Hook +For example, checking thresholds: +```js +const EC = require('eight-colors'); +const coverageOptions = { + name: 'My Coverage Report', + outputDir: './coverage-reports', + onEnd: (coverageResults) => { + const thresholds = { + bytes: 80, + lines: 60 + }; + console.log('check thresholds ...', thresholds); + const errors = []; + const { summary } = coverageResults; + Object.keys(thresholds).forEach((k) => { + const pct = summary[k].pct; + if (pct < thresholds[k]) { + errors.push(`Coverage threshold for ${k} (${pct} %) not met: ${thresholds[k]} %`); + } + }); + if (errors.length) { + const errMsg = errors.join('\n'); + console.log(EC.red(errMsg)); + // throw new Error(errMsg); + // process.exit(1); + } + } +} +``` + +## Ignoring Uncovered Codes +To ignore codes, use the special comment which starts with `v8 ignore `: +- Ignoring all until stop +```js +/* v8 ignore start */ +function uncovered() { +} +/* v8 ignore stop */ +``` +- Ignoring the next line or next N lines +```js +/* v8 ignore next */ +const os = platform === 'wind32' ? 'Windows' : 'Other'; + +const os = platform === 'wind32' ? 'Windows' /* v8 ignore next */ : 'Other'; + +// v8 ignore next 3 +if (platform === 'linux') { + console.log('hello linux'); +} +``` +- Compatible with [c8 coverage](https://github.com/bcoe/c8/?tab=readme-ov-file#ignoring-all-lines-until-told) or [nodejs coverage](https://nodejs.org/docs/latest/api/test.html#collecting-code-coverage) syntax +```js +/* c8 ignore start */ +function uncovered() { +} +/* c8 ignore stop */ + +/* node:coverage disable */ +function uncovered() { +} +/* node:coverage enable */ +``` + +## Multiprocessing Support +> The data will be added to `[outputDir]/.cache`, After the generation of the report, this data will be removed unless debugging has been enabled or a raw report has been used, see [Debug for Coverage and Sourcemap](#debug-for-coverage-and-sourcemap) +- Main process, before the start of testing +```js +const MCR = require('monocart-coverage-reports'); +const coverageOptions = require('path-to/same-options.js'); +const mcr = MCR(coverageOptions); +// clean previous cache before the start of testing +// unless the running environment is new and no cache +mcr.cleanCache(); +``` + +- Sub process 1, testing stage 1 +```js +const MCR = require('monocart-coverage-reports'); +const coverageOptions = require('path-to/same-options.js'); +const mcr = MCR(coverageOptions); +await mcr.add(coverageData1); +``` + +- Sub process 2, testing stage 2 +```js +const MCR = require('monocart-coverage-reports'); +const coverageOptions = require('path-to/same-options.js'); +const mcr = MCR(coverageOptions); +await mcr.add(coverageData2); +``` + +- Main process, after the completion of testing +```js +// generate coverage reports after the completion of testing +const MCR = require('monocart-coverage-reports'); +const coverageOptions = require('path-to/same-options.js'); +const mcr = MCR(coverageOptions); +await mcr.generate(); +``` + +## Command Line +> The CLI will run the program as a [child process](https://nodejs.org/docs/latest/api/child_process.html) with `NODE_V8_COVERAGE=dir` until it exits gracefully, and generate the coverage report with the coverage data from the `dir`. + +- Installing globally +```sh +npm i monocart-coverage-reports -g +mcr node ./test/specs/node.test.js -r v8,console-details --lcov +``` + +- Locally in your project +```sh +npm i monocart-coverage-reports +npx mcr node ./test/specs/node.test.js -r v8,console-details --lcov +``` + +- CLI Options +see all options with running `mcr` or `mcr --help` + +- Use `--` to separate sub CLI args +```sh +mcr -c mcr.config.js -- sub-cli -c sub-cli.config.js +``` + +- Examples + - [Mocha](#mocha) + - [TypeScript](#typescript) + - [AVA](#ava) + +## Config File +Loading config file by priority: +- Custom config file: + - CLI: `mcr --config ` + - API: `await mcr.loadConfig("my-config-file-path")` +- `mcr.config.js` +- `mcr.config.cjs` +- `mcr.config.mjs` +- `mcr.config.json` - json format +- `mcr.config.ts` (requires preloading the ts execution module) + +## Merge Coverage Reports +The following usage scenarios may require merging coverage reports: +- When the code is executed in different environments, like Node.js `server side` and browser `client side` (`Next.js` for instance). Each environment may generate its own coverage report. Merging them can give a more comprehensive view of the test coverage. +- When the code is subjected to different kinds of testing. For example, `unit tests` with `Jest` might cover certain parts of the code, while `end-to-end tests` with `Playwright` might cover other parts. Merging these different coverage reports can provide a holistic view of what code has been tested. +- When tests are run on different machines or containers, each might produce its own coverage report. Merging these can give a complete picture of the test coverage across all machines or shards. + +### Automatic Merging +- The `MCR` will automatically merge all the added coverage data when executing `generate()`. And it supports adding coverage data asynchronously across processes, see [Multiprocessing Support](#multiprocessing-support) +- For `Next.js`, it can actually add coverage data including both server side and client side before executing `generate()`, see example [nextjs-with-playwright](https://github.com/cenfun/nextjs-with-playwright) +- Using `Codecov`, a popular online code coverage service, which supports automatic merging of reports. Please use report `codecov`, it will generate report file `codecov.json`. If multiple `codecov.json` files are generated, upload all these files, they will be automatically merged. see [Codecov](#codecov) and [merging reports](https://docs.codecov.com/docs/merging-reports) + +### Manual Merging +If the reports cannot be merged automatically, then here is how to manually merge the reports. +First, using the `raw` report to export the original coverage data to the specified directory. +- For example, we have `raw` coverage data from `unit test`, which is output to `./coverage-reports/unit/raw`. Unit test examples: + - `Jest` + [jest-monocart-coverage](https://github.com/cenfun/jest-monocart-coverage) + - `Vitest` + [vitest-monocart-coverage](https://github.com/cenfun/vitest-monocart-coverage) +```js +const coverageOptions = { + name: 'My Unit Test Coverage Report', + outputDir: "./coverage-reports/unit", + reports: [ + ['raw', { + // relative path will be "./coverage-reports/unit/raw" + // defaults to raw + outputDir: "raw" + }], + ['v8'], + ['console-details'] + ] +}; +``` + +- We also have `raw` coverage data from `e2e test`, which is output to `./coverage-reports/e2e/raw`. E2E test examples: + - `Playwright` + [monocart-reporter](https://github.com/cenfun/monocart-reporter) with coverage API + - `Playwright` + `MCR`, see [playwright-coverage](https://github.com/cenfun/playwright-coverage) + - see more [Integration Examples](#integration-examples) + +- Then create a script `merge-coverage.js` to generate a merged report with option `inputDir`. +```js +// merge-coverage.js +const fs = require('fs'); +const { CoverageReport } = require('monocart-coverage-reports'); +const inputDir = [ + './coverage-reports/unit/raw', + './coverage-reports/e2e/raw' +]; +const coverageOptions = { + name: 'My Merged Coverage Report', + inputDir, + outputDir: './coverage-reports/merged', + + // filter for both unit and e2e + entryFilter: { + '**/node_modules/**': false, + '**/*': true + }, + sourceFilter: { + '**/node_modules/**': false, + '**/src/**': true + }, + + sourcePath: (filePath, info) => { + // Unify the file path for the same files + // For example, the file index.js has different paths: + // unit: unit-dist/src/index.js + // e2e: e2e-dist/src/index.js + // return filePath.replace("unit-dist/", "").replace("e2e-dist/", "") + return filePath; + }, + + reports: [ + ['v8'], + ['console-details'] + ], + + onEnd: () => { + // remove the raw files if it useless + // inputDir.forEach((p) => { + // fs.rmSync(p, { + // recursive: true, + // force: true + // }); + // }); + } +}; +await new CoverageReport(coverageOptions).generate(); +``` +- Running script `node path/to/merge-coverage.js` after all the tests are completed. All the command scripts are probably like following: +```json +{ + "scripts": { + "test:unit": "jest", + "test:e2e": "playwright test", + "merge-coverage": "node path/to/merge-coverage.js", + "test": "npm run test:unit && npm run test:e2e && npm run merge-coverage" + } +} +``` +see example: [merge-code-coverage](https://github.com/cenfun/merge-code-coverage) + +## Common issues +### Unexpected coverage +In most cases, it happens when the coverage of the generated code is converted to the coverage of the original code through a sourcemap. In other words, it's an issue with the sourcemap. Most of the time, we can solve this by setting `minify` to `false` in the configuration of build tools. Let's take a look at an example: +```js +const a = tf ? 'true' : 'false'; + ^ ^ ^ + m1 p m2 +``` +In the generated code, there is a position `p`, and we need to find out its corresponding position in the original code. Unfortunately, there is no matched mapping for the position `p`. Instead, it has two adjacent upstream and downstream mappings `m1` and `m2`, so, the original position of `p` that we are looking for, might not be able to be precisely located. Especially, the generated code is different from the original code, such as the code was minified, compressed or converted, it is difficult to find the exact original position without matched mapping. +- Further understanding of sourcemap, try [Debug for Coverage and Sourcemap](#debug-for-coverage-and-sourcemap) + +How `MCR` Works: +- 1, Trying to fix the original position with string comparison and [`diff-sequences`](https://github.com/jestjs/jest/tree/main/packages/diff-sequences). However, for non-JS code, such as Vue template, JSX, etc., it might be hard to find a perfect solution. +- 2, Finding all functions, statements and branches by parsing the source code [AST](https://github.com/acornjs/acorn). (There is a small issue is the V8 cannot provide effective branch coverage information for `AssignmentPattern`) + + +### Unparsable source +It happens during the parsing of the source code into AST, if the source code is not in the standard ECMAScript. For example `ts`, `jsx` and so on. There is a option to fix it, which is to manually compile the source code for these files. +```js +import * as fs from "fs"; +import * as path from "path"; +import { fileURLToPath } from "url"; +import * as TsNode from 'ts-node'; +const coverageOptions = { + onEntry: async (entry) => { + const filePath = fileURLToPath(entry.url) + const originalSource = fs.readFileSync(filePath).toString("utf-8"); + const fileName = path.basename(filePath); + const tn = TsNode.create({}); + const source = tn.compile(originalSource, fileName); + entry.fake = false; + entry.source = source; + } +} +``` + +### JavaScript heap out of memory +When there are a lot of raw v8 coverage files to process, it may cause OOM. We can try the following Node.js options: +```sh +- run: npm run test:coverage + env: + NODE_OPTIONS: --max-old-space-size=8192 +``` + + +## Debug for Coverage and Sourcemap +> Sometimes, the coverage is not what we expect. The next step is to figure out why, and we can easily find out the answer step by step through debugging. +- Start debugging for v8 report with option `logging: 'debug'` +```js +const coverageOptions = { + logging: 'debug', + reports: [ + ['v8'], + ['console-details'] + ] +}; +``` +When `logging` is `debug`, the raw report data will be preserved in `[outputDir]/.cache` or `[outputDir]/raw` if `raw` report is used. And the dist file will be preserved in the V8 list, and by opening the browser's devtool, it makes data verification visualization effortless. +![](./assets/debug-coverage.png) + +- Check sourcemap with [Source Map Visualization](https://evanw.github.io/source-map-visualization/) + +![](./assets/debug-sourcemap.png) + +- Generate additional source and sourcemap files to cache or raw dir +```js +const coverageOptions = { + logging: 'debug', + sourceMap: true +}; +``` + +- Show time logs with env `MCR_LOG_TIME` +```js +process.env.MCR_LOG_TIME = true +``` + +## Integration with Any Testing Framework +- API + - Collecting coverage data when any stage of the test is completed, and adding the coverage data to the coverage reporter. `await mcr.add(coverageData)` + - Generating the coverage reports after the completion of all tests. `await mcr.generate()` + - see [Multiprocessing Support](#multiprocessing-support) +- CLI + - Wrapping with any CLI. `mcr your-cli --your-arguments` + - see [Command line](#command-line) + +## Integration Examples + +### [Playwright](https://github.com/microsoft/playwright) +- [playwright-coverage](https://github.com/cenfun/playwright-coverage) - Example for Playwright coverage reports +- [playwright-bdd-coverage](https://github.com/cenfun/playwright-bdd-coverage) - Example for Playwright BDD coverage reports +- [monocart-reporter](https://github.com/cenfun/monocart-reporter) - Playwright custom reporter, supports generating [Code coverage report](https://github.com/cenfun/monocart-reporter?#code-coverage-report) +- Coverage for component testing with `monocart-reporter`: + - [playwright-ct-vue](https://github.com/cenfun/playwright-ct-vue) + - [playwright-ct-react](https://github.com/cenfun/playwright-ct-react) + - [playwright-ct-svelte](https://github.com/cenfun/playwright-ct-svelte) +- Coverage for Next.js, both server side and client side: + - [nextjs-with-playwright](https://github.com/cenfun/nextjs-with-playwright) + - [nextjs-with-playwright-istanbul](https://github.com/cenfun/nextjs-with-playwright-istanbul) +- Coverage for Remix: + - [remix-with-playwright](https://github.com/cenfun/remix-with-playwright) +- see [Collecting V8 Coverage Data with Playwright](#collecting-v8-coverage-data-with-playwright) + +### [c8](https://github.com/bcoe/c8) +- c8 has integrated `MCR` as an experimental feature since [v10.1.0](https://github.com/bcoe/c8/releases/tag/v10.1.0) +```sh +c8 --experimental-monocart --reporter=v8 --reporter=console-details node foo.js +``` + +### [CodeceptJS](https://github.com/codeceptjs/CodeceptJS) +- CodeceptJS is a [BDD](https://codecept.io/bdd/) + [AI](https://codecept.io/ai/) testing framework for e2e testing, it has integrated `MCR` since [v3.5.15](https://github.com/codeceptjs/CodeceptJS/releases/tag/3.5.15), see [plugins/coverage](https://codecept.io/plugins/#coverage) + +### [VSCode](https://github.com/microsoft/vscode) +- [Monocart Coverage for VSCode](https://github.com/cenfun/monocart-coverage-vscode) - Shows native V8 code coverage in VSCode + +### [Jest](https://github.com/jestjs/jest/) +- [jest-monocart-coverage](https://github.com/cenfun/jest-monocart-coverage) - Jest custom reporter for coverage reports +- [merge-code-coverage](https://github.com/cenfun/merge-code-coverage) - Example for merging code coverage (Jest unit + Playwright e2e sharding) + +### [Vitest](https://github.com/vitest-dev/vitest) +- [vitest-monocart-coverage](https://github.com/cenfun/vitest-monocart-coverage) - Vitest custom provider module for coverage reports +- [merge-code-coverage-vitest](https://github.com/cenfun/merge-code-coverage-vitest) - Example for merging code coverage (Vitest unit + Playwright e2e sharding) + +### [Node Test Runner](https://nodejs.org/docs/latest/api/test.html) +- [node-monocart-coverage](https://github.com/cenfun/node-monocart-coverage) - Custom reporter for Node test runner for coverage + +### [Puppeteer](https://github.com/puppeteer/puppeteer/) +- [jest-puppeteer-coverage](https://github.com/cenfun/jest-puppeteer-coverage) - Example for Jest puppeteer coverage +- [maplibre-gl-js](https://github.com/maplibre/maplibre-gl-js) - Example for Jest (unit) + Puppeteer (e2e) + Codecov +- see [Collecting Raw V8 Coverage Data with Puppeteer](#collecting-raw-v8-coverage-data-with-puppeteer) + +### [Cypress](https://github.com/cypress-io/cypress) +- [cypress-monocart-coverage](https://github.com/cenfun/cypress-monocart-coverage) - Cypress plugin for coverage reports + +### [WebdriverIO](https://github.com/webdriverio/webdriverio) +- [wdio-monocart-service](https://github.com/cenfun/wdio-monocart-service) - WebdriverIO service for coverage reports + +### [Storybook Test Runner](https://github.com/storybookjs/test-runner) +- [storybook-monocart-coverage](https://github.com/cenfun/storybook-monocart-coverage) - Example for Storybook V8 coverage reports + +### [TestCafe](https://github.com/DevExpress/testcafe) +- [testcafe-reporter-coverage](https://github.com/cenfun/testcafe-reporter-coverage) - TestCafe custom reporter for coverage reports + +### [Selenium Webdriver](https://github.com/seleniumhq/selenium) +- [selenium-webdriver-coverage](https://github.com/cenfun/selenium-webdriver-coverage) - Example for Selenium Webdriver V8 coverage reports + +### [Mocha](https://github.com/mochajs/mocha) +```sh +mcr mocha ./test/**/*.js +``` + +### [TypeScript](https://github.com/microsoft/typescript) + +- [tsx](https://github.com/privatenumber/tsx) +```sh +cross-env NODE_OPTIONS="--import tsx" npx mcr tsx ./src/example.ts +cross-env NODE_OPTIONS="--import tsx" npx mcr mocha ./test/**/*.ts +# Node.js v18.19.0 + +mcr --import tsx tsx ./src/example.ts +mcr --import tsx mocha ./test/**/*.ts +``` +- [ts-node](https://github.com/TypeStrong/ts-node) +```sh +cross-env NODE_OPTIONS="--loader ts-node/esm --no-warnings" npx mcr ts-node ./src/example.ts +cross-env NODE_OPTIONS="--loader ts-node/esm --no-warnings" npx mcr mocha ./test/**/*.ts +``` + +### [AVA](https://github.com/avajs/ava) +```sh +mcr ava +``` + +### [Codecov](https://codecov.com/) +[![codecov](https://codecov.io/gh/cenfun/monocart-coverage-reports/graph/badge.svg?token=H0LW7UKYU3)](https://codecov.io/gh/cenfun/monocart-coverage-reports) +- Supports native `codecov` built-in report ([specification](https://docs.codecov.com/docs/codecov-custom-coverage-format)) +```js +const coverageOptions = { + outputDir: "./coverage-reports", + reports: [ + ['codecov'] + ] +}; +``` +- Github actions: +```yml +- name: Codecov + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ./coverage-reports/codecov.json +``` + +### [Codacy](https://www.codacy.com/) +[![Codacy](https://app.codacy.com/project/badge/Coverage/715016ea8e90479db875b777db8bad55)](https://app.codacy.com/gh/cenfun/monocart-coverage-reports/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage) +- Using `lcov` report: +```js +const coverageOptions = { + outputDir: "./coverage-reports", + lcov: true +}; +``` +- Github actions: +```yml +- name: Codacy Coverage Reporter + uses: codacy/codacy-coverage-reporter-action@v1 + with: + project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} + coverage-reports: ./docs/mcr/lcov.info +``` + +### [Coveralls](https://coveralls.io/) +[![Coverage Status](https://coveralls.io/repos/github/cenfun/monocart-coverage-reports/badge.svg?branch=main)](https://coveralls.io/github/cenfun/monocart-coverage-reports?branch=main) +- Using `lcov` report: +```js +const coverageOptions = { + outputDir: "./coverage-reports", + lcov: true +}; +``` +- Github actions: +```yml +- name: Coveralls + uses: coverallsapp/github-action@v2 + with: + files: ./coverage-reports/lcov.info +``` + +### [Sonar Cloud](https://sonarcloud.io/) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=monocart-coverage-reports&metric=coverage)](https://sonarcloud.io/summary/new_code?id=monocart-coverage-reports) +- Using `lcov` report. Github actions example: +```yml +- name: Analyze with SonarCloud + uses: sonarsource/sonarcloud-github-action@master + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + with: + projectBaseDir: ./ + args: > + -Dsonar.organization=cenfun + -Dsonar.projectKey=monocart-coverage-reports + -Dsonar.projectName=monocart-coverage-reports + -Dsonar.javascript.lcov.reportPaths=docs/mcr/lcov.info + -Dsonar.sources=lib + -Dsonar.tests=test + -Dsonar.exclusions=dist/*,packages/* +``` + +## Contributing +- Node.js 20+ +- VSCode (extensions: eslint/stylelint/vue) +```sh +npm install +npx playwright install --with-deps + +npm run build +npm run test + +npm run dev +``` +- Refreshing `eol=lf` for snapshot of test (Windows) +```sh +git add . -u +git commit -m "Saving files before refreshing line endings" + +npm run eol +``` + +## Thanks +- [@bcoe](https://github.com/bcoe) +- [@edumserrano](https://github.com/edumserrano) \ No newline at end of file diff --git a/node_modules/monocart-coverage-reports/README.zh-Hans.md b/node_modules/monocart-coverage-reports/README.zh-Hans.md new file mode 100644 index 0000000..3d33448 --- /dev/null +++ b/node_modules/monocart-coverage-reports/README.zh-Hans.md @@ -0,0 +1,1191 @@ +# Monocart Coverage Reports + +[![npm](https://img.shields.io/npm/v/monocart-coverage-reports)](https://www.npmjs.com/package/monocart-coverage-reports) +![license](https://img.shields.io/github/license/cenfun/monocart-coverage-reports) +![build](https://img.shields.io/github/actions/workflow/status/cenfun/monocart-coverage-reports/ci.yml) +[![install size](https://packagephobia.com/badge?p=monocart-coverage-reports)](https://packagephobia.com/result?p=monocart-coverage-reports) +[![npm graph](https://img.shields.io/badge/npm-graph-blue)](https://npmgraph.js.org/?q=monocart-coverage-reports) +![dependencies](https://img.shields.io/librariesio/github/cenfun/monocart-coverage-reports) +[![downloads](https://devimg.vercel.app/npm/downloads/monocart-coverage-reports?label={total}%20downloads/month)](https://www.npmjs.com/package/monocart-coverage-reports) + +🌐 [English](README.md) | 简体中文 + +> JS代码覆盖率工具,用来生成原生的[V8](https://v8.dev/blog/javascript-code-coverage)或者[Istanbul](https://istanbul.js.org/)代码覆盖率报告 + +* [用法](#usage) +* [选项配置](#options) +* [所有支持的报告类型](#available-reports) +* [比较两种报告](#compare-reports) +* [如何收集Istanbul覆盖率数据](#collecting-istanbul-coverage-data) +* [如何收集V8覆盖率数据](#collecting-v8-coverage-data) + - [用Playwright](#collecting-v8-coverage-data-with-playwright) + - [用Puppeteer](#collecting-raw-v8-coverage-data-with-puppeteer) + - [从Node.js](#collecting-v8-coverage-data-from-nodejs) + - [使用`CDPClient`API](#collecting-v8-coverage-data-with-cdpclient-api) + - [参考V8覆盖率的API](#v8-coverage-data-api) +* [过滤V8覆盖率数据](#filtering-results) +* [使用 `sourcePath` 修改源文件路径](#resolve-sourcepath-for-the-source-files) +* [为未测试的文件添加空的覆盖率报告](#adding-empty-coverage-for-untested-files) +* [onEnd回调函数](#onend-hook) +* [如何忽略未覆盖的代码](#ignoring-uncovered-codes) +* [多进程支持](#multiprocessing-support) +* [如何使用CLI命令行](#command-line) +* [如何加载配置文件](#config-file) +* [如何合并覆盖率报告](#merge-coverage-reports) + - [自动合并](#automatic-merging) + - [手动合并](#manual-merging) +* [常见问题](#common-issues) + - [Unexpected coverage](#unexpected-coverage) + - [Unparsable source](#unparsable-source) + - [JavaScript heap out of memory](#javascript-heap-out-of-memory) +* [如何调试覆盖率数据和查看sourcemap](#debug-for-coverage-and-sourcemap) +* [如何跟其他框架集成](#integration-with-any-testing-framework) +* [集成的例子](#integration-examples) + - [Playwright](#playwright) + - [c8](#c8) + - [CodeceptJS](#codeceptjs) + - [VSCode](#vscode) + - [Jest](#jest) + - [Vitest](#vitest) + - [Node Test Runner](#node-test-runner) + - [Puppeteer](#puppeteer) + - [Cypress](#cypress) + - [WebdriverIO](#webdriverio) + - [Storybook Test Runner](#storybook-test-runner) + - [TestCafe](#testcafe) + - [Selenium Webdriver](#selenium-webdriver) + - [Mocha](#mocha) + - [TypeScript](#typescript) + - [AVA](#ava) + - [Codecov](#codecov) + - [Codacy](#codacy) + - [Coveralls](#coveralls) + - [Sonar Cloud](#sonar-cloud) +* [Contributing](#contributing) +* [更新日志](CHANGELOG.md) +* [感谢](#thanks) + +## Usage +> 推荐使用 [Node.js 20+](https://nodejs.org/). +- 安装 +```sh +npm install monocart-coverage-reports +``` +- API +```js +const MCR = require('monocart-coverage-reports'); +const mcr = MCR({ + name: 'My Coverage Report - 2024-02-28', + outputDir: './coverage-reports', + reports: ["v8", "console-details"], + cleanCache: true +}); +await mcr.add(coverageData); +await mcr.generate(); +``` +也可以使用ESM的 `import` 然后加载[配置文件](#config-file) +```js +import { CoverageReport } from 'monocart-coverage-reports'; +const mcr = new CoverageReport(); +await mcr.loadConfig(); +``` +参见 [多进程支持](#multiprocessing-support) + +- CLI +```sh +mcr node my-app.js -r v8,console-details +``` +参见 [命令行](#command-line) + +## Options +- 默认选项: [lib/default/options.js](./lib/default/options.js) +- 选项的类型描述,见 `CoverageReportOptions` [lib/index.d.ts](./lib/index.d.ts) +- [配置文件](#config-file) + +## Available Reports + +> 内置V8报告(仅V8格式数据支持): + +- `v8` + - 推荐使用: + - 全新的原生V8覆盖率报告界面,更好的用户体验 + - 支持原生的Bytes覆盖率指标 + - 支持高性能处理大数据 + - 支持任何运行时代码的覆盖率(压缩后的) + - 支持CSS代码覆盖率(用于分析CSS的冗余代码) + - 对Sourcemap转换有更好的支持 + - 预览: [V8](https://cenfun.github.io/monocart-coverage-reports/v8) and [more](https://cenfun.github.io/monocart-coverage-reports/) + +![](./assets/v8.gif) + +- `v8-json` + - 保存 `CoverageResults` 到一个json文件 (默认是 [`coverage-report.json`](https://cenfun.github.io/monocart-coverage-reports/v8-and-istanbul/coverage-report.json)) + - 用于VSCode扩展来显示原生V8代码覆盖率: [Monocart Coverage for VSCode](https://github.com/cenfun/monocart-coverage-vscode) + +![](./assets/mcv.gif) + +> 内置Istanbul报告 (V8和Istanbul格式数据都支持): + +- `clover` +- `cobertura` +- `html` + - [Istanbul html](https://cenfun.github.io/monocart-coverage-reports/istanbul/) + - [V8 to Istanbul](https://cenfun.github.io/monocart-coverage-reports/v8-and-istanbul/istanbul) +- `html-spa` +- `json` +- `json-summary` +- `lcov` +- `lcovonly` + - [V8 lcov.info](https://cenfun.github.io/monocart-coverage-reports/v8/lcov.info) + - [Istanbul lcov.info](https://cenfun.github.io/monocart-coverage-reports/istanbul/lcov.info) +- `none` +- `teamcity` +- `text` +- `text-lcov` +- `text-summary` + +> 其他内置报告 (V8和Istanbul格式数据都支持): + +- `codecov` 保存覆盖率数据到 [Codecov](https://docs.codecov.com/docs/codecov-custom-coverage-format) 专属的json文件 (默认是`codecov.json`), 见[例子](https://app.codecov.io/github/cenfun/monocart-coverage-reports) + +- `codacy` 保存覆盖率数据到 [Codacy](https://api.codacy.com/swagger#tocscoveragereport) 专属的json文件 (默认是`codacy.json`) + +- `console-summary` 在控制台显示覆盖率概要 + +![](./assets/console-summary.png) + +- `console-details` 在控制台显示每个文件的覆盖率概要。如果是Github actions,可以使用环境变量`FORCE_COLOR: true`来强制开启颜色支持 + +![](./assets/console-details.png) + +- `markdown-summary` 保存概要信息到markdown文件 (默认是`coverage-summary.md`)。 如果是Github actions, 可以把markdown的内容添加到[a job summary](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary) +```sh +cat path-to/coverage-summary.md >> $GITHUB_STEP_SUMMARY +``` +![](./assets/markdown-summary.png) + +- `markdown-details` 保存覆盖率详情到markdown文件 (默认是 `coverage-details.md`) + - 预览运行结果 [runs](https://github.com/cenfun/monocart-coverage-reports/actions/workflows/ci.yml) + +- `raw` 只是保存原始覆盖率数据, 用于使用`inputDir`参数来导入多个原始数据进行合并报告。参见 [合并覆盖率报告](#merge-coverage-reports) + +- 自定义报告 + ```js + { + reports: [ + [path.resolve('./test/custom-istanbul-reporter.js'), { + type: 'istanbul', + file: 'custom-istanbul-coverage.text' + }], + [path.resolve('./test/custom-v8-reporter.js'), { + type: 'v8', + outputFile: 'custom-v8-coverage.json' + }], + [path.resolve('./test/custom-v8-reporter.mjs'), { + type: 'both' + }] + ] + } + ``` + - Istanbul自定义报告 + > 例子: [./test/custom-istanbul-reporter.js](./test/custom-istanbul-reporter.js), see [istanbul built-in reporters' implementation](https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-reports/lib) for reference. + - V8自定义报告 + > 例子: [./test/custom-v8-reporter.js](./test/custom-v8-reporter.js) + +### Multiple Reports: +如何配置多个报告 +```js +const MCR = require('monocart-coverage-reports'); +const coverageOptions = { + outputDir: './coverage-reports', + reports: [ + // build-in reports + ['console-summary'], + ['v8'], + ['html', { + subdir: 'istanbul' + }], + ['json', { + file: 'my-json-file.json' + }], + 'lcovonly', + + // custom reports + // Specify reporter name with the NPM package + ["custom-reporter-1"], + ["custom-reporter-2", { + type: "istanbul", + key: "value" + }], + // Specify reporter name with local path + ['/absolute/path/to/custom-reporter.js'] + ] +} +const mcr = MCR(coverageOptions); +``` + +## Compare Reports +> 如果是V8数据格式使用Istanbul的报告,将自动从V8转换到Istanbul + +| | Istanbul | V8 | V8 to Istanbul | +| :--------------| :------ | :------ | :---------------------- | +| 数据格式 | [Istanbul](https://github.com/gotwarlost/istanbul/blob/master/coverage.json.md) (Object) | [V8](#v8-coverage-data-format) (Array) | [V8](#v8-coverage-data-format) (Array) | +| 输出报告 | [Istanbul reports](#available-reports) | [V8 reports](#available-reports) | [Istanbul reports](#available-reports) | +| - Bytes 字节覆盖率 | ❌ | ✅ | ❌ | +| - Statements 语句覆盖率 | ✅ | ✅ | ✅ | +| - Branches 分支覆盖率 | ✅ | ✅ | ✅ | +| - Functions 函数覆盖率 | ✅ | ✅ | ✅ | +| - Lines 行覆盖率 | ✅ | ✅ | ✅ | +| - Execution counts 函数执行数 | ✅ | ✅ | ✅ | +| CSS 覆盖率 | ❌ | ✅ | ✅ | +| 压缩过的代码 | ❌ | ✅ | ❌ | + +## Collecting Istanbul Coverage Data +- 在收集Istanbul覆盖率数据之前,需要编译源代码来安装Istanbul计数器 + - webpack babel-loader: [babel-plugin-istanbul](https://github.com/istanbuljs/babel-plugin-istanbul), 参见例子: [webpack.config-istanbul.js](./test/build/webpack.config-istanbul.js) + - 官方CLI: [nyc instrument](https://github.com/istanbuljs/nyc/blob/master/docs/instrument.md) 或API: [istanbul-lib-instrument](https://github.com/istanbuljs/istanbuljs/blob/main/packages/istanbul-lib-instrument/api.md) + - vite: [vite-plugin-istanbul](https://github.com/ifaxity/vite-plugin-istanbul) + - rollup: [rollup-plugin-istanbul](https://github.com/artberri/rollup-plugin-istanbul) + - swc: [swc-plugin-coverage-instrument](https://github.com/kwonoj/swc-plugin-coverage-instrument) + +- 从浏览器 + - Istanbul的覆盖率数据会保存到全局的`window.__coverage__`,直接读取即可, 参见例子: [test-istanbul.js](./test/test-istanbul.js) + +- 从Node.js + - 同理对于Node.js会保存到全局的`global.__coverage__` + +- 使用CDP + - `getIstanbulCoverage()` 参见[`CDPClient` API](#collecting-v8-coverage-data-with-cdpclient-api) + +## Collecting V8 Coverage Data +- 在收集V8覆盖率数据之前,需要开启构建工具的`sourcemap`支持,并且不要压缩代码 + - [webpack](https://webpack.js.org/configuration/): `devtool: source-map` and `mode: development`, example [webpack.config-v8.js](./test/build/webpack.config-v8.js) + - [rollup](https://rollupjs.org/configuration-options/): `sourcemap: true` and `treeshake: false` + - [esbuild](https://esbuild.github.io/api/): `sourcemap: true`, `treeShaking: false` and `minify: false` + - [vite](https://vitejs.dev/config/build-options.html): `sourcemap: true` and `minify: false` + +- 浏览器 (仅支持基于Chromium的浏览器) + - [使用Playwright](#collecting-v8-coverage-data-with-playwright) + - [使用Puppeteer](#collecting-raw-v8-coverage-data-with-puppeteer) + +- 从Node.js + - [从Node.js收集V8覆盖率数据](#collecting-v8-coverage-data-from-nodejs) + +- 使用CDP + - [使用`CDPClient` API收集V8覆盖率数据](#collecting-v8-coverage-data-with-cdpclient-api) + +### Collecting V8 Coverage Data with Playwright +使用Playwright的覆盖接口收集覆盖率数据 +```js +await Promise.all([ + page.coverage.startJSCoverage({ + // reportAnonymousScripts: true, + resetOnNavigation: false + }), + page.coverage.startCSSCoverage({ + // Note, anonymous styles (without sourceURLs) are not supported, alternatively, you can use CDPClient + resetOnNavigation: false + }) +]); + +await page.goto("your page url"); + +const [jsCoverage, cssCoverage] = await Promise.all([ + page.coverage.stopJSCoverage(), + page.coverage.stopCSSCoverage() +]); + +const coverageData = [... jsCoverage, ... cssCoverage]; + +``` +使用 `@playwright/test` 的 [`Automatic fixtures`](https://playwright.dev/docs/test-fixtures#automatic-fixtures)收集覆盖率数据, 见例子: [fixtures.ts](https://github.com/cenfun/playwright-coverage/blob/main/fixtures.ts) +参见例子 [./test/test-v8.js](./test/test-v8.js), [css](./test/test-css.js) + + +### Collecting Raw V8 Coverage Data with Puppeteer +使用Puppeteer的覆盖接口收集覆盖率数据,注意Puppeteer默认不会提供原生V8的覆盖率数据,需要设置`includeRawScriptCoverage` +```js +await Promise.all([ + page.coverage.startJSCoverage({ + // reportAnonymousScripts: true, + resetOnNavigation: false, + // provide raw v8 coverage data + includeRawScriptCoverage: true + }), + page.coverage.startCSSCoverage({ + resetOnNavigation: false + }) +]); + +await page.goto("your page url"); + +const [jsCoverage, cssCoverage] = await Promise.all([ + page.coverage.stopJSCoverage(), + page.coverage.stopCSSCoverage() +]); + +// to raw V8 script coverage +const coverageData = [... jsCoverage.map((it) => { + return { + source: it.text, + ... it.rawScriptCoverage + }; +}), ... cssCoverage]; +``` +参见: [./test/test-puppeteer.js](./test/test-puppeteer.js) + +### Collecting V8 Coverage Data from Node.js +有多种方法可以从Node.js收集V8覆盖率数据: +- [NODE_V8_COVERAGE](https://nodejs.org/docs/latest/api/cli.html#node_v8_coveragedir)=`dir` + - 使用Node.js环境变量`NODE_V8_COVERAGE`=`dir`来启动程序, 然后在进程正常结束之后,覆盖率数据将自动保存到指定的`dir`目录. + - 从`dir`目录读取所有的JSON文件,来生成覆盖率报告 + - 参见例子: + > cross-env NODE_V8_COVERAGE=`.temp/v8-coverage-env` node [./test/test-node-env.js](./test/test-node-env.js) && node [./test/generate-report.js](./test/generate-report.js) + +- [V8](https://nodejs.org/docs/latest/api/v8.html#v8takecoverage) API + NODE_V8_COVERAGE + - 如果进程不能正常结束,比如被强制关闭,或者压根就不结束,比如启动了一个服务类的,那么需要手动写入覆盖率数据,这里需要调用接口`v8.takeCoverage()` + - 参见例子: + > cross-env NODE_V8_COVERAGE=`.temp/v8-coverage-api` node [./test/test-node-api.js](./test/test-node-api.js) + +- [Inspector](https://nodejs.org/docs/latest/api/inspector.html) API + - 首先连接到Node.js的V8 inspector + - 然后使用inspector的覆盖相关API来开启和收集覆盖率数据 + - 参见例子: + > node [./test/test-node-ins.js](./test/test-node-ins.js) + - vm的例子 (注意这里需要使用`scriptOffset`,因为vm里一般都会加一层包裹代码,需要这个偏移位置来修正覆盖率数据块的位置): + > node [./test/test-node-vm.js](./test/test-node-vm.js) + +- [CDP](https://chromedevtools.github.io/devtools-protocol/) API + - 开启[Node调试](https://nodejs.org/en/guides/debugging-getting-started/) + - 使用CDP的覆盖率接口开启和收集覆盖率数据 + - 参见例子: + > node --inspect=9229 [./test/test-node-cdp.js](./test/test-node-cdp.js) + +- [Node Debugging](https://nodejs.org/en/guides/debugging-getting-started) + CDP + NODE_V8_COVERAGE + V8 API + - 如果启动了一个Node服务,可以手动调用`v8.takeCoverage()`接口来保存覆盖率数据,开启Node调试就可以远程通过CDP连接的`Runtime.evaluate`,来调用这个接口. + - 参见[koa](https://github.com/koajs/koa)的例子: + > node [./test/test-node-koa.js](./test/test-node-koa.js) + +- [Child Process](https://nodejs.org/docs/latest/api/child_process.html) + NODE_V8_COVERAGE + - 如果是子进程,可参见 [命令行](#command-line) + +### Collecting V8 Coverage Data with `CDPClient` API +- `CDPClient`为`MCR`提供的内置接口类,用来更便捷的处理覆盖率相关数据,所有的API如下 +```js +// 开始和停止并收集JS的覆盖率数据 +startJSCoverage: () => Promise; +stopJSCoverage: () => Promise; + +// 开始和停止并收集CSS的覆盖率数据,支持匿名文件(比如style里的css) +startCSSCoverage: () => Promise; +stopCSSCoverage: () => Promise; + +// 开始和停止并收集JS和CSS的覆盖率数据 +startCoverage: () => Promise; +stopCoverage: () => Promise; + +/** 如果开启了NODE_V8_COVERAGE,这个接口用来手动保存当前覆盖率数据 */ +writeCoverage: () => Promise; + +/** 收集istanbul覆盖率数据 */ +getIstanbulCoverage: (coverageKey?: string) => Promise; +``` + +- 结合使用Node调试端口`--inspect=9229` 或者浏览器调试端口 `--remote-debugging-port=9229` +```js +const MCR = require('monocart-coverage-reports'); +const client = await MCR.CDPClient({ + port: 9229 +}); +await client.startJSCoverage(); +// run your test here +const coverageData = await client.stopJSCoverage(); +``` + +- 结合使用 [Playwright CDPSession](https://playwright.dev/docs/api/class-cdpsession) +```js +const { chromium } = require('playwright'); +const MCR = require('monocart-coverage-reports'); +const browser = await chromium.launch(); +const page = await browser.newPage(); +const session = await page.context().newCDPSession(page); +const client = await MCR.CDPClient({ + session +}); +// both js and css coverage +await client.startCoverage(); +// run your test page here +await page.goto("your page url"); +const coverageData = await client.stopCoverage(); +``` + +- 结合使用 [Puppeteer CDPSession](https://pptr.dev/api/puppeteer.cdpsession) +```js +const puppeteer = require('puppeteer'); +const MCR = require('monocart-coverage-reports'); +const browser = await puppeteer.launch({}); +const page = await browser.newPage(); +const session = await page.target().createCDPSession(); +const client = await MCR.CDPClient({ + session +}); +// both js and css coverage +await client.startCoverage(); +// run your test page here +await page.goto("your page url"); +const coverageData = await client.stopCoverage(); +``` + +- 结合使用 [Selenium Webdriver](https://www.selenium.dev/documentation/webdriver/) WebSocket (仅支持Chrome/Edge浏览器) +```js +const { Builder, Browser } = require('selenium-webdriver'); +const MCR = require('monocart-coverage-reports'); +const driver = await new Builder().forBrowser(Browser.CHROME).build(); +const pageCdpConnection = await driver.createCDPConnection('page'); +const session = new MCR.WSSession(pageCdpConnection._wsConnection); +const client = await MCR.CDPClient({ + session +}) +``` + +### V8 Coverage Data API +- [JavaScript V8代码覆盖官方说明](https://v8.dev/blog/javascript-code-coverage) +- [Playwright的覆盖率接口](https://playwright.dev/docs/api/class-coverage) +- [Puppeteer的覆盖率接口](https://pptr.dev/api/puppeteer.coverage) +- [DevTools Protocol的覆盖率接口](https://chromedevtools.github.io/devtools-protocol/tot/Profiler/#method-startPreciseCoverage) 参见 [ScriptCoverage](https://chromedevtools.github.io/devtools-protocol/tot/Profiler/#type-ScriptCoverage) 和 [v8-coverage](https://github.com/bcoe/v8-coverage) +```js +// Coverage data for a source range. +export interface CoverageRange { + // JavaScript script source offset for the range start. + startOffset: integer; + // JavaScript script source offset for the range end. + endOffset: integer; + // Collected execution count of the source range. + count: integer; +} +// Coverage data for a JavaScript function. +/** + * @functionName can be an empty string. + * @ranges is always non-empty. The first range is called the "root range". + * @isBlockCoverage indicates if the function has block coverage information. + If this is false, it usually means that the functions was never called. + It seems to be equivalent to ranges.length === 1 && ranges[0].count === 0. +*/ +export interface FunctionCoverage { + // JavaScript function name. + functionName: string; + // Source ranges inside the function with coverage data. + ranges: CoverageRange[]; + // Whether coverage data for this function has block granularity. + isBlockCoverage: boolean; +} +// Coverage data for a JavaScript script. +export interface ScriptCoverage { + // JavaScript script id. + scriptId: Runtime.ScriptId; + // JavaScript script name or url. + url: string; + // Functions contained in the script that has coverage data. + functions: FunctionCoverage[]; +} +export type V8CoverageData = ScriptCoverage[]; +``` + +| JavaScript Runtime | V8 Coverage | | +| :--------------| :----: | :---------------------- | +| Chrome (65%) | ✅ | Chromium-based | +| Safari (18%) | ❌ | | +| Edge (5%) | ✅ | Chromium-based | +| Firefox (2%) | ❌ | | +| Node.js | ✅ | | +| Deno | ❌ | [issue](https://github.com/denoland/deno/issues/23359) | +| Bun | ❌ | | + +## Filtering Results +## Using `entryFilter` and `sourceFilter` to filter the results for V8 report +当收集到V8的覆盖数据时,它实际上包含了所有的入口文件的覆盖率数据, 比如有以下3个文件: + +- *dist/main.js* +- *dist/vendor.js* +- *dist/something-else.js* + +这个时候可以使用`entryFilter`来过滤这些入口文件. 比如我们不需要看到`vendor.js`和`something-else.js`的覆盖率,就可以过滤掉,只剩下1个文件 + +- *dist/main.js* + +如果一个入口文件存在行内或者链接的sourcemap文件,那么我们会尝试读取并解析sourcemap,以获取入口文件包含的所有源文件,并添加到列表。此时如果`logging`没有设置成`debug`,那么这个入口文件在成功解出源文件后会被移除 + +- *src/index.js* +- *src/components/app.js* +- *node_modules/dependency/dist/dependency.js* + +这个时候可以使用`sourceFilter`来过滤这些源文件。比如我们不需要看到源文件`dependency.js`的覆盖率,就可以过滤掉,最后只剩下如下文件 + +- *src/index.js* +- *src/components/app.js* + +过滤可以使用函数: +```js +const coverageOptions = { + entryFilter: (entry) => entry.url.indexOf("main.js") !== -1, + sourceFilter: (sourcePath) => sourcePath.search(/src\//) !== -1 +}; +``` +也可以使用便捷的[`minimatch`](https://github.com/isaacs/minimatch)来匹配(推荐): +```js +const coverageOptions = { + entryFilter: "**/main.js", + sourceFilter: "**/src/**" +}; +``` +支持多个匹配: +```js +const coverageOptions = { + entryFilter: { + '**/node_modules/**': false, + '**/vendor.js': false, + '**/src/**': true + }, + sourceFilter: { + '**/node_modules/**': false, + '**/**': true + } +}; +``` +作为CLI参数(JSON字符串,Added in: v2.8): +```sh +mcr --sourceFilter "{'**/node_modules/**':false,'**/**':true}" +``` +注意,这些匹配实际上会转换成一个过滤函数(如下),所以如果一个匹配成功则会直接返回,后面的将不再继续匹配。请注意先后顺序,如果存在包含关系的,可以调整上下顺序,最后如果都未匹配,则默认返回false +```js +const coverageOptions = { + entryFilter: (entry) => { + if (minimatch(entry.url, '**/node_modules/**')) { return false; } + if (minimatch(entry.url, '**/vendor.js')) { return false; } + if (minimatch(entry.url, '**/src/**')) { return true; } + return false; // else unmatched + } +}; +``` + +### Using `filter` instead of `entryFilter` and `sourceFilter` +如果你不想定义两个过滤器,可以使用 `filter` 选项代替,可以将多个匹配合并在一起. (Added in: v2.8) +```js +const coverageOptions = { + // combined patterns + filter: { + '**/node_modules/**': false, + '**/vendor.js': false, + '**/src/**': true + '**/**': true + } +}; +``` + +## Resolve `sourcePath` for the Source Files +当一个文件从sourcemap解包,它的路径可能是个虚拟路径, 此时可以使用`sourcePath`选项来修改文件路径。比如,我们测试了多个dist包的入口文件,它们的源文件可能包含了一些共同的文件,但路径可能不同,如果我们需要相同的文件覆盖率数据可以自动合并,那么需要使用`sourcePath`来统一这些相同文件的路径 +```js +const coverageOptions = { + sourcePath: (filePath) => { + // Remove the virtual prefix + const list = ['my-dist-file1/', 'my-dist-file2/']; + for (const str of list) { + if (filePath.startsWith(str)) { + return filePath.slice(str.length); + } + } + return filePath; + } +}; +``` +它也支持简单key/value的替换: +```js +const coverageOptions = { + sourcePath: { + 'my-dist-file1/': '', + 'my-dist-file2/': '' + } +}; +``` +解决文件路径不完整的问题: +```js +const path = require("path") + +// MCR coverage options +const coverageOptions = { + sourcePath: (filePath, info)=> { + if (!filePath.includes('/') && info.distFile) { + return `${path.dirname(info.distFile)}/${filePath}`; + } + return filePath; + } +} +``` + +## Adding Empty Coverage for Untested Files +默认,未测试的文件是不会包含到覆盖率报告的,需要使用`all`选项来为这些文件添加一个空的覆盖率,也就是0% +```js +const coverageOptions = { + all: './src', + + // 支持多个目录 + all: ['./src', './lib'], +}; +``` +未测试的文件也适用于`sourceFilter`过滤器. 而且也可以指定自己的`filter`过滤器 (可以返回文件类型来支持js或css的覆盖率格式): +```js +const coverageOptions = { + all: { + dir: ['./src'], + filter: { + // exclude files + '**/ignored-*.js': false, + '**/*.html': false, + // empty css coverage + '**/*.scss': "css", + '**/*': true + } + } +}; +``` +我们可能需要编译.ts, .jsx, .vue等等这样的文件, 这样才能被默认的AST解析器解析,以得到更多的覆盖率指标的数据 +```js +const path = require("path"); +const swc = require("@swc/core"); +const coverageOptions = { + all: { + dir: ['./src'], + transformer: async (entry) => { + const { code, map } = await swc.transform(entry.source, { + filename: path.basename(entry.url), + sourceMaps: true, + isModule: true, + jsc: { + parser: { + syntax: "typescript", + jsx: true + }, + transform: {} + } + }); + entry.source = code; + entry.sourceMap = JSON.parse(map); + } + } +}; +``` + +## onEnd Hook +结束回调可以用来自定义业务需求,比如检测覆盖率是否达标,对比每个指标的thresholds,如果低于要求的值则可以抛出一个错误退出 +```js +const EC = require('eight-colors'); +const coverageOptions = { + name: 'My Coverage Report', + outputDir: './coverage-reports', + onEnd: (coverageResults) => { + const thresholds = { + bytes: 80, + lines: 60 + }; + console.log('check thresholds ...', thresholds); + const errors = []; + const { summary } = coverageResults; + Object.keys(thresholds).forEach((k) => { + const pct = summary[k].pct; + if (pct < thresholds[k]) { + errors.push(`Coverage threshold for ${k} (${pct} %) not met: ${thresholds[k]} %`); + } + }); + if (errors.length) { + const errMsg = errors.join('\n'); + console.log(EC.red(errMsg)); + // throw new Error(errMsg); + // process.exit(1); + } + } +} +``` + +## Ignoring Uncovered Codes +使用特定的注释,以`v8 ignore `开头可以忽略未覆盖的代码: +- 忽略开始到结束 +```js +/* v8 ignore start */ +function uncovered() { +} +/* v8 ignore stop */ +``` +- 忽略接下来一行或者多行 +```js +/* v8 ignore next */ +const os = platform === 'wind32' ? 'Windows' : 'Other'; + +const os = platform === 'wind32' ? 'Windows' /* v8 ignore next */ : 'Other'; + +// v8 ignore next 3 +if (platform === 'linux') { + console.log('hello linux'); +} +``` +- 兼容支持 [c8 coverage](https://github.com/bcoe/c8/?tab=readme-ov-file#ignoring-all-lines-until-told) 或 [nodejs coverage](https://nodejs.org/docs/latest/api/test.html#collecting-code-coverage) 的语法格式 +```js +/* c8 ignore start */ +function uncovered() { +} +/* c8 ignore stop */ + +/* node:coverage disable */ +function uncovered() { +} +/* node:coverage enable */ +``` + +## Multiprocessing Support +> 多进程支持可以很好的解决异步并行的情况。所有的覆盖率数据会保存到`[outputDir]/.cache`,在报告生成之后,这些缓存数据会被清除。除非开启了[调试模式](#debug-for-coverage-and-sourcemap),或者使用了`raw`报告 +- 主进程,初始化,清理之前的缓存 +```js +const MCR = require('monocart-coverage-reports'); +const coverageOptions = require('path-to/same-options.js'); +const mcr = MCR(coverageOptions); +// clean previous cache before the start of testing +// unless the running environment is new and no cache +mcr.cleanCache(); +``` + +- 子进程1, 测试业务1 +```js +const MCR = require('monocart-coverage-reports'); +const coverageOptions = require('path-to/same-options.js'); +const mcr = MCR(coverageOptions); +await mcr.add(coverageData1); +``` + +- 子进程2, 测试业务2 +```js +const MCR = require('monocart-coverage-reports'); +const coverageOptions = require('path-to/same-options.js'); +const mcr = MCR(coverageOptions); +await mcr.add(coverageData2); +``` + +- 主进程,所有测试完成之后 +```js +// generate coverage reports after the completion of testing +const MCR = require('monocart-coverage-reports'); +const coverageOptions = require('path-to/same-options.js'); +const mcr = MCR(coverageOptions); +await mcr.generate(); +``` + +## Command Line +> 使用`mcr`命令行将使用`NODE_V8_COVERAGE=dir`来启动一个[子进程](https://nodejs.org/docs/latest/api/child_process.html)运行程序,直到正常退出,然后自动从`dir`目录来读取覆盖率数据,并生成覆盖率报告 + +- 全局安装 +```sh +npm i monocart-coverage-reports -g +mcr node ./test/specs/node.test.js -r v8,console-details --lcov +``` + +- 本地项目安装 +```sh +npm i monocart-coverage-reports +npx mcr node ./test/specs/node.test.js -r v8,console-details --lcov +``` + +- 命令行参数 +直接运行 `mcr` 或 `mcr --help` 查看所有CLI的参数 + +- 使用 `--` 可以隔离子程序参数,以免两种参数混淆 +```sh +mcr -c mcr.config.js -- sub-cli -c sub-cli.config.js +``` + +- 参见例子 + - [Mocha](#mocha) + - [TypeScript](#typescript) + - [AVA](#ava) + +## Config File +根据以下优先级加载配置文件 +- 自定义配置文件(如果没有指定则加载后面的默认配置文件): + - CLI: `mcr --config ` + - API: `await mcr.loadConfig("my-config-file-path")` +- `mcr.config.js` +- `mcr.config.cjs` +- `mcr.config.mjs` +- `mcr.config.json` - json format +- `mcr.config.ts` (requires preloading the ts execution module) + +## Merge Coverage Reports +以下这些使用场景可能需要使用合并覆盖率报告: +- 多个执行环境,比如Node.js服务端,以及浏览器客户端,比如`Next.js` +- 多种测试类型,比如`Jest`单元测试,以及`Playwright`的端到端自动化测试 +- 分布式测试,测试结果保存到了多台机器或不同的容器中 + +### Automatic Merging +- 默认`MCR`在执行`generate()`时会自动合并覆盖率数据。所以可以在[多进程支持](#multiprocessing-support)下,多次添加覆盖率数据,最后将自动合并 +- 比如`Next.js`就可以同时添加前后端覆盖率数据,最后再执行`generate()`生成覆盖率报告,见例子[nextjs-with-playwright](https://github.com/cenfun/nextjs-with-playwright) +- 使用`Codecov`在线覆盖率报告服务,请设置输出`codecov`报告, 它会生成专属的`codecov.json`,如果有多个`codecov.json`文件上传,它们会自动合并数据,参见[Codecov](#codecov) 和 [合并报告说明](https://docs.codecov.com/docs/merging-reports) + +### Manual Merging +手动合并覆盖率报告需要使用`raw`报告来导出原始的覆盖率数据到指定的目录 +- 比如,单元测试保存到`./coverage-reports/unit/raw`,见例子 + - `Jest` + [jest-monocart-coverage](https://github.com/cenfun/jest-monocart-coverage) + - `Vitest` + [vitest-monocart-coverage](https://github.com/cenfun/vitest-monocart-coverage) +```js +const coverageOptions = { + name: 'My Unit Test Coverage Report', + outputDir: "./coverage-reports/unit", + reports: [ + ['raw', { + // relative path will be "./coverage-reports/unit/raw" + // defaults to raw + outputDir: "raw" + }], + ['v8'], + ['console-details'] + ] +}; +``` + +- 同样的,E2E测试保存到`./coverage-reports/e2e/raw`. 见例子: + - `Playwright` + [monocart-reporter](https://github.com/cenfun/monocart-reporter) with coverage API + - `Playwright` + `MCR`, see [playwright-coverage](https://github.com/cenfun/playwright-coverage) + - see more [Integration Examples](#integration-examples) + +- 然后创建一个`merge-coverage.js`文件,使用`inputDir`参数导入`raw`数据,来生成合并的覆盖率报告. +```js +// merge-coverage.js +const fs = require('fs'); +const { CoverageReport } = require('monocart-coverage-reports'); +const inputDir = [ + './coverage-reports/unit/raw', + './coverage-reports/e2e/raw' +]; +const coverageOptions = { + name: 'My Merged Coverage Report', + inputDir, + outputDir: './coverage-reports/merged', + + // filter for both unit and e2e + entryFilter: { + '**/node_modules/**': false, + '**/*': true + }, + sourceFilter: { + '**/node_modules/**': false, + '**/src/**': true + }, + + sourcePath: (filePath, info) => { + // Unify the file path for the same files + // For example, the file index.js has different paths: + // unit: unit-dist/src/index.js + // e2e: e2e-dist/src/index.js + // return filePath.replace("unit-dist/", "").replace("e2e-dist/", "") + return filePath; + }, + + reports: [ + ['v8'], + ['console-details'] + ], + + onEnd: () => { + // remove the raw files if it useless + // inputDir.forEach((p) => { + // fs.rmSync(p, { + // recursive: true, + // force: true + // }); + // }); + } +}; +await new CoverageReport(coverageOptions).generate(); +``` +- 最后在所有测试完成后运行`node path/to/merge-coverage.js`. 所有的执行脚本大概如下: +```json +{ + "scripts": { + "test:unit": "jest", + "test:e2e": "playwright test", + "merge-coverage": "node path/to/merge-coverage.js", + "test": "npm run test:unit && npm run test:e2e && npm run merge-coverage" + } +} +``` +参见例子: [merge-code-coverage](https://github.com/cenfun/merge-code-coverage) + +## Common issues +> 常见问题 +### Unexpected coverage +覆盖率看起来不正确,多数情况是因为sourcemap转换的问题导致的. 可以先尝试设置构建工具的 `minify=false` 也就是不要压缩代码来解决。下面来看看sourcemap存在问题的具体原因: +```js +const a = tf ? 'true' : 'false'; + ^ ^ ^ + m1 p m2 +``` +上面是经过构建工具编译过的代码,通过AST分析,位置`p`对应的原始位置是我们要找的,而从sourcemap里仅能找到离`p`最近的位置映射`m1`和`m2`,也就是位置`p`并没有精确的映射保存到sourcemap里,从而无法直接获取精确的原始位置,但我们能知道`p`的原始位置应该在`m1`和`m2`之间。 +- 参见 [调试覆盖率和sourcemap](#debug-for-coverage-and-sourcemap) + +`MCR`如何解决这个问题: +- 1, 首先会尝试使用[`diff-sequences`](https://github.com/jestjs/jest/tree/main/packages/diff-sequences)工具来比较`m1`和`m2`之间的生成代码和原始代码,找到`p`对应的字符位置,可以解决绝大多数问题。但是如果代码是非JS格式的,比如Vue模板是HTML,或JSX这些,不管怎么比较也是很难精确找到对应位置的,甚至此时的sourcemap本身都比较乱。 +- 2, 然后就是通过分析[AST](https://github.com/acornjs/acorn),找到所有的functions, statements 和 branches,因为V8覆盖率本身不提供这些指标的覆盖率. (对于分支覆盖暂不支持`AssignmentPattern`类型,因为即使分析AST也无法从V8覆盖率找到它的数据)。 + + +### Unparsable source +源码无法解析问题。由上面我们知道`MCR`通过分析源码的AST获取更多指标的覆盖率信息,但源码如果不是标准的 ECMAScript,比如`ts`, `jsx`这些,那么分析的时候就会报错,此时我们可以手动来编译这些文件(可行但不推荐). +```js +import * as fs from "fs"; +import * as path from "path"; +import { fileURLToPath } from "url"; +import * as TsNode from 'ts-node'; +const coverageOptions = { + onEntry: async (entry) => { + const filePath = fileURLToPath(entry.url) + const originalSource = fs.readFileSync(filePath).toString("utf-8"); + const fileName = path.basename(filePath); + const tn = TsNode.create({}); + const source = tn.compile(originalSource, fileName); + entry.fake = false; + entry.source = source; + } +} +``` + +### JavaScript heap out of memory +内存溢出问题可能出现在有太多的原生V8覆盖率文件要处理. 我们可以使用Node.js的一个选项来增加内存使用: +```sh +- run: npm run test:coverage + env: + NODE_OPTIONS: --max-old-space-size=8192 +``` + + +## Debug for Coverage and Sourcemap +> 当你觉得覆盖率存在问题的时候,`MCR`支持自行调试来核验覆盖率的准确性 +- 首先打开调试设置`logging: 'debug'` +```js +const coverageOptions = { + logging: 'debug', + reports: [ + ['v8'], + ['console-details'] + ] +}; +``` +调试模式下,也就是`logging`为`debug`的时候, 原始的覆盖率数据将保留在`[outputDir]/.cache`缓存目录下,不会删除,如果使用了`raw`报告,那么位置变为`[outputDir]/raw`下,这样我们可以打开v8报告的html文件,通过下面新增的一些调试帮助信息来核对覆盖率 +![](./assets/debug-coverage.png) + +- 调试sourcemap可以直接使用[Source Map Visualization](https://evanw.github.io/source-map-visualization/) (esbuild作者提供的sourcemap在线查看器) + +![](./assets/debug-sourcemap.png) + +- 生成额外的source和sourcemap文件到cache或raw文件夹 +```js +const coverageOptions = { + logging: 'debug', + sourceMap: true +}; +``` + +- 使用环境变量`MCR_LOG_TIME`显示时间日志 +```js +process.env.MCR_LOG_TIME = true +``` + +## Integration with Any Testing Framework +通用集成方案 +- 通过API接口在程序集成 + - 首先,要自行收集覆盖率数据,然后,添加到报告实例 `await mcr.add(coverageData)` + - 最后,生成覆盖率报告 `await mcr.generate()` + - 参见 [多进程支持](#multiprocessing-support) +- 通过CLI命令行与其他命令行集成 + - 直接在其他命令行前面添加mcr的命令行即可 `mcr your-cli --your-arguments` + - 参见 [命令行](#command-line) + +## Integration Examples + +### [Playwright](https://github.com/microsoft/playwright) +- [playwright-coverage](https://github.com/cenfun/playwright-coverage) - Example for Playwright coverage reports +- [playwright-bdd-coverage](https://github.com/cenfun/playwright-bdd-coverage) - Example for Playwright BDD coverage reports +- [monocart-reporter](https://github.com/cenfun/monocart-reporter) - Playwright custom reporter, supports generating [Code coverage report](https://github.com/cenfun/monocart-reporter?#code-coverage-report) +- Coverage for component testing with `monocart-reporter`: + - [playwright-ct-vue](https://github.com/cenfun/playwright-ct-vue) + - [playwright-ct-react](https://github.com/cenfun/playwright-ct-react) + - [playwright-ct-svelte](https://github.com/cenfun/playwright-ct-svelte) +- Coverage for Next.js, both server side and client side: + - [nextjs-with-playwright](https://github.com/cenfun/nextjs-with-playwright) + - [nextjs-with-playwright-istanbul](https://github.com/cenfun/nextjs-with-playwright-istanbul) +- Coverage for Remix: + - [remix-with-playwright](https://github.com/cenfun/remix-with-playwright) +- see [Collecting V8 Coverage Data with Playwright](#collecting-v8-coverage-data-with-playwright) + +### [c8](https://github.com/bcoe/c8) +- c8 has integrated `MCR` as an experimental feature since [v10.1.0](https://github.com/bcoe/c8/releases/tag/v10.1.0) +```sh +c8 --experimental-monocart --reporter=v8 --reporter=console-details node foo.js +``` + +### [CodeceptJS](https://github.com/codeceptjs/CodeceptJS) +- CodeceptJS is a [BDD](https://codecept.io/bdd/) + [AI](https://codecept.io/ai/) testing framework for e2e testing, it has integrated `MCR` since [v3.5.15](https://github.com/codeceptjs/CodeceptJS/releases/tag/3.5.15), see [plugins/coverage](https://codecept.io/plugins/#coverage) + +### [VSCode](https://github.com/microsoft/vscode) +- [Monocart Coverage for VSCode](https://github.com/cenfun/monocart-coverage-vscode) - Shows native V8 code coverage in VSCode + +### [Jest](https://github.com/jestjs/jest/) +- [jest-monocart-coverage](https://github.com/cenfun/jest-monocart-coverage) - Jest custom reporter for coverage reports +- [merge-code-coverage](https://github.com/cenfun/merge-code-coverage) - Example for merging code coverage (Jest unit + Playwright e2e sharding) + +### [Vitest](https://github.com/vitest-dev/vitest) +- [vitest-monocart-coverage](https://github.com/cenfun/vitest-monocart-coverage) - Vitest custom provider module for coverage reports +- [merge-code-coverage-vitest](https://github.com/cenfun/merge-code-coverage-vitest) - Example for merging code coverage (Vitest unit + Playwright e2e sharding) + +### [Node Test Runner](https://nodejs.org/docs/latest/api/test.html) +- [node-monocart-coverage](https://github.com/cenfun/node-monocart-coverage) - Custom reporter for Node test runner for coverage + +### [Puppeteer](https://github.com/puppeteer/puppeteer/) +- [jest-puppeteer-coverage](https://github.com/cenfun/jest-puppeteer-coverage) - Example for Jest puppeteer coverage +- [maplibre-gl-js](https://github.com/maplibre/maplibre-gl-js) - Example for Jest (unit) + Puppeteer (e2e) + Codecov +- see [Collecting Raw V8 Coverage Data with Puppeteer](#collecting-raw-v8-coverage-data-with-puppeteer) + +### [Cypress](https://github.com/cypress-io/cypress) +- [cypress-monocart-coverage](https://github.com/cenfun/cypress-monocart-coverage) - Cypress plugin for coverage reports + +### [WebdriverIO](https://github.com/webdriverio/webdriverio) +- [wdio-monocart-service](https://github.com/cenfun/wdio-monocart-service) - WebdriverIO service for coverage reports + +### [Storybook Test Runner](https://github.com/storybookjs/test-runner) +- [storybook-monocart-coverage](https://github.com/cenfun/storybook-monocart-coverage) - Example for Storybook V8 coverage reports + +### [TestCafe](https://github.com/DevExpress/testcafe) +- [testcafe-reporter-coverage](https://github.com/cenfun/testcafe-reporter-coverage) - TestCafe custom reporter for coverage reports + +### [Selenium Webdriver](https://github.com/seleniumhq/selenium) +- [selenium-webdriver-coverage](https://github.com/cenfun/selenium-webdriver-coverage) - Example for Selenium Webdriver V8 coverage reports + +### [Mocha](https://github.com/mochajs/mocha) +```sh +mcr mocha ./test/**/*.js +``` + +### [TypeScript](https://github.com/microsoft/typescript) + +- [tsx](https://github.com/privatenumber/tsx) +```sh +cross-env NODE_OPTIONS="--import tsx" npx mcr tsx ./src/example.ts +cross-env NODE_OPTIONS="--import tsx" npx mcr mocha ./test/**/*.ts +# Node.js v18.19.0 + +mcr --import tsx tsx ./src/example.ts +mcr --import tsx mocha ./test/**/*.ts +``` +- [ts-node](https://github.com/TypeStrong/ts-node) +```sh +cross-env NODE_OPTIONS="--loader ts-node/esm --no-warnings" npx mcr ts-node ./src/example.ts +cross-env NODE_OPTIONS="--loader ts-node/esm --no-warnings" npx mcr mocha ./test/**/*.ts +``` + + +### [AVA](https://github.com/avajs/ava) +```sh +mcr ava +``` + +### [Codecov](https://codecov.com/) +[![codecov](https://codecov.io/gh/cenfun/monocart-coverage-reports/graph/badge.svg?token=H0LW7UKYU3)](https://codecov.io/gh/cenfun/monocart-coverage-reports) +- Supports native `codecov` built-in report ([specification](https://docs.codecov.com/docs/codecov-custom-coverage-format)) +```js +const coverageOptions = { + outputDir: "./coverage-reports", + reports: [ + ['codecov'] + ] +}; +``` +- Github actions: +```yml +- name: Codecov + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ./coverage-reports/codecov.json +``` + +### [Codacy](https://www.codacy.com/) +[![Codacy](https://app.codacy.com/project/badge/Coverage/715016ea8e90479db875b777db8bad55)](https://app.codacy.com/gh/cenfun/monocart-coverage-reports/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage) +- Using `lcov` report: +```js +const coverageOptions = { + outputDir: "./coverage-reports", + lcov: true +}; +``` +- Github actions: +```yml +- name: Codacy Coverage Reporter + uses: codacy/codacy-coverage-reporter-action@v1 + with: + project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} + coverage-reports: ./docs/mcr/lcov.info +``` + +### [Coveralls](https://coveralls.io/) +[![Coverage Status](https://coveralls.io/repos/github/cenfun/monocart-coverage-reports/badge.svg?branch=main)](https://coveralls.io/github/cenfun/monocart-coverage-reports?branch=main) +- Using `lcov` report: +```js +const coverageOptions = { + outputDir: "./coverage-reports", + lcov: true +}; +``` +- Github actions: +```yml +- name: Coveralls + uses: coverallsapp/github-action@v2 + with: + files: ./coverage-reports/lcov.info +``` + +### [Sonar Cloud](https://sonarcloud.io/) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=monocart-coverage-reports&metric=coverage)](https://sonarcloud.io/summary/new_code?id=monocart-coverage-reports) +- Using `lcov` report. Github actions example: +```yml +- name: Analyze with SonarCloud + uses: sonarsource/sonarcloud-github-action@master + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + with: + projectBaseDir: ./ + args: > + -Dsonar.organization=cenfun + -Dsonar.projectKey=monocart-coverage-reports + -Dsonar.projectName=monocart-coverage-reports + -Dsonar.javascript.lcov.reportPaths=docs/mcr/lcov.info + -Dsonar.sources=lib + -Dsonar.tests=test + -Dsonar.exclusions=dist/*,packages/* +``` + +## Contributing +- Node.js 20+ +- VSCode (extensions: eslint/stylelint/vue) +```sh +npm install +npx playwright install --with-deps + +npm run build +npm run test + +npm run dev +``` +- Refreshing `eol=lf` for snapshot of test (Windows) +```sh +git add . -u +git commit -m "Saving files before refreshing line endings" + +npm run eol +``` + +## Thanks +- [@bcoe](https://github.com/bcoe) +- [@edumserrano](https://github.com/edumserrano) \ No newline at end of file diff --git a/node_modules/monocart-coverage-reports/lib/assets.js b/node_modules/monocart-coverage-reports/lib/assets.js new file mode 100644 index 0000000..218a3df --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/assets.js @@ -0,0 +1,98 @@ +const fs = require('fs'); +const path = require('path'); +const { deflateSync } = require('lz-utils'); +const Util = require('./utils/util.js'); +const assetsMap = require('./packages/monocart-coverage-assets.js'); + +const Assets = { + + getFileContent: (id) => { + const content = assetsMap[id]; + if (!content) { + Util.logError(`Not found module: ${id}`); + return ''; + } + return content; + }, + + saveHtmlReport: async (options) => { + + const { + inline, + reportData, + jsFiles, + assetsPath, + outputDir, + htmlFile, + + saveReportPath, + + reportDataFile + } = options; + + // save path + const htmlPath = path.resolve(outputDir, htmlFile); + const reportPath = Util.relativePath(htmlPath); + if (saveReportPath) { + reportData[saveReportPath] = reportPath; + } + + // report data + const reportDataCompressed = deflateSync(JSON.stringify(reportData)); + const reportDataStr = `window.reportData = '${reportDataCompressed}';`; + + // js libs + const jsList = []; + + // deps + jsFiles.forEach((id) => { + jsList.push({ + filename: `${id}.js`, + str: Assets.getFileContent(id) + }); + }); + + // html content + let htmlStr = ''; + const EOL = Util.getEOL(); + if (inline) { + htmlStr = [ + '' + ].join(EOL); + } else { + + await Util.writeFile(path.resolve(outputDir, reportDataFile), reportDataStr); + + const assetsDir = path.resolve(outputDir, assetsPath); + const relAssetsDir = Util.relativePath(assetsDir, outputDir); + + for (const item of jsList) { + const filePath = path.resolve(assetsDir, item.filename); + if (!fs.existsSync(filePath)) { + await Util.writeFile(filePath, item.str); + } + } + + htmlStr = [ + ``, + ... jsList.map((it) => ``) + ].join(EOL); + } + + // html + const template = Assets.getFileContent('template'); + const html = Util.replace(template, { + title: reportData.title, + content: htmlStr + }); + + await Util.writeFile(htmlPath, html); + + return reportPath; + } +}; + +module.exports = Assets; diff --git a/node_modules/monocart-coverage-reports/lib/cli.js b/node_modules/monocart-coverage-reports/lib/cli.js new file mode 100755 index 0000000..caae0ac --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/cli.js @@ -0,0 +1,251 @@ +#!/usr/bin/env node + +const path = require('path'); +const EC = require('eight-colors'); + +const { program } = require('commander'); +const { foregroundChild } = require('foreground-child'); + +const MCR = require('./index.js'); +const Util = require('./utils/util.js'); + +const version = require('../package.json').version; + +const getRegisterPath = (filename) => { + const rel = Util.relativePath(path.resolve(__dirname, 'register', filename)); + if (rel.startsWith('.')) { + return rel; + } + return `./${rel}`; +}; + +const getInitNodeOptions = async (cliOptions) => { + const nodeOptions = []; + if (process.env.NODE_OPTIONS) { + nodeOptions.push(process.env.NODE_OPTIONS); + } + + if (cliOptions.import) { + nodeOptions.push(`--import ${cliOptions.import}`); + // for load mcr.config.ts + await import(cliOptions.import); + } else if (cliOptions.require) { + nodeOptions.push(`--require ${cliOptions.require}`); + // for load mcr.config.ts + await import(cliOptions.require); + } + + return nodeOptions; +}; + +const getPreloadType = (nodeOptions) => { + const hasImport = nodeOptions.find((it) => it.includes('--import')); + if (hasImport) { + return '--import'; + } + return '--require'; +}; + +const checkRegisterFeature = () => { + const nv = process.versions.node; + + // "module.register" added in Node.js: v20.6.0 + // if (Util.cmpVersion(nv, '20.6.0') >= 0) { + // return true; + // } + // but also added in: v18.19.0 + const requiredNV = '18.19.0'; + if (Util.cmpVersion(nv, requiredNV) < 0) { + Util.logInfo(`The current Node.js version "${nv}" does NOT support "module.register", it requires "${requiredNV}" or higher.`); + return false; + } + + // could be < 20.6.0 but just ignore it, please using latest minor version + + return true; +}; + +const loadEnv = (cliOptions) => { + if (!cliOptions.env) { + return; + } + const envFile = cliOptions.env === true ? '.env' : cliOptions.env; + const loadEnvFile = process.loadEnvFile; + if (typeof loadEnvFile === 'function') { + loadEnvFile(envFile); + } +}; + +const initNodeOptions = async (cliOptions) => { + + loadEnv(cliOptions); + + const supportRegister = checkRegisterFeature(); + if (!supportRegister) { + return; + } + + const nodeOptions = await getInitNodeOptions(cliOptions); + // console.log(nodeOptions); + + const preloadType = getPreloadType(nodeOptions); + + // export source after + if (preloadType === '--import') { + const importPath = getRegisterPath('register.mjs'); + nodeOptions.unshift(`--import ${importPath}`); + } else { + const requirePath = getRegisterPath('register.js'); + nodeOptions.unshift(`--require ${requirePath}`); + } + + // console.log(nodeOptions); + const nodeOptionsStr = nodeOptions.join(' '); + Util.logDebug(`node options: ${EC.cyan(nodeOptionsStr)}`); + + process.env.NODE_OPTIONS = nodeOptionsStr; + +}; + +const initNodeV8CoverageDir = (coverageOptions) => { + // dir for node v8 coverage + const nodeV8CoverageDir = Util.relativePath(path.resolve(coverageOptions.outputDir, '.v8-coverage')); + process.env.NODE_V8_COVERAGE = nodeV8CoverageDir; + // clean v8 cache before running + Util.rmSync(nodeV8CoverageDir); + // Util.logInfo(`V8 coverage dir: ${EC.cyan(nodeV8CoverageDir)}`); + + return nodeV8CoverageDir; +}; + +const mergeCoverage = async (cliOptions) => { + const coverageReport = MCR(cliOptions); + await coverageReport.loadConfig(cliOptions.config); + coverageReport.cleanCache(); + await coverageReport.generate(); +}; + +const executeCommand = async (command, cliOptions) => { + + Util.logInfo(`Execute: ${EC.cyan(command)}`); + + if (command === 'merge') { + return mergeCoverage(cliOptions); + } + + // before load config + await initNodeOptions(cliOptions); + + // console.log(options); + const coverageReport = MCR(cliOptions); + await coverageReport.loadConfig(cliOptions.config); + coverageReport.cleanCache(); + + const coverageOptions = coverageReport.options; + const nodeV8CoverageDir = initNodeV8CoverageDir(coverageOptions); + + // ========================================= + // onStart hook + const onStart = coverageOptions.onStart; + if (typeof onStart === 'function') { + await onStart(coverageReport); + } + // ========================================= + + const subprocess = foregroundChild(command, { + shell: true + }, async (code, signal) => { + + // generate coverage even it is failed. code != 0 + + // ========================================= + // onReady hook before adding coverage data. + // Sometimes, the child process has not yet finished writing the coverage data, and it needs to wait here. + const onReady = coverageOptions.onReady; + if (typeof onReady === 'function') { + await onReady(coverageReport, nodeV8CoverageDir, subprocess); + } + // ========================================= + + await coverageReport.addFromDir(nodeV8CoverageDir); + await coverageReport.generate(); + + // remove nodeV8CoverageDir + if (!Util.isDebug()) { + Util.rmSync(nodeV8CoverageDir); + } + + return process.exitCode; + }); + +}; + +process.on('uncaughtException', function(err) { + Util.logError(`Process uncaughtException: ${err.message}`); + console.log(err.stack); +}); + +// the -- separator +const argv = []; +const subArgv = []; +let separator = false; +process.argv.forEach((it) => { + if (!separator && it === '--') { + separator = true; + } + if (separator) { + subArgv.push(it); + } else { + argv.push(it); + } +}); + +program + .name('mcr') + .description('CLI to generate coverage reports') + .version(version, '-v, --version', 'output the current version') + .argument('[command]', 'command to execute') + .allowUnknownOption() + .allowExcessArguments() + .option('-c, --config ', 'custom config file path') + .option('-l, --logging ', 'off, error, info, debug') + + .option('-n, --name ', 'report name for title') + .option('-r, --reports ', 'coverage reports to use') + + .option('-o, --outputDir ', 'output dir for reports') + .option('-i, --inputDir ', 'input dir for merging raw files') + .option('-b, --baseDir ', 'base dir for normalizing path') + + .option('-a, --all ', 'include all files from dir') + + .option('--entryFilter ', 'entry url filter') + .option('--sourceFilter ', 'source path filter') + .option('--filter ', 'the combined filter') + + .option('--outputFile ', 'output file for v8 report') + .option('--inline', 'inline html for v8 report') + .option('--assetsPath ', 'assets path if not inline') + + .option('--lcov', 'generate lcov.info file') + + .option('--import ', 'preload module at startup') + .option('--require ', 'preload module at startup') + + .option('--env [path]', 'env file (default: ".env")') + + .action((_command, cliOptions) => { + const args = [].concat(program.args).concat(subArgv); + if (args[0] === '--') { + args.shift(); + } + const command = args.join(' ').trim(); + if (!command) { + program.outputHelp(); + return; + } + + executeCommand(command, cliOptions); + }); + +program.parse(argv); diff --git a/node_modules/monocart-coverage-reports/lib/client/cdp-client.js b/node_modules/monocart-coverage-reports/lib/client/cdp-client.js new file mode 100644 index 0000000..c91efaf --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/client/cdp-client.js @@ -0,0 +1,143 @@ + +const EC = require('eight-colors'); + +const { WebSocket } = require('../packages/monocart-coverage-vendor.js'); +const Util = require('../utils/util.js'); + +const WSSession = require('./ws-session.js'); +const CoverageClient = require('./coverage-client.js'); + +const getDebuggerUrl = async (options) => { + + const protocol = options.secure ? 'https' : 'http'; + + const url = `${protocol}://${options.host}:${options.port}/json/list`; + const [err, res] = await Util.request(url); + if (err) { + return [err]; + } + + const targets = res.data; + if (!Util.isList(targets)) { + return [new Error(`Invalid response data: ${url}`)]; + } + + // console.log(targets); + const target = options.target(targets); + if (!target) { + return [new Error(`Not found target: ${url}`)]; + } + + return [null, target.webSocketDebuggerUrl]; +}; + +const getCDPUrl = async (options) => { + if (options.url) { + return [null, options.url]; + } + + // get debugger url + const [err, debuggerUrl] = await getDebuggerUrl(options); + if (err) { + return [err]; + } + + return [null, debuggerUrl]; + +}; + +const getCDPSession = async (options) => { + + if (options.session) { + return [null, options.session]; + } + + // create session + const [err, url] = await getCDPUrl(options); + + return new Promise((resolve) => { + + if (err) { + resolve([err]); + return; + } + + const timeoutId = setTimeout(() => { + resolve([new Error(`Timeout to connect: ${url}`)]); + }, options.timeout); + + Util.logDebug(`Connect to ${url}`); + const ws = new WebSocket(url, [], { + maxPayload: 256 * 1024 * 1024, + perMessageDeflate: false, + followRedirects: true, + ... options.ws + }); + + ws.once('error', (wsErr) => { + clearTimeout(timeoutId); + resolve([wsErr]); + }); + + ws.once('open', () => { + clearTimeout(timeoutId); + Util.logDebug(`${EC.green('Connected')} ${url}`); + const session = new WSSession(ws); + resolve([null, session]); + }); + + }); + + +}; + + +const CDPClient = async (cdpOptions) => { + + const defaultOptions = { + session: null, + url: null, + port: 9222, + host: 'localhost', + secure: false, + target: (targets) => { + // defaults to first page + const page = targets.find((it) => it.webSocketDebuggerUrl && it.type === 'page'); + if (page) { + return page; + } + return targets.find((it) => it.webSocketDebuggerUrl); + }, + ws: {}, + timeout: 10 * 1000 + }; + + if (typeof cdpOptions === 'string') { + cdpOptions = { + url: cdpOptions + }; + } + + const options = { + ... defaultOptions, + ... cdpOptions + }; + + const [err, session] = await getCDPSession(options); + + return new Promise((resolve) => { + + if (err) { + Util.logError(err); + resolve(); + return; + } + + const helper = new CoverageClient(session); + resolve(helper); + + }); + +}; + +module.exports = CDPClient; diff --git a/node_modules/monocart-coverage-reports/lib/client/coverage-client.js b/node_modules/monocart-coverage-reports/lib/client/coverage-client.js new file mode 100644 index 0000000..c6e2d65 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/client/coverage-client.js @@ -0,0 +1,322 @@ +const Util = require('../utils/util.js'); + +const bindEvents = (target, events) => { + Object.keys(events).forEach((eventType) => { + target.on(eventType, events[eventType]); + }); +}; + +const unbindEvents = (target, events) => { + Object.keys(events).forEach((eventType) => { + target.off(eventType, events[eventType]); + }); +}; + +// keep same ranges with playwright +// eslint-disable-next-line complexity +const convertToDisjointRanges = (nestedRanges) => { + const points = []; + for (const range of nestedRanges) { + points.push({ + offset: range.start, + type: 0, + range + }); + points.push({ + offset: range.end, + type: 1, + range + }); + } + // Sort points to form a valid parenthesis sequence. + points.sort((a, b) => { + // Sort with increasing offsets. + if (a.offset !== b.offset) { + return a.offset - b.offset; + } + // All "end" points should go before "start" points. + if (a.type !== b.type) { + return b.type - a.type; + } + const aLength = a.range.end - a.range.start; + const bLength = b.range.end - b.range.start; + // For two "start" points, the one with longer range goes first. + if (a.type === 0) { + return bLength - aLength; + } + // For two "end" points, the one with shorter range goes first. + return aLength - bLength; + }); + + const hitCountStack = []; + const results = []; + let lastOffset = 0; + // Run scanning line to intersect all ranges. + for (const point of points) { + if (hitCountStack.length && lastOffset < point.offset && hitCountStack[hitCountStack.length - 1] > 0) { + const lastResult = results.length ? results[results.length - 1] : null; + if (lastResult && lastResult.end === lastOffset) { + lastResult.end = point.offset; + } else { + results.push({ + start: lastOffset, + end: point.offset + }); + } + } + lastOffset = point.offset; + if (point.type === 0) { + hitCountStack.push(point.range.count); + } else { + hitCountStack.pop(); + } + } + // Filter out empty ranges. + return results.filter((range) => range.end - range.start > 1); +}; + +class CoverageClient { + constructor(session) { + this.session = session; + } + + // ================================================================================================= + async startJSCoverage() { + if (!this.session || this.enabledJS) { + return; + } + this.enabledJS = true; + this.scriptSources = new Map(); + this.jsEvents = { + 'Debugger.scriptParsed': (params) => { + const { scriptId } = params; + this.session.send('Debugger.getScriptSource', { + scriptId + }).then((res) => { + this.scriptSources.set(scriptId, res && res.scriptSource); + }); + }, + 'Debugger.paused': () => { + this.send('Debugger.resume'); + } + }; + + bindEvents(this.session, this.jsEvents); + + await this.session.send('Debugger.enable'); + await this.session.send('Debugger.setSkipAllPauses', { + skip: true + }); + + await this.session.send('Profiler.enable'); + await this.session.send('Profiler.startPreciseCoverage', { + callCount: true, + detailed: true + }); + + // Util.logDebug('startJSCoverage'); + + } + + async stopJSCoverage() { + if (!this.session || !this.enabledJS) { + return; + } + + const profileResponse = await this.session.send('Profiler.takePreciseCoverage'); + await this.session.send('Profiler.stopPreciseCoverage'); + await this.session.send('Profiler.disable'); + // await this.session.send('Debugger.disable'); + + unbindEvents(this.session, this.jsEvents); + this.jsEvents = null; + + const jsCoverage = []; + + // console.log('coverageList', coverageList); + if (profileResponse && profileResponse.result) { + profileResponse.result.forEach((entry) => { + // anonymous url + entry.url = entry.url || ''; + // add source + const source = this.scriptSources.get(entry.scriptId); + if (!source) { + Util.logDebug(`Not found js source: ${entry.url}`); + } + entry.source = source || ''; + jsCoverage.push(entry); + }); + } + + this.scriptSources.clear(); + this.enabledJS = false; + + return jsCoverage; + } + + // ================================================================================================= + + async startCSSCoverage() { + if (!this.session || this.enabledCSS) { + return; + } + this.enabledCSS = true; + this.styleEntries = new Map(); + + this.cssEvents = { + 'CSS.styleSheetAdded': (e) => { + const { sourceURL, styleSheetId } = e.header; + + // anonymous url + const url = sourceURL || ''; + this.session.send('CSS.getStyleSheetText', { + styleSheetId + }).then((res) => { + // add source + const text = res && res.text; + if (!text) { + Util.logDebug(`Not found css source: ${url}`); + } + this.styleEntries.set(styleSheetId, { + url, + text: text || '', + ranges: [] + }); + }); + } + }; + + bindEvents(this.session, this.cssEvents); + + await this.session.send('DOM.enable'); + await this.session.send('CSS.enable'); + await this.session.send('CSS.startRuleUsageTracking'); + + // Util.logDebug('startCSSCoverage'); + } + + async stopCSSCoverage() { + if (!this.session || !this.enabledCSS) { + return; + } + + const ruleTrackingResponse = await this.session.send('CSS.stopRuleUsageTracking'); + await this.session.send('CSS.disable'); + await this.session.send('DOM.disable'); + + unbindEvents(this.session, this.cssEvents); + this.cssEvents = null; + + const cssCoverage = []; + + if (ruleTrackingResponse) { + for (const usage of ruleTrackingResponse.ruleUsage) { + const entry = this.styleEntries.get(usage.styleSheetId); + if (entry) { + entry.ranges.push({ + start: usage.startOffset, + end: usage.endOffset, + count: usage.used ? 1 : 0 + }); + } + } + this.styleEntries.forEach((entry) => { + entry.ranges = convertToDisjointRanges(entry.ranges); + cssCoverage.push(entry); + }); + } + + this.styleEntries.clear(); + this.enabledCSS = false; + + return cssCoverage; + } + + // ================================================================================================= + + async startCoverage() { + await Promise.all([ + this.startJSCoverage(), + this.startCSSCoverage() + ]); + } + + async stopCoverage() { + if (!this.session) { + return; + } + const [jsCoverage, cssCoverage] = await Promise.all([ + this.stopJSCoverage(), + this.stopCSSCoverage() + ]); + // could be undefined + let coverageList = []; + if (jsCoverage) { + coverageList = coverageList.concat(jsCoverage); + } + if (cssCoverage) { + coverageList = coverageList.concat(cssCoverage); + } + return coverageList; + } + + // ================================================================================================= + // write the coverage started by NODE_V8_COVERAGE to disk on demand + async writeCoverage() { + if (!this.session) { + return; + } + + await this.session.send('Runtime.enable'); + + // write the coverage started by NODE_V8_COVERAGE to disk on demand + const res = await this.session.send('Runtime.evaluate', { + expression: `new Promise((resolve) => { + require("v8").takeCoverage(); + resolve(process.env.NODE_V8_COVERAGE); + })`, + includeCommandLineAPI: true, + returnByValue: true, + awaitPromise: true + }); + + await this.session.send('Runtime.disable'); + + return res && res.result && res.result.value; + } + + // get istanbul coverage data + async getIstanbulCoverage(coverageKey = '__coverage__') { + if (!this.session) { + return; + } + + await this.session.send('Runtime.enable'); + + // both browser and Node.js + const res = await this.session.send('Runtime.evaluate', { + expression: `new Promise((resolve) => { + const globalTarget = typeof window !== 'undefined' ? window : global; + resolve(globalTarget['${coverageKey}']); + })`, + includeCommandLineAPI: true, + returnByValue: true, + awaitPromise: true + }); + + await this.session.send('Runtime.disable'); + + return res && res.result && res.result.value; + } + + // ================================================================================================= + async close() { + if (!this.session) { + return; + } + await this.session.detach(); + this.session = null; + } +} + +module.exports = CoverageClient; diff --git a/node_modules/monocart-coverage-reports/lib/client/ws-session.js b/node_modules/monocart-coverage-reports/lib/client/ws-session.js new file mode 100644 index 0000000..cb35ad3 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/client/ws-session.js @@ -0,0 +1,63 @@ +const { EventEmitter } = require('events'); + +class WSSession extends EventEmitter { + constructor(ws) { + super(); + this.ws = ws; + this.requestId = 1; + this.requestCache = new Map(); + ws.on('message', (data, isBinary) => { + + const message = JSON.parse(data); + // console.log(message); + + const { id, method } = message; + if (id) { + const request = this.requestCache.get(id); + this.requestCache.delete(id); + if (request) { + request.resolve(message.result); + } + return; + } + + if (method) { + this.emit(method, message.params, message.sessionId); + } + + }); + } + + send(method, params) { + return new Promise((resolve, reject) => { + if (!this.ws) { + reject(new Error('Invalid websocket')); + return; + } + const id = this.requestId++; + const message = { + id, + method, + params: params || {} + }; + this.ws.send(JSON.stringify(message), (err) => { + if (err) { + reject(err); + return; + } + this.requestCache.set(id, { + resolve + }); + }); + }); + } + + detach() { + if (this.ws) { + this.ws.terminate(); + this.ws = null; + } + } +} + +module.exports = WSSession; diff --git a/node_modules/monocart-coverage-reports/lib/converter/ast-visitor.js b/node_modules/monocart-coverage-reports/lib/converter/ast-visitor.js new file mode 100644 index 0000000..b25fb5b --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/converter/ast-visitor.js @@ -0,0 +1,809 @@ +const Util = require('../utils/util.js'); + +const BranchTypes = { + ConditionalExpression: 'ConditionalExpression', + LogicalExpression: 'LogicalExpression', + IfStatement: 'IfStatement', + SwitchStatement: 'SwitchStatement', + AssignmentPattern: 'AssignmentPattern' +}; + +const setGeneratedOnly = (block, generatedOnly) => { + if (block && generatedOnly) { + block.generatedOnly = true; + } +}; + +const getParentFunctionState = (reverseParents) => { + const parentFunction = reverseParents.find((it) => it._state && it._state.isFunction); + if (!parentFunction) { + return; + } + return parentFunction._state; +}; + +const getParentCount = (reverseParents, functionCount) => { + // parent count + const parent = reverseParents.find((it) => it._state); + if (parent) { + return parent._state.count; + } + // root function count + return functionCount; +}; + +const getFunctionRange = (start, end, type, coverageInfo) => { + + const { + functionMap, functionNameMap, functionStaticRanges, functionUncoveredRanges + } = coverageInfo; + + // exact matched in functionMap + const range = functionMap.get(start); + if (range) { + return range; + } + // exact matched in functionNameMap + const nameRange = functionNameMap.get(start); + if (nameRange) { + return nameRange; + } + + if (type === 'StaticBlock' && functionStaticRanges.length) { + const staticRange = Util.findInRanges(start, end, functionStaticRanges, 'startOffset', 'endOffset'); + if (staticRange) { + return staticRange; + } + } + + // find in uncoveredRanges + return Util.findInRanges(start, end, functionUncoveredRanges, 'startOffset', 'endOffset'); +}; + +const getFunctionBlock = (start, end, functionState) => { + if (!functionState) { + return; + } + + const { range } = functionState; + if (!range) { + return; + } + + const { + blockMap, blockUncoveredRanges, blockCoveredRanges + } = range; + + if (!blockMap) { + return; + } + + const block = blockMap.get(start); + if (block) { + return block; + } + + const uncoveredBlock = Util.findInRanges(start, end, blockUncoveredRanges, 'startOffset', 'endOffset'); + if (uncoveredBlock) { + return uncoveredBlock; + } + + // the block is not exact correct, if there is a block wrapped + // [x8]{ var a = b || [x4]c }, b is no block, but it can be found in x8 block + const coveredBlocks = blockCoveredRanges.filter((it) => start >= it.startOffset && end <= it.endOffset); + if (coveredBlocks.length) { + return coveredBlocks.pop(); + } + +}; + +const addNodeCount = (item) => { + + const { node, reverseParents } = item; + + if (node._state) { + return; + } + + const { start, end } = node; + const functionState = getParentFunctionState(reverseParents); + const block = getFunctionBlock(start, end, functionState); + if (block) { + node._state = { + count: block.count + }; + } + +}; + +// ======================================================================================= + +const createBranchGroup = (type, node, parents, branchMap) => { + const { start, end } = node; + // clone and reverse parents + const reverseParents = [].concat(parents).reverse(); + const group = { + type, + + start, + // could be updated if multiple locations + end, + + locations: [], + reverseParents + }; + + if (type === BranchTypes.LogicalExpression) { + // && or || + group.operator = node.operator; + } + + // could be same start + const branchKey = `${start}_${end}`; + + branchMap.set(branchKey, group); + return group; +}; + +const addBranch = (group, node, locationMap) => { + const { + start, end, type + } = node; + + const branchKey = `${group.start}_${group.end}`; + + const branchInfo = { + // for get previous group for LogicalExpression + branchKey, + start, + end, + // branch count default to 0 + count: 0 + }; + + if (type === 'SwitchCase') { + + // console.log(node); + + // check break + if (node.consequent) { + const breakItem = node.consequent.find((it) => it.type === 'BreakStatement'); + if (breakItem) { + branchInfo.hasBreak = true; + } + } + + // check default + if (!node.test) { + branchInfo.isDefault = true; + } + } + + group.locations.push(branchInfo); + + // update group end + if (end > group.end) { + group.end = end; + } + + locationMap.set(start, branchInfo); + + return branchInfo; +}; + +const addNoneBranch = (group) => { + group.locations.push({ + none: true, + count: 0 + }); +}; + +// ======================================================================================= + +const updateBlockLocations = (locations) => { + const noBlockList = []; + let blockCount = 0; + locations.forEach((item, i) => { + if (item.block) { + item.count = item.block.count; + blockCount += item.count; + return; + } + // for calculate mo break branches + item.index = i; + noBlockList.push(item); + }); + + return { + noBlockList, + blockCount + }; +}; + +// const a = tf1 ? 'true' : 'false'; +const ConditionalExpression = (group, parentCount) => { + const { noBlockList, blockCount } = updateBlockLocations(group.locations); + if (!noBlockList.length) { + return; + } + let count = parentCount - blockCount; + noBlockList.forEach((item) => { + item.count = count; + count = 0; + }); +}; + +const IfStatement = (group, parentCount) => { + const { noBlockList, blockCount } = updateBlockLocations(group.locations); + if (!noBlockList.length) { + return; + } + // console.log(parentCount, 'uncovered list', noBlockList.length, group.start); + let count = parentCount - blockCount; + noBlockList.forEach((item) => { + item.count = count; + count = 0; + }); + +}; + +// const b = tf2 || tf1 || a; +const LogicalExpression = (group, parentCount) => { + + // from left to right + group.locations.forEach((item, i) => { + if (item.block) { + item.count = item.block.count; + } else { + item.count = parentCount; + } + }); + +}; + +const SwitchStatement = (group, parentCount) => { + + const locations = group.locations; + + const { noBlockList, blockCount } = updateBlockLocations(locations); + if (!noBlockList.length) { + return; + } + + // calculate switch/case count + const countLeft = parentCount - blockCount; + noBlockList.forEach((item) => { + + let hasCount = false; + + // check no break branches + for (let i = item.index - 1; i >= 0; i--) { + const b = locations[i]; + if (b && !b.hasBreak && b.count > 0) { + item.count += b.count; + hasCount = true; + continue; + } + break; + } + + if (!hasCount) { + item.count = countLeft; + } + }); +}; + +const AssignmentPattern = (group, parentCount) => { + group.locations.forEach((item) => { + item.count = parentCount; + }); +}; + +// ======================================================================================= + +const updateBranchCount = (group) => { + + const { + type, locations, reverseParents + } = group; + + const functionState = getParentFunctionState(reverseParents); + + const functionCount = functionState.count; + + // default is 0, no need continue + if (functionCount === 0) { + return; + } + + // parent is block statement or function + let parentCount = getParentCount(reverseParents, functionCount); + // parent is group range + const groupBlock = getFunctionBlock(group.start, group.end, functionState); + if (groupBlock) { + parentCount = groupBlock.count; + setGeneratedOnly(groupBlock, group.generatedOnly); + } + + // calculate branches count + locations.forEach((item) => { + const { + start, end, none + } = item; + if (none) { + return; + } + + item.block = getFunctionBlock(start, end, functionState); + setGeneratedOnly(item.block, group.generatedOnly); + + }); + + + const handlers = { + ConditionalExpression, + LogicalExpression, + IfStatement, + SwitchStatement, + AssignmentPattern + }; + + const handler = handlers[type]; + if (handler) { + handler(group, parentCount); + } + +}; + +const generateBranches = (branchMap) => { + + // calculate count for all branches + branchMap.forEach((group) => { + updateBranchCount(group); + }); + + // init branches + const branches = []; + branchMap.forEach((group) => { + + // add start/end for none with group start/end + group.locations.forEach((item) => { + if (item.none) { + item.start = group.start; + item.end = group.end; + } + }); + + const branch = { + type: group.type, + start: group.start, + end: group.end, + locations: group.locations + }; + + setGeneratedOnly(branch, group.generatedOnly); + + branches.push(branch); + }); + + // sort branches + branches.sort((a, b) => { + return a.start - b.start; + }); + + return branches; +}; + +// ======================================================================================= +// All programs in JavaScript are made of statements and they end with semicolons (;) except block statements which is used to group zero or more statements. +// Statements are just perform some actions but do not produce any value or output whereas expressions return some value. +// Expressions return value, statements do not. +const generateStatements = (statementNodes) => { + + statementNodes.forEach((item) => { + const { + node, + reverseParents + } = item; + + const { start, end } = node; + + item.count = 1; + + // isFunction + if (node._state) { + item.count = node._state.count; + return; + } + + const functionState = getParentFunctionState(reverseParents); + if (!functionState) { + // there is a root range, it impossible not found + return; + } + + // function uncovered + if (functionState.count === 0) { + item.count = 0; + return; + } + + const block = getFunctionBlock(start, end, functionState); + if (block) { + item.count = block.count; + return; + } + + item.count = functionState.count; + + }); + + // remove block statement + statementNodes = statementNodes.filter((item) => { + return item.node.type !== 'BlockStatement'; + }); + + const statements = statementNodes.map((item) => { + const { + node, + count + } = item; + const { start, end } = node; + return { + start, + end, + count + }; + }); + + return statements; +}; + +// ======================================================================================= +// handle special generated codes for original coverage + +const webpackWrapHandler = (node) => { + // ignore webpack wrap for original function + // id: { type: 'Identifier', name: '__webpack_modules__' }, + const name = node.id && node.id.name; + if (name === '__webpack_modules__' && node.init && node.init.properties) { + // mark all as wrap function + node.init.properties.forEach((it) => { + it.value._webpackWrapKey = it.key && it.key.value; + }); + // console.log('==========================', node.type); + // console.log(name, parents.length); + } +}; + +const viteImportDefaultHandler = (node, group) => { + // ignore vite conditional expression for __esModule default + const testObj = node.test.object; + const testName = testObj && testObj.name; + if (testName && testName.startsWith('__vite__cjsImport')) { + setGeneratedOnly(group, true); + } + +}; + + +// ======================================================================================= + +const collectNodes = (ast) => { + const functionNodes = []; + const statementNodes = []; + const blockNodes = []; + const branchMap = new Map(); + // locationMap for chain LogicalExpression locations + const locationMap = new Map(); + + Util.visitAst(ast, { + + VariableDeclarator(node, parents) { + + webpackWrapHandler(node); + + }, + + // =============================================================================== + // statements + + Statement: (node, parents) => { + const reverseParents = [].concat(parents).reverse(); + statementNodes.push({ + node, + reverseParents + }); + }, + + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static + // as a function "functionName": "", + StaticBlock: (node, parents) => { + const reverseParents = [].concat(parents).reverse(); + functionNodes.push({ + node, + reverseParents + }); + }, + + // =============================================================================== + // functions + // Function include FunctionDeclaration, ArrowFunctionExpression, FunctionExpression + Function(node, parents) { + const reverseParents = [].concat(parents).reverse(); + functionNodes.push({ + node, + reverseParents + }); + }, + + // =============================================================================== + // branches + + // `for` block, the count not equal to parent + BlockStatement: (node, parents) => { + + // fix branch count: BRDA + const reverseParents = [].concat(parents).reverse(); + blockNodes.push({ + node, + reverseParents + }); + + }, + + // default-arg assignment logic. + // function default arguments + AssignmentPattern: (node, parents) => { + const group = createBranchGroup(BranchTypes.AssignmentPattern, node, parents, branchMap); + addBranch(group, node, locationMap); + }, + + // cond-expr a ternary expression. e.g.: x ? y : z + // Ternary + // var b = a ? 'consequent' : 'alternate'; + ConditionalExpression: (node, parents) => { + + const { consequent, alternate } = node; + const group = createBranchGroup(BranchTypes.ConditionalExpression, node, parents, branchMap); + addBranch(group, consequent, locationMap); + addBranch(group, alternate, locationMap); + + viteImportDefaultHandler(node, group); + + }, + + // if an if statement; can also be else if. + // An IF statement always has exactly two branches: + // one where the condition is FALSE and one where the condition is TRUE + IfStatement: (node, parents) => { + const { consequent, alternate } = node; + const group = createBranchGroup(BranchTypes.IfStatement, node, parents, branchMap); + addBranch(group, consequent, locationMap); + + // console.log('if type', consequent.type); + + if (alternate) { + addBranch(group, alternate, locationMap); + } else { + // add none branch + addNoneBranch(group); + // no need update group end, there is no end + } + }, + + // binary-expr a logical expression with a binary operand. e.g.: x && y + // var b = a || b || c; + // do not use BinaryExpression + LogicalExpression: (node, parents) => { + const { left, right } = node; + // console.log(left.start, right.start); + + // could be same branch start + // const da = arguments.length > 1 && typeof arguments[1] !== 'undefined' ? arguments[1] : true; + + let group; + // link to same branch start if LogicalExpression + const prevLocation = locationMap.get(node.start); + if (prevLocation) { + // console.log('link branch ==================', type); + group = branchMap.get(prevLocation.branchKey); + } else { + group = createBranchGroup(BranchTypes.LogicalExpression, node, parents, branchMap); + addBranch(group, left, locationMap); + } + + addBranch(group, right, locationMap); + + // console.log(group.locations.map((it) => it.start)); + + // sort branch locations + // a || b || c + // first, left a and right c + // then, left a and right b + if (prevLocation) { + const { locations } = group; + locations.sort((a, b) => { + return a.start - b.start; + }); + // update group end after sorted + const lastEnd = locations[locations.length - 1].end; + if (lastEnd > group.end) { + group.end = lastEnd; + } + } + }, + + // switch a switch statement. + SwitchStatement: (node, parents) => { + const group = createBranchGroup(BranchTypes.SwitchStatement, node, parents, branchMap); + const cases = node.cases; + cases.forEach((switchCase) => { + // console.log('switchCase', switchCase.start); + addBranch(group, switchCase, locationMap); + }); + } + + }); + + return { + functionNodes, + statementNodes, + blockNodes, + branchMap + }; +}; + +const getRootFunctionState = (ast, coverageInfo) => { + const rootState = { + isFunction: true, + count: 1 + }; + const rootRange = coverageInfo.rootRange; + if (rootRange) { + rootState.range = rootRange; + rootState.count = rootRange.count; + + // could be not from 0 + // 0 881 { startOffset: 77, endOffset: 881, + // const { start, end } = ast; + // console.log(start, end, rootRange); + + } + ast._state = rootState; + + return rootState; +}; + +// eslint-disable-next-line complexity +const findFunctionRange = (item, coverageInfo) => { + + const { node, reverseParents } = item; + const { + start, end, type + } = node; + + // try function start/end + const functionRange = getFunctionRange(start, end, type, coverageInfo); + if (functionRange) { + return functionRange; + } + + // `static async` case: + // [1]static [2]async [3]covered(active) { + // v8 start: 2 + // ast start: 1,3 + + // fixed by async or static + + // handle for static async + if (node.async) { + // 'async '.length + const asyncLen = 6; + const asyncStart = start - asyncLen; + // console.log(asyncStart, 'asyncStart ==============================================='); + const asyncRange = getFunctionRange(asyncStart, end, type, coverageInfo); + if (asyncRange) { + return asyncRange; + } + } + + // try if class MethodDefinition + // 0 is function self + const parent = reverseParents[1]; + if (parent && parent.type === 'MethodDefinition') { + + const parentRange = getFunctionRange(parent.start, parent.end, parent.type, coverageInfo); + if (parentRange) { + return parentRange; + } + + if (parent.static) { + // 'static '.length + const staticLen = 7; + const staticStart = parent.start + staticLen; + // console.log(staticStart, ' staticStart ============================================'); + const staticRange = getFunctionRange(staticStart, parent.end, parent.type, coverageInfo); + if (staticRange) { + return staticRange; + } + } + + } + + +}; + +const collectAstInfo = (ast, coverageInfo) => { + + const { + functionNodes, statementNodes, blockNodes, branchMap + } = collectNodes(ast); + + // root function state + const rootState = getRootFunctionState(ast, coverageInfo); + + const functions = []; + functionNodes.forEach((item) => { + const { node } = item; + const { + start, end, id + } = node; + + const bodyStart = node.body.start; + const bodyEnd = node.body.end; + const functionName = id && id.name; + const _webpackWrapKey = node._webpackWrapKey; + + const functionItem = { + start, + end, + bodyStart, + bodyEnd, + functionName, + count: rootState.count + }; + + setGeneratedOnly(functionItem, _webpackWrapKey); + + functions.push(functionItem); + + const functionState = { + isFunction: true, + count: functionItem.count + }; + + const functionRange = findFunctionRange(item, coverageInfo); + if (functionRange) { + + setGeneratedOnly(functionRange, _webpackWrapKey); + + functionState.range = functionRange; + functionState.count = functionRange.count; + functionItem.count = functionRange.count; + } + node._state = functionState; + + // console.log(item.reverseParents.map((it) => it.type)); + + }); + + blockNodes.forEach((item) => { + addNodeCount(item); + }); + + const branches = generateBranches(branchMap); + const statements = generateStatements(statementNodes); + + return { + functions, + branches, + statements + }; + +}; + +module.exports = { + BranchTypes, + collectAstInfo +}; diff --git a/node_modules/monocart-coverage-reports/lib/converter/ast.js b/node_modules/monocart-coverage-reports/lib/converter/ast.js new file mode 100644 index 0000000..5c7dd70 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/converter/ast.js @@ -0,0 +1,364 @@ +const acorn = require('acorn'); +const acornLoose = require('acorn-loose'); +const { parseCss } = require('../packages/monocart-coverage-vendor.js'); +const Util = require('../utils/util.js'); + +const { collectAstInfo } = require('./ast-visitor.js'); + +const getCoverageInfo = (coverageList) => { + const functionMap = new Map(); + const functionNameMap = new Map(); + const functionStaticRanges = []; + const functionUncoveredRanges = []; + + let rootRange; + coverageList.forEach((block) => { + const { + functionName, ranges, root + } = block; + + let functionRange; + const blockRanges = []; + + ranges.forEach((range, i) => { + if (i === 0) { + // function range + functionRange = range; + return; + } + blockRanges.push(range); + }); + + functionRange.functionName = functionName; + + // blocks + if (blockRanges.length) { + const blockMap = new Map(); + blockRanges.forEach((item) => { + blockMap.set(item.startOffset, item); + }); + functionRange.blockMap = blockMap; + // uncovered is unique + const blockUncoveredRanges = blockRanges.filter((it) => it.count === 0); + Util.sortOffsetRanges(blockUncoveredRanges); + functionRange.blockUncoveredRanges = blockUncoveredRanges; + functionRange.blockCoveredRanges = blockRanges.filter((it) => it.count > 0); + } + + // root function from vm + if (root) { + rootRange = functionRange; + return; + } + + // root function from first range + if (!rootRange) { + rootRange = functionRange; + } + + functionMap.set(functionRange.startOffset, functionRange); + if (functionName) { + // can not handle `async functionName` + const possibleNameOffset = functionRange.startOffset + functionName.length; + functionNameMap.set(possibleNameOffset, functionRange); + } + + if (functionName === '') { + functionStaticRanges.push(functionRange); + } + + // cache uncovered + if (functionRange.count === 0) { + functionUncoveredRanges.push(functionRange); + } + + }); + + // sort ranges + Util.sortOffsetRanges(functionUncoveredRanges); + + return { + functionMap, + functionNameMap, + functionStaticRanges, + functionUncoveredRanges, + rootRange + }; + +}; + +const getFakeAstInfo = (coverageList) => { + const functions = []; + const branches = []; + const statements = []; + coverageList.forEach((block) => { + const { + isBlockCoverage, functionName, ranges, root + } = block; + + ranges.forEach((range, i) => { + + const { + startOffset, endOffset, count + } = range; + + if (i === 0 && root) { + return; + } + + statements.push({ + start: startOffset, + end: endOffset, + count + }); + + if (isBlockCoverage) { + // branches + branches.push({ + type: 'branch', + start: startOffset, + end: endOffset, + locations: [{ + start: startOffset, + end: endOffset, + count + }] + }); + } + + if (i === 0) { + // function range + functions.push({ + start: startOffset, + end: endOffset, + bodyStart: startOffset, + bodyEnd: endOffset, + count, + functionName + }); + + } + }); + + }); + + // console.log('fake functions', functions.map((it) => it)); + + return { + functions, + branches, + statements + }; +}; + +const getJsAstInfo = (item, coverageList) => { + + const { + source, fake, empty + } = item; + + if (fake) { + return getFakeAstInfo(coverageList); + } + + const options = { + ecmaVersion: 'latest', + // most time for node.js file + allowReturnOutsideFunction: true, + allowImportExportEverywhere: true, + allowAwaitOutsideFunction: true, + allowSuperOutsideMethod: true, + // first line: #!/usr/bin/env node + allowHashBang: true + }; + + let err; + let ast; + try { + ast = acorn.parse(source, options); + } catch (e) { + err = e; + } + + if (err) { + + // empty = untested file + // could be .ts, .vue and so on, that can not be parsed normally + if (empty) { + return { + functions: [], + branches: [], + statements: [] + }; + } + + // runtime code should be parsed successful + Util.logInfo(`Unparsable source: ${item.sourcePath} ${err.message}`); + + // it could be jsx even it is `.js` + + // https://github.com/acornjs/acorn/tree/master/acorn-loose + // It is recommended to always try a parse with the regular acorn parser first, + // and only fall back to this parser when that one finds syntax errors. + ast = acornLoose.parse(source, options); + + } + + const coverageInfo = getCoverageInfo(coverageList); + coverageInfo.item = item; + + return collectAstInfo(ast, coverageInfo); +}; + +// ========================================================================================================= + +const addRule = (item, coverageList, coveredRanges, count = 0) => { + + const { source } = item; + const { start, end } = source; + const startOffset = start.offset; + const endOffset = end.offset; + + if (!count) { + const coveredRange = Util.findInRanges(startOffset, endOffset, coveredRanges, 'startOffset', 'endOffset'); + if (coveredRange) { + count = 1; + } + } + + coverageList.push({ + start: startOffset, + end: endOffset, + count + }); + + return count; + +}; + +const addAtRule = (item, coverageList, coveredRanges, empty) => { + const { name, nodes } = item; + + const defaultCount = empty ? 0 : 1; + + if (['charset', 'import', 'namespace'].includes(name)) { + addRule(item, coverageList, coveredRanges, defaultCount); + return; + } + + if (['media', 'supports', 'container', 'layer'].includes(name)) { + + const childCoverageList = []; + const count = addCssRules(nodes, childCoverageList, coveredRanges, empty); + if (count) { + + coverageList.push({ + start: item.source.start.offset, + end: childCoverageList[0].start, + count: 1 + }); + + let end; + childCoverageList.forEach((it) => { + coverageList.push(it); + end = it.end; + }); + + coverageList.push({ + start: end, + end: item.source.end.offset, + count: 1 + }); + + return; + } + + } + + addRule(item, coverageList, coveredRanges); + +}; + +const addCssRules = (list, coverageList, coveredRanges, empty) => { + + if (!Util.isList(list)) { + return 0; + } + + let count = 0; + + // line and line is 1-base + list.forEach((item) => { + + const { type } = item; + + if (type === 'comment') { + return; + } + + if (type === 'rule') { + count += addRule(item, coverageList, coveredRanges); + return; + } + + // console.log('============================================================================='); + // Object.keys(item).forEach((k) => { + // if (k === 'parent') { + // return; + // } + // if (k === 'raws') { + // return; + // } + // if (k === 'nodes') { + // console.log(k, item[k].length); + // return; + // } + // if (k === 'source') { + // console.log(k, item[k].start, item[k].end); + // return; + // } + // console.log(k, item[k]); + // }); + + if (type === 'atrule') { + addAtRule(item, coverageList, coveredRanges, empty); + } + + }); + + return count; +}; + +const getCssAstInfo = (item, coverageList) => { + + const { + source, ranges, empty + } = item; + + // sort covered ranges + ranges.sort((a, b) => a.start - b.start); + + // to offset covered ranges + const coveredRanges = ranges.map((it) => { + return { + startOffset: it.start, + endOffset: it.end + }; + }); + + const ast = parseCss(source); + + addCssRules(ast.nodes, coverageList, coveredRanges, empty); + + return { + functions: [], + branches: [], + statements: [] + }; +}; + + +module.exports = { + getJsAstInfo, + getCssAstInfo +}; diff --git a/node_modules/monocart-coverage-reports/lib/converter/collect-source-maps.js b/node_modules/monocart-coverage-reports/lib/converter/collect-source-maps.js new file mode 100644 index 0000000..6d3bcf4 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/converter/collect-source-maps.js @@ -0,0 +1,287 @@ +const fs = require('fs'); +const path = require('path'); +const EC = require('eight-colors'); +const { fileURLToPath, pathToFileURL } = require('url'); +const Concurrency = require('../platform/concurrency.js'); +const { convertSourceMap } = require('../packages/monocart-coverage-vendor.js'); +const { flattenSourceMaps } = require('./flatten-source-maps.js'); + +const Util = require('../utils/util.js'); + +const defaultSourceMapResolver = async (url = '') => { + + if (url.startsWith('file:')) { + const p = fileURLToPath(url); + const content = Util.readFileSync(p); + if (!content) { + Util.logDebug(EC.red(`failed to load sourcemap ${p}`)); + return; + } + return Util.jsonParse(content); + } + + const [err, res] = await Util.request(url); + + if (err) { + Util.logDebug(EC.red(`${err.message} ${url}`)); + return; + } + + const content = res.data; + + // could be string not json, if Content-Type is application/octet-stream + if (typeof content === 'string') { + return Util.jsonParse(content); + } + + return content; +}; + +const loadSourceMap = async (url, options) => { + if (typeof options.sourceMapResolver === 'function') { + const content = await options.sourceMapResolver(url, defaultSourceMapResolver); + if (typeof content === 'string') { + return Util.jsonParse(content); + } + return content; + } + return defaultSourceMapResolver(url); +}; + +const getSourceMapUrl = (content, url) => { + + const m = content.match(convertSourceMap.mapFileCommentRegex); + if (!m) { + return; + } + + const comment = m.pop(); + const r = convertSourceMap.mapFileCommentRegex.exec(comment); + // for some odd reason //# .. captures in 1 and /* .. */ in 2 + const filename = r[1] || r[2]; + + const urlObj = Util.resolveUrl(filename, url); + if (urlObj) { + return urlObj.toString(); + } + + const mapUrl = Util.resolveUrl(filename, pathToFileURL(url).toString()); + if (mapUrl) { + return mapUrl.toString(); + } +}; + +const resolveSourcesContent = (data, url) => { + + const { sources, sourcesContent } = data; + + // sources [1,2,3] + // sourcesContent could be [null, null, "content"] + // some of contents could be missed + + let hasSourceContent = false; + sources.forEach((file, i) => { + if (typeof sourcesContent[i] === 'string') { + hasSourceContent = true; + return; + } + + const sourceUrl = Util.resolveUrl(file, url); + if (sourceUrl) { + let sourcePath = sourceUrl.toString(); + // could be no `file:` + if (sourcePath.startsWith('file:')) { + sourcePath = fileURLToPath(sourcePath); + } + const content = Util.readFileSync(path.resolve(sourcePath)); + if (typeof content === 'string') { + sourcesContent[i] = content; + hasSourceContent = true; + return; + } + } + + sourcesContent[i] = ''; + Util.logDebug(EC.red(`failed to load source content: ${file}`)); + + }); + + + if (hasSourceContent) { + return data; + } +}; + +const checkSourcesContent = (data) => { + const { sourcesContent, sources } = data; + + if (!sourcesContent) { + data.sourcesContent = []; + return false; + } + + // all should be string, could be [null] + const contents = sourcesContent.filter((content) => typeof content === 'string'); + if (contents.length === sources.length) { + return true; + } + + return false; +}; + +const resolveSectionedSourceMap = (data, url, sections) => { + + let hasSourceContent = false; + sections.forEach((item) => { + // offset: { line: 1, column: 0 }, + // map: { sources, sourcesContent } + + const map = item.map; + + if (checkSourcesContent(map)) { + hasSourceContent = true; + return; + } + + const done = resolveSourcesContent(map, url); + if (done) { + hasSourceContent = true; + } + + }); + + if (hasSourceContent) { + return flattenSourceMaps(data); + } +}; + +const resolveSourceMap = (data, url) => { + if (!data) { + return; + } + const { + sections, sources, mappings + } = data; + + if (sections) { + return resolveSectionedSourceMap(data, url, sections); + } + + if (!sources || !mappings) { + return; + } + + // check sources content + if (checkSourcesContent(data)) { + return data; + } + + // load sources content by sources + return resolveSourcesContent(data, url); + +}; + +const getInlineSourceMap = (content) => { + let smc; + try { + smc = convertSourceMap.fromSource(content); + } catch (e) { + // ignore "//# sourceMappingURL=" in a string + // console.log(e); + } + return smc; +}; + +const collectSourceMaps = async (v8list, options) => { + + const sourceList = []; + const sourcemapList = []; + const concurrency = new Concurrency(); + for (const item of v8list) { + + const { + type, url, id, source, sourceMap + } = item; + + // source and sourceMap will be saved as separated file (could be cached) + // just keep functions coverage ( could be multiple times, will be merged ) + // so remove source and sourceMap + delete item.source; + delete item.sourceMap; + + // source and sourceMap already saved + const { cachePath } = Util.getCacheFileInfo('source', id, options.cacheDir); + if (fs.existsSync(cachePath)) { + continue; + } + + // save source and sourceMap to separated json file + const sourceData = { + id, + url, + source, + sourceMap + }; + + // remove comments if not debug + if (!Util.isDebug()) { + sourceData.source = convertSourceMap.removeComments(source); + } + + // check sourceMap only for js + if (type === 'js' && !sourceData.sourceMap) { + // from inline sync + const smc = getInlineSourceMap(source); + if (smc) { + sourceData.sourceMap = resolveSourceMap(smc.sourcemap, url); + sourcemapList.push({ + url, + inline: true + }); + sourceList.push(sourceData); + continue; + } + // from url async + const sourceMapUrl = getSourceMapUrl(source, item.url); + if (sourceMapUrl) { + concurrency.addItem({ + sourceMapUrl, + sourceData + }); + continue; + } + } + + // no need check sourceMap + sourceList.push(sourceData); + + } + + // from url concurrency + await concurrency.start(async (item) => { + const { sourceMapUrl, sourceData } = item; + const { url } = sourceData; + const data = await loadSourceMap(sourceMapUrl, options); + if (data) { + sourceData.sourceMap = resolveSourceMap(data, url); + sourcemapList.push({ + url, + sourceMapUrl + }); + } + + sourceList.push(sourceData); + + }); + + return { + sourceList, + sourcemapList + }; + +}; + +module.exports = { + collectSourceMaps, + resolveSourceMap +}; diff --git a/node_modules/monocart-coverage-reports/lib/converter/converter.js b/node_modules/monocart-coverage-reports/lib/converter/converter.js new file mode 100644 index 0000000..44eb155 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/converter/converter.js @@ -0,0 +1,1823 @@ +/** + * V8 Coverage Data Converter + * @copyright https://github.com/cenfun/monocart-coverage-reports + * @author cenfun@gmail.com + */ + +const EC = require('eight-colors'); + +const { Locator } = require('monocart-locator'); +const Util = require('../utils/util.js'); + +const findOriginalRange = require('./find-original-range.js'); +const { getJsAstInfo, getCssAstInfo } = require('./ast.js'); +const { getIgnoredRanges } = require('./ignore.js'); + +const { getUntestedList } = require('./untested.js'); + +const { + sortRanges, dedupeCountRanges, mergeRangesWith +} = require('../utils/dedupe.js'); +const { getSourceType, initSourceMapSourcesPath } = require('../utils/source-path.js'); + +const { decode } = require('../packages/monocart-coverage-vendor.js'); + +const InfoBranch = require('./info-branch.js'); +const InfoFunction = require('./info-function.js'); +const InfoStatement = require('./info-statement.js'); + +// ======================================================================================================== + +// debug info +const logMappingErrors = (type, result) => { + + // const { + // errors, start, end, sourcePath + // } = result; + // // if (!sourcePath.endsWith('monocart-v8.js') || type !== 'byte') { + // // return; + // // } + // const list = [ + // Util.EC.red('[Mapping]'), + // Util.EC.magenta(type), + // errors.join(' -> '), + // Util.EC.blue(`${start} ~ ${end}`), + // sourcePath + // ]; + // console.log(list.join(' ')); + +}; + +// ======================================================================================================== + +const handleIgnoredRanges = (list, ignoredRanges) => { + list.forEach((item) => { + const range = Util.findInRanges(item.start, item.end, ignoredRanges); + if (range) { + // console.log(item, range); + item.ignored = true; + } + }); +}; + + +const applyBytesToLines = (bytes, locator, lineMap) => { + bytes.forEach((range) => { + const { + start, end, count, ignored + } = range; + + // no need handle ignored byte + if (ignored) { + return; + } + + const sLoc = locator.offsetToLocation(start); + const eLoc = locator.offsetToLocation(end); + + // update lines coverage + const lines = Util.getRangeLines(sLoc, eLoc); + Util.updateLinesCoverage(lines, count, lineMap); + + }); + + // no ignore items + lineMap.forEach((lineItem, line) => { + + const { + uncoveredEntire, uncoveredPieces, coveredCount + } = lineItem; + + // default count to 1, both js and css + let count = 1; + // full covered true/false for entire line + let covered = true; + + if (uncoveredEntire) { + count = 0; + covered = false; + } else { + count = coveredCount; + const uncoveredLen = uncoveredPieces.length; + if (uncoveredLen > 0) { + covered = false; + // uncovered + count = `1/${uncoveredLen + 1}`; + } + } + + lineItem.covered = covered; + lineItem.count = count; + + }); + +}; + +const handleLinesCoverage = (bytes, locator, ignoredRanges) => { + + // init lines + let blankCount = 0; + let commentCount = 0; + const dataExtras = {}; + // line 1 based + const lineMap = new Map(); + locator.lines.forEach((lineItem) => { + // line 1-base + const line = lineItem.line + 1; + + // exclude blank and comment + if (lineItem.blank) { + blankCount += 1; + dataExtras[line] = 'b'; + return; + } + if (lineItem.comment) { + commentCount += 1; + dataExtras[line] = 'c'; + return; + } + const ignored = Util.findInRanges(lineItem.start, lineItem.end, ignoredRanges); + if (ignored) { + dataExtras[line] = 'i'; + return; + } + + Util.initLineCoverage(lineItem); + + lineMap.set(line, lineItem); + }); + + applyBytesToLines(bytes, locator, lineMap); + + const summaryLines = { + total: 0, + covered: 0, + blank: blankCount, + comment: commentCount + }; + // data lines + const dataLines = {}; + + // no ignore items + lineMap.forEach((lineItem, line) => { + const { count, covered } = lineItem; + // data lines + dataLines[line] = count; + + summaryLines.total += 1; + if (covered) { + summaryLines.covered += 1; + } + }); + + return { + dataLines, + dataExtras, + summaryLines + }; +}; + +// ======================================================================================================== + +const calculateV8Summary = (list) => { + + const summary = { + total: 0, + covered: 0 + }; + + list.forEach((item) => { + if (item.ignored) { + return; + } + + summary.total += 1; + if (item.count > 0) { + summary.covered += 1; + } + }); + + return summary; +}; + +// ======================================================================================================== +// istanbul coverage format +// https://github.com/istanbuljs/istanbuljs/blob/master/docs/raw-output.md +/** + * * `path` - the file path for which coverage is being tracked + * * `statementMap` - map of statement locations keyed by statement index + * * `fnMap` - map of function metadata keyed by function index + * * `branchMap` - map of branch metadata keyed by branch index + * * `s` - hit counts for statements + * * `f` - hit count for functions + * * `b` - hit count for branches + */ +const collectFileCoverage = (v8Data, state, options) => { + + const { + bytes, + functions, + branches, + statements, + + sourcePath, + locator + } = state; + + // ========================================== + // v8 data + const data = { + bytes: dedupeCountRanges(bytes), + functions: [], + branches: [], + statements: [] + }; + + // ========================================== + // ignore + const ignoredRanges = getIgnoredRanges(locator, options); + if (ignoredRanges) { + + data.ignores = ignoredRanges; + + // data bytes is start/end/count object + handleIgnoredRanges(data.bytes, ignoredRanges); + + // functions start/end/count instance + handleIgnoredRanges(functions, ignoredRanges); + + // branches start/end/count instance + handleIgnoredRanges(branches, ignoredRanges); + + // branch locations start/end/count object + branches.forEach((group) => { + if (group.ignored) { + // all branch group ignored + group.locations.forEach((it) => { + it.ignored = true; + }); + } else { + handleIgnoredRanges(group.locations, ignoredRanges); + } + }); + + // statements start/end/count instance + handleIgnoredRanges(statements, ignoredRanges); + + // console.log(ignoredRanges); + + } + + // ========================================== + // lines + // after bytes with ignored, before calculateV8Lines + const { + dataLines, dataExtras, summaryLines + } = handleLinesCoverage(data.bytes, locator, ignoredRanges); + + data.lines = dataLines; + data.extras = dataExtras; + + // console.log('statements', state.sourcePath, statements.length); + + // ========================================== + + data.functions = functions.map((info, i) => { + return info.getRange(i); + }); + sortRanges(data.functions); + + // branch group with locations to flat branches + data.branches = branches.map((info) => { + return info.getRanges(); + }).flat(); + sortRanges(data.branches); + + data.statements = statements.map((info) => { + return info.getRange(); + }); + sortRanges(data.statements); + + // ========================================== + + const summary = { + functions: calculateV8Summary(data.functions), + branches: calculateV8Summary(data.branches), + statements: calculateV8Summary(data.statements), + lines: summaryLines + }; + + // ========================================== + // v8 data and summary + v8Data.data = data; + v8Data.summary = summary; + + // ========================================== + // istanbul + const istanbulData = { + path: sourcePath, + + statementMap: {}, + fnMap: {}, + branchMap: {}, + + s: {}, + f: {}, + b: {} + }; + + statements.filter((it) => !it.ignored).forEach((statement, index) => { + istanbulData.statementMap[`${index}`] = statement.generate(locator); + istanbulData.s[`${index}`] = statement.count; + }); + + functions.filter((it) => !it.ignored).forEach((fn, index) => { + istanbulData.fnMap[`${index}`] = fn.generate(locator, index); + istanbulData.f[`${index}`] = fn.count; + }); + + branches.filter((it) => !it.ignored).forEach((branch, index) => { + const { map, counts } = branch.generate(locator); + istanbulData.branchMap[`${index}`] = map; + istanbulData.b[`${index}`] = counts; + }); + + return istanbulData; + +}; + +// ======================================================================================================== + +const addJsBytesCoverage = (state, range) => { + const { + startOffset, endOffset, count + } = range; + // add bytes range + const byte = { + start: startOffset, + // the end could be > source.length + end: Math.min(endOffset, state.maxContentLength), + count + }; + // for debug + if (Util.isDebug() && state.original) { + byte.generatedStart = range.generatedStart; + byte.generatedEnd = range.generatedEnd; + } + state.bytes.push(byte); +}; + +const addCssBytesCoverage = (state, range) => { + const { + start, end, count + } = range; + // add css bytes range, already start, end + state.bytes.push({ + start, + end, + count + }); +}; + +// ======================================================================================================== + +const checkOriginalRangeCode = (range, state, startEndMap, type) => { + + // only for original + if (!state.original) { + return true; + } + + const { start, end } = range; + if (start >= end) { + // console.log('invalid branch', state.sourcePath, range); + return false; + } + + // could be vue code + const text = state.locator.getSlice(start, end).trim(); + if (!text) { + return false; + } + + // do not check text for `bytes` + // it could be `} ` uncovered in `try { } catch` + // instead, use `dedupeCountRanges` to accumulate count + if (type === 'bytes') { + return true; + } + + // invalid original code + // Matches any character that is not a word character from the basic Latin alphabet. + // Equivalent to [^A-Za-z0-9_] + if (text.length === 1 && (/\W/).test(text)) { + // ; } = + // console.log(text, type, state.sourcePath, range); + return false; + } + + // type: bytes, functions, branches, statements + + // check repeated range + const key = `${start}_${end}`; + if (startEndMap.has(key)) { + return false; + } + startEndMap.set(key, range); + + return true; +}; + +const handleFunctionsCoverage = (state) => { + + // functions only for js + if (!state.js) { + return; + } + + const startEndMap = new Map(); + const { functions, astInfo } = state; + astInfo.functions.forEach((it) => { + + if (!checkOriginalRangeCode(it, state, startEndMap, 'functions')) { + return; + } + + functions.push(new InfoFunction(it, state.original)); + }); + +}; + +const handleBranchesCoverage = (state) => { + + // functions only for js + if (!state.js) { + return; + } + + const startEndMap = new Map(); + const { branches, astInfo } = state; + astInfo.branches.forEach((it) => { + + if (!checkOriginalRangeCode(it, state, startEndMap, 'branches')) { + return; + } + + branches.push(new InfoBranch(it, state.original)); + }); + +}; + +const handleStatementsCoverage = (state) => { + + // statement only for js + if (!state.js) { + return; + } + + const startEndMap = new Map(); + const { statements, astInfo } = state; + astInfo.statements.forEach((it) => { + + if (!checkOriginalRangeCode(it, state, startEndMap, 'statements')) { + return; + } + + statements.push(new InfoStatement(it, state.original)); + }); + +}; + +const handleOriginalBytesCoverage = (state) => { + const startEndMap = new Map(); + state.bytes = state.bytes.filter((it) => { + return checkOriginalRangeCode(it, state, startEndMap, 'bytes'); + }); +}; + +const handleGeneratedBytesCoverage = (state) => { + + // it could be a dist file, do not handle twice + if (state.addedGeneratedBytes) { + return; + } + + const { js, coverageList } = state; + + if (js) { + coverageList.forEach((block) => { + block.ranges.forEach((range) => { + + const { fixedStart, fixedEnd } = Util.fixSourceRange(state.locator, range.startOffset, range.endOffset); + range.startOffset = fixedStart; + range.endOffset = fixedEnd; + + addJsBytesCoverage(state, range); + }); + }); + } else { + coverageList.forEach((range) => { + addCssBytesCoverage(state, range); + }); + } + + state.addedGeneratedBytes = true; + +}; + +// ======================================================================================================== + +const handleOriginalFunctionsCoverage = (state, originalStateMap) => { + + // functions only for js + if (!state.js) { + return; + } + + // console.log(state.astInfo.functions); + + const updateFunctionBodyRange = (start, end, bodyStart, bodyEnd, originalFunction) => { + if (bodyStart !== start || bodyEnd !== end) { + const result = findOriginalRange(bodyStart, bodyEnd, state, originalStateMap); + if (result.error) { + logMappingErrors('function body', result); + } else { + originalFunction.bodyStart = result.start; + originalFunction.bodyEnd = result.end; + } + } + }; + + // function count + state.astInfo.functions.forEach((it) => { + + // remove webpack wrap functions for functions count, not for ranges here + if (it.generatedOnly) { + return; + } + + const { + start, end, bodyStart, bodyEnd + } = it; + + const result = findOriginalRange(start, end, state, originalStateMap, { + checkName: true + }); + if (result.error) { + logMappingErrors('function', result); + return; + } + + const originalFunction = { + ... it, + generatedStart: start, + generatedEnd: end, + start: result.start, + end: result.end, + bodyStart: result.start, + bodyEnd: result.end + }; + + if (result.name) { + originalFunction.functionName = result.name; + } + + // body start and end + updateFunctionBodyRange(start, end, bodyStart, bodyEnd, originalFunction); + + // add back to original ast + result.originalState.astInfo.functions.push(originalFunction); + + }); + +}; + +const handleOriginalBranchesCoverage = (state, originalStateMap) => { + + // branches only for js + if (!state.js) { + return; + } + + // console.log(state.astInfo.branches); + + // function count + state.astInfo.branches.forEach((group) => { + + if (group.generatedOnly) { + return; + } + + const { type, locations } = group; + + // start + const result = findOriginalRange(group.start, group.end, state, originalStateMap); + if (result.error) { + logMappingErrors('branch group', result); + return; + } + + // new group start and end + const groupStart = result.start; + const groupEnd = result.end; + + let hasError; + const newLocations = locations.map((oLoc) => { + + const newLoc = { + ... oLoc + }; + + if (newLoc.none) { + newLoc.start = groupStart; + newLoc.end = groupEnd; + return newLoc; + } + + const locResult = findOriginalRange(newLoc.start, newLoc.end, state, originalStateMap); + if (locResult.error) { + // It should not happen unless it is minify files, the SourceMap has some order problems + logMappingErrors('branch', locResult); + hasError = true; + return newLoc; + } + + // before new range + newLoc.generatedStart = newLoc.start; + newLoc.generatedEnd = newLoc.end; + // mapping to new range + newLoc.start = locResult.start; + newLoc.end = locResult.end; + + return newLoc; + }); + + // ignored group when found error + if (hasError) { + return; + } + + // add back to original ast + result.originalState.astInfo.branches.push({ + type, + start: groupStart, + end: groupEnd, + locations: newLocations + }); + + }); + +}; + +const handleOriginalStatementsCoverage = (state, originalStateMap) => { + + // statements only for js + if (!state.js) { + return; + } + + // statement count + state.astInfo.statements.forEach((it) => { + + if (it.generatedOnly) { + return; + } + + const { start, end } = it; + + const result = findOriginalRange(start, end, state, originalStateMap); + if (result.error) { + logMappingErrors('statement', result); + return; + } + + // add back to original ast + result.originalState.astInfo.statements.push({ + ... it, + generatedStart: start, + generatedEnd: end, + start: result.start, + end: result.end + }); + + }); + + originalStateMap.forEach((originalState) => { + const statements = originalState.astInfo.statements; + if (Util.isList(statements)) { + return; + } + // fake source nothing matched + statements.push({ + start: 0, + end: originalState.source.length, + count: 1 + }); + + }); + +}; + +// ======================================================================================================== + +const handleOriginalEmptyBytesCoverage = (state, originalStateMap) => { + const checkList = []; + + // check original bytes if fully in a wrapper range + originalStateMap.forEach((originalState) => { + const bytes = originalState.bytes; + if (Util.isList(bytes)) { + return; + } + + const { decodedMappings } = originalState; + const len = decodedMappings.length; + if (len < 2) { + return; + } + // sort by original line/column + const startMapping = decodedMappings[0]; + const endMapping = decodedMappings[len - 1]; + // console.log(startMapping, endMapping); + const startOffset = startMapping.generatedOffset; + + if (!endMapping.generatedEndOffset) { + // line last one + const line = state.locator.getLine(endMapping.generatedLine + 1); + // could be no line found + if (line) { + // last column + endMapping.generatedEndOffset = line.end; + } else { + endMapping.generatedEndOffset = endMapping.generatedOffset; + } + } + const endOffset = endMapping.generatedEndOffset; + + // console.log('===========================================================', originalState.sourcePath); + // console.log(originalState.source.length, endMapping); + + checkList.push({ + originalState, + startOffset, + endOffset + }); + + }); + + // no file to handle + if (!checkList.length) { + return; + } + + // there is no state.bytes if not in debug + // should using coverageList to generate bytes first + handleGeneratedBytesCoverage(state); + + checkList.forEach((it) => { + + const { + originalState, startOffset, endOffset + } = it; + + // console.log('=============', 'no bytes', originalState.sourcePath); + + // only check uncovered range + // because a uncovered range could be in a covered wrapper + // { start: 0, end: 12137, count: 1 }, could be { start: > 0, end: < 12137, count: 0 } + for (const range of state.bytes) { + if (range.count > 0) { + continue; + } + if (startOffset >= range.start && endOffset <= range.end) { + // console.log('------------', 'added'); + originalState.bytes.push({ + start: 0, + end: originalState.source.length, + count: 0 + }); + break; + } + } + + }); +}; + + +const handleAllOriginalBytesCoverage = (state, originalStateMap) => { + + const { js, coverageList } = state; + + // only for js, no sourcemap for css for now + if (!js) { + return; + } + + // v8 coverage + coverageList.forEach((block) => { + block.ranges.forEach((range) => { + + // remove wrap functions for original files + if (range.generatedOnly) { + return; + } + + const { + startOffset, endOffset, count + } = range; + + const result = findOriginalRange(startOffset, endOffset, state, originalStateMap, { + fixOriginalRange: true + }); + if (result.error) { + logMappingErrors('byte', result); + return; + } + + addJsBytesCoverage(result.originalState, { + generatedStart: startOffset, + generatedEnd: endOffset, + startOffset: result.start, + endOffset: result.end, + count + }); + + }); + }); + + handleOriginalEmptyBytesCoverage(state, originalStateMap); + +}; + +// ======================================================================================================== + +const decodeSourceMappings = (state, originalDecodedMap) => { + + const generatedLocator = state.locator; + + const { + sources, mappings, decodedMappings + } = state.sourceMap; + + const decodedList = decodedMappings || decode(mappings); + + // console.log(decodedList); + + sources.forEach((source, i) => { + originalDecodedMap.set(i, []); + }); + + const allDecodedMappings = []; + decodedList.forEach((segments, generatedLine) => { + + if (!segments.length) { + return; + } + + // line segments + const lastIndex = segments.length - 1; + segments.forEach((segment, i) => { + + // const COLUMN = 0; + // const SOURCES_INDEX = 1; + // const SOURCE_LINE = 2; + // const SOURCE_COLUMN = 3; + // const NAMES_INDEX = 4; + const [generatedColumn, sourceIndex, originalLine, originalColumn, nameIndex] = segment; + // the segment length could be 1, 4 or 5 + + if (typeof sourceIndex === 'undefined') { + // console.log('============================ sourceIndex undefined'); + // console.log(segment); + return; + } + + // 1-base + const generatedSN = generatedLine + 1; + + const generatedOffset = generatedLocator.locationToOffset({ + // 1-base + line: generatedSN, + column: generatedColumn + }); + + const info = { + generatedOffset, + generatedLine, + generatedColumn, + + sourceIndex, + originalLine, + originalColumn, + nameIndex + }; + + // first and last column + if (i === 0) { + info.first = true; + } + if (i === lastIndex) { + info.last = true; + } + + allDecodedMappings.push(info); + originalDecodedMap.get(sourceIndex).push(info); + + // calculate line end column + if (!info.last) { + return; + } + + const lineItem = generatedLocator.getLine(generatedSN); + if (!lineItem) { + // console.log('============================== not found line item'); + return; + } + + // console.log(generatedSN, generatedColumn, lineItem.length, lineItem.text); + + if (generatedColumn >= lineItem.length) { + return; + } + + const endColumn = { + generatedOffset: generatedOffset + (lineItem.length - generatedColumn), + generatedLine, + generatedColumn: lineItem.length, + + end: true, + + sourceIndex, + originalLine, + originalColumn, + nameIndex + }; + + // console.log(generatedSN, generatedColumn, info, endColumn); + + allDecodedMappings.push(endColumn); + originalDecodedMap.get(sourceIndex).push(endColumn); + + }); + + + }); + + // defaults to sort by generated offset, no need sort + // allDecodedMappings.sort((a, b) => { + // return a.generatedOffset - b.generatedOffset; + // }); + + return allDecodedMappings; +}; + +const getOriginalDecodedMappings = (originalDecodedMap, sourceIndex, locator) => { + // all mappings for the original file sorted + const decodedMappings = originalDecodedMap.get(sourceIndex); + + if (!decodedMappings) { + return []; + } + + // calculate line end column + decodedMappings.forEach((item) => { + if (!item.end) { + return; + } + const originalSN = item.originalLine + 1; + const lineItem = locator.getLine(originalSN); + // console.log(originalSN, item.originalColumn, lineItem.length, lineItem.text); + if (lineItem) { + item.originalColumn = lineItem.length; + } + }); + + // sort by original line/column + decodedMappings.sort((a, b) => { + if (a.originalLine === b.originalLine) { + return a.originalColumn - b.originalColumn; + } + return a.originalLine - b.originalLine; + }); + + // add offset and index + decodedMappings.forEach((item, i) => { + item.originalOffset = locator.locationToOffset({ + line: item.originalLine + 1, + column: item.originalColumn + }); + }); + + return decodedMappings; +}; + +// ======================================================================================================== + +const initOriginalList = (state, originalDecodedMap, options) => { + + // source filter + const sourceFilter = Util.getSourceFilter(options); + + // create original content mappings + const originalStateMap = new Map(); + + const { sources, sourcesContent } = state.sourceMap; + + const lengthBefore = sources.length; + let lengthAfter = 0; + + sources.forEach((sourcePath, sourceIndex) => { + + // filter + // do not change for sourceIndex + if (!sourceFilter(sourcePath)) { + // console.log('-', sourcePath); + return; + } + // console.log(sourcePath); + + // console.log(`add source: ${k}`); + const sourceContent = sourcesContent?.[sourceIndex]; + if (typeof sourceContent !== 'string') { + Util.logError(`not found source content: ${sourcePath}`); + return; + } + + const locator = new Locator(sourceContent); + const maxContentLength = sourceContent.length; + + const decodedMappings = getOriginalDecodedMappings(originalDecodedMap, sourceIndex, locator); + + // unpacked file always is js + + const type = getSourceType(sourcePath); + + const originalState = { + original: true, + // original file is js + js: true, + type, + source: sourceContent, + sourcePath, + locator, + maxContentLength, + decodedMappings, + // coverage info + bytes: [], + functions: [], + branches: [], + statements: [], + astInfo: { + functions: [], + branches: [], + statements: [] + }, + // coverage data + v8Data: {} + }; + + originalStateMap.set(sourceIndex, originalState); + lengthAfter += 1; + }); + + Util.logFilter(`source filter (${state.sourcePath}):`, lengthBefore, lengthAfter); + + return originalStateMap; +}; + +const collectOriginalList = (state, originalStateMap) => { + + const { fileUrls } = state; + const distFile = state.sourcePath; + + let added = 0; + + // collect original files + originalStateMap.forEach((originalState) => { + + const { + js, type, sourcePath, source + } = originalState; + + // add file item + const url = fileUrls[sourcePath] || sourcePath; + + // add dist for id + const id = Util.calculateSha1(sourcePath + source); + + const sourceItem = { + url, + id, + js, + type, + sourcePath, + distFile, + source + }; + + // save v8 data and add to originalList + originalState.v8Data = sourceItem; + state.originalList.push(originalState); + added += 1; + }); + + Util.logDebug(`added source files: ${EC.yellow(added)}`); + +}; + +// ======================================================================================================== + +const generateCoverageForDist = (state) => { + + handleFunctionsCoverage(state); + handleBranchesCoverage(state); + handleStatementsCoverage(state); + handleGeneratedBytesCoverage(state); + +}; + +const handleUncoveredInCovered = (state, originalStateMap) => { + if (!state.fake) { + return; + } + + // fake statements/branches/functions + originalStateMap.forEach((originalState) => { + const { bytes } = originalState; + const list = []; + originalState.bytes = bytes.filter((item) => { + if (item.count === 0) { + const range = bytes.find((it) => { + if (it.count === 0) { + return false; + } + if (it.start > item.end) { + return false; + } + if (it.end < item.start) { + return false; + } + return true; + }); + if (range) { + list.push(item); + return false; + } + } + return true; + }); + + if (!list.length) { + return; + } + + list.forEach((item) => { + ['statements', 'branches', 'functions'].forEach((key) => { + originalState[key] = originalState[key].filter((it) => { + if (it.start === item.start && it.end === item.end) { + return false; + } + return true; + }); + }); + }); + + }); + +}; + +const unpackSourceMap = (state, options) => { + + const { sourceMap, sourcePath } = state; + + // keep original urls + const fileUrls = {}; + initSourceMapSourcesPath(fileUrls, sourceMap, sourcePath, options); + state.fileUrls = fileUrls; + // for function names + state.sourceMapNames = sourceMap.names || []; + + // =============================================== + // decode mappings for each original file + + const originalDecodedMap = new Map(); + // for find-original-range + state.decodedMappings = decodeSourceMappings(state, originalDecodedMap); + + // filter original list and init list + const originalStateMap = initOriginalList(state, originalDecodedMap, options); + + originalDecodedMap.clear(); + + // =============================================== + + // handle functions before handle original state functions + handleOriginalFunctionsCoverage(state, originalStateMap); + handleOriginalBranchesCoverage(state, originalStateMap); + handleOriginalStatementsCoverage(state, originalStateMap); + + // handle lines info before handle ranges to update line count + originalStateMap.forEach((originalState) => { + + handleFunctionsCoverage(originalState); + handleBranchesCoverage(originalState); + handleStatementsCoverage(originalState); + + // if (originalState.sourcePath.endsWith('demo.js')) { + // console.log('=================================', originalState.sourcePath); + // } + + }); + + // handle bytes ranges + handleAllOriginalBytesCoverage(state, originalStateMap); + + originalStateMap.forEach((originalState) => { + handleOriginalBytesCoverage(originalState); + }); + + // remove uncovered in covered for fake + handleUncoveredInCovered(state, originalStateMap); + + // collect coverage for original list + collectOriginalList(state, originalStateMap); + +}; + +const unpackDistFile = (item, state, options) => { + + if (state.sourceMap) { + if (Util.isDebug()) { + // js self + item.debug = true; + generateCoverageForDist(state); + } else { + item.dedupe = true; + } + + // unpack source map + unpackSourceMap(state, options); + + } else { + + // css/js self + generateCoverageForDist(state); + + } + +}; + +// ======================================================================================================== + +const filterCoverageList = (item) => { + const { + functions, scriptOffset, source + } = item; + + // no script offset + if (!scriptOffset) { + return functions; + } + + // vm script offset + const minOffset = scriptOffset; + // the inline sourcemap could be removed + const maxOffset = source.length; + + const wrapperList = []; + + const coverageList = functions.filter((block) => { + + const { ranges } = block; + + // first one is function coverage info + const functionRange = ranges[0]; + const { startOffset, endOffset } = functionRange; + if (startOffset >= minOffset && endOffset <= maxOffset) { + return true; + } + + wrapperList.push(block); + + return false; + }); + + if (wrapperList.length) { + const rootBlock = wrapperList.pop(); + rootBlock.root = true; + coverageList.unshift(rootBlock); + } + + // if (item.sourcePath.includes('PlaceB.tsx')) { + // console.log(coverageList); + // } + + return coverageList; +}; + +const initJsCoverageList = (item) => { + const coverageList = filterCoverageList(item); + + // if (item.sourcePath.includes('PlaceB.tsx')) { + // console.log(coverageList[0]); + // } + + // function could be covered even it is defined after an uncovered return, see case closures.js + // fix uncovered range if there are covered ranges in uncovered range + + const uncoveredBlocks = []; + const uncoveredList = []; + coverageList.forEach((block) => { + block.ranges.forEach((range, i) => { + const { + count, startOffset, endOffset + } = range; + + if (i === 0) { + // check only first level + if (count > 0) { + const inUncoveredRange = Util.findInRanges(startOffset, endOffset, uncoveredBlocks, 'startOffset', 'endOffset'); + if (inUncoveredRange) { + if (!inUncoveredRange.coveredList) { + inUncoveredRange.coveredList = []; + uncoveredList.push(inUncoveredRange); + } + inUncoveredRange.coveredList.push(range); + } + } + return; + } + + if (count === 0) { + uncoveredBlocks.push({ + ... range, + index: i, + ranges: block.ranges + }); + } + + }); + }); + + if (uncoveredList.length) { + + uncoveredList.forEach((it) => { + const { + ranges, index, count, coveredList + } = it; + + // remove previous range first + const args = [index, 1]; + + Util.sortOffsetRanges(coveredList); + let startOffset = it.startOffset; + coveredList.forEach((cov) => { + // ignore sub functions in the function + if (cov.startOffset > startOffset) { + args.push({ + startOffset, + endOffset: cov.startOffset, + count + }); + startOffset = cov.endOffset; + } + }); + + if (it.endOffset > startOffset) { + args.push({ + startOffset, + endOffset: it.endOffset, + count + }); + } + + ranges.splice(... args); + + }); + } + + return coverageList; +}; + +const logConvertTime = (msg, time_start, untested) => { + if (untested) { + return; + } + Util.logTime(msg, time_start); +}; + +const convertCoverages = (list, options, untested) => { + const stateList = []; + + for (const item of list) { + // console.log([item.id]); + + const time_start_ast = Date.now(); + + const { + type, source, fake, sourcePath + } = item; + + // for source file, type could be ts or vue as extname, but js = true + const js = type === 'js'; + item.js = js; + + // source mapping + const locator = new Locator(source); + const maxContentLength = source.length; + + // ============================ + // move sourceMap + const sourceMap = item.sourceMap; + if (sourceMap) { + delete item.sourceMap; + } + + // ============================ + // move functions and ranges to coverageList + let coverageList = []; + let astInfo; + if (js) { + coverageList = initJsCoverageList(item); + // remove original functions + if (!Util.isDebug()) { + delete item.functions; + } + astInfo = getJsAstInfo(item, coverageList); + } else { + // convent css covered ranges to rules ranges and include uncovered ranges + astInfo = getCssAstInfo(item, coverageList); + // remove original ranges + if (!Util.isDebug()) { + delete item.ranges; + } + } + + logConvertTime(`${EC.magenta('│ ')}${EC.cyan('├')} [convert] parsed ast: ${sourcePath} (${EC.cyan(Util.BSF(maxContentLength))})`, time_start_ast, untested); + + // console.log(sourcePath, astInfo.statements.length); + // ============================ + + const time_start_unpack = Date.now(); + + // current file and it's sources from sourceMap + // see const originalState + const state = { + js, + type, + source, + fake, + sourcePath, + sourceMap, + locator, + maxContentLength, + decodedMappings: [], + rangeCache: new Map(), + diffCache: new Map(), + + // alignTextList: [], + + // coverage info + bytes: [], + functions: [], + branches: [], + statements: [], + astInfo, + // for sub source files + coverageList, + originalList: [], + // coverage data + v8Data: item + }; + + unpackDistFile(item, state, options); + const unpackedFiles = EC.cyan(`${state.originalList.length} files`); + + stateList.push(state); + + logConvertTime(`${EC.magenta('│ ')}${EC.cyan('├')} [convert] unpacked sourcemap: ${sourcePath} (${unpackedFiles})`, time_start_unpack, untested); + + } + + return stateList; +}; + +// ======================================================================================================== + +const isUncoveredRange = (range, key, uncoveredGroups) => { + + let uncovered = true; + uncoveredGroups.forEach((group) => { + const { groupMap, state } = group; + + // ======================================================== + // self key + if (groupMap.has(key)) { + return; + } + + // ======================================================== + // in all group + for (const item of groupMap.values()) { + if (range.start >= item.start && range.end <= item.end) { + return; + } + } + + // ======================================================== + // no sourcemap mappings in range + // check original range in decodedMappings + const { decodedMappings } = state; + const item = decodedMappings.find((it) => it.originalOffset >= range.start && it.originalOffset <= range.end); + if (!item) { + return; + } + + // ======================================================== + uncovered = false; + + }); + + return uncovered; + +}; + +const mergeV8Data = (state, stateList) => { + // console.log(stateList); + + // let debug = false; + // if (state.sourcePath.endsWith('counter')) { + // debug = true; + // console.log('merge v8 data ===================================', state.sourcePath); + // console.log('bytes before ============', stateList.map((it) => it.bytes)); + // // console.log('statements ==============', stateList.map((it) => it.statements)); + // // console.log('functions ==============', stateList.map((it) => it.functions)); + // // console.log('branches ======================', stateList.map((it) => it.branches.map((b) => [`${b.start}-${b.end}`, JSON.stringify(b.locations.map((l) => l.count))]))); + // } + + // =========================================================== + // bytes + const mergedBytes = []; + + const coveredMap = new Map(); + const uncoveredMap = new Map(); + const uncoveredGroups = []; + stateList.forEach((st) => { + const groupMap = new Map(); + const bytes = dedupeCountRanges(st.bytes); + bytes.forEach((range) => { + const key = `${range.start}_${range.end}`; + if (range.count) { + mergedBytes.push(range); + coveredMap.set(key, true); + } else { + uncoveredMap.set(key, range); + groupMap.set(key, range); + } + }); + + uncoveredGroups.push({ + groupMap, + state: st + }); + }); + + // if (debug) { + // console.log('coveredMap ============', coveredMap); + // console.log('uncoveredMap ============', uncoveredMap); + // console.log('uncoveredGroups ============', uncoveredGroups); + // } + + uncoveredMap.forEach((range, key) => { + + // in covered range + if (coveredMap.has(key)) { + return; + } + + if (isUncoveredRange(range, key, uncoveredGroups)) { + mergedBytes.push(range); + } + + }); + + // will be dedupeCountRanges in collectFileCoverage + state.bytes = mergedBytes; + + // if (debug) { + // console.log('bytes after ============', mergedBytes); + // } + + // =========================================================== + // functions + const allFunctions = stateList.map((it) => it.functions).flat(); + const functionComparer = (lastRange, range) => { + // if (lastRange.start === range.start && lastRange.end === range.end) { + // return true; + // } + + // function range could be from sourcemap, not exact matched + + // end is same + // {start: 2017, end: 2315, count: 481} + // {start: 2018, end: 2315, count: 14} + + // start is same + // {start: 10204, end: 10379, count: 0} + // {start: 10204, end: 10393, count: 5} + + // only one position matched could be same + if (lastRange.start === range.start || lastRange.end === range.end) { + // console.log(lastRange.start, range.start, lastRange.end, range.end); + + // if (lastRange.start === range.start) { + // console.log(range.end - lastRange.end, lastRange.start, lastRange.end, 'end', range.end, state.sourcePath); + // } else { + // console.log(range.start - lastRange.start, lastRange.start, lastRange.end, 'start', range.start, state.sourcePath); + // } + + return true; + } + + return false; + }; + const functionHandler = (lastRange, range) => { + lastRange.count += range.count; + }; + const mergedFunctions = mergeRangesWith(allFunctions, functionComparer, functionHandler); + state.functions = mergedFunctions; + + // =========================================================== + // statements + const allStatements = stateList.map((it) => it.statements).flat(); + const statementComparer = (lastRange, range) => { + // exact matched because the statement range is generated from ast + return lastRange.start === range.start && lastRange.end === range.end; + }; + const statementHandler = (lastRange, range) => { + // merge statements count + lastRange.count += range.count; + }; + const mergedStatements = mergeRangesWith(allStatements, statementComparer, statementHandler); + state.statements = mergedStatements; + + // =========================================================== + // branches + const allBranches = stateList.map((it) => it.branches).flat(); + const branchComparer = (lastRange, range) => { + // exact matched because the branch range is generated from ast + return lastRange.start === range.start && lastRange.end === range.end; + }; + const branchHandler = (lastRange, range) => { + // merge locations count + lastRange.locations.forEach((item, i) => { + const loc = range.locations[i]; + if (loc) { + item.count += loc.count; + } + }); + }; + const mergedBranches = mergeRangesWith(allBranches, branchComparer, branchHandler); + state.branches = mergedBranches; + + // if (sourcePath.endsWith('scroll_zoom.ts')) { + // console.log(mergedBytes); + // console.log(mergedFunctions); + // console.log(mergedBranches.map((b) => [`${b.start}-${b.end}`, JSON.stringify(b.locations.map((l) => l.count))])); + // } + + +}; + +const addUntestedFiles = async (stateList, options) => { + + const time_start_untested = Date.now(); + + const testedMap = new Map(); + stateList.forEach((state) => { + const { v8Data, originalList } = state; + // dedupe dist file if not debug + if (!v8Data.dedupe) { + testedMap.set(state.sourcePath, true); + } + originalList.forEach((originalState) => { + testedMap.set(originalState.sourcePath, true); + }); + }); + + // console.log('testedMap', testedMap); + + const untestedList = await getUntestedList(testedMap, options, 'v8'); + if (!untestedList) { + return; + } + + const untestedStateList = convertCoverages(untestedList, options, true); + + // console.log(untestedStateList); + untestedStateList.forEach((state) => { + stateList.push(state); + }); + + // console.log('untestedList', untestedList); + + Util.logTime(`${EC.magenta('│ ')}${EC.cyan('├')} [convert] added untested files: ${EC.yellow(untestedList.length)}`, time_start_untested); + + +}; + +const generateV8DataList = (stateList, options) => { + + const stateMap = new Map(); + + // all original files from dist + const allOriginalList = []; + stateList.forEach((state) => { + const { v8Data, originalList } = state; + // dedupe dist file if not debug + if (!v8Data.dedupe) { + stateMap.set(v8Data.id, state); + } + allOriginalList.push(originalList); + }); + + // merge istanbul and v8(converted) + const mergeMap = new Map(); + allOriginalList.flat().forEach((originalState) => { + const { v8Data } = originalState; + const id = v8Data.id; + // exists item + const prevState = stateMap.get(id); + if (prevState) { + // ignore empty item, just override it + if (!prevState.v8Data.empty) { + if (mergeMap.has(id)) { + mergeMap.get(id).push(originalState); + } else { + mergeMap.set(id, [prevState, originalState]); + } + return; + } + } + stateMap.set(id, originalState); + }); + + const mergeIds = mergeMap.keys(); + for (const id of mergeIds) { + const state = stateMap.get(id); + // for source the type could be ts, so just use js (boolean) + if (state.js) { + mergeV8Data(state, mergeMap.get(id)); + } else { + // should no css here, css can not be in sources + } + } + + // new v8 data list (includes sources) + const v8DataList = []; + // global file sources and istanbul coverage data + const fileSources = {}; + const coverageData = {}; + stateMap.forEach((state) => { + const { v8Data } = state; + const istanbulData = collectFileCoverage(v8Data, state, options); + const { sourcePath, source } = v8Data; + v8DataList.push(v8Data); + fileSources[sourcePath] = source; + coverageData[sourcePath] = istanbulData; + }); + + // sort v8DataList (files) + v8DataList.sort((a, b) => { + if (a.sourcePath > b.sourcePath) { + return 1; + } + return -1; + }); + + return { + v8DataList, + fileSources, + coverageData + }; +}; + +const convertV8List = async (v8list, options) => { + + // for tested files + const stateList = convertCoverages(v8list, options); + + // empty coverage handler + await addUntestedFiles(stateList, options); + + const time_start_convert = Date.now(); + const dataList = generateV8DataList(stateList, options); + const dataFiles = EC.cyan(`${dataList.v8DataList.length} files`); + Util.logTime(`${EC.magenta('│ ')}${EC.cyan('├')} [convert] converted data list (${dataFiles})`, time_start_convert); + + return dataList; +}; + +module.exports = { + convertV8List +}; diff --git a/node_modules/monocart-coverage-reports/lib/converter/find-original-range.js b/node_modules/monocart-coverage-reports/lib/converter/find-original-range.js new file mode 100644 index 0000000..a1cf3a5 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/converter/find-original-range.js @@ -0,0 +1,980 @@ +const { diffSequence } = require('../packages/monocart-coverage-vendor.js'); +const Util = require('../utils/util.js'); +const EC = Util.EC; + +const findMapping = (list, offset) => { + let start = 0; + let end = list.length - 1; + while (end - start > 1) { + const i = Math.floor((start + end) * 0.5); + const item = list[i]; + if (offset < item.generatedOffset) { + end = i; + continue; + } + if (offset > item.generatedOffset) { + start = i; + continue; + } + return list[i]; + } + // last two items, less is start + const startItem = list[start]; + if (offset === startItem.generatedOffset) { + return startItem; + } + const endItem = list[end]; + if (offset === endItem.generatedOffset) { + return endItem; + } + + // between two mappings + if (offset > startItem.generatedOffset && offset < endItem.generatedOffset) { + return [startItem, endItem]; + } + + // not found the mappings + +}; + +// ======================================================================================================== + +const alignText = (gt, ot, info) => { + + const { diffCache } = info.state; + + if (diffCache.has(gt)) { + const subMap = diffCache.get(gt); + if (subMap.has(ot)) { + return subMap.get(ot); + } + } + + const toList = (s) => { + return s.split('').map((v, i) => { + return { + index: i, + value: v + }; + }); + }; + + const mergeList = (gList, oList) => { + const oLen = oList.length; + if (!oLen) { + return; + } + const gLen = gList.length; + if (gLen === oLen) { + gList.forEach((item, i) => { + item.original = oList[i]; + }); + } + }; + + const gl = toList(gt); + const ol = toList(ot); + + // console.log(gl); + // console.log(ol); + + const commonItems = []; + diffSequence(gl.length, ol.length, (gi, oi) => { + return gl[gi].value === ol[oi].value; + }, (len, gi, oi) => { + commonItems.push([gi, oi, len]); + }); + + // console.log(commonItems); + // console.log('================================================================'); + // merge list + // previous index + let gpi = 0; + let opi = 0; + commonItems.forEach(([gi, oi, len]) => { + + if (gpi !== gi) { + const gList = gl.slice(gpi, gi); + const oList = ol.slice(opi, oi); + mergeList(gList, oList); + } + + for (let i = 0; i < len; i++) { + + const gii = gi + i; + const oii = oi + i; + const gItem = gl[gii]; + gItem.original = ol[oii]; + + // matching a word end + if (i === len - 1 && len > 1) { + gItem.wordEnd = true; + } + + } + gpi = gi + len; + opi = oi + len; + }); + + // console.log(JSON.stringify(data.gt)); + // console.log(JSON.stringify(data.ot)); + if (gpi < gl.length && opi < ol.length) { + const gList = gl.slice(gpi); + const oList = ol.slice(opi); + mergeList(gList, oList); + } + + if (diffCache.has(gt)) { + const subMap = diffCache.get(gt); + subMap.set(ot, gl); + } else { + const subMap = new Map(); + diffCache.set(gt, subMap); + subMap.set(ot, gl); + } + + // console.log(gl); + return gl; +}; + +const getWordEndPosition = (list, gp, direction) => { + // for end only + if (direction !== 'end') { + return; + } + + const prev = list[gp - 1]; + if (prev && prev.original && prev.wordEnd) { + const op = prev.original.index + 1; + // console.log(gp, JSON.stringify(gt)); + // console.log(op, JSON.stringify(ot)); + return { + pos: op + }; + } +}; + +const getAlignPosition = (info, direction) => { + + const gt = info.generatedText; + const gp = info.generatedPos; + const ot = info.originalText; + + // const alignTextItem = { + // gt, ot, gp + // }; + // info.state.alignTextList.push(it); + + // there is no need to align for long text + const maxLength = 100; + if (gt.length > maxLength || ot.length > maxLength) { + // console.log(gt.length, ot.length, gp); + return; + } + + // generatedText: '"false";\n', + // originalText: "'false';\r\n ", + // generatedPos: 7 + + // left matched + + // originalText: '1;', + // generatedText: '1;else', + // generatedLeft: '1;' + + // right matched + // only for original first line text + + // exclusive + const list = alignText(gt, ot, info); + const item = list[gp]; + if (item && item.original) { + + // alignTextItem.op = item.original.index; + + return { + pos: item.original.index + }; + } + + // inclusive, for end only + return getWordEndPosition(list, gp, direction); + +}; + +// ======================================================================================================== + +const getBlockStartPosition = (originalLineText) => { + // originalText: 'argument) {', + // generatedLeft: 'o', + // generatedRight: '&&' + + // function/block could be started with {( + const startBlockIndex = originalLineText.search(/[<{(]/); + if (startBlockIndex !== -1) { + return { + pos: startBlockIndex + }; + } + + // end a block + const list = ['>', '}', ')']; + for (const s of list) { + const endBlockIndex = originalLineText.lastIndexOf(s); + if (endBlockIndex !== -1) { + return { + pos: endBlockIndex + 1 + }; + } + } + + // ============================ + // end characters + + // ends with ">" in vue + // + + // originalText: '">', + // generatedText: ' ? ((0,vue__.openBlock)(), ' + + // originalMethod?.apply + // originalText: '?.' no ? + + const indexEndBlock = originalLineText.search(/(?<=[;,:"'\s])/); + if (indexEndBlock !== -1) { + return { + pos: indexEndBlock + }; + } + +}; + +const getBlockEndPosition = (originalLineText) => { + + // generatedText: 'e),', + // generatedPos: 2, + // originalText: 'prop))' + + // generatedText: ' = false)', + // generatedPos: 8, + // originalText: '=false"' + + // generatedText: '), 1 /* TEXT */)])])) : (0,vue__...)("v-if", true)], 6 /* CLASS, STYLE */);', + // generatedPos: 17, + // originalText: ' }}' + + // end marks + const list = ['>', '}', ')']; + for (const s of list) { + const endBlockIndex = originalLineText.lastIndexOf(s); + if (endBlockIndex !== -1) { + return { + pos: endBlockIndex + 1 + }; + } + } + + const startBlockIndex = originalLineText.search(/[<{(]/); + if (startBlockIndex !== -1) { + return { + pos: startBlockIndex + }; + } + +}; + +// ======================================================================================================== + +const getComparedPosition = (info, direction) => { + + const gt = info.generatedText; + const gp = info.generatedPos; + const ot = info.originalText; + const olt = info.originalLineText; + + // seems direction is start only + if (gp === 0) { + return; + } + + // whole generated text + if (gp >= gt.length) { + // console.log(JSON.stringify(gt), gt.length, gp); + // console.log(JSON.stringify(ot)); + return { + pos: olt.length + }; + } + + // ============================= + // trim + + const gtt = gt.trim(); + // no generated content after trim + if (!gtt) { + return; + } + + const ott = ot.trim(); + // no original content after trim + if (!ott) { + return { + pos: direction === 'start' ? ot.length : 0 + }; + } + + // same content + if (gtt === ott) { + // fix indent + const blankBlock = /\S/; + const gi = gt.search(blankBlock); + const oi = ot.search(blankBlock); + + return { + pos: gp - gi + oi + }; + } + + // ============================= + + return getAlignPosition(info, direction); + +}; + + +const getSimilarPosition = (info, direction) => { + + const originalText = info.originalText; + // never cross line, using first line of original text + // trim end remove \r\n and \n + const originalLines = originalText.split(/\n/); + if (originalLines.length === 1) { + // already single line + info.originalLineText = originalText.trimEnd(); + } else { + // multiple liens + info.originalLineText = originalLines[0].trimEnd(); + } + + // no need comparison for fake source + if (info.state.fake) { + return; + } + + const textPos = getComparedPosition(info, direction); + if (textPos) { + return textPos; + } + + // console.log('===================================================================='); + // console.log(`${EC.magenta(direction)} similar position can NOT be fixed`, info.originalState.sourcePath); + // console.log({ + // direction, + // generatedText: info.generatedText, + // generatedPos: info.generatedPos, + // originalText + // }); + +}; + +const getFixedPosition = (info, direction) => { + + const similarPos = getSimilarPosition(info, direction); + if (similarPos) { + return similarPos.pos; + } + + + // generatedText: never cross lines + // originalText: could be multiple lines + // originalLineText: single line originalText + const { originalLineText } = info; + + if (direction === 'start') { + const blockPos = getBlockStartPosition(originalLineText); + if (blockPos) { + return blockPos.pos; + } + return 0; + } + + const blockPos = getBlockEndPosition(originalLineText); + if (blockPos) { + return blockPos.pos; + } + return originalLineText.length; +}; + +// ======================================================================================================== + +const getOriginalEndOffset = (m, originalState) => { + if (!m.originalEndOffset) { + const line = originalState.locator.getLine(m.originalLine + 1); + m.originalEndOffset = line ? line.end : m.originalOffset; + } + return m.originalEndOffset; +}; + +const getOriginalText = (m1, m2, originalState, startNextLine) => { + const originalLocator = originalState.locator; + + const o1 = m1.originalOffset; + const o2 = m2.originalOffset; + const sameLine = m2.originalLine === m1.originalLine; + + // o1 < o2: most of time + if (o1 < o2) { + + // could be in comments + // it must be wrong sourcemap, do not fix it here + // if (originalLocator.lineParser.commentParser.isComment(o1, o2)) { + // console.log('in comments', originalLocator.getSlice(o1, o2), originalLocator.offsetToLocation(o1), originalLocator.offsetToLocation(o2), cache.originalState.sourcePath); + // return { + // originalOffset: o1, + // originalText: '' + // }; + // } + + if (sameLine) { + return { + originalOffset: o1, + originalText: originalLocator.getSlice(o1, o2) + }; + } + + // start from next line + if (startNextLine) { + const nextLine = originalState.locator.getLine(m1.originalLine + 2); + if (nextLine) { + // console.log(nextLine); + return { + originalOffset: nextLine.start + nextLine.indent, + originalText: nextLine.text.slice(nextLine.indent) + }; + } + } + + // could be multiple lines for original text + return { + originalOffset: o1, + originalText: originalLocator.getSlice(o1, getOriginalEndOffset(m1, originalState)) + }; + } + + // esbuild fixing two mapping have same original + // m1 to end line + if (o1 === o2) { + return { + originalOffset: o1, + originalText: originalLocator.getSlice(o1, getOriginalEndOffset(m1, originalState)) + }; + } + + // o1 > o2: should be wrong sourcemap + + // just reverse offsets if same line + if (sameLine) { + return { + originalOffset: o2, + originalText: originalLocator.getSlice(o2, o1) + }; + } + + // if (direction === 'start') { + // should be m2 ? + // console.log(direction, cache.originalState.sourcePath); + // console.log(m1, m2); + // } + + // should be wrong, ignore m2 + return { + originalOffset: o1, + originalText: originalLocator.getSlice(o1, getOriginalEndOffset(m1, originalState)) + }; + +}; + +const getGeneratedText = (m1, m2, state, offset) => { + const generatedLocator = state.locator; + + const o1 = m1.generatedOffset; + const o2 = m2.generatedOffset; + + // same line + if (m1.generatedLine === m2.generatedLine) { + return { + generatedText: generatedLocator.getSlice(o1, o2), + generatedPos: offset - o1 + }; + } + + // ======================================= + // different lines + // never cross lines + + // 1-base + const lineInfo = generatedLocator.offsetToLocation(offset); + // 0-base + const targetLine = lineInfo.line - 1; + + // m1 p (case 1, right to end) + // p (case 2, mid line) + // p (case 3) m2 + + // case 1 + if (targetLine === m1.generatedLine) { + return { + generatedText: generatedLocator.getSlice(o1, lineInfo.end), + generatedPos: offset - o1 + }; + } + + // case 3 + if (targetLine === m2.generatedLine) { + return { + generatedText: generatedLocator.getSlice(lineInfo.start, o2), + generatedPos: offset - lineInfo.start + }; + } + + // case 2 + return { + generatedText: lineInfo.text, + generatedPos: offset - lineInfo.start + }; + +}; + +// ======================================================================================================== +const getFunctionName = (mp, state, options) => { + if (options.checkName && typeof mp.nameIndex !== 'undefined') { + return state.sourceMapNames[mp.nameIndex]; + } +}; + +const getFixedOriginalStart = (start, mappings, state, cache, options) => { + + const [m1, m2] = mappings; + const { originalState, crossStart } = cache; + + // cross file from start of line + if (crossStart) { + return { + originalStart: m2.originalOffset, + originalName: getFunctionName(m2, state, options) + }; + } + + // skip last and end column mapping + let startNextLine = false; + if (m1.end || m1.last) { + const locStart = state.locator.offsetToLocation(start); + // 1-base + const lineIndex = locStart.line - 1; + if (lineIndex > m1.generatedLine) { + startNextLine = true; + // console.log(originalState.sourcePath, start, m1, m2); + } + } + + const { originalText, originalOffset } = getOriginalText(m1, m2, originalState, startNextLine); + const { generatedText, generatedPos } = getGeneratedText(m1, m2, state, start); + const direction = 'start'; + + const info = { + state, + generatedText, + generatedPos, + originalText, + originalState + }; + + const originalPos = getFixedPosition(info, direction); + + // if (start === 2660) { + // console.log('====================================================='); + // console.log('fixed start', originalState.sourcePath); + // console.log({ + // generatedText, + // generatedPos, + // originalText, + // originalPos + // }); + // } + + return { + originalStart: originalOffset + originalPos, + originalName: getFunctionName(m1, state, options) + }; +}; + +const getFixedOriginalEnd = (end, mappings, state, cache) => { + + const [m1, m2] = mappings; + const { originalState, crossEnd } = cache; + + // cross file until e1 line end (not file end) + if (crossEnd) { + const originalEndOffset = getOriginalEndOffset(m1, originalState); + return { + originalEnd: originalEndOffset + }; + } + + // end is exclusive + // quick check previous one if exact match + // most of case is matching "}" + if (m1.generatedOffset === end - 1) { + return { + originalEnd: m1.originalOffset + 1 + }; + } + + + const { originalText, originalOffset } = getOriginalText(m1, m2, originalState); + const { generatedText, generatedPos } = getGeneratedText(m1, m2, state, end); + const direction = 'end'; + + const info = { + state, + offset: end, + generatedText, + generatedPos, + originalText, + originalState + }; + + const originalPos = getFixedPosition(info, direction); + + // if (end === 1304578) { + // console.log('====================================================='); + // console.log('fixed end', originalState.sourcePath); + // console.log({ + // generatedText, + // generatedPos, + // originalText, + // originalPos, + // originalLineText: info.originalLineText + // }); + // } + + return { + originalEnd: originalOffset + originalPos + }; +}; + +// ======================================================================================================== + +const getOriginalStartPosition = (cache, state, options) => { + + const { start, startMappings } = cache; + + if (Array.isArray(startMappings)) { + return getFixedOriginalStart(start, startMappings, state, cache, options); + } + + // Exact match + return { + originalStart: startMappings.originalOffset, + originalName: getFunctionName(startMappings, state, options) + }; +}; + +const getOriginalExclusiveEnd = (cache, state) => { + // end, exclusive mappings + const { end } = cache; + const { decodedMappings } = state; + const endMappings = findMapping(decodedMappings, end); + if (!endMappings) { + return { + error: true, + errors: ['not found end mappings'] + }; + } + if (Array.isArray(endMappings)) { + return getFixedOriginalEnd(end, endMappings, state, cache); + } + + // Exact match end + return { + originalEnd: endMappings.originalOffset + }; +}; + +const getOriginalEndPosition = (cache, state) => { + + const { endMappings, originalState } = cache; + + // (end - 1), inclusive + if (Array.isArray(endMappings)) { + return getOriginalExclusiveEnd(cache, state); + } + + // Exact match (end - 1) + + // check end char + const oi = endMappings.originalOffset; + const originalEndChar = originalState.locator.getSlice(oi, oi + 1); + // the char should never end with "{" or "(" + if (['{', '('].includes(originalEndChar)) { + return getOriginalExclusiveEnd(cache, state); + } + + // inclusive to exclusive + return { + originalEnd: oi + 1 + }; +}; + +// ======================================================================================================== + +const checkSourceFileIndexes = (startIndexes, endIndexes) => { + + const checkIndex11 = (s1, e1) => { + if (s1 === e1) { + return { + sourceIndex: s1 + }; + } + }; + + const checkIndex21 = (s1, s2, e1) => { + if (s1 === e1 || s2 === e1) { + if (s1 === s2) { + return { + sourceIndex: e1 + }; + } + return { + crossStart: true, + sourceIndex: e1 + }; + } + }; + + const checkIndex12 = (s1, e1, e2) => { + if (s1 === e1 || s1 === e2) { + if (e1 === e2) { + return { + sourceIndex: s1 + }; + } + return { + crossEnd: true, + sourceIndex: s1 + }; + } + }; + + const checkIndex22 = (s1, s2, e1, e2) => { + // 4 same + if (s1 === s2 && e1 === e2 && s1 === e1) { + return { + sourceIndex: s1 + }; + } + + if (e1 === e2) { + return checkIndex21(s1, s2, e1); + } + + if (s1 === s2) { + return checkIndex12(s1, e1, e2); + } + + if (s2 === e1) { + return { + crossStart: true, + crossEnd: true, + sourceIndex: s2 + }; + } + + // both between two mappings: 38,39 ~ 38,39 + // if (s1 === e1 && s2 === e2) { + // } + }; + + // both exact matched + if (startIndexes.length === 1 && endIndexes.length === 1) { + return checkIndex11(startIndexes[0], endIndexes[0]); + } + + if (startIndexes.length === 2 && endIndexes.length === 1) { + return checkIndex21(startIndexes[0], startIndexes[1], endIndexes[0]); + } + + if (startIndexes.length === 1 && endIndexes.length === 2) { + return checkIndex12(startIndexes[0], endIndexes[0], endIndexes[1]); + } + + // both 2 mappings + return checkIndex22(startIndexes[0], startIndexes[1], endIndexes[0], endIndexes[1]); + +}; + +const getOriginalState = (start, end, state, originalMap) => { + + const mappingInfo = getMappingInfo(start, end, state); + if (mappingInfo.error) { + return mappingInfo; + } + + const { startMappings, endMappings } = mappingInfo; + + // check source file indexes + const startIndexes = [].concat(startMappings).map((it) => it.sourceIndex); + const endIndexes = [].concat(endMappings).map((it) => it.sourceIndex); + const results = checkSourceFileIndexes(startIndexes, endIndexes); + if (!results) { + return { + error: true, + errors: [`invalid source indexes: ${EC.yellow(`${startIndexes} ~ ${endIndexes}`)}`] + }; + } + + const { + sourceIndex, crossStart, crossEnd + } = results; + + // if (crossStart || crossEnd) { + // console.log(EC.magenta('cross file'), EC.yellow(`${startIndexes} ~ ${endIndexes}`)); + // } + + const originalState = originalMap.get(sourceIndex); + if (!originalState) { + return { + error: true, + errors: [`not found original file: ${EC.yellow(sourceIndex)}`] + }; + } + + // cache for original info + return { + // for debug + // startIndexes, + // endIndexes, + + start, + end, + startMappings, + endMappings, + + sourceIndex, + crossStart, + crossEnd, + originalState + }; +}; + +const getMappingInfo = (start, end, state) => { + + const { decodedMappings } = state; + // possible no length + if (decodedMappings.length < 2) { + return { + error: true, + errors: ['invalid decoded mappings (length < 2)'] + }; + } + + // start: inclusive + const startMappings = findMapping(decodedMappings, start); + if (!startMappings) { + return { + error: true, + errors: ['not found start mappings'] + }; + } + + // end: exclusive + const endMappings = findMapping(decodedMappings, end - 1); + if (!endMappings) { + return { + error: true, + errors: ['not found end mappings'] + }; + } + + // could be 4 mappings found + return { + startMappings, + endMappings + }; +}; + + +const findOriginalRange = (start, end, state, originalMap, options = {}) => { + + const { sourcePath, rangeCache } = state; + + const key = `${start}_${end}_${Boolean(options.fixOriginalRange)}`; + if (rangeCache.has(key)) { + return rangeCache.get(key); + } + + const createMappingError = (errors) => { + const res = { + error: true, + start, + end, + sourcePath, + errors + }; + + // cache error response + rangeCache.set(key, res); + + return res; + }; + + const cache = getOriginalState(start, end, state, originalMap); + if (cache.error) { + return createMappingError(cache.errors); + } + + const originalStartResult = getOriginalStartPosition(cache, state, options); + const { originalStart, originalName } = originalStartResult; + // could be used for end + cache.originalStart = originalStart; + + const originalEndResult = getOriginalEndPosition(cache, state); + if (originalEndResult.error) { + return createMappingError(originalEndResult.errors); + } + const { originalEnd } = originalEndResult; + + // range start > end + if (originalStart > originalEnd) { + return createMappingError([`invalid original start > end: ${EC.yellow(originalStart)} > ${EC.yellow(originalEnd)}`]); + } + + const { originalState } = cache; + const locator = originalState.locator; + + const inComment = locator.lineParser.commentParser.isComment(originalStart, originalEnd); + if (inComment) { + return createMappingError(['the range in a original comment']); + } + + const res = { + start: originalStart, + end: originalEnd, + name: originalName, + originalState + }; + + if (options.fixOriginalRange) { + const { fixedStart, fixedEnd } = Util.fixSourceRange(locator, originalStart, originalEnd); + res.start = fixedStart; + res.end = fixedEnd; + } + + // cache response + rangeCache.set(key, res); + + return res; + +}; + +module.exports = findOriginalRange; diff --git a/node_modules/monocart-coverage-reports/lib/converter/flatten-source-maps.js b/node_modules/monocart-coverage-reports/lib/converter/flatten-source-maps.js new file mode 100644 index 0000000..0a2b773 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/converter/flatten-source-maps.js @@ -0,0 +1,186 @@ +const { decode } = require('../packages/monocart-coverage-vendor.js'); + +const COLUMN = 0; +const SOURCES_INDEX = 1; +const SOURCE_LINE = 2; +const SOURCE_COLUMN = 3; +const NAMES_INDEX = 4; + +function getLine(arr, index) { + for (let i = arr.length; i <= index; i++) { + arr[i] = []; + } + return arr[index]; +} + +function getMapping(seg, column, sourcesOffset, namesOffset) { + + const sourcesIndex = sourcesOffset + seg[SOURCES_INDEX]; + const sourceLine = seg[SOURCE_LINE]; + const sourceColumn = seg[SOURCE_COLUMN]; + + if (seg.length === 4) { + return [column, sourcesIndex, sourceLine, sourceColumn]; + } + + return [column, sourcesIndex, sourceLine, sourceColumn, namesOffset + seg[NAMES_INDEX]]; +} + +function addMappings(options, sourcesOffset, namesOffset) { + + const { + input, + lineOffset, + columnOffset, + stopLine, + stopColumn + } = options; + + const decoded = decode(input.mappings); + + for (let i = 0; i < decoded.length; i++) { + const lineI = lineOffset + i; + + if (lineI > stopLine) { + return; + } + + const out = getLine(options.decodedMappings, lineI); + const cOffset = i === 0 ? columnOffset : 0; + + const line = decoded[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + const column = cOffset + seg[COLUMN]; + + if (lineI === stopLine && column >= stopColumn) { + return; + } + + if (seg.length === 1) { + out.push([column]); + continue; + } + + out.push(getMapping(seg, column, sourcesOffset, namesOffset)); + } + } +} + +function addSection(options) { + + const { input } = options; + + const { sections } = input; + if (sections) { + return flatten(options); + } + + const sourcesOffset = options.sources.length; + const namesOffset = options.names.length; + + // sources and sourcesContent + if (!input.sourcesContent) { + input.sourcesContent = []; + } + input.sources.forEach((src, i) => { + options.sources.push(src); + options.sourcesContent.push(input.sourcesContent[i] || null); + }); + + // names + if (input.names) { + input.names.forEach((n) => { + options.names.push(n); + }); + } + + addMappings(options, sourcesOffset, namesOffset); + +} + +function flatten(options) { + + const { + input, + lineOffset, + columnOffset, + stopLine, + stopColumn + } = options; + + const { sections } = input; + + for (let i = 0, l = sections.length; i < l; i++) { + const { map, offset } = sections[i]; + + let sl = stopLine; + let sc = stopColumn; + if (i + 1 < sections.length) { + const nextOffset = sections[i + 1].offset; + sl = Math.min(stopLine, lineOffset + nextOffset.line); + + if (sl === stopLine) { + sc = Math.min(stopColumn, columnOffset + nextOffset.column); + } else if (sl < stopLine) { + sc = columnOffset + nextOffset.column; + } + } + + options.input = map; + options.lineOffset = lineOffset + offset.line; + options.columnOffset = columnOffset + offset.column; + options.stopLine = sl; + options.stopColumn = sc; + + addSection(options); + } +} + +const flattenSourceMaps = function(indexedMap, mapUrl) { + + const sections = indexedMap.sections; + if (!sections) { + return indexedMap; + } + + const decodedMappings = []; + const sources = []; + const sourcesContent = []; + const names = []; + + const lineOffset = 0; + const columnOffset = 0; + const stopLine = Infinity; + const stopColumn = Infinity; + + flatten({ + input: indexedMap, + + mapUrl, + + decodedMappings, + sources, + sourcesContent, + + names, + + lineOffset, + columnOffset, + stopLine, + stopColumn + }); + + indexedMap.sources = sources; + indexedMap.sourcesContent = sourcesContent; + indexedMap.names = names; + indexedMap.decodedMappings = decodedMappings; + + // console.log(decodedMappings); + + return indexedMap; +}; + +module.exports = { + flattenSourceMaps +}; diff --git a/node_modules/monocart-coverage-reports/lib/converter/ignore.js b/node_modules/monocart-coverage-reports/lib/converter/ignore.js new file mode 100644 index 0000000..636d7bb --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/converter/ignore.js @@ -0,0 +1,225 @@ +const Util = require('../utils/util.js'); + +const getNextN = (content, currentLine, item, locator) => { + + // v-8 ignore next N + if (content) { + const n = parseInt(content); + if (n && n > 0) { + return n; + } + return 1; + } + + // block comment not end of line, same line + if (item.block) { + // has code between comment and line end + const text = locator.getSlice(item.end, currentLine.end).trim(); + if (text) { + return 0; + } + } + + // v-8 ignore next + return 1; +}; + +const extendStart = (start, source) => { + // extend left, include + while (start > 0 && Util.isBlank(source[start - 1])) { + start -= 1; + } + return start; +}; + +const extendEnd = (end, source, maxLength) => { + // extend right, exclude + while (end < maxLength && Util.isBlank(source[end])) { + end += 1; + } + return end; +}; + +const addNextIgnore = (list, content, item, locator) => { + + const { lineParser, source } = locator; + const maxLength = source.length; + + const start = extendStart(item.start, source); + + // findLine 0-base + const currentLine = lineParser.findLine(item.end); + const n = getNextN(content, currentLine, item, locator); + + // console.log('current line', currentLine.line, 'lines', lines); + + // getLine 1-base + const line = currentLine.line + 1; + const endLine = locator.getLine(line + n); + const end = extendEnd(endLine ? endLine.end : maxLength, source, maxLength); + + const nextItem = { + type: 'next', + n, + start, + end + }; + + list.push(nextItem); +}; + +// both v8 or c8 +const getStartEndNextInfo = (content) => { + content = content.trim(); + + const start = 'start'; + const stop = 'stop'; + const next = 'next'; + if (content.startsWith(start)) { + return { + type: 'range', + value: stop + }; + } + if (content.startsWith(stop)) { + return { + type: 'range', + value: stop + }; + } + if (content.startsWith(next)) { + return { + type: 'next', + value: content.slice(next.length) + }; + } +}; + +const getDisableEnableNextInfo = (content) => { + content = content.trim(); + + const start = 'disable'; + const stop = 'enable'; + const next = 'ignore next'; + if (content.startsWith(start)) { + return { + type: 'range', + value: stop + }; + } + if (content.startsWith(stop)) { + return { + type: 'range', + value: stop + }; + } + if (content.startsWith(next)) { + return { + type: 'next', + value: content.slice(next.length) + }; + } +}; + + +const getIgnoreInfo = (content) => { + content = content.trim(); + + const v8_ignore = 'v8 ignore'; + if (content.startsWith(v8_ignore)) { + return getStartEndNextInfo(content.slice(v8_ignore.length)); + } + + const c8_ignore = 'c8 ignore'; + if (content.startsWith(c8_ignore)) { + return getStartEndNextInfo(content.slice(c8_ignore.length)); + } + + const node_coverage = 'node:coverage'; + if (content.startsWith(node_coverage)) { + return getDisableEnableNextInfo(content.slice(node_coverage.length)); + } + +}; + +const getIgnoredRanges = (locator, options) => { + if (!options.v8Ignore) { + return; + } + + const { lineParser, source } = locator; + const maxLength = source.length; + + const comments = lineParser.comments; + if (!Util.isList(comments)) { + return; + } + + const list = []; + let ignoreStart = null; + + comments.forEach((item) => { + const { + block, start, end, text + } = item; + + const content = block ? text.slice(2, -2) : text.slice(2); + const ignoreInfo = getIgnoreInfo(content); + if (!ignoreInfo) { + return; + } + + const { type, value } = ignoreInfo; + + if (ignoreStart) { + // v-8 ignore stop + if (type === 'range' && value === ignoreStart.value) { + ignoreStart.ignoreData.end = extendEnd(end, source, maxLength); + ignoreStart = null; + } + return; + } + + // v-8 ignore start + if (type === 'range') { + // add first for sort by start + const ignoreData = { + type, + start: extendStart(start, source), + end: start + }; + list.push(ignoreData); + ignoreStart = { + ignoreData, + value + }; + return; + } + + // next N + if (type === 'next') { + addNextIgnore(list, value.trim(), item, locator); + } + + }); + + // ignore not stop + if (ignoreStart) { + ignoreStart.end = locator.source.length; + ignoreStart = null; + } + + if (!list.length) { + return; + } + + // console.log('============================================='); + // console.log(list); + + return list; +}; + + +module.exports = { + getIgnoredRanges +}; diff --git a/node_modules/monocart-coverage-reports/lib/converter/info-branch.js b/node_modules/monocart-coverage-reports/lib/converter/info-branch.js new file mode 100644 index 0000000..211bd00 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/converter/info-branch.js @@ -0,0 +1,93 @@ +const Util = require('../utils/util.js'); +module.exports = class InfoBranch { + constructor(data, original) { + const { + start, end, locations, type + } = data; + + this.start = start; + this.end = end; + this.locations = locations; + this.type = type; + this.data = data; + this.original = original; + } + + getRanges() { + return this.locations.map((item) => { + const range = { + start: item.start, + end: item.end, + count: item.count + }; + if (item.none) { + range.none = true; + } + if (item.ignored) { + range.ignored = true; + } + // for debug + if (Util.isDebug() && this.original) { + range.generatedStart = item.generatedStart; + range.generatedEnd = item.generatedEnd; + } + return range; + }); + } + + generate(locator) { + const groupLoc = { + start: this.start, + end: this.end + }; + Util.updateOffsetToLocation(locator, groupLoc); + const line = groupLoc.start.line; + + // remove ignored + // do NOT change previous number type to object, need used for sourcemap + const newLocations = this.locations.filter((it) => !it.ignored).map((it) => { + const item = { + start: it.start, + end: it.end, + none: it.none, + count: it.count + }; + + // [ { start:{line,column}, end:{line,column}, count }, ...] + Util.updateOffsetToLocation(locator, item); + + return item; + }); + + const map = { + loc: groupLoc, + type: this.type, + locations: newLocations.map((item) => { + const { + start, end, none + } = item; + if (none) { + // none with group start/end, should be empty for istanbul + return { + start: {}, + end: {} + }; + } + return { + start, + end + }; + + }), + line: line + }; + + const counts = newLocations.map((item) => item.count); + + return { + map, + counts + }; + } + +}; diff --git a/node_modules/monocart-coverage-reports/lib/converter/info-function.js b/node_modules/monocart-coverage-reports/lib/converter/info-function.js new file mode 100644 index 0000000..6cf96dc --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/converter/info-function.js @@ -0,0 +1,66 @@ +const Util = require('../utils/util.js'); +module.exports = class InfoFunction { + constructor(data, original) { + + const { + start, end, bodyStart, bodyEnd, functionName, count + } = data; + + this.start = start; + this.end = end; + this.bodyStart = bodyStart; + this.bodyEnd = bodyEnd; + this.count = count; + this.functionName = functionName; + this.data = data; + this.original = original; + } + + getName(index) { + return this.functionName || `(anonymous_${index})`; + } + + getRange(index) { + const range = { + name: this.getName(index), + start: this.start, + end: this.end, + count: this.count + }; + if (this.ignored) { + range.ignored = true; + } + // for debug + if (Util.isDebug() && this.original) { + range.generatedStart = this.data.generatedStart; + range.generatedEnd = this.data.generatedEnd; + } + return range; + } + + generate(locator, index) { + + const decl = { + start: this.start, + end: this.bodyStart + }; + + Util.updateOffsetToLocation(locator, decl); + + const loc = { + start: this.bodyStart, + end: this.end + }; + + Util.updateOffsetToLocation(locator, loc); + + const line = loc.start.line; + + return { + name: this.getName(index), + decl: decl, + loc: loc, + line: line + }; + } +}; diff --git a/node_modules/monocart-coverage-reports/lib/converter/info-statement.js b/node_modules/monocart-coverage-reports/lib/converter/info-statement.js new file mode 100644 index 0000000..24e3bee --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/converter/info-statement.js @@ -0,0 +1,43 @@ +const Util = require('../utils/util.js'); +module.exports = class InfoStatement { + constructor(data, original) { + const { + start, end, count + } = data; + + this.start = start; + this.end = end; + this.count = count; + this.data = data; + this.original = original; + } + + getRange() { + const range = { + start: this.start, + end: this.end, + count: this.count + }; + if (this.ignored) { + range.ignored = true; + } + // for debug + if (Util.isDebug() && this.original) { + range.generatedStart = this.data.generatedStart; + range.generatedEnd = this.data.generatedEnd; + } + return range; + } + + generate(locator) { + + const loc = { + start: this.start, + end: this.end + }; + + Util.updateOffsetToLocation(locator, loc); + + return loc; + } +}; diff --git a/node_modules/monocart-coverage-reports/lib/converter/untested.js b/node_modules/monocart-coverage-reports/lib/converter/untested.js new file mode 100644 index 0000000..cee9bad --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/converter/untested.js @@ -0,0 +1,315 @@ +const fs = require('fs'); +const path = require('path'); +const Util = require('../utils/util.js'); + +const { pathToFileURL, fileURLToPath } = require('url'); + +const { normalizeSourcePath, getSourcePathReplacer } = require('../utils/source-path.js'); + +// const EC = require('eight-colors'); +const { convertSourceMap } = require('../packages/monocart-coverage-vendor.js'); + +// ======================================================================================================== + +const resolveAllDirList = (input) => { + const dirs = Util.toList(input, ','); + if (!dirs.length) { + return; + } + const dirList = dirs.filter((it) => fs.existsSync(it)); + if (!dirList.length) { + return; + } + return dirList; +}; + +const resolveAllFilter = (input) => { + // for function handler + if (typeof input === 'function') { + return input; + } + + // for single minimatch pattern + if (input && typeof input === 'string') { + // string to multiple patterns "{...}" + const obj = Util.strToObj(input); + if (obj) { + input = obj; + } else { + return (filePath) => { + return Util.betterMinimatch(filePath, input); + }; + } + } + + // for patterns + if (input && typeof input === 'object') { + const patterns = Object.keys(input); + return (filePath) => { + for (const pattern of patterns) { + if (Util.betterMinimatch(filePath, pattern)) { + return input[pattern]; + } + } + // false if not matched + }; + } + + // default + return () => true; +}; + +const resolveAllOptions = (input) => { + if (!input) { + return; + } + + let dir; + let filter; + let transformer; + + if (typeof input === 'string') { + const obj = Util.strToObj(input); + if (obj) { + dir = obj.dir; + filter = obj.filter; + transformer = obj.transformer; + } else { + dir = input; + } + } else if (Array.isArray(input)) { + dir = input; + } else { + dir = input.dir; + filter = input.filter; + transformer = input.transformer; + } + + const dirList = resolveAllDirList(dir); + if (!dirList) { + return; + } + + const fileFilter = resolveAllFilter(filter); + const fileTransformer = typeof transformer === 'function' ? transformer : () => {}; + + return { + dirList, + fileFilter, + fileTransformer + }; +}; + +const resolveFileType = (fileType, filePath) => { + if (fileType === 'js' || fileType === 'css') { + return fileType; + } + const extname = path.extname(filePath); + if (['.css', '.scss', '.sass', '.less'].includes(extname)) { + return 'css'; + } + return 'js'; +}; + +const saveUntestedFileSource = async (entryFile, options) => { + const { + id, + url, + source, + sourceMap + } = entryFile; + // console.log('-', entry.sourcePath); + + const { cachePath } = Util.getCacheFileInfo('source', id, options.cacheDir); + if (fs.existsSync(cachePath)) { + return; + } + + // save source and sourceMap to separated json file + const sourceData = { + id, + url, + source, + sourceMap + }; + + // remove comments if not debug + if (!Util.isDebug()) { + sourceData.source = convertSourceMap.removeComments(source); + } + + // console.log('save untested file', id, url); + + await Util.saveSourceCacheFile(sourceData, options); + +}; + +const getUntestedCoverageData = async (entryList, options, coverageType) => { + + // save all empty coverage, 20 - 5(empty) + const dataId = Util.uid(15, 'empty'); + const results = { + id: dataId + }; + + if (coverageType === 'istanbul') { + results.type = 'istanbul'; + results.data = {}; + } else { + results.type = 'v8'; + results.data = []; + } + + const emptyCoverageList = []; + + // save all empty source and sourcemap + for (const entry of entryList) { + + // for raw report: source file + // id, url, source, sourceMap + await saveUntestedFileSource(entry, options); + + if (coverageType === 'istanbul') { + + // =============================================== + const item = { + path: fileURLToPath(entry.url), + statementMap: {}, + fnMap: {}, + branchMap: {}, + s: {}, + f: {}, + b: {} + }; + // object + results.data[item.path] = item; + emptyCoverageList.push(item); + + } else { + + // =============================================== + Util.setEmptyV8Coverage(entry); + + const item = { + ... entry + }; + delete item.source; + delete item.sourceMap; + + // array + results.data.push(item); + // will be parsed to AST and converted to V8 coverage + emptyCoverageList.push(entry); + + } + + } + + // for raw report: coverage file + const { cachePath } = Util.getCacheFileInfo('coverage', dataId, options.cacheDir); + await Util.writeFile(cachePath, JSON.stringify(results)); + + return emptyCoverageList; +}; + +const getEmptyCoverages = async (testedMap, options, coverageType, fileList, fileTransformer) => { + const sourceFilter = Util.getSourceFilter(options); + const sourcePathReplacer = getSourcePathReplacer(options); + const baseDir = options.baseDir; + + // console.log(fileList); + + const entryList = []; + for (const item of fileList) { + + const { fileType, filePath } = item; + const type = resolveFileType(fileType, filePath); + const url = pathToFileURL(filePath).toString(); + const source = Util.readFileSync(filePath); + const entry = { + empty: true, + type, + url, + source + }; + + // normalize sourcePath here + let sourcePath = normalizeSourcePath(url, baseDir); + if (sourcePathReplacer) { + const newSourcePath = sourcePathReplacer(sourcePath, entry); + if (typeof newSourcePath === 'string' && newSourcePath) { + sourcePath = newSourcePath; + } + } + + // console.log(sourcePath); + + if (testedMap.has(sourcePath)) { + continue; + } + + if (!sourceFilter(sourcePath)) { + continue; + } + + entry.sourcePath = sourcePath; + + await fileTransformer(entry, coverageType); + // after transformer + entry.id = Util.calculateSha1(entry.sourcePath + entry.source); + + entryList.push(entry); + } + + + // console.log('fileList', fileList); + if (!entryList.length) { + return; + } + + + // save empty coverage for merging raw reports + return getUntestedCoverageData(entryList, options, coverageType); +}; + +const getUntestedList = (testedMap, options, coverageType = 'v8') => { + const allOptions = resolveAllOptions(options.all); + // console.log('allOptions', all, allOptions); + if (!allOptions) { + return; + } + + const { + dirList, fileFilter, fileTransformer + } = allOptions; + + const fileList = []; + dirList.forEach((dir) => { + Util.forEachFile(dir, [], (fileName, fileDir) => { + const filePath = path.resolve(fileDir, fileName); + // return file extname for file type + const fileType = fileFilter(filePath); + if (fileType) { + fileList.push({ + filePath, + fileType, + fileDir, + fileName + }); + } + + }); + }); + + if (!fileList.length) { + return; + } + + return getEmptyCoverages(testedMap, options, coverageType, fileList, fileTransformer); + +}; + + +module.exports = { + getUntestedList +}; diff --git a/node_modules/monocart-coverage-reports/lib/default/options.js b/node_modules/monocart-coverage-reports/lib/default/options.js new file mode 100644 index 0000000..5c3280a --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/default/options.js @@ -0,0 +1,107 @@ +module.exports = { + + // {string} logging levels: off, error, info, debug + logging: 'info', + + // {string} Report name. Defaults to "Coverage Report". + name: 'Coverage Report', + + // {string} v8 or html for istanbul by default + // {array} multiple reports with options + // v8 report or istanbul supported reports + // reports: [ + // ['v8'], + // ['html', { + // subdir: 'my-sub-dir' + // }], + // 'lcov' + // ], + reports: '', + + // {string} output dir + outputDir: './coverage-reports', + + // {string|string[]} input raw dir(s) + inputDir: null, + + // {string} base dir for normalizing the relative source path, defaults to cwd + baseDir: null, + + // {string} coverage data dir, alternative to method `addFromDir()`, defaults to null + dataDir: null, + + // (V8 only) {function} A filter function to execute for each element in the V8 list. + // entryFilter: (entry) => { + // if (entry.url.indexOf('googleapis.com') !== -1) { + // return false; + // } + // return true; + // }, + entryFilter: null, + + // (V8 only) {function} A filter function to execute for each element in the sources which unpacked from the source map. + // sourceFilter: (sourcePath) => sourcePath.search(/src\/.+/) !== -1, + sourceFilter: null, + + // The combined filter for entryFilter and sourceFilter + filter: null, + + // {function} Source path handler. + // sourcePath: (filePath) => `wwwroot/${filePath}`, + sourcePath: null, + + // (V8 only) {string} Output [sub dir/]filename. Defaults to "index.html" + outputFile: 'index.html', + + // (V8 only) {boolean} Inline all scripts to the single HTML file. Defaults to false. + inline: false, + + // (V8 only) {string} Assets path if not inline. Defaults to "./assets" + assetsPath: './assets', + + // (Istanbul only) defaultSummarizer, sourceFinder + + // {boolean} Generate lcov.info file, same as lcovonly report. Defaults to false. + lcov: false, + + // options for adding empty coverage for all files + // all: { + // dir: ['src'], + // filter: (sourcePath) => true, + // transformer: (entry) => {} + // }, + all: null, + + // (V8 only) {boolean} Enable/Disable ignoring uncovered codes with the special comments: v8 ignore next/next N/start/stop + v8Ignore: true, + + // {string|function} Specify the report path, especially when there are multiple reports. Defaults to outputDir/index.html. + reportPath: null, + + // {array} watermarks for low/medium/high. Defaults to [50, 80] + // {object} { bytes:[50,80], statements:[50,80], branches:[50,80], functions:[50,80], lines:[50,80] } + watermarks: [50, 80], + + // {boolean} Indicates whether to clean previous files in output dir before generating report. Defaults to true. + clean: true, + + // {boolean} Indicates whether to clean previous cache in output dir before generating report. Defaults to false. + cleanCache: false, + + // {number} gc threshold + gc: null, + + // {boolean} Indicates whether to save source and sourcemap file for debug (require logging="debug") + sourceMap: false, + + // {function} Custom resolver for sourcemap content + sourceMapResolver: null, + + // {function} onEntry hook + // onEntry: async (entry) => {} + onEntry: null, + + // {function} onEnd hook + // onEnd: async (reportData) => {} + onEnd: null +}; diff --git a/node_modules/monocart-coverage-reports/lib/generate.js b/node_modules/monocart-coverage-reports/lib/generate.js new file mode 100644 index 0000000..a663513 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/generate.js @@ -0,0 +1,494 @@ +const fs = require('fs'); +const path = require('path'); +const { fileURLToPath } = require('url'); +const EC = require('eight-colors'); + +const Util = require('./utils/util.js'); +const { convertV8List } = require('./converter/converter.js'); +const { resolveSourceMap } = require('./converter/collect-source-maps.js'); +const { StreamZip } = require('./packages/monocart-coverage-vendor.js'); + +// ======================================================================================================== +// built-in reports + +// istanbul +const { mergeIstanbulCoverage, saveIstanbulReports } = require('./istanbul/istanbul.js'); + +// v8 +const { mergeV8Coverage, saveV8Report } = require('./v8/v8.js'); + +// both +const { codecovReport } = require('./reports/codecov.js'); +const { codacyReport } = require('./reports/codacy.js'); + +const { consoleDetailsReport } = require('./reports/console-details.js'); +const { consoleSummaryReport } = require('./reports/console-summary.js'); + +const { markdownDetailsReport } = require('./reports/markdown-details.js'); +const { markdownSummaryReport } = require('./reports/markdown-summary.js'); + +const { rawReport } = require('./reports/raw.js'); + +const { customReport } = require('./reports/custom.js'); + +const allBuiltInReports = { + // v8 + 'v8': 'v8', + 'v8-json': 'v8', + + // istanbul + 'clover': 'istanbul', + 'cobertura': 'istanbul', + 'html': 'istanbul', + 'html-spa': 'istanbul', + 'json': 'istanbul', + 'json-summary': 'istanbul', + 'lcov': 'istanbul', + 'lcovonly': 'istanbul', + 'none': 'istanbul', + 'teamcity': 'istanbul', + 'text': 'istanbul', + 'text-lcov': 'istanbul', + 'text-summary': 'istanbul', + + // both + 'codecov': 'both', + 'codacy': 'both', + 'console-details': 'both', + 'console-summary': 'both', + 'markdown-details': 'both', + 'markdown-summary': 'both', + 'raw': 'both' +}; + +const bothBuiltInReports = { + 'codecov': codecovReport, + 'codacy': codacyReport, + + 'console-details': consoleDetailsReport, + 'console-summary': consoleSummaryReport, + + 'markdown-details': markdownDetailsReport, + 'markdown-summary': markdownSummaryReport, + + 'raw': rawReport +}; + +// ======================================================================================================== + +const getReportGroup = (reports, lcov, dataType) => { + + const reportMap = {}; + + const reportList = Util.toList(reports, ','); + reportList.forEach((it) => { + if (Util.isList(it)) { + // ["v8"], ["v8", {}] + const id = it[0]; + if (typeof id === 'string' && id) { + reportMap[id] = { + ... it[1] + }; + } + return; + } + if (typeof it === 'string' && it) { + reportMap[it] = {}; + } + }); + + // using default report if no reports + if (!Object.keys(reportMap).length) { + const defaultReport = dataType === 'v8' ? 'v8' : 'html'; + reportMap[defaultReport] = {}; + } + + // add lcovonly report after default report + if (lcov && !reportMap.lcovonly) { + reportMap.lcovonly = {}; + } + + // group v8 and istanbul + const groupMap = new Map(); + Object.keys(reportMap).forEach((k) => { + const options = reportMap[k]; + + let type = allBuiltInReports[k]; + if (!type) { + // for custom reporter + type = options.type || 'v8'; + } + + let group = groupMap.get(type); + if (!group) { + group = new Map(); + groupMap.set(type, group); + } + + group.set(k, options); + + }); + + // requires a default istanbul report if data is istanbul + if (dataType === 'istanbul' && !groupMap.has('istanbul')) { + const istanbulGroup = new Map(); + istanbulGroup.set('html', {}); + groupMap.set('istanbul', istanbulGroup); + } + + return groupMap; +}; + +// ======================================================================================================== + +// maybe v8 or to istanbul reports +const generateV8ListReports = async (v8list, coverageData, fileSources, options) => { + let istanbulReportPath; + // v8 to istanbul reports + if (options.reportGroup.has('istanbul')) { + const istanbulCoverageResults = await saveIstanbulReports(coverageData, fileSources, options); + istanbulReportPath = istanbulCoverageResults.reportPath; + } + + // v8 reports and v8 coverage results + // could be no v8 or v8-json, but requires v8 coverage results + const v8CoverageResults = await saveV8Report(v8list, options, istanbulReportPath); + return v8CoverageResults; +}; + +const getCoverageResults = async (dataList, sourceCache, options) => { + // get first and check v8list or istanbul data + const firstData = dataList[0]; + const dataType = firstData.type; + // console.log('data type', dataType); + + // init reports + options.reportGroup = getReportGroup(options.reports, options.lcov, dataType); + // console.log('reportGroup', options.reportGroup); + + // v8list + if (dataType === 'v8') { + // merge v8list first + const t1 = Date.now(); + const v8list = await mergeV8Coverage(dataList, sourceCache, options); + Util.logTime(`${EC.magenta('├')} [generate] merged v8 coverage data`, t1); + // console.log('after merge', v8list.map((it) => it.url)); + + const t2 = Date.now(); + const results = await convertV8List(v8list, options); + Util.logTime(`${EC.magenta('├')} [generate] converted coverage data`, t2); + + const { + v8DataList, coverageData, fileSources + } = results; + return generateV8ListReports(v8DataList, coverageData, fileSources, options); + } + + // istanbul data + const t3 = Date.now(); + const istanbulData = await mergeIstanbulCoverage(dataList, options); + Util.logTime(`${EC.magenta('├')} [generate] prepared istanbul coverage data`, t3); + const fileSources = options.fileSources || {}; + const results = await saveIstanbulReports(istanbulData, fileSources, options); + return results; +}; + +const generateCoverageReports = async (dataList, sourceCache, options) => { + const coverageResults = await getCoverageResults(dataList, sourceCache, options); + + // [ 'type', 'reportPath', 'name', 'watermarks', 'summary', 'files' ] + // console.log(Object.keys(coverageResults)); + + if (options.reportGroup.has('both')) { + const bothGroup = options.reportGroup.get('both'); + for (const [reportName, reportOptions] of bothGroup) { + const builtInHandler = bothBuiltInReports[reportName]; + const t1 = Date.now(); + if (builtInHandler) { + await builtInHandler(coverageResults, reportOptions, options); + } else { + await customReport(reportName, coverageResults, reportOptions, options); + } + Util.logTime(`${EC.magenta('├')} [generate] saved report: ${reportName}`, t1); + } + } + + return coverageResults; +}; + + +// ======================================================================================================== + +const getInputList = (mcr) => { + // get input dirs + const { inputDir, cacheDir } = mcr.options; + + const inputDirs = Util.toList(inputDir, ','); + + const inputList = inputDirs.filter((dir) => { + const hasDir = fs.existsSync(dir); + if (!hasDir) { + // could be empty + Util.logInfo(`Input coverage not exists: ${Util.relativePath(dir)}`); + } + return hasDir; + }); + + if (mcr.hasCache()) { + inputList.push(cacheDir); + } + + return inputList; +}; + +const addJsonData = async (mcr, dataList, sourceCache, input, filename) => { + const isCoverage = filename.startsWith('coverage-'); + const isSource = filename.startsWith('source-'); + if (isCoverage || isSource) { + let json = input; + if (typeof input === 'string') { + if (mcr.fileCache.has(filename)) { + json = mcr.fileCache.get(filename); + } else { + json = await Util.readJson(path.resolve(input, filename)); + } + } + if (json) { + if (isCoverage) { + dataList.push(json); + } else { + sourceCache.set(json.id, json); + } + } + } +}; + +const addDirData = async (mcr, dataList, sourceCache, dir) => { + const allFiles = fs.readdirSync(dir); + if (!allFiles.length) { + return; + } + for (const filename of allFiles) { + // only json file + if (filename.endsWith('.json')) { + await addJsonData(mcr, dataList, sourceCache, dir, filename); + } + } +}; + +const addZipData = async (mcr, dataList, sourceCache, dir) => { + const zip = new StreamZip({ + file: dir + }); + const entries = await zip.entries(); + for (const entry of Object.values(entries)) { + if (entry.isDirectory) { + continue; + } + const entryName = entry.name; + const filename = path.basename(entryName); + // console.log('============================', filename); + if (filename.endsWith('.json')) { + const buf = await zip.entryData(entryName); + const json = JSON.parse(buf.toString('utf-8')); + await addJsonData(mcr, dataList, sourceCache, json, filename); + } + + } + // Do not forget to close the file once you're done + await zip.close(); +}; + +const getInputData = async (mcr) => { + + const inputList = getInputList(mcr); + // console.log('input list', inputList); + + const dataList = []; + const sourceCache = new Map(); + + for (const dir of inputList) { + + const info = fs.statSync(dir); + if (info.isDirectory()) { + await addDirData(mcr, dataList, sourceCache, dir); + } else if (info.isFile()) { + await addZipData(mcr, dataList, sourceCache, dir); + } else { + Util.logError(`Invalid input: ${dir}`); + } + + } + + if (!dataList.length) { + const dirs = inputList.map((dir) => Util.relativePath(dir)); + Util.logError(`Not found coverage data in dir(s): ${dirs.join(', ')}`); + return; + } + + return { + dataList, + sourceCache + }; +}; + +// ======================================================================================================== + +const resolveEntrySource = (entry, sourceMapCache, sourceCache) => { + + const url = entry.url; + + // source from `source-id.json` + const sourceData = sourceCache.get(url); + if (sourceData) { + entry.source = sourceData.source; + return; + } + + // source for typescript file from source map cache + // Note: no runtime code but lineLengths + const tsExtensionsPattern = /\.([cm]?ts|[tj]sx)($|\?)/; + if (tsExtensionsPattern.test(url)) { + const sourcemapData = sourceMapCache[url]; + const lineLengths = sourcemapData && sourcemapData.lineLengths; + + // for fake source file (can not parse to AST) + if (lineLengths) { + let fakeSource = ''; + sourcemapData.lineLengths.forEach((length) => { + fakeSource += `${''.padEnd(length, '*')}\n`; + }); + entry.fake = true; + entry.source = fakeSource; + return; + } + + } + + // Note: it could be jsx format even extname is `.js` + const filePath = fileURLToPath(url); + if (fs.existsSync(filePath)) { + entry.source = fs.readFileSync(filePath).toString('utf8'); + } + +}; + +const resolveEntrySourceMap = (entry, sourceMapCache) => { + // sourcemap data + const sourcemapData = sourceMapCache[entry.url]; + if (sourcemapData) { + if (sourcemapData.data) { + entry.sourceMap = resolveSourceMap(sourcemapData.data, entry.url); + } + } +}; + +const readCoverageData = async (dir, filename, entryFilter, sourceCache) => { + + const content = await Util.readFile(path.resolve(dir, filename)); + if (!content) { + return; + } + const json = JSON.parse(content); + if (!json) { + return; + } + + // raw v8 json + let coverageData = json.result; + if (!Util.isList(coverageData)) { + return; + } + + // filter node internal files, should no anonymous for nodejs + coverageData = coverageData.filter((entry) => entry.url && entry.url.startsWith('file:')); + + const lengthBefore = coverageData.length; + coverageData = coverageData.filter(entryFilter); + const lengthAfter = coverageData.length; + Util.logFilter('entry filter (addFromDir):', lengthBefore, lengthAfter); + + if (!Util.isList(coverageData)) { + // Util.logDebug('No coverage data after filter'); + return; + } + + const sourceMapCache = json['source-map-cache'] || {}; + for (const entry of coverageData) { + resolveEntrySource(entry, sourceMapCache, sourceCache); + resolveEntrySourceMap(entry, sourceMapCache); + } + + return coverageData; +}; + +const readSourceList = async (dir, sourceList) => { + const sourceCache = new Map(); + + for (const filename of sourceList) { + const content = await Util.readFile(path.resolve(dir, filename)); + if (!content) { + continue; + } + const json = JSON.parse(content); + if (!json) { + continue; + } + if (json.url) { + sourceCache.set(json.url, json); + } + } + + return sourceCache; +}; + +const readFromDir = async (mcr, dir) => { + + if (!dir || !fs.existsSync(dir)) { + Util.logInfo(`Not found V8 coverage dir: ${dir}`); + return; + } + + const files = fs.readdirSync(dir); + + const coverageList = []; + const sourceList = []; + + files.forEach((filename) => { + // read all json files + if (filename.endsWith('.json')) { + // could be source files generated by register hooks + if (filename.startsWith('source-')) { + sourceList.push(filename); + } else { + coverageList.push(filename); + } + } + }); + + if (!coverageList.length) { + Util.logInfo(`No coverage files in the dir: ${dir}`); + return; + } + + const sourceCache = await readSourceList(dir, sourceList); + + const entryFilter = mcr.getEntryFilter(); + + for (const filename of coverageList) { + const coverageData = await readCoverageData(dir, filename, entryFilter, sourceCache); + if (coverageData) { + await mcr.add(coverageData); + } + } + + // GC + sourceCache.clear(); + +}; + +module.exports = { + getInputData, + readFromDir, + generateCoverageReports +}; diff --git a/node_modules/monocart-coverage-reports/lib/index.d.ts b/node_modules/monocart-coverage-reports/lib/index.d.ts new file mode 100644 index 0000000..dc1d83c --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/index.d.ts @@ -0,0 +1,606 @@ +declare namespace MCR { + + export interface V8CoverageEntry { + url: string; + + /** entry type */ + type?: "js" | "css"; + + /** css only */ + text?: string; + /** css only */ + ranges?: any[]; + + /** js only */ + source?: string; + /** js only */ + scriptId?: string; + /** js only */ + functions?: any[]; + + /** js only */ + sourceMap?: any; + /** js only */ + scriptOffset?: number; + /** js only */ + distFile?: string; + + /** empty coverage */ + empty?: boolean; + /** fake source */ + fake?: boolean; + + [key: string]: any; + } + + export type Watermarks = [number, number] | { + /** V8 only */ + bytes?: [number, number]; + statements: [number, number]; + branches?: [number, number]; + functions?: [number, number]; + lines?: [number, number]; + } + + export type ReportDescription = + ['v8'] | ["v8", { + /** + * defaults to `index.html` + */ + outputFile?: string; + inline?: boolean; + assetsPath?: string; + metrics?: Array<"bytes" | "statements" | "branches" | "functions" | "lines">; + }] | + ['v8-json'] | ["v8-json", { + /** + * defaults to `coverage-report.json` + */ + outputFile?: string; + }] | + ['clover'] | ['clover', { + file?: string; + }] | + ['cobertura'] | ['cobertura', { + file?: string; + timestamp?: string; + projectRoot?: string; + }] | + ['html'] | ['html', { + subdir?: string; + verbose?: boolean; + linkMapper?: any; + skipEmpty?: boolean; + }] | + ['html-spa'] | ['html-spa', { + subdir?: string; + verbose?: boolean; + linkMapper?: any; + skipEmpty?: boolean; + metricsToShow?: Array<"statements" | "branches" | "functions" | "lines">; + }] | + ['json'] | ['json', { + file?: string; + }] | + ['json-summary'] | ['json-summary', { + file?: string; + }] | + ['lcov'] | ['lcov', { + file?: string; + projectRoot?: string; + }] | + ['lcovonly'] | ['lcovonly', { + file?: string; + projectRoot?: string; + }] | + ['none'] | + ['teamcity'] | ['teamcity', { + file?: string; + blockName?: string; + }] | + ['text'] | ['text', { + file?: string; + maxCols?: number; + skipEmpty?: boolean; + skipFull?: boolean; + }] | + ['text-lcov'] | ['text-lcov', { + projectRoot?: string; + }] | + ['text-summary'] | ['text-summary', { + file?: string; + }] | + ['codecov'] | ["codecov", { + /** + * defaults to `codecov.json` + */ + outputFile?: string; + }] | + ['codacy'] | ["codacy", { + /** + * defaults to `codacy.json` + */ + outputFile?: string; + }] | + ['console-summary'] | ['console-summary', { + metrics?: Array<"bytes" | "statements" | "branches" | "functions" | "lines">; + }] | + ['console-details'] | ['console-details', { + maxCols?: number; + skipPercent?: number; + metrics?: Array<"bytes" | "statements" | "branches" | "functions" | "lines">; + filter?: string | { + [pattern: string]: boolean; + } | ((file: CoverageFile) => boolean); + }] | + ['markdown-summary'] | ['markdown-summary', { + color: 'unicode' | 'html' | 'tex' | string; + metrics?: Array<"bytes" | "statements" | "branches" | "functions" | "lines">; + /** + * defaults to `coverage-summary.md` + */ + outputFile?: string; + }] | + ['markdown-details'] | ['markdown-details', { + baseUrl?: string; + color: 'unicode' | 'html' | 'tex' | string; + maxCols?: number; + skipPercent?: number; + metrics?: Array<"bytes" | "statements" | "branches" | "functions" | "lines">; + filter?: string | { + [pattern: string]: boolean; + } | ((file: CoverageFile) => boolean); + /** + * defaults to `coverage-details.md` + */ + outputFile?: string; + }] | + ['raw'] | ['raw', { + merge?: boolean; + zip?: boolean; + outputDir?: string; + }] | + [string] | [string, { + type?: "v8" | "istanbul" | "both" | string; + [key: string]: any; + }]; + + export type AddedResults = { + id: string; + path: string; + type: "v8" | "istanbul"; + data: any; + }; + + + export interface MetricsSummary { + covered: number; + uncovered?: number; + total: number; + pct: number | ""; + status: "low" | "medium" | "high" | "unknown"; + /** V8 lines only */ + blank?: number; + /** V8 lines only */ + comment?: number; + } + + export interface CoverageSummary { + /** V8 only */ + bytes?: MetricsSummary; + statements: MetricsSummary; + branches: MetricsSummary; + functions: MetricsSummary; + lines: MetricsSummary; + } + + /** V8 only */ + export interface CoverageRange { + start: number; + end: number; + count: number; + /** ignored by special comment which starts with `v8 ignore` */ + ignored?: boolean; + /** + * branch only, for example: + * there is only `if` branch but no `else` branch, then `none` will be true, it shows `else path uncovered` + */ + none?: boolean; + /** function only, function name */ + name?: boolean; + } + + export interface IgnoredRange { + start: number; + end: number; + /** ignore type: `next` or `range` */ + type: string; + /** n lines for `next` type */ + n?: number; + } + + export interface CoverageFile { + sourcePath: string; + summary: CoverageSummary; + /** V8 only */ + url?: string; + /** V8 only */ + id?: string; + /** V8 only */ + type?: string; + /** V8 only */ + source?: string; + /** V8 only */ + distFile?: string; + /** V8 only */ + js?: boolean; + /** V8 only */ + data?: { + bytes?: CoverageRange[]; + statements?: CoverageRange[]; + branches?: CoverageRange[]; + functions?: CoverageRange[]; + ignores?: IgnoredRange[]; + lines?: { + /** + * key: line number; + * number: hits (0 means uncovered); + * string: partial covered + */ + [key: string]: number | string; + }; + extras?: { + /** + * key: line number; + * b: blank; + * c: comment; + * i: ignored; + */ + [key: string]: "b" | "c" | "i"; + } + } + } + + export type CoverageResults = { + type: "v8" | "istanbul"; + reportPath: string; + version: string; + name: string; + watermarks: Watermarks; + summary: CoverageSummary; + files: CoverageFile[]; + }; + + export type LoggingType = "off" | "error" | "info" | "debug"; + export interface CoverageReportOptions { + + /** {string} logging levels: off, error, info, debug */ + logging?: LoggingType; + + /** {string} Report name. Defaults to "Coverage Report". */ + name?: string; + + /** + * + * {string} 'v8', 'v8,console-details' + * + * {array} ['v8'], ['v8', ['console-details', { skipPercent: 80 }]] + * + * By default, `v8` for V8 data, `html` for Istanbul data + */ + reports?: string | (string | ReportDescription)[]; + + /** {string} output dir */ + outputDir?: string; + + /** {string|string[]} input raw dir(s) */ + inputDir?: string | string[]; + + /** {string} base dir for normalizing the relative source path, defaults to cwd */ + baseDir?: string; + + /** {string} coverage data dir, alternative to method `addFromDir()`, defaults to null */ + dataDir?: string; + + /** (V8 only) + * + * {string} `minimatch` pattern for entry url; + * {object} multiple patterns; + * {function} A filter function for each entry file in the V8 list. + */ + entryFilter?: string | { + [pattern: string]: boolean; + } | ((entry: V8CoverageEntry) => boolean); + + /** (V8 only) + * + * {string} `minimatch` pattern for source path; + * {object} multiple patterns; + * {function} A filter function for each source path when the source is unpacked from the source map. + */ + sourceFilter?: string | { + [pattern: string]: boolean; + } | ((sourcePath: string) => boolean); + + /** + * The combined filter for entryFilter and sourceFilter + */ + filter?: string | { + [pattern: string]: boolean; + } | ((input: string | V8CoverageEntry) => boolean); + + /** + * {function} Source path handler. + * + * {object} Replace key with value. + * */ + sourcePath?: ((filePath: string, info: { + /** the related dist file of current source file */ + distFile?: string; + [key: string]: any; + }) => string) | { + [key: string]: string; + }; + + + /** (V8 only) {string} Output [sub dir/]filename. Defaults to "index.html" */ + outputFile?: string; + /** (V8 only) {boolean} Inline all scripts to the single HTML file. Defaults to false. */ + inline?: boolean; + /** (V8 only) {string} Assets path if not inline. Defaults to "./assets" */ + assetsPath?: string; + + /** (Istanbul only) defaultSummarizer, sourceFinder */ + + /** {boolean} Generate lcov.info file, same as lcovonly report. Defaults to false. */ + lcov?: boolean; + + /** + * options for adding empty coverage for all files + */ + all?: string | string[] | { + /** the dir(s) of all files */ + dir: string | string[]; + + /** + * the file filter is triggered before `sourceFilter`, no need to use it in normal case + * the filter could return the file type, if true, defaults to css if ".css" otherwise is js + * {string} `minimatch` pattern for file path; {object} multiple patterns; {function} A filter function for file path; + */ + filter?: string | { + [pattern: string]: "js" | "css" | boolean; + } | ((filePath: string) => "js" | "css" | boolean); + + /** + * the file transformer for source and sourceMap + * some of untested files like .ts/.jsx/.vue can not be parsed to AST directly by acorn + * so this is the function which can transform the original source to generated source and sourceMap + */ + transformer?: (entry: any) => Promise; + + }; + + /** (V8 only) {boolean} Enable/Disable ignoring uncovered codes with the special comments: v8 ignore next/next N/start/stop */ + v8Ignore?: boolean; + + /** {string|function} Specify the report path, especially when there are multiple reports. Defaults to outputDir/index.html. */ + reportPath?: string | (() => string); + + /** {array} watermarks for low/medium/high. Defaults to [50, 80] + * {object} { bytes:[50,80], statements:[50,80], branches:[50,80], functions:[50,80], lines:[50,80] } */ + watermarks?: Watermarks; + + /** + * {boolean} Indicates whether to clean previous reports in output dir before generating new reports. Defaults to true. + * + * If true, the API `clean()` will execute automatically. + * */ + clean?: boolean; + + /** + * {boolean} Indicates whether to clean previous cache in output dir on start. Defaults to false. + * + * If true, the API `cleanCache()` will execute automatically. + */ + cleanCache?: boolean; + + /** + * {number} gc threshold + * for example: sets gc to 1024 means that force gc when the memory > 1024M at certain critical stages + * https://nodejs.org/docs/latest/api/v8.html#v8setflagsfromstringflags + */ + gc?: number; + + /** + * {boolean} Indicates whether to save source and sourcemap file for debug (require logging="debug") + */ + sourceMap?: boolean; + + /** + * {function} Custom resolver for sourcemap content + */ + sourceMapResolver?: (url: string, defaultResolver: Function) => Promise; + + /** (V8 only) {function} onEntry hook */ + onEntry?: (entry: V8CoverageEntry) => Promise; + + /** {function} onEnd hook */ + onEnd?: (coverageResults: CoverageResults | undefined) => Promise; + + [key: string]: any; + } + + export interface McrCliOptions extends CoverageReportOptions { + + /** (CLI only) {function} onStart hook */ + onStart?: (coverageReport: CoverageReport) => Promise; + + /** (CLI only) {function} onReady hook before adding coverage data. + * + * Sometimes, the child process has not yet finished writing the coverage data, and it needs to wait here. + */ + onReady?: (coverageReport: CoverageReport, nodeV8CoverageDir: string, subprocess: any) => Promise; + + } + + export class CoverageReport { + + /** + * @param options coverage report options + */ + constructor(options?: CoverageReportOptions); + + /** add coverage data + * + * @param coverageData {array} V8 format, {object} Istanbul format */ + add: (coverageData: any[] | any) => Promise; + + /** + * add V8 coverage from a dir + * @param dir node v8 coverage dir + */ + addFromDir: (dir: string) => Promise; + + /** generate report */ + generate: () => Promise; + + /** check if cache exists */ + hasCache: () => boolean; + + /** clean previous cache, return `false` if no cache */ + cleanCache: () => boolean; + + /** clean previous reports except cache dir and v8 coverage dir */ + clean: () => void; + + /** get entry filter handler, it can be used to filter the coverage data list before adding it. */ + getEntryFilter: () => ((entry: V8CoverageEntry) => boolean); + + /** load config file. + * + * @param configFile custom config file path + * + * Supports loading default config file if no custom config specified: + 'mcr.config.js', + 'mcr.config.cjs', + 'mcr.config.mjs', + 'mcr.config.json', + 'mcr.config.ts' + */ + loadConfig: (configFile?: string) => Promise; + } + + //===================================================================================================== + + export interface CoverageSnapshot { + type: "v8" | "istanbul"; + summary: { + bytes?: string; + statements: string; + branches: string; + functions: string; + lines: string; + }, + files: { + [sourcePath: string]: { + bytes?: string; + statements: string; + branches: string; + functions: string; + lines: string; + uncoveredLines: string; + extras: string; + } + } + } + + /** get snapshot from coverage report data */ + export function getSnapshot(coverageResults: CoverageResults): CoverageSnapshot; + + /** diff two snapshots */ + export function diffSnapshot(oldData: CoverageSnapshot, newData: CoverageSnapshot, diffOptions: { + skipEqual?: boolean; + showSummary?: boolean; + maxCols?: number; + metrics?: Array<"bytes" | "statements" | "branches" | "functions" | "lines">; + }): { + change: boolean; + results: any[]; + message: string; + }; + + //===================================================================================================== + + export class CoverageClient { + /** start js coverage */ + startJSCoverage: () => Promise; + /** stop and return js coverage */ + stopJSCoverage: () => Promise; + + /** start css coverage */ + startCSSCoverage: () => Promise; + /** stop and return css coverage */ + stopCSSCoverage: () => Promise; + + /** start both js and css coverage */ + startCoverage: () => Promise; + /** stop and return both js and css coverage */ + stopCoverage: () => Promise; + + /** write the coverage started by NODE_V8_COVERAGE to disk on demand, returns v8 coverage dir */ + writeCoverage: () => Promise; + + /** get istanbul coverage data + * @param coverageKey defaults to `__coverage__` + */ + getIstanbulCoverage: (coverageKey?: string) => Promise; + + close: () => Promise + } + + /** Adapt to the CDPSession of Playwright or Puppeteer */ + export interface CDPSession { + send: (method: string, params?: any) => Promise; + on: (type: string, handler: (e: any) => void) => void; + detach: () => Promise; + } + + /** custom websocket CDPSession */ + export class WSSession implements CDPSession { + constructor(ws: any); + send: (method: string, params?: any) => Promise; + on: (type: string, handler: (e: any) => void) => void; + detach: () => Promise; + } + + export interface CDPOptions { + /** Adapt to the CDPSession of Playwright or Puppeteer */ + session?: CDPSession; + /** websocket debugger url */ + url?: string; + /** debugger port, defaults to 9222 */ + port?: number; + /** debugger host, defaults to localhost */ + host?: string; + /** enable https, defaults to false (http) */ + secure?: boolean; + /** target filter, defaults to first page */ + target?: (targets: any) => any; + /** websocket options */ + ws?: any; + /** timeout, defaults to 10 * 1000 */ + timeout?: number; + } + + export function CDPClient(cdpOptions: CDPOptions): Promise; + + export const Util: { + initLoggingLevel: (logging: LoggingType) => string; + }; + +} + +/** create coverage report */ +declare function MCR(options?: MCR.CoverageReportOptions): MCR.CoverageReport; + +export = MCR; diff --git a/node_modules/monocart-coverage-reports/lib/index.js b/node_modules/monocart-coverage-reports/lib/index.js new file mode 100644 index 0000000..802f81f --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/index.js @@ -0,0 +1,280 @@ +const fs = require('fs'); +const path = require('path'); +const { pathToFileURL } = require('url'); +const EC = require('eight-colors'); + +const defaultOptions = require('./default/options.js'); +const Util = require('./utils/util.js'); + +const { initV8ListAndSourcemap } = require('./v8/v8.js'); +const { + getInputData, readFromDir, generateCoverageReports +} = require('./generate.js'); +const { getSnapshot, diffSnapshot } = require('./utils/snapshot.js'); + +const WSSession = require('./client/ws-session.js'); +const CDPClient = require('./client/cdp-client.js'); + +const resolveConfigOptions = async (configPath) => { + // json format + const ext = path.extname(configPath); + if (ext === '.json' || configPath.slice(-2) === 'rc') { + return JSON.parse(Util.readFileSync(configPath)); + } + + let configOptions; + let err; + try { + configOptions = await import(pathToFileURL(configPath)); + } catch (ee) { + err = ee; + } + + if (err) { + Util.logError(`ERROR: failed to load config "${configPath}": ${err && err.message} `); + return; + } + + // could be multiple level default + while (configOptions && configOptions.default) { + configOptions = configOptions.default; + } + + return configOptions; +}; + +class CoverageReport { + + constructor(options = {}) { + this.cacheDirName = '.cache'; + this.constructorOptions = options; + this.options = { + ... defaultOptions, + ... options + }; + this.initOptions(); + this.fileCache = new Map(); + } + + initOptions(force) { + + if (this.fixedOptions && !force) { + return; + } + + // before clean cache, do no call initOptions again in hasCache + this.fixedOptions = true; + + // init logging for clean after generated + this.logging = Util.initLoggingLevel(this.options.logging); + + if (Util.isNum(this.options.gc)) { + Util.setGC(this.options.gc); + } + + // init outputDir + const outputDir = `${this.options.outputDir || defaultOptions.outputDir}`; + this.options.outputDir = outputDir; + + // cache dir, it is useful if runs in multiple processes. + // cache coverage- data and source- files + // it will be removed after generated if logging it not debug. + const cacheDir = path.resolve(outputDir, this.cacheDirName); + this.options.cacheDir = cacheDir; + + // If true, the API `cleanCache()` will execute automatically. + if (this.options.cleanCache) { + this.cleanCache(); + } + + } + + // add coverage data: {array} V8 format, {object} Istanbul format + async add(data) { + + const time_start = Date.now(); + + this.initOptions(); + + if (!Util.checkCoverageData(data)) { + Util.logError(`${this.options.name}: The added coverage data must be Array(V8) or Object(Istanbul)`); + return; + } + + const dataId = Util.uid(); + const results = { + id: dataId + }; + + if (Array.isArray(data)) { + results.type = 'v8'; + // could be empty list after entryFilter + results.data = await initV8ListAndSourcemap(this, data); + } else { + results.type = 'istanbul'; + results.data = data; + } + + // save data to cache + const { cacheName, cachePath } = Util.getCacheFileInfo('coverage', dataId, this.options.cacheDir); + this.fileCache.set(cacheName, results); + await Util.writeFile(cachePath, JSON.stringify(results)); + + Util.logTime(`added coverage data: ${results.type}`, time_start); + + return results; + } + + // add coverage from dir + async addFromDir(dir) { + const time_start = Date.now(); + await readFromDir(this, dir); + Util.logTime(`added from dir: ${dir}`, time_start); + } + + // generate report + async generate() { + + const time_start = Date.now(); + + this.initOptions(); + + const dataDir = this.options.dataDir; + if (dataDir) { + await this.addFromDir(dataDir); + } + + const inputData = await getInputData(this); + if (!inputData) { + return; + } + + // GC, no OOM + this.fileCache.clear(); + + const { dataList, sourceCache } = inputData; + + // empty output dir except cache dir before generate reports + const outputDir = this.options.outputDir; + + if (fs.existsSync(outputDir)) { + // if assets dir is out of output dir will be ignore + if (this.options.clean) { + this.clean(); + } + } else { + fs.mkdirSync(outputDir, { + recursive: true + }); + } + + Util.logTime(`${EC.magenta('├')} [generate] prepared coverage data`, time_start); + + const coverageResults = await generateCoverageReports(dataList, sourceCache, this.options); + + const onEnd = this.options.onEnd; + if (typeof onEnd === 'function') { + await onEnd.call(this, coverageResults); + } + + // remove cache dir after finished + if (!Util.isDebug()) { + Util.rmSync(this.options.cacheDir); + } + + let reportPath = ''; + if (coverageResults.reportPath) { + reportPath = EC.cyan(coverageResults.reportPath); + } + Util.logTime(`generated coverage reports: ${reportPath}`, time_start); + + return coverageResults; + } + + // check if cache dir exists + hasCache() { + this.initOptions(); + return fs.existsSync(this.options.cacheDir); + } + + // cache clean dir + cleanCache() { + // clean previous artifacts + if (this.hasCache()) { + Util.rmSync(this.options.cacheDir); + return true; + } + return false; + } + + // clean previous reports except cache dir and v8 coverage dir + clean() { + const outputDir = this.options.outputDir; + let v8DirName; + const nodeV8CoverageDir = process.env.NODE_V8_COVERAGE; + if (nodeV8CoverageDir) { + v8DirName = path.relative(outputDir, nodeV8CoverageDir); + } + fs.readdirSync(outputDir).forEach((itemName) => { + if (itemName === this.cacheDirName) { + return; + } + if (itemName === v8DirName) { + return; + } + Util.rmSync(path.resolve(outputDir, itemName)); + }); + } + + // get entry filter handler + getEntryFilter() { + return Util.getEntryFilter(this.options); + } + + // load config file + async loadConfig(customConfigFile) { + + const configPath = Util.findUpConfig(customConfigFile); + if (!configPath) { + if (customConfigFile) { + Util.logError(`The config file does not exist: ${customConfigFile}`); + } + // not found config + return; + } + + const configOptions = await resolveConfigOptions(configPath); + if (!configOptions) { + // failed to load config options + if (customConfigFile) { + Util.logError(`Failed to load config file: ${customConfigFile}`); + } + return; + } + + Util.logInfo(`Loaded: ${EC.cyan(Util.relativePath(configPath))}`); + + // init options again + this.options = { + ... defaultOptions, + ... configOptions, + ... this.constructorOptions + }; + this.initOptions(true); + + } + +} + +/** create coverage report */ +const MCR = function(options) { + return new CoverageReport(options); +}; +MCR.CoverageReport = CoverageReport; +MCR.getSnapshot = getSnapshot; +MCR.diffSnapshot = diffSnapshot; +MCR.WSSession = WSSession; +MCR.CDPClient = CDPClient; +MCR.Util = Util; + +module.exports = MCR; diff --git a/node_modules/monocart-coverage-reports/lib/index.mjs b/node_modules/monocart-coverage-reports/lib/index.mjs new file mode 100644 index 0000000..3ebf53c --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/index.mjs @@ -0,0 +1,9 @@ +import MCR from './index.js'; +export default MCR; +export const CoverageReport = MCR.CoverageReport; +export const getSnapshot = MCR.getSnapshot; +export const diffSnapshot = MCR.diffSnapshot; + +export const WSSession = MCR.WSSession; +export const CDPClient = MCR.CDPClient; +export const Util = MCR.Util; diff --git a/node_modules/monocart-coverage-reports/lib/istanbul/istanbul-summary.js b/node_modules/monocart-coverage-reports/lib/istanbul/istanbul-summary.js new file mode 100644 index 0000000..a92d312 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/istanbul/istanbul-summary.js @@ -0,0 +1,73 @@ +const istanbulLibReport = require('istanbul-lib-report'); + +const ReportBase = istanbulLibReport.ReportBase; +class IstanbulSummary extends ReportBase { + + onStart(root, context) { + this.context = context; + this.summary = {}; + this.files = []; + } + + addStatus(data) { + Object.keys(data).forEach((k) => { + const item = data[k]; + // low, medium, high, unknown + item.status = this.context.classForPercent(k, item.pct); + }); + } + + onSummary(node) { + if (!node.isRoot()) { + return; + } + this.summary = node.getCoverageSummary().data; + this.addStatus(this.summary); + } + + onDetail(node) { + const fileSummary = node.getCoverageSummary().data; + this.addStatus(fileSummary); + const sourcePath = node.getQualifiedName(); + + const fileCoverage = node.getFileCoverage(); + const lines = fileCoverage.getLineCoverage(); + // no extras for istanbul + const extras = {}; + + this.files.push({ + sourcePath, + summary: fileSummary, + data: { + lines, + extras + } + }); + } + + onEnd() { + // console.log('onEnd'); + } + + getReport() { + + // remove branchesTrue + delete this.summary.branchesTrue; + + // add uncovered + Object.keys(this.summary).forEach((id) => { + const item = this.summary[id]; + item.uncovered = item.total - item.covered; + }); + + // console.log(this.summary); + + return { + summary: this.summary, + files: this.files + }; + } +} + + +module.exports = IstanbulSummary; diff --git a/node_modules/monocart-coverage-reports/lib/istanbul/istanbul.js b/node_modules/monocart-coverage-reports/lib/istanbul/istanbul.js new file mode 100644 index 0000000..4636cf7 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/istanbul/istanbul.js @@ -0,0 +1,170 @@ +const fs = require('fs'); +const path = require('path'); +const istanbulReports = require('istanbul-reports'); +const istanbulLibCoverage = require('istanbul-lib-coverage'); +const istanbulLibReport = require('istanbul-lib-report'); +const EC = require('eight-colors'); + +const Util = require('../utils/util.js'); +const IstanbulSummary = require('./istanbul-summary.js'); + +const { initIstanbulSourcePath } = require('../utils/source-path.js'); +const { getUntestedList } = require('../converter/untested.js'); + +const findHtmlPath = (outputDir) => { + const defaultHtml = path.resolve(outputDir, 'index.html'); + if (fs.existsSync(defaultHtml)) { + return defaultHtml; + } + + const htmlList = []; + Util.forEachFile(outputDir, ['.html'], (name, dir) => { + const htmlPath = path.resolve(dir, name); + if (name === 'index.html') { + htmlList.unshift(htmlPath); + return 'break'; + } + htmlList.push(htmlPath); + }); + + if (htmlList.length) { + return htmlList[0]; + } + + return defaultHtml; + +}; + +const saveIstanbulReports = (coverageData, fileSources, options) => { + + coverageData = initIstanbulSourcePath(coverageData, fileSources, options); + + const coverageMap = istanbulLibCoverage.createCoverageMap(coverageData); + + const defaultWatermarks = { + statements: [50, 80], + branches: [50, 80], + functions: [50, 80], + lines: [50, 80] + }; + const watermarks = Util.resolveWatermarks(defaultWatermarks, options.watermarks); + + // https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-lib-report + + // defaultSummarizer and sourceFinder can be passed from options + const contextOptions = { + coverageMap, + // The summarizer to default to (may be overridden by some reports) + // values can be nested/flat/pkg. Defaults to 'pkg' + defaultSummarizer: options.defaultSummarizer || 'nested', + + dir: options.outputDir, + watermarks, + sourceFinder: (filePath) => { + + // console.log(`find file source: ${filePath}`); + + if (fileSources) { + const source = fileSources[filePath]; + if (source) { + return source; + } + } + + if (typeof options.sourceFinder === 'function') { + const source = options.sourceFinder(filePath); + if (source) { + return source; + } + } + + if (fs.existsSync(filePath)) { + return fs.readFileSync(filePath, 'utf8'); + } + + // console.log('Not found source file:', filePath); + + return `Not found source file: ${filePath}`; + } + }; + + // create a context for report generation + const context = istanbulLibReport.createContext(contextOptions); + + const istanbulGroup = options.reportGroup.get('istanbul'); + // already has + if (istanbulGroup) { + for (const [reportName, reportOptions] of istanbulGroup) { + const t1 = Date.now(); + const report = istanbulReports.create(reportName, reportOptions); + report.execute(context); + Util.logTime(`${EC.magenta('├')} [generate] saved report: ${reportName}`, t1); + } + } + + // add watermarks and color + const coverageReport = new IstanbulSummary(); + coverageReport.execute(context); + + const reportPath = Util.resolveReportPath(options, () => { + // find first index.html path for preview + const htmlPath = findHtmlPath(options.outputDir); + return Util.relativePath(htmlPath); + }); + + const coverageResults = { + type: 'istanbul', + reportPath, + version: Util.version, + name: options.name, + watermarks: contextOptions.watermarks, + // summary and files + ... coverageReport.getReport() + }; + + return coverageResults; +}; + +const addUntestedFiles = async (istanbulData, options) => { + const testedMap = new Map(); + Object.keys(istanbulData).forEach((filePath) => { + const sourcePath = Util.relativePath(filePath); + testedMap.set(sourcePath, true); + }); + + // untested files + const untestedList = await getUntestedList(testedMap, options, 'istanbul'); + if (!untestedList) { + return; + } + + // console.log('istanbul untestedList', untestedList); + untestedList.forEach((item) => { + if (!istanbulData[item.path]) { + istanbulData[item.path] = istanbulLibCoverage.createFileCoverage(item); + } + }); + +}; + +const mergeIstanbulDataList = (dataList, options) => { + const istanbulCoverageList = dataList.map((it) => it.data); + const coverageMap = istanbulLibCoverage.createCoverageMap(); + istanbulCoverageList.forEach((coverage) => { + coverageMap.merge(coverage); + }); + const istanbulData = coverageMap.toJSON(); + return istanbulData; +}; + +const mergeIstanbulCoverage = async (dataList, options) => { + const istanbulData = mergeIstanbulDataList(dataList, options); + await addUntestedFiles(istanbulData, options); + return istanbulData; +}; + +module.exports = { + saveIstanbulReports, + mergeIstanbulDataList, + mergeIstanbulCoverage +}; diff --git a/node_modules/monocart-coverage-reports/lib/packages/monocart-coverage-assets.js b/node_modules/monocart-coverage-reports/lib/packages/monocart-coverage-assets.js new file mode 100644 index 0000000..19258d9 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/packages/monocart-coverage-assets.js @@ -0,0 +1,4 @@ +module.exports = { + "template": "\n\n\n \n \n \n {title}\n \n\n\n
\n \n \n \n
\n{content}\n\n\n", + "monocart-coverage-app": "var a=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var s=a((b,o)=>{o.exports=`(()=>{var x=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports);var S=x((V,R)=>{var _=0,p=-3;function b(){this.table=new Uint16Array(16),this.trans=new Uint16Array(288)}function N(e,n){this.source=e,this.sourceIndex=0,this.tag=0,this.bitcount=0,this.dest=n,this.destLen=0,this.ltree=new b,this.dtree=new b}var y=new b,k=new b,w=new Uint8Array(30),h=new Uint16Array(30),L=new Uint8Array(30),T=new Uint16Array(30),O=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),A=new b,c=new Uint8Array(320);function D(e,n,r,a){var t,i;for(t=0;t>>=1,n}function u(e,n,r){if(!n)return r;for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>16-n;return e.tag>>>=n,e.bitcount-=n,a+r}function v(e,n){for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>=1,++t,r+=n.table[t],a-=n.table[t];while(a>=0);return e.tag=i,e.bitcount-=t,n.trans[r+a]}function C(e,n,r){var a,t,i,o,s,f;for(a=u(e,5,257),t=u(e,5,1),i=u(e,4,4),o=0;o<19;++o)c[o]=0;for(o=0;o8;)e.sourceIndex--,e.bitcount-=8;if(n=e.source[e.sourceIndex+1],n=256*n+e.source[e.sourceIndex],r=e.source[e.sourceIndex+3],r=256*r+e.source[e.sourceIndex+2],n!==(~r&65535))return p;for(e.sourceIndex+=4,a=n;a;--a)e.dest[e.destLen++]=e.source[e.sourceIndex++];return e.bitcount=0,_}function j(e,n){var r=new N(e,n),a,t,i;do{switch(a=B(r),t=u(r,2,0),t){case 0:i=K(r);break;case 1:i=U(r,y,k);break;case 2:C(r,r.ltree,r.dtree),i=U(r,r.ltree,r.dtree);break;default:i=p}if(i!==_)throw new Error(\"Data error\")}while(!a);return r.destLen{var G=S(),H=e=>Uint8Array.from(atob(e),n=>n.charCodeAt(0)),J=e=>new TextDecoder().decode(e);q.exports=function(e){if(e){let[n,r]=e.split(\".\");if(n&&r){let a=H(n),t=new Uint8Array(parseInt(r));return G(a,t),J(t)}}}});var P=E();onmessage=function(e){postMessage(P(e.data))};postMessage(\"workerReady\");})();\n`});var c=a((l,i)=>{var u=s();i.exports=r=>new Promise(e=>{let t=new Worker(URL.createObjectURL(new Blob([u],{type:\"application/javascript\"})));t.onmessage=n=>{if(n.data===\"workerReady\"){t.postMessage(r);return}e(n.data),t.terminate()},t.onerror=n=>{e({error:n}),t.terminate()}})});var f=c();f(\"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.1041907\").then(r=>{let e=document.createElement(\"script\");e.innerHTML=r,document.body.appendChild(e)});\n" +}; \ No newline at end of file diff --git a/node_modules/monocart-coverage-reports/lib/packages/monocart-coverage-vendor.js b/node_modules/monocart-coverage-reports/lib/packages/monocart-coverage-vendor.js new file mode 100644 index 0000000..8f31aba --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/packages/monocart-coverage-vendor.js @@ -0,0 +1,35 @@ +var ea=Object.create;var Ut=Object.defineProperty;var ta=Object.getOwnPropertyDescriptor;var ra=Object.getOwnPropertyNames;var na=Object.getPrototypeOf,ia=Object.prototype.hasOwnProperty;var b=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports),sa=(n,e)=>{for(var t in e)Ut(n,t,{get:e[t],enumerable:!0})},Kn=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of ra(e))!ia.call(n,i)&&i!==t&&Ut(n,i,{get:()=>e[i],enumerable:!(r=ta(e,i))||r.enumerable});return n};var j=(n,e,t)=>(t=n!=null?ea(na(n)):{},Kn(e||!n||!n.__esModule?Ut(t,"default",{value:n,enumerable:!0}):t,n)),oa=n=>Kn(Ut({},"__esModule",{value:!0}),n);var Qn=b(z=>{"use strict";Object.defineProperty(z,"commentRegex",{get:function(){return/^\s*?\/[\/\*][@#]\s+?sourceMappingURL=data:(((?:application|text)\/json)(?:;charset=([^;,]+?)?)?)?(?:;(base64))?,(.*?)$/mg}});Object.defineProperty(z,"mapFileCommentRegex",{get:function(){return/(?:\/\/[@#][ \t]+?sourceMappingURL=([^\s'"`]+?)[ \t]*?$)|(?:\/\*[@#][ \t]+sourceMappingURL=([^*]+?)[ \t]*?(?:\*\/){1}[ \t]*?$)/mg}});var kt;typeof Buffer<"u"?typeof Buffer.from=="function"?kt=la:kt=aa:kt=fa;function la(n){return Buffer.from(n,"base64").toString()}function aa(n){if(typeof value=="number")throw new TypeError("The value to decode must not be of type number.");return new Buffer(n,"base64").toString()}function fa(n){return decodeURIComponent(escape(atob(n)))}function ua(n){return n.split(",").pop()}function ca(n,e){var t=z.mapFileCommentRegex.exec(n),r=t[1]||t[2];try{var n=e(r);return n!=null&&typeof n.catch=="function"?n.catch(i):n}catch(s){i(s)}function i(s){throw new Error("An error occurred while trying to read the map file at "+r+` +`+s.stack)}}function Y(n,e){e=e||{},e.hasComment&&(n=ua(n)),e.encoding==="base64"?n=kt(n):e.encoding==="uri"&&(n=decodeURIComponent(n)),(e.isJSON||e.encoding)&&(n=JSON.parse(n)),this.sourcemap=n}Y.prototype.toJSON=function(n){return JSON.stringify(this.sourcemap,null,n)};typeof Buffer<"u"?typeof Buffer.from=="function"?Y.prototype.toBase64=ha:Y.prototype.toBase64=da:Y.prototype.toBase64=pa;function ha(){var n=this.toJSON();return Buffer.from(n,"utf8").toString("base64")}function da(){var n=this.toJSON();if(typeof n=="number")throw new TypeError("The json to encode must not be of type number.");return new Buffer(n,"utf8").toString("base64")}function pa(){var n=this.toJSON();return btoa(unescape(encodeURIComponent(n)))}Y.prototype.toURI=function(){var n=this.toJSON();return encodeURIComponent(n)};Y.prototype.toComment=function(n){var e,t,r;return n!=null&&n.encoding==="uri"?(e="",t=this.toURI()):(e=";base64",t=this.toBase64()),r="sourceMappingURL=data:application/json;charset=utf-8"+e+","+t,n!=null&&n.multiline?"/*# "+r+" */":"//# "+r};Y.prototype.toObject=function(){return JSON.parse(this.toJSON())};Y.prototype.addProperty=function(n,e){if(this.sourcemap.hasOwnProperty(n))throw new Error('property "'+n+'" already exists on the sourcemap, use set property instead');return this.setProperty(n,e)};Y.prototype.setProperty=function(n,e){return this.sourcemap[n]=e,this};Y.prototype.getProperty=function(n){return this.sourcemap[n]};z.fromObject=function(n){return new Y(n)};z.fromJSON=function(n){return new Y(n,{isJSON:!0})};z.fromURI=function(n){return new Y(n,{encoding:"uri"})};z.fromBase64=function(n){return new Y(n,{encoding:"base64"})};z.fromComment=function(n){var e,t;return n=n.replace(/^\/\*/g,"//").replace(/\*\/$/g,""),e=z.commentRegex.exec(n),t=e&&e[4]||"uri",new Y(n,{encoding:t,hasComment:!0})};function Jn(n){return new Y(n,{isJSON:!0})}z.fromMapFileComment=function(n,e){if(typeof e=="string")throw new Error("String directory paths are no longer supported with `fromMapFileComment`\nPlease review the Upgrading documentation at https://github.com/thlorenz/convert-source-map#upgrading");var t=ca(n,e);return t!=null&&typeof t.then=="function"?t.then(Jn):Jn(t)};z.fromSource=function(n){var e=n.match(z.commentRegex);return e?z.fromComment(e.pop()):null};z.fromMapFileSource=function(n,e){if(typeof e=="string")throw new Error("String directory paths are no longer supported with `fromMapFileSource`\nPlease review the Upgrading documentation at https://github.com/thlorenz/convert-source-map#upgrading");var t=n.match(z.mapFileCommentRegex);return t?z.fromMapFileComment(t.pop(),e):null};z.removeComments=function(n){return n.replace(z.commentRegex,"")};z.removeMapFileComments=function(n){return n.replace(z.mapFileCommentRegex,"")};z.generateMapFileComment=function(n,e){var t="sourceMappingURL="+n;return e&&e.multiline?"/*# "+t+" */":"//# "+t}});var Cr=b((yh,xr)=>{var zt=process||{},ii=zt.argv||[],Bt=zt.env||{},ya=!(Bt.NO_COLOR||ii.includes("--no-color"))&&(!!Bt.FORCE_COLOR||ii.includes("--color")||zt.platform==="win32"||(zt.stdout||{}).isTTY&&Bt.TERM!=="dumb"||!!Bt.CI),Sa=(n,e,t=n)=>r=>{let i=""+r,s=i.indexOf(e,n.length);return~s?n+va(i,e,t,s)+e:n+i+e},va=(n,e,t,r)=>{let i="",s=0;do i+=n.substring(s,r)+t,s=r+e.length,r=n.indexOf(e,s);while(~r);return i+n.substring(s)},si=(n=ya)=>{let e=n?Sa:()=>String;return{isColorSupported:n,reset:e("\x1B[0m","\x1B[0m"),bold:e("\x1B[1m","\x1B[22m","\x1B[22m\x1B[1m"),dim:e("\x1B[2m","\x1B[22m","\x1B[22m\x1B[2m"),italic:e("\x1B[3m","\x1B[23m"),underline:e("\x1B[4m","\x1B[24m"),inverse:e("\x1B[7m","\x1B[27m"),hidden:e("\x1B[8m","\x1B[28m"),strikethrough:e("\x1B[9m","\x1B[29m"),black:e("\x1B[30m","\x1B[39m"),red:e("\x1B[31m","\x1B[39m"),green:e("\x1B[32m","\x1B[39m"),yellow:e("\x1B[33m","\x1B[39m"),blue:e("\x1B[34m","\x1B[39m"),magenta:e("\x1B[35m","\x1B[39m"),cyan:e("\x1B[36m","\x1B[39m"),white:e("\x1B[37m","\x1B[39m"),gray:e("\x1B[90m","\x1B[39m"),bgBlack:e("\x1B[40m","\x1B[49m"),bgRed:e("\x1B[41m","\x1B[49m"),bgGreen:e("\x1B[42m","\x1B[49m"),bgYellow:e("\x1B[43m","\x1B[49m"),bgBlue:e("\x1B[44m","\x1B[49m"),bgMagenta:e("\x1B[45m","\x1B[49m"),bgCyan:e("\x1B[46m","\x1B[49m"),bgWhite:e("\x1B[47m","\x1B[49m"),blackBright:e("\x1B[90m","\x1B[39m"),redBright:e("\x1B[91m","\x1B[39m"),greenBright:e("\x1B[92m","\x1B[39m"),yellowBright:e("\x1B[93m","\x1B[39m"),blueBright:e("\x1B[94m","\x1B[39m"),magentaBright:e("\x1B[95m","\x1B[39m"),cyanBright:e("\x1B[96m","\x1B[39m"),whiteBright:e("\x1B[97m","\x1B[39m"),bgBlackBright:e("\x1B[100m","\x1B[49m"),bgRedBright:e("\x1B[101m","\x1B[49m"),bgGreenBright:e("\x1B[102m","\x1B[49m"),bgYellowBright:e("\x1B[103m","\x1B[49m"),bgBlueBright:e("\x1B[104m","\x1B[49m"),bgMagentaBright:e("\x1B[105m","\x1B[49m"),bgCyanBright:e("\x1B[106m","\x1B[49m"),bgWhiteBright:e("\x1B[107m","\x1B[49m")}};xr.exports=si();xr.exports.createColors=si});var br=b((Sh,li)=>{"use strict";var Gt=/[\t\n\f\r "#'()/;[\\\]{}]/g,Wt=/[\t\n\f\r !"#'():;@[\\\]{}]|\/(?=\*)/g,xa=/.[\r\n"'(/\\]/,oi=/[\da-f]/i;li.exports=function(e,t={}){let r=e.css.valueOf(),i=t.ignoreErrors,s,o,a,l,f,u,h,c,d,m,p=r.length,_=0,v=[],C=[];function I(){return _}function L(P){throw e.error("Unclosed "+P,_)}function R(){return C.length===0&&_>=p}function O(P){if(C.length)return C.pop();if(_>=p)return;let A=P?P.ignoreUnclosed:!1;switch(s=r.charCodeAt(_),s){case 10:case 32:case 9:case 13:case 12:{l=_;do l+=1,s=r.charCodeAt(l);while(s===32||s===10||s===9||s===13||s===12);u=["space",r.slice(_,l)],_=l-1;break}case 91:case 93:case 123:case 125:case 58:case 59:case 41:{let G=String.fromCharCode(s);u=[G,G,_];break}case 40:{if(m=v.length?v.pop()[1]:"",d=r.charCodeAt(_+1),m==="url"&&d!==39&&d!==34&&d!==32&&d!==10&&d!==9&&d!==12&&d!==13){l=_;do{if(h=!1,l=r.indexOf(")",l+1),l===-1)if(i||A){l=_;break}else L("bracket");for(c=l;r.charCodeAt(c-1)===92;)c-=1,h=!h}while(h);u=["brackets",r.slice(_,l+1),_,l],_=l}else l=r.indexOf(")",_+1),o=r.slice(_,l+1),l===-1||xa.test(o)?u=["(","(",_]:(u=["brackets",o,_,l],_=l);break}case 39:case 34:{f=s===39?"'":'"',l=_;do{if(h=!1,l=r.indexOf(f,l+1),l===-1)if(i||A){l=_+1;break}else L("string");for(c=l;r.charCodeAt(c-1)===92;)c-=1,h=!h}while(h);u=["string",r.slice(_,l+1),_,l],_=l;break}case 64:{Gt.lastIndex=_+1,Gt.test(r),Gt.lastIndex===0?l=r.length-1:l=Gt.lastIndex-2,u=["at-word",r.slice(_,l+1),_,l],_=l;break}case 92:{for(l=_,a=!0;r.charCodeAt(l+1)===92;)l+=1,a=!a;if(s=r.charCodeAt(l+1),a&&s!==47&&s!==32&&s!==10&&s!==9&&s!==13&&s!==12&&(l+=1,oi.test(r.charAt(l)))){for(;oi.test(r.charAt(l+1));)l+=1;r.charCodeAt(l+1)===32&&(l+=1)}u=["word",r.slice(_,l+1),_,l],_=l;break}default:{s===47&&r.charCodeAt(_+1)===42?(l=r.indexOf("*/",_+2)+1,l===0&&(i||A?l=r.length:L("comment")),u=["comment",r.slice(_,l+1),_,l],_=l):(Wt.lastIndex=_+1,Wt.test(r),Wt.lastIndex===0?l=r.length-1:l=Wt.lastIndex-2,u=["word",r.slice(_,l+1),_,l],v.push(u),_=l);break}}return _++,u}function B(P){C.push(P)}return{back:B,endOfFile:R,nextToken:O,position:I}}});var Lr=b((vh,ui)=>{"use strict";var K=Cr(),Ca=br(),ai;function ba(n){ai=n}var La={";":K.yellow,":":K.yellow,"(":K.cyan,")":K.cyan,"[":K.yellow,"]":K.yellow,"{":K.yellow,"}":K.yellow,"at-word":K.cyan,brackets:K.cyan,call:K.cyan,class:K.yellow,comment:K.gray,hash:K.magenta,string:K.green};function Oa([n,e],t){if(n==="word"){if(e[0]===".")return"class";if(e[0]==="#")return"hash"}if(!t.endOfFile()){let r=t.nextToken();if(t.back(r),r[0]==="brackets"||r[0]==="(")return"call"}return n}function fi(n){let e=Ca(new ai(n),{ignoreErrors:!0}),t="";for(;!e.endOfFile();){let r=e.nextToken(),i=La[Oa(r,e)];i?t+=r[1].split(/\r?\n/).map(s=>i(s)).join(` +`):t+=r[1]}return t}fi.registerInput=ba;ui.exports=fi});var Or=b((xh,di)=>{"use strict";var ci=Cr(),hi=Lr(),ft=class n extends Error{constructor(e,t,r,i,s,o){super(e),this.name="CssSyntaxError",this.reason=e,s&&(this.file=s),i&&(this.source=i),o&&(this.plugin=o),typeof t<"u"&&typeof r<"u"&&(typeof t=="number"?(this.line=t,this.column=r):(this.line=t.line,this.column=t.column,this.endLine=r.line,this.endColumn=r.column)),this.setMessage(),Error.captureStackTrace&&Error.captureStackTrace(this,n)}setMessage(){this.message=this.plugin?this.plugin+": ":"",this.message+=this.file?this.file:"",typeof this.line<"u"&&(this.message+=":"+this.line+":"+this.column),this.message+=": "+this.reason}showSourceCode(e){if(!this.source)return"";let t=this.source;e==null&&(e=ci.isColorSupported);let r=u=>u,i=u=>u,s=u=>u;if(e){let{bold:u,gray:h,red:c}=ci.createColors(!0);i=d=>u(c(d)),r=d=>h(d),hi&&(s=d=>hi(d))}let o=t.split(/\r?\n/),a=Math.max(this.line-3,0),l=Math.min(this.line+2,o.length),f=String(l).length;return o.slice(a,l).map((u,h)=>{let c=a+1+h,d=" "+(" "+c).slice(-f)+" | ";if(c===this.line){if(u.length>160){let p=20,_=Math.max(0,this.column-p),v=Math.max(this.column+p,this.endColumn+p),C=u.slice(_,v),I=r(d.replace(/\d/g," "))+u.slice(0,Math.min(this.column-1,p-1)).replace(/[^\t]/g," ");return i(">")+r(d)+s(C)+` + `+I+i("^")}let m=r(d.replace(/\d/g," "))+u.slice(0,this.column-1).replace(/[^\t]/g," ");return i(">")+r(d)+s(u)+` + `+m+i("^")}return" "+r(d)+s(u)}).join(` +`)}toString(){let e=this.showSourceCode();return e&&(e=` + +`+e+` +`),this.name+": "+this.message+e}};di.exports=ft;ft.default=ft});var Ir=b((Ch,mi)=>{"use strict";var pi={after:` +`,beforeClose:` +`,beforeComment:` +`,beforeDecl:` +`,beforeOpen:" ",beforeRule:` +`,colon:": ",commentLeft:" ",commentRight:" ",emptyBody:"",indent:" ",semicolon:!1};function Ia(n){return n[0].toUpperCase()+n.slice(1)}var ut=class{constructor(e){this.builder=e}atrule(e,t){let r="@"+e.name,i=e.params?this.rawValue(e,"params"):"";if(typeof e.raws.afterName<"u"?r+=e.raws.afterName:i&&(r+=" "),e.nodes)this.block(e,r+i);else{let s=(e.raws.between||"")+(t?";":"");this.builder(r+i+s,e)}}beforeAfter(e,t){let r;e.type==="decl"?r=this.raw(e,null,"beforeDecl"):e.type==="comment"?r=this.raw(e,null,"beforeComment"):t==="before"?r=this.raw(e,null,"beforeRule"):r=this.raw(e,null,"beforeClose");let i=e.parent,s=0;for(;i&&i.type!=="root";)s+=1,i=i.parent;if(r.includes(` +`)){let o=this.raw(e,null,"indent");if(o.length)for(let a=0;a0&&e.nodes[t].type==="comment";)t-=1;let r=this.raw(e,"semicolon");for(let i=0;i{if(i=l.raws[t],typeof i<"u")return!1})}return typeof i>"u"&&(i=pi[r]),o.rawCache[r]=i,i}rawBeforeClose(e){let t;return e.walk(r=>{if(r.nodes&&r.nodes.length>0&&typeof r.raws.after<"u")return t=r.raws.after,t.includes(` +`)&&(t=t.replace(/[^\n]+$/,"")),!1}),t&&(t=t.replace(/\S/g,"")),t}rawBeforeComment(e,t){let r;return e.walkComments(i=>{if(typeof i.raws.before<"u")return r=i.raws.before,r.includes(` +`)&&(r=r.replace(/[^\n]+$/,"")),!1}),typeof r>"u"?r=this.raw(t,null,"beforeDecl"):r&&(r=r.replace(/\S/g,"")),r}rawBeforeDecl(e,t){let r;return e.walkDecls(i=>{if(typeof i.raws.before<"u")return r=i.raws.before,r.includes(` +`)&&(r=r.replace(/[^\n]+$/,"")),!1}),typeof r>"u"?r=this.raw(t,null,"beforeRule"):r&&(r=r.replace(/\S/g,"")),r}rawBeforeOpen(e){let t;return e.walk(r=>{if(r.type!=="decl"&&(t=r.raws.between,typeof t<"u"))return!1}),t}rawBeforeRule(e){let t;return e.walk(r=>{if(r.nodes&&(r.parent!==e||e.first!==r)&&typeof r.raws.before<"u")return t=r.raws.before,t.includes(` +`)&&(t=t.replace(/[^\n]+$/,"")),!1}),t&&(t=t.replace(/\S/g,"")),t}rawColon(e){let t;return e.walkDecls(r=>{if(typeof r.raws.between<"u")return t=r.raws.between.replace(/[^\s:]/g,""),!1}),t}rawEmptyBody(e){let t;return e.walk(r=>{if(r.nodes&&r.nodes.length===0&&(t=r.raws.after,typeof t<"u"))return!1}),t}rawIndent(e){if(e.raws.indent)return e.raws.indent;let t;return e.walk(r=>{let i=r.parent;if(i&&i!==e&&i.parent&&i.parent===e&&typeof r.raws.before<"u"){let s=r.raws.before.split(` +`);return t=s[s.length-1],t=t.replace(/\S/g,""),!1}}),t}rawSemicolon(e){let t;return e.walk(r=>{if(r.nodes&&r.nodes.length&&r.last.type==="decl"&&(t=r.raws.semicolon,typeof t<"u"))return!1}),t}rawValue(e,t){let r=e[t],i=e.raws[t];return i&&i.value===r?i.raw:r}root(e){this.body(e),e.raws.after&&this.builder(e.raws.after)}rule(e){this.block(e,this.rawValue(e,"selector")),e.raws.ownSemicolon&&this.builder(e.raws.ownSemicolon,e,"end")}stringify(e,t){if(!this[e.type])throw new Error("Unknown AST node type "+e.type+". Maybe you need to change PostCSS stringifier.");this[e.type](e,t)}};mi.exports=ut;ut.default=ut});var _i=b((bh,gi)=>{"use strict";var Na=Ir();function Nr(n,e){new Na(e).stringify(n)}gi.exports=Nr;Nr.default=Nr});var Rr=b((Lh,Tr)=>{"use strict";Tr.exports.isClean=Symbol("isClean");Tr.exports.my=Symbol("my")});var qt=b((Oh,Ei)=>{"use strict";var Ta=Or(),Ra=Ir(),Aa=_i(),{isClean:ct,my:Da}=Rr();function Ar(n,e){let t=new n.constructor;for(let r in n){if(!Object.prototype.hasOwnProperty.call(n,r)||r==="proxyCache")continue;let i=n[r],s=typeof i;r==="parent"&&s==="object"?e&&(t[r]=e):r==="source"?t[r]=i:Array.isArray(i)?t[r]=i.map(o=>Ar(o,t)):(s==="object"&&i!==null&&(i=Ar(i)),t[r]=i)}return t}function ge(n,e){if(e&&typeof e.offset<"u")return e.offset;let t=1,r=1,i=0;for(let s=0;se.root().toProxy():e[t]},set(e,t,r){return e[t]===r||(e[t]=r,(t==="prop"||t==="value"||t==="name"||t==="params"||t==="important"||t==="text")&&e.markDirty()),!0}}}markClean(){this[ct]=!0}markDirty(){if(this[ct]){this[ct]=!1;let e=this;for(;e=e.parent;)e[ct]=!1}}next(){if(!this.parent)return;let e=this.parent.index(this);return this.parent.nodes[e+1]}positionBy(e={}){let t=this.source.start;if(e.index)t=this.positionInside(e.index);else if(e.word){let r="document"in this.source.input?this.source.input.document:this.source.input.css,s=r.slice(ge(r,this.source.start),ge(r,this.source.end)).indexOf(e.word);s!==-1&&(t=this.positionInside(s))}return t}positionInside(e){let t=this.source.start.column,r=this.source.start.line,i="document"in this.source.input?this.source.input.document:this.source.input.css,s=ge(i,this.source.start),o=s+e;for(let a=s;atypeof l=="object"&&l.toJSON?l.toJSON(null,t):l);else if(typeof a=="object"&&a.toJSON)r[o]=a.toJSON(null,t);else if(o==="source"){if(a==null)continue;let l=t.get(a.input);l==null&&(l=s,t.set(a.input,s),s++),r[o]={end:a.end,inputId:l,start:a.start}}else r[o]=a}return i&&(r.inputs=[...t.keys()].map(o=>o.toJSON())),r}toProxy(){return this.proxyCache||(this.proxyCache=new Proxy(this,this.getProxyProcessor())),this.proxyCache}toString(e=Aa){e.stringify&&(e=e.stringify);let t="";return e(this,r=>{t+=r}),t}warn(e,t,r={}){let i={node:this};for(let s in r)i[s]=r[s];return e.warn(t,i)}};Ei.exports=ht;ht.default=ht});var Dr=b((Ih,wi)=>{"use strict";var Ma=qt(),dt=class extends Ma{constructor(e){super(e),this.type="comment"}};wi.exports=dt;dt.default=dt});var Mr=b((Nh,yi)=>{"use strict";var Pa=qt(),pt=class extends Pa{get variable(){return this.prop.startsWith("--")||this.prop[0]==="$"}constructor(e){e&&typeof e.value<"u"&&typeof e.value!="string"&&(e={...e,value:String(e.value)}),super(e),this.type="decl"}};yi.exports=pt;pt.default=pt});var mt=b((Th,Ni)=>{"use strict";var Si=Dr(),vi=Mr(),Fa=qt(),{isClean:xi,my:Ci}=Rr(),Pr,bi,Li,Fr;function Oi(n){return n.map(e=>(e.nodes&&(e.nodes=Oi(e.nodes)),delete e.source,e))}function Ii(n){if(n[xi]=!1,n.proxyOf.nodes)for(let e of n.proxyOf.nodes)Ii(e)}var ce=class n extends Fa{get first(){if(this.proxyOf.nodes)return this.proxyOf.nodes[0]}get last(){if(this.proxyOf.nodes)return this.proxyOf.nodes[this.proxyOf.nodes.length-1]}append(...e){for(let t of e){let r=this.normalize(t,this.last);for(let i of r)this.proxyOf.nodes.push(i)}return this.markDirty(),this}cleanRaws(e){if(super.cleanRaws(e),this.nodes)for(let t of this.nodes)t.cleanRaws(e)}each(e){if(!this.proxyOf.nodes)return;let t=this.getIterator(),r,i;for(;this.indexes[t]e[t](...r.map(i=>typeof i=="function"?(s,o)=>i(s.toProxy(),o):i)):t==="every"||t==="some"?r=>e[t]((i,...s)=>r(i.toProxy(),...s)):t==="root"?()=>e.root().toProxy():t==="nodes"?e.nodes.map(r=>r.toProxy()):t==="first"||t==="last"?e[t].toProxy():e[t]:e[t]},set(e,t,r){return e[t]===r||(e[t]=r,(t==="name"||t==="params"||t==="selector")&&e.markDirty()),!0}}}index(e){return typeof e=="number"?e:(e.proxyOf&&(e=e.proxyOf),this.proxyOf.nodes.indexOf(e))}insertAfter(e,t){let r=this.index(e),i=this.normalize(t,this.proxyOf.nodes[r]).reverse();r=this.index(e);for(let o of i)this.proxyOf.nodes.splice(r+1,0,o);let s;for(let o in this.indexes)s=this.indexes[o],r"u")e=[];else if(Array.isArray(e)){e=e.slice(0);for(let i of e)i.parent&&i.parent.removeChild(i,"ignore")}else if(e.type==="root"&&this.type!=="document"){e=e.nodes.slice(0);for(let i of e)i.parent&&i.parent.removeChild(i,"ignore")}else if(e.type)e=[e];else if(e.prop){if(typeof e.value>"u")throw new Error("Value field is missed in node creation");typeof e.value!="string"&&(e.value=String(e.value)),e=[new vi(e)]}else if(e.selector||e.selectors)e=[new Fr(e)];else if(e.name)e=[new Pr(e)];else if(e.text)e=[new Si(e)];else throw new Error("Unknown node type in node creation");return e.map(i=>(i[Ci]||n.rebuild(i),i=i.proxyOf,i.parent&&i.parent.removeChild(i),i[xi]&&Ii(i),i.raws||(i.raws={}),typeof i.raws.before>"u"&&t&&typeof t.raws.before<"u"&&(i.raws.before=t.raws.before.replace(/\S/g,"")),i.parent=this.proxyOf,i))}prepend(...e){e=e.reverse();for(let t of e){let r=this.normalize(t,this.first,"prepend").reverse();for(let i of r)this.proxyOf.nodes.unshift(i);for(let i in this.indexes)this.indexes[i]=this.indexes[i]+r.length}return this.markDirty(),this}push(e){return e.parent=this,this.proxyOf.nodes.push(e),this}removeAll(){for(let e of this.proxyOf.nodes)e.parent=void 0;return this.proxyOf.nodes=[],this.markDirty(),this}removeChild(e){e=this.index(e),this.proxyOf.nodes[e].parent=void 0,this.proxyOf.nodes.splice(e,1);let t;for(let r in this.indexes)t=this.indexes[r],t>=e&&(this.indexes[r]=t-1);return this.markDirty(),this}replaceValues(e,t,r){return r||(r=t,t={}),this.walkDecls(i=>{t.props&&!t.props.includes(i.prop)||t.fast&&!i.value.includes(t.fast)||(i.value=i.value.replace(e,r))}),this.markDirty(),this}some(e){return this.nodes.some(e)}walk(e){return this.each((t,r)=>{let i;try{i=e(t,r)}catch(s){throw t.addToError(s)}return i!==!1&&t.walk&&(i=t.walk(e)),i})}walkAtRules(e,t){return t?e instanceof RegExp?this.walk((r,i)=>{if(r.type==="atrule"&&e.test(r.name))return t(r,i)}):this.walk((r,i)=>{if(r.type==="atrule"&&r.name===e)return t(r,i)}):(t=e,this.walk((r,i)=>{if(r.type==="atrule")return t(r,i)}))}walkComments(e){return this.walk((t,r)=>{if(t.type==="comment")return e(t,r)})}walkDecls(e,t){return t?e instanceof RegExp?this.walk((r,i)=>{if(r.type==="decl"&&e.test(r.prop))return t(r,i)}):this.walk((r,i)=>{if(r.type==="decl"&&r.prop===e)return t(r,i)}):(t=e,this.walk((r,i)=>{if(r.type==="decl")return t(r,i)}))}walkRules(e,t){return t?e instanceof RegExp?this.walk((r,i)=>{if(r.type==="rule"&&e.test(r.selector))return t(r,i)}):this.walk((r,i)=>{if(r.type==="rule"&&r.selector===e)return t(r,i)}):(t=e,this.walk((r,i)=>{if(r.type==="rule")return t(r,i)}))}};ce.registerParse=n=>{bi=n};ce.registerRule=n=>{Fr=n};ce.registerAtRule=n=>{Pr=n};ce.registerRoot=n=>{Li=n};Ni.exports=ce;ce.default=ce;ce.rebuild=n=>{n.type==="atrule"?Object.setPrototypeOf(n,Pr.prototype):n.type==="rule"?Object.setPrototypeOf(n,Fr.prototype):n.type==="decl"?Object.setPrototypeOf(n,vi.prototype):n.type==="comment"?Object.setPrototypeOf(n,Si.prototype):n.type==="root"&&Object.setPrototypeOf(n,Li.prototype),n[Ci]=!0,n.nodes&&n.nodes.forEach(e=>{ce.rebuild(e)})}});var Ri=b((Rh,Ti)=>{var Ua="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict",ka=(n,e=21)=>(t=e)=>{let r="",i=t|0;for(;i--;)r+=n[Math.random()*n.length|0];return r},Ba=(n=21)=>{let e="",t=n|0;for(;t--;)e+=Ua[Math.random()*64|0];return e};Ti.exports={nanoid:Ba,customAlphabet:ka}});var Di=b(Ur=>{var Ai="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");Ur.encode=function(n){if(0<=n&&n{var Mi=Di(),kr=5,Pi=1<>1;return e?-t:t}Br.encode=function(e){var t="",r,i=za(e);do r=i&Fi,i>>>=kr,i>0&&(r|=Ui),t+=Mi.encode(r);while(i>0);return t};Br.decode=function(e,t,r){var i=e.length,s=0,o=0,a,l;do{if(t>=i)throw new Error("Expected more digits in base 64 VLQ value.");if(l=Mi.decode(e.charCodeAt(t++)),l===-1)throw new Error("Invalid base64 digit: "+e.charAt(t-1));a=!!(l&Ui),l&=Fi,s=s+(l<{function Wa(n,e,t){if(e in n)return n[e];if(arguments.length===3)return t;throw new Error('"'+e+'" is a required argument.')}$.getArg=Wa;var ki=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,qa=/^data:.+\,.+$/;function gt(n){var e=n.match(ki);return e?{scheme:e[1],auth:e[2],host:e[3],port:e[4],path:e[5]}:null}$.urlParse=gt;function qe(n){var e="";return n.scheme&&(e+=n.scheme+":"),e+="//",n.auth&&(e+=n.auth+"@"),n.host&&(e+=n.host),n.port&&(e+=":"+n.port),n.path&&(e+=n.path),e}$.urlGenerate=qe;var ja=32;function $a(n){var e=[];return function(t){for(var r=0;rja&&e.pop(),s}}var Gr=$a(function(e){var t=e,r=gt(e);if(r){if(!r.path)return e;t=r.path}for(var i=$.isAbsolute(t),s=[],o=0,a=0;;)if(o=a,a=t.indexOf("/",o),a===-1){s.push(t.slice(o));break}else for(s.push(t.slice(o,a));a=0;a--)l=s[a],l==="."?s.splice(a,1):l===".."?f++:f>0&&(l===""?(s.splice(a+1,f),f=0):(s.splice(a,2),f--));return t=s.join("/"),t===""&&(t=i?"/":"."),r?(r.path=t,qe(r)):t});$.normalize=Gr;function Bi(n,e){n===""&&(n="."),e===""&&(e=".");var t=gt(e),r=gt(n);if(r&&(n=r.path||"/"),t&&!t.scheme)return r&&(t.scheme=r.scheme),qe(t);if(t||e.match(qa))return e;if(r&&!r.host&&!r.path)return r.host=e,qe(r);var i=e.charAt(0)==="/"?e:Gr(n.replace(/\/+$/,"")+"/"+e);return r?(r.path=i,qe(r)):i}$.join=Bi;$.isAbsolute=function(n){return n.charAt(0)==="/"||ki.test(n)};function Va(n,e){n===""&&(n="."),n=n.replace(/\/$/,"");for(var t=0;e.indexOf(n+"/")!==0;){var r=n.lastIndexOf("/");if(r<0||(n=n.slice(0,r),n.match(/^([^\/]+:\/)?\/*$/)))return e;++t}return Array(t+1).join("../")+e.substr(n.length+1)}$.relative=Va;var zi=(function(){var n=Object.create(null);return!("__proto__"in n)})();function Gi(n){return n}function Ha(n){return Wi(n)?"$"+n:n}$.toSetString=zi?Gi:Ha;function Za(n){return Wi(n)?n.slice(1):n}$.fromSetString=zi?Gi:Za;function Wi(n){if(!n)return!1;var e=n.length;if(e<9||n.charCodeAt(e-1)!==95||n.charCodeAt(e-2)!==95||n.charCodeAt(e-3)!==111||n.charCodeAt(e-4)!==116||n.charCodeAt(e-5)!==111||n.charCodeAt(e-6)!==114||n.charCodeAt(e-7)!==112||n.charCodeAt(e-8)!==95||n.charCodeAt(e-9)!==95)return!1;for(var t=e-10;t>=0;t--)if(n.charCodeAt(t)!==36)return!1;return!0}function Ya(n,e,t){var r=_e(n.source,e.source);return r!==0||(r=n.originalLine-e.originalLine,r!==0)||(r=n.originalColumn-e.originalColumn,r!==0||t)||(r=n.generatedColumn-e.generatedColumn,r!==0)||(r=n.generatedLine-e.generatedLine,r!==0)?r:_e(n.name,e.name)}$.compareByOriginalPositions=Ya;function Xa(n,e,t){var r;return r=n.originalLine-e.originalLine,r!==0||(r=n.originalColumn-e.originalColumn,r!==0||t)||(r=n.generatedColumn-e.generatedColumn,r!==0)||(r=n.generatedLine-e.generatedLine,r!==0)?r:_e(n.name,e.name)}$.compareByOriginalPositionsNoSource=Xa;function Ka(n,e,t){var r=n.generatedLine-e.generatedLine;return r!==0||(r=n.generatedColumn-e.generatedColumn,r!==0||t)||(r=_e(n.source,e.source),r!==0)||(r=n.originalLine-e.originalLine,r!==0)||(r=n.originalColumn-e.originalColumn,r!==0)?r:_e(n.name,e.name)}$.compareByGeneratedPositionsDeflated=Ka;function Ja(n,e,t){var r=n.generatedColumn-e.generatedColumn;return r!==0||t||(r=_e(n.source,e.source),r!==0)||(r=n.originalLine-e.originalLine,r!==0)||(r=n.originalColumn-e.originalColumn,r!==0)?r:_e(n.name,e.name)}$.compareByGeneratedPositionsDeflatedNoLine=Ja;function _e(n,e){return n===e?0:n===null?1:e===null?-1:n>e?1:-1}function Qa(n,e){var t=n.generatedLine-e.generatedLine;return t!==0||(t=n.generatedColumn-e.generatedColumn,t!==0)||(t=_e(n.source,e.source),t!==0)||(t=n.originalLine-e.originalLine,t!==0)||(t=n.originalColumn-e.originalColumn,t!==0)?t:_e(n.name,e.name)}$.compareByGeneratedPositionsInflated=Qa;function ef(n){return JSON.parse(n.replace(/^\)]}'[^\n]*\n/,""))}$.parseSourceMapInput=ef;function tf(n,e,t){if(e=e||"",n&&(n[n.length-1]!=="/"&&e[0]!=="/"&&(n+="/"),e=n+e),t){var r=gt(t);if(!r)throw new Error("sourceMapURL could not be parsed");if(r.path){var i=r.path.lastIndexOf("/");i>=0&&(r.path=r.path.substring(0,i+1))}e=Bi(qe(r),e)}return Gr(e)}$.computeSourceURL=tf});var jr=b(qi=>{var Wr=je(),qr=Object.prototype.hasOwnProperty,Pe=typeof Map<"u";function Ee(){this._array=[],this._set=Pe?new Map:Object.create(null)}Ee.fromArray=function(e,t){for(var r=new Ee,i=0,s=e.length;i=0)return t}else{var r=Wr.toSetString(e);if(qr.call(this._set,r))return this._set[r]}throw new Error('"'+e+'" is not in the set.')};Ee.prototype.at=function(e){if(e>=0&&e{var ji=je();function rf(n,e){var t=n.generatedLine,r=e.generatedLine,i=n.generatedColumn,s=e.generatedColumn;return r>t||r==t&&s>=i||ji.compareByGeneratedPositionsInflated(n,e)<=0}function jt(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0}}jt.prototype.unsortedForEach=function(e,t){this._array.forEach(e,t)};jt.prototype.add=function(e){rf(this._last,e)?(this._last=e,this._array.push(e)):(this._sorted=!1,this._array.push(e))};jt.prototype.toArray=function(){return this._sorted||(this._array.sort(ji.compareByGeneratedPositionsInflated),this._sorted=!0),this._array};$i.MappingList=jt});var $r=b(Hi=>{var _t=zr(),W=je(),$t=jr().ArraySet,nf=Vi().MappingList;function re(n){n||(n={}),this._file=W.getArg(n,"file",null),this._sourceRoot=W.getArg(n,"sourceRoot",null),this._skipValidation=W.getArg(n,"skipValidation",!1),this._ignoreInvalidMapping=W.getArg(n,"ignoreInvalidMapping",!1),this._sources=new $t,this._names=new $t,this._mappings=new nf,this._sourcesContents=null}re.prototype._version=3;re.fromSourceMap=function(e,t){var r=e.sourceRoot,i=new re(Object.assign(t||{},{file:e.file,sourceRoot:r}));return e.eachMapping(function(s){var o={generated:{line:s.generatedLine,column:s.generatedColumn}};s.source!=null&&(o.source=s.source,r!=null&&(o.source=W.relative(r,o.source)),o.original={line:s.originalLine,column:s.originalColumn},s.name!=null&&(o.name=s.name)),i.addMapping(o)}),e.sources.forEach(function(s){var o=s;r!==null&&(o=W.relative(r,s)),i._sources.has(o)||i._sources.add(o);var a=e.sourceContentFor(s);a!=null&&i.setSourceContent(s,a)}),i};re.prototype.addMapping=function(e){var t=W.getArg(e,"generated"),r=W.getArg(e,"original",null),i=W.getArg(e,"source",null),s=W.getArg(e,"name",null);!this._skipValidation&&this._validateMapping(t,r,i,s)===!1||(i!=null&&(i=String(i),this._sources.has(i)||this._sources.add(i)),s!=null&&(s=String(s),this._names.has(s)||this._names.add(s)),this._mappings.add({generatedLine:t.line,generatedColumn:t.column,originalLine:r!=null&&r.line,originalColumn:r!=null&&r.column,source:i,name:s}))};re.prototype.setSourceContent=function(e,t){var r=e;this._sourceRoot!=null&&(r=W.relative(this._sourceRoot,r)),t!=null?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[W.toSetString(r)]=t):this._sourcesContents&&(delete this._sourcesContents[W.toSetString(r)],Object.keys(this._sourcesContents).length===0&&(this._sourcesContents=null))};re.prototype.applySourceMap=function(e,t,r){var i=t;if(t==null){if(e.file==null)throw new Error(`SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map's "file" property. Both were omitted.`);i=e.file}var s=this._sourceRoot;s!=null&&(i=W.relative(s,i));var o=new $t,a=new $t;this._mappings.unsortedForEach(function(l){if(l.source===i&&l.originalLine!=null){var f=e.originalPositionFor({line:l.originalLine,column:l.originalColumn});f.source!=null&&(l.source=f.source,r!=null&&(l.source=W.join(r,l.source)),s!=null&&(l.source=W.relative(s,l.source)),l.originalLine=f.line,l.originalColumn=f.column,f.name!=null&&(l.name=f.name))}var u=l.source;u!=null&&!o.has(u)&&o.add(u);var h=l.name;h!=null&&!a.has(h)&&a.add(h)},this),this._sources=o,this._names=a,e.sources.forEach(function(l){var f=e.sourceContentFor(l);f!=null&&(r!=null&&(l=W.join(r,l)),s!=null&&(l=W.relative(s,l)),this.setSourceContent(l,f))},this)};re.prototype._validateMapping=function(e,t,r,i){if(t&&typeof t.line!="number"&&typeof t.column!="number"){var s="original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.";if(this._ignoreInvalidMapping)return typeof console<"u"&&console.warn&&console.warn(s),!1;throw new Error(s)}if(!(e&&"line"in e&&"column"in e&&e.line>0&&e.column>=0&&!t&&!r&&!i)){if(e&&"line"in e&&"column"in e&&t&&"line"in t&&"column"in t&&e.line>0&&e.column>=0&&t.line>0&&t.column>=0&&r)return;var s="Invalid mapping: "+JSON.stringify({generated:e,source:r,original:t,name:i});if(this._ignoreInvalidMapping)return typeof console<"u"&&console.warn&&console.warn(s),!1;throw new Error(s)}};re.prototype._serializeMappings=function(){for(var e=0,t=1,r=0,i=0,s=0,o=0,a="",l,f,u,h,c=this._mappings.toArray(),d=0,m=c.length;d0){if(!W.compareByGeneratedPositionsInflated(f,c[d-1]))continue;l+=","}l+=_t.encode(f.generatedColumn-e),e=f.generatedColumn,f.source!=null&&(h=this._sources.indexOf(f.source),l+=_t.encode(h-o),o=h,l+=_t.encode(f.originalLine-1-i),i=f.originalLine-1,l+=_t.encode(f.originalColumn-r),r=f.originalColumn,f.name!=null&&(u=this._names.indexOf(f.name),l+=_t.encode(u-s),s=u)),a+=l}return a};re.prototype._generateSourcesContent=function(e,t){return e.map(function(r){if(!this._sourcesContents)return null;t!=null&&(r=W.relative(t,r));var i=W.toSetString(r);return Object.prototype.hasOwnProperty.call(this._sourcesContents,i)?this._sourcesContents[i]:null},this)};re.prototype.toJSON=function(){var e={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return this._file!=null&&(e.file=this._file),this._sourceRoot!=null&&(e.sourceRoot=this._sourceRoot),this._sourcesContents&&(e.sourcesContent=this._generateSourcesContent(e.sources,e.sourceRoot)),e};re.prototype.toString=function(){return JSON.stringify(this.toJSON())};Hi.SourceMapGenerator=re});var Zi=b(Fe=>{Fe.GREATEST_LOWER_BOUND=1;Fe.LEAST_UPPER_BOUND=2;function Vr(n,e,t,r,i,s){var o=Math.floor((e-n)/2)+n,a=i(t,r[o],!0);return a===0?o:a>0?e-o>1?Vr(o,e,t,r,i,s):s==Fe.LEAST_UPPER_BOUND?e1?Vr(n,o,t,r,i,s):s==Fe.LEAST_UPPER_BOUND?o:n<0?-1:n}Fe.search=function(e,t,r,i){if(t.length===0)return-1;var s=Vr(-1,t.length,e,t,r,i||Fe.GREATEST_LOWER_BOUND);if(s<0)return-1;for(;s-1>=0&&r(t[s],t[s-1],!0)===0;)--s;return s}});var Ki=b(Xi=>{function sf(n){function e(i,s,o){var a=i[s];i[s]=i[o],i[o]=a}function t(i,s){return Math.round(i+Math.random()*(s-i))}function r(i,s,o,a){if(o{var S=je(),Zr=Zi(),$e=jr().ArraySet,lf=zr(),Et=Ki().quickSort;function M(n,e){var t=n;return typeof n=="string"&&(t=S.parseSourceMapInput(n)),t.sections!=null?new he(t,e):new H(t,e)}M.fromSourceMap=function(n,e){return H.fromSourceMap(n,e)};M.prototype._version=3;M.prototype.__generatedMappings=null;Object.defineProperty(M.prototype,"_generatedMappings",{configurable:!0,enumerable:!0,get:function(){return this.__generatedMappings||this._parseMappings(this._mappings,this.sourceRoot),this.__generatedMappings}});M.prototype.__originalMappings=null;Object.defineProperty(M.prototype,"_originalMappings",{configurable:!0,enumerable:!0,get:function(){return this.__originalMappings||this._parseMappings(this._mappings,this.sourceRoot),this.__originalMappings}});M.prototype._charIsMappingSeparator=function(e,t){var r=e.charAt(t);return r===";"||r===","};M.prototype._parseMappings=function(e,t){throw new Error("Subclasses must implement _parseMappings")};M.GENERATED_ORDER=1;M.ORIGINAL_ORDER=2;M.GREATEST_LOWER_BOUND=1;M.LEAST_UPPER_BOUND=2;M.prototype.eachMapping=function(e,t,r){var i=t||null,s=r||M.GENERATED_ORDER,o;switch(s){case M.GENERATED_ORDER:o=this._generatedMappings;break;case M.ORIGINAL_ORDER:o=this._originalMappings;break;default:throw new Error("Unknown order of iteration.")}for(var a=this.sourceRoot,l=e.bind(i),f=this._names,u=this._sources,h=this._sourceMapURL,c=0,d=o.length;c=0){var o=this._originalMappings[s];if(e.column===void 0)for(var a=o.originalLine;o&&o.originalLine===a;)i.push({line:S.getArg(o,"generatedLine",null),column:S.getArg(o,"generatedColumn",null),lastColumn:S.getArg(o,"lastGeneratedColumn",null)}),o=this._originalMappings[++s];else for(var l=o.originalColumn;o&&o.originalLine===t&&o.originalColumn==l;)i.push({line:S.getArg(o,"generatedLine",null),column:S.getArg(o,"generatedColumn",null),lastColumn:S.getArg(o,"lastGeneratedColumn",null)}),o=this._originalMappings[++s]}return i};Vt.SourceMapConsumer=M;function H(n,e){var t=n;typeof n=="string"&&(t=S.parseSourceMapInput(n));var r=S.getArg(t,"version"),i=S.getArg(t,"sources"),s=S.getArg(t,"names",[]),o=S.getArg(t,"sourceRoot",null),a=S.getArg(t,"sourcesContent",null),l=S.getArg(t,"mappings"),f=S.getArg(t,"file",null);if(r!=this._version)throw new Error("Unsupported version: "+r);o&&(o=S.normalize(o)),i=i.map(String).map(S.normalize).map(function(u){return o&&S.isAbsolute(o)&&S.isAbsolute(u)?S.relative(o,u):u}),this._names=$e.fromArray(s.map(String),!0),this._sources=$e.fromArray(i,!0),this._absoluteSources=this._sources.toArray().map(function(u){return S.computeSourceURL(o,u,e)}),this.sourceRoot=o,this.sourcesContent=a,this._mappings=l,this._sourceMapURL=e,this.file=f}H.prototype=Object.create(M.prototype);H.prototype.consumer=M;H.prototype._findSourceIndex=function(n){var e=n;if(this.sourceRoot!=null&&(e=S.relative(this.sourceRoot,e)),this._sources.has(e))return this._sources.indexOf(e);var t;for(t=0;t0&&(n[e]=s,n[e+1]=i)}else if(r<20)for(let i=e;ie;s--){let o=n[s-1],a=n[s];if(Hr(o,a)<=0)break;n[s-1]=a,n[s]=o}else Et(n,Hr,e)}H.prototype._parseMappings=function(e,t){var r=1,i=0,s=0,o=0,a=0,l=0,f=e.length,u=0,h={},c={},d=[],m=[],p,_,v,C,I;let L=0;for(;u1&&(p.source=a+v[1],a+=v[1],p.originalLine=s+v[2],s=p.originalLine,p.originalLine+=1,p.originalColumn=o+v[3],o=p.originalColumn,v.length>4&&(p.name=l+v[4],l+=v[4])),m.push(p),typeof p.originalLine=="number"){let O=p.source;for(;d.length<=O;)d.push(null);d[O]===null&&(d[O]=[]),d[O].push(p)}}Ji(m,L),this.__generatedMappings=m;for(var R=0;R=0){var i=this._generatedMappings[r];if(i.generatedLine===t.generatedLine){var s=S.getArg(i,"source",null);s!==null&&(s=this._sources.at(s),s=S.computeSourceURL(this.sourceRoot,s,this._sourceMapURL));var o=S.getArg(i,"name",null);return o!==null&&(o=this._names.at(o)),{source:s,line:S.getArg(i,"originalLine",null),column:S.getArg(i,"originalColumn",null),name:o}}}return{source:null,line:null,column:null,name:null}};H.prototype.hasContentsOfAllSources=function(){return this.sourcesContent?this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some(function(e){return e==null}):!1};H.prototype.sourceContentFor=function(e,t){if(!this.sourcesContent)return null;var r=this._findSourceIndex(e);if(r>=0)return this.sourcesContent[r];var i=e;this.sourceRoot!=null&&(i=S.relative(this.sourceRoot,i));var s;if(this.sourceRoot!=null&&(s=S.urlParse(this.sourceRoot))){var o=i.replace(/^file:\/\//,"");if(s.scheme=="file"&&this._sources.has(o))return this.sourcesContent[this._sources.indexOf(o)];if((!s.path||s.path=="/")&&this._sources.has("/"+i))return this.sourcesContent[this._sources.indexOf("/"+i)]}if(t)return null;throw new Error('"'+i+'" is not in the SourceMap.')};H.prototype.generatedPositionFor=function(e){var t=S.getArg(e,"source");if(t=this._findSourceIndex(t),t<0)return{line:null,column:null,lastColumn:null};var r={source:t,originalLine:S.getArg(e,"line"),originalColumn:S.getArg(e,"column")},i=this._findMapping(r,this._originalMappings,"originalLine","originalColumn",S.compareByOriginalPositions,S.getArg(e,"bias",M.GREATEST_LOWER_BOUND));if(i>=0){var s=this._originalMappings[i];if(s.source===r.source)return{line:S.getArg(s,"generatedLine",null),column:S.getArg(s,"generatedColumn",null),lastColumn:S.getArg(s,"lastGeneratedColumn",null)}}return{line:null,column:null,lastColumn:null}};Vt.BasicSourceMapConsumer=H;function he(n,e){var t=n;typeof n=="string"&&(t=S.parseSourceMapInput(n));var r=S.getArg(t,"version"),i=S.getArg(t,"sections");if(r!=this._version)throw new Error("Unsupported version: "+r);this._sources=new $e,this._names=new $e;var s={line:-1,column:0};this._sections=i.map(function(o){if(o.url)throw new Error("Support for url field in sections not implemented.");var a=S.getArg(o,"offset"),l=S.getArg(a,"line"),f=S.getArg(a,"column");if(l{var af=$r().SourceMapGenerator,Ht=je(),ff=/(\r?\n)/,uf=10,Ve="$$$isSourceNode$$$";function Q(n,e,t,r,i){this.children=[],this.sourceContents={},this.line=n??null,this.column=e??null,this.source=t??null,this.name=i??null,this[Ve]=!0,r!=null&&this.add(r)}Q.fromStringWithSourceMap=function(e,t,r){var i=new Q,s=e.split(ff),o=0,a=function(){var c=m(),d=m()||"";return c+d;function m(){return o=0;t--)this.prepend(e[t]);else if(e[Ve]||typeof e=="string")this.children.unshift(e);else throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e);return this};Q.prototype.walk=function(e){for(var t,r=0,i=this.children.length;r0){for(t=[],r=0;r{Zt.SourceMapGenerator=$r().SourceMapGenerator;Zt.SourceMapConsumer=es().SourceMapConsumer;Zt.SourceNode=rs().SourceNode});var os=b((qh,ss)=>{"use strict";var{existsSync:cf,readFileSync:hf}=require("fs"),{dirname:Xr,join:df}=require("path"),{SourceMapConsumer:ns,SourceMapGenerator:is}=Yr();function pf(n){return Buffer?Buffer.from(n,"base64").toString():window.atob(n)}var wt=class{constructor(e,t){if(t.map===!1)return;this.loadAnnotation(e),this.inline=this.startWith(this.annotation,"data:");let r=t.map?t.map.prev:void 0,i=this.loadMap(t.from,r);!this.mapFile&&t.from&&(this.mapFile=t.from),this.mapFile&&(this.root=Xr(this.mapFile)),i&&(this.text=i)}consumer(){return this.consumerCache||(this.consumerCache=new ns(this.text)),this.consumerCache}decodeInline(e){let t=/^data:application\/json;charset=utf-?8;base64,/,r=/^data:application\/json;base64,/,i=/^data:application\/json;charset=utf-?8,/,s=/^data:application\/json,/,o=e.match(i)||e.match(s);if(o)return decodeURIComponent(e.substr(o[0].length));let a=e.match(t)||e.match(r);if(a)return pf(e.substr(a[0].length));let l=e.match(/data:application\/json;([^,]+),/)[1];throw new Error("Unsupported source map encoding "+l)}getAnnotationURL(e){return e.replace(/^\/\*\s*# sourceMappingURL=/,"").trim()}isMap(e){return typeof e!="object"?!1:typeof e.mappings=="string"||typeof e._mappings=="string"||Array.isArray(e.sections)}loadAnnotation(e){let t=e.match(/\/\*\s*# sourceMappingURL=/g);if(!t)return;let r=e.lastIndexOf(t.pop()),i=e.indexOf("*/",r);r>-1&&i>-1&&(this.annotation=this.getAnnotationURL(e.substring(r,i)))}loadFile(e){if(this.root=Xr(e),cf(e))return this.mapFile=e,hf(e,"utf-8").toString().trim()}loadMap(e,t){if(t===!1)return!1;if(t){if(typeof t=="string")return t;if(typeof t=="function"){let r=t(e);if(r){let i=this.loadFile(r);if(!i)throw new Error("Unable to load previous source map: "+r.toString());return i}}else{if(t instanceof ns)return is.fromSourceMap(t).toString();if(t instanceof is)return t.toString();if(this.isMap(t))return JSON.stringify(t);throw new Error("Unsupported previous source map format: "+t.toString())}}else{if(this.inline)return this.decodeInline(this.annotation);if(this.annotation){let r=this.annotation;return e&&(r=df(Xr(e),r)),this.loadFile(r)}}}startWith(e,t){return e?e.substr(0,t.length)===t:!1}withContent(){return!!(this.consumer().sourcesContent&&this.consumer().sourcesContent.length>0)}};ss.exports=wt;wt.default=wt});var hs=b((jh,cs)=>{"use strict";var{nanoid:mf}=Ri(),{isAbsolute:Qr,resolve:en}=require("path"),{SourceMapConsumer:gf,SourceMapGenerator:_f}=Yr(),{fileURLToPath:ls,pathToFileURL:Yt}=require("url"),as=Or(),Ef=os(),Kr=Lr(),Jr=Symbol("lineToIndexCache"),wf=!!(gf&&_f),fs=!!(en&&Qr);function us(n){if(n[Jr])return n[Jr];let e=n.css.split(` +`),t=new Array(e.length),r=0;for(let i=0,s=e.length;i"u"||typeof e=="object"&&!e.toString)throw new Error(`PostCSS received ${e} instead of CSS string`);if(this.css=e.toString(),this.css[0]==="\uFEFF"||this.css[0]==="\uFFFE"?(this.hasBOM=!0,this.css=this.css.slice(1)):this.hasBOM=!1,this.document=this.css,t.document&&(this.document=t.document.toString()),t.from&&(!fs||/^\w+:\/\//.test(t.from)||Qr(t.from)?this.file=t.from:this.file=en(t.from)),fs&&wf){let r=new Ef(this.css,t);if(r.text){this.map=r;let i=r.consumer().file;!this.file&&i&&(this.file=this.mapResolve(i))}}this.file||(this.id=""),this.map&&(this.map.file=this.from)}error(e,t,r,i={}){let s,o,a,l,f;if(t&&typeof t=="object"){let h=t,c=r;if(typeof h.offset=="number"){l=h.offset;let d=this.fromOffset(l);t=d.line,r=d.col}else t=h.line,r=h.column,l=this.fromLineAndColumn(t,r);if(typeof c.offset=="number"){a=c.offset;let d=this.fromOffset(a);o=d.line,s=d.col}else o=c.line,s=c.column,a=this.fromLineAndColumn(c.line,c.column)}else if(r)l=this.fromLineAndColumn(t,r);else{l=t;let h=this.fromOffset(l);t=h.line,r=h.col}let u=this.origin(t,r,o,s);return u?f=new as(e,u.endLine===void 0?u.line:{column:u.column,line:u.line},u.endLine===void 0?u.column:{column:u.endColumn,line:u.endLine},u.source,u.file,i.plugin):f=new as(e,o===void 0?t:{column:r,line:t},o===void 0?r:{column:s,line:o},this.css,this.file,i.plugin),f.input={column:r,endColumn:s,endLine:o,endOffset:a,line:t,offset:l,source:this.css},this.file&&(Yt&&(f.input.url=Yt(this.file).toString()),f.input.file=this.file),f}fromLineAndColumn(e,t){return us(this)[e-1]+t-1}fromOffset(e){let t=us(this),r=t[t.length-1],i=0;if(e>=r)i=t.length-1;else{let s=t.length-2,o;for(;i>1),e=t[o+1])i=o+1;else{i=o;break}}return{col:e-t[i]+1,line:i+1}}mapResolve(e){return/^\w+:\/\//.test(e)?e:en(this.map.consumer().sourceRoot||this.map.root||".",e)}origin(e,t,r,i){if(!this.map)return!1;let s=this.map.consumer(),o=s.originalPositionFor({column:t,line:e});if(!o.source)return!1;let a;typeof r=="number"&&(a=s.originalPositionFor({column:i,line:r}));let l;Qr(o.source)?l=Yt(o.source):l=new URL(o.source,this.map.consumer().sourceRoot||Yt(this.map.mapFile));let f={column:o.column,endColumn:a&&a.column,endLine:a&&a.line,line:o.line,url:l.toString()};if(l.protocol==="file:")if(ls)f.file=ls(l);else throw new Error("file: protocol is not available in this PostCSS build");let u=s.sourceContentFor(o.source);return u&&(f.source=u),f}toJSON(){let e={};for(let t of["hasBOM","css","file","id"])this[t]!=null&&(e[t]=this[t]);return this.map&&(e.map={...this.map},e.map.consumerCache&&(e.map.consumerCache=void 0)),e}};cs.exports=He;He.default=He;Kr&&Kr.registerInput&&Kr.registerInput(He)});var ms=b(($h,ps)=>{"use strict";var ds=mt(),Ze=class extends ds{constructor(e){super(e),this.type="atrule"}append(...e){return this.proxyOf.nodes||(this.nodes=[]),super.append(...e)}prepend(...e){return this.proxyOf.nodes||(this.nodes=[]),super.prepend(...e)}};ps.exports=Ze;Ze.default=Ze;ds.registerAtRule(Ze)});var ys=b((Vh,ws)=>{"use strict";var gs=mt(),_s,Es,Ce=class extends gs{constructor(e){super(e),this.type="root",this.nodes||(this.nodes=[])}normalize(e,t,r){let i=super.normalize(e);if(t){if(r==="prepend")this.nodes.length>1?t.raws.before=this.nodes[1].raws.before:delete t.raws.before;else if(this.first!==t)for(let s of i)s.raws.before=t.raws.before}return i}removeChild(e,t){let r=this.index(e);return!t&&r===0&&this.nodes.length>1&&(this.nodes[1].raws.before=this.nodes[r].raws.before),super.removeChild(e)}toResult(e={}){return new _s(new Es,this,e).stringify()}};Ce.registerLazyResult=n=>{_s=n};Ce.registerProcessor=n=>{Es=n};ws.exports=Ce;Ce.default=Ce;gs.registerRoot(Ce)});var vs=b((Hh,Ss)=>{"use strict";var yt={comma(n){return yt.split(n,[","],!0)},space(n){let e=[" ",` +`," "];return yt.split(n,e)},split(n,e,t){let r=[],i="",s=!1,o=0,a=!1,l="",f=!1;for(let u of n)f?f=!1:u==="\\"?f=!0:a?u===l&&(a=!1):u==='"'||u==="'"?(a=!0,l=u):u==="("?o+=1:u===")"?o>0&&(o-=1):o===0&&e.includes(u)&&(s=!0),s?(i!==""&&r.push(i.trim()),i="",s=!1):i+=u;return(t||i!=="")&&r.push(i.trim()),r}};Ss.exports=yt;yt.default=yt});var bs=b((Zh,Cs)=>{"use strict";var xs=mt(),yf=vs(),Ye=class extends xs{get selectors(){return yf.comma(this.selector)}set selectors(e){let t=this.selector?this.selector.match(/,\s*/):null,r=t?t[0]:","+this.raw("between","beforeOpen");this.selector=e.join(r)}constructor(e){super(e),this.type="rule",this.nodes||(this.nodes=[])}};Cs.exports=Ye;Ye.default=Ye;xs.registerRule(Ye)});var Ns=b((Yh,Is)=>{"use strict";var Sf=ms(),vf=Dr(),xf=Mr(),Cf=ys(),Ls=bs(),bf=br(),Os={empty:!0,space:!0};function Lf(n){for(let e=n.length-1;e>=0;e--){let t=n[e],r=t[3]||t[2];if(r)return r}}var tn=class{constructor(e){this.input=e,this.root=new Cf,this.current=this.root,this.spaces="",this.semicolon=!1,this.createTokenizer(),this.root.source={input:e,start:{column:1,line:1,offset:0}}}atrule(e){let t=new Sf;t.name=e[1].slice(1),t.name===""&&this.unnamedAtrule(t,e),this.init(t,e[2]);let r,i,s,o=!1,a=!1,l=[],f=[];for(;!this.tokenizer.endOfFile();){if(e=this.tokenizer.nextToken(),r=e[0],r==="("||r==="["?f.push(r==="("?")":"]"):r==="{"&&f.length>0?f.push("}"):r===f[f.length-1]&&f.pop(),f.length===0)if(r===";"){t.source.end=this.getPosition(e[2]),t.source.end.offset++,this.semicolon=!0;break}else if(r==="{"){a=!0;break}else if(r==="}"){if(l.length>0){for(s=l.length-1,i=l[s];i&&i[0]==="space";)i=l[--s];i&&(t.source.end=this.getPosition(i[3]||i[2]),t.source.end.offset++)}this.end(e);break}else l.push(e);else l.push(e);if(this.tokenizer.endOfFile()){o=!0;break}}t.raws.between=this.spacesAndCommentsFromEnd(l),l.length?(t.raws.afterName=this.spacesAndCommentsFromStart(l),this.raw(t,"params",l),o&&(e=l[l.length-1],t.source.end=this.getPosition(e[3]||e[2]),t.source.end.offset++,this.spaces=t.raws.between,t.raws.between="")):(t.raws.afterName="",t.params=""),a&&(t.nodes=[],this.current=t)}checkMissedSemicolon(e){let t=this.colon(e);if(t===!1)return;let r=0,i;for(let s=t-1;s>=0&&(i=e[s],!(i[0]!=="space"&&(r+=1,r===2)));s--);throw this.input.error("Missed semicolon",i[0]==="word"?i[3]+1:i[2])}colon(e){let t=0,r,i,s;for(let[o,a]of e.entries()){if(i=a,s=i[0],s==="("&&(t+=1),s===")"&&(t-=1),t===0&&s===":")if(!r)this.doubleColon(i);else{if(r[0]==="word"&&r[1]==="progid")continue;return o}r=i}return!1}comment(e){let t=new vf;this.init(t,e[2]),t.source.end=this.getPosition(e[3]||e[2]),t.source.end.offset++;let r=e[1].slice(2,-2);if(/^\s*$/.test(r))t.text="",t.raws.left=r,t.raws.right="";else{let i=r.match(/^(\s*)([^]*\S)(\s*)$/);t.text=i[2],t.raws.left=i[1],t.raws.right=i[3]}}createTokenizer(){this.tokenizer=bf(this.input)}decl(e,t){let r=new xf;this.init(r,e[0][2]);let i=e[e.length-1];for(i[0]===";"&&(this.semicolon=!0,e.pop()),r.source.end=this.getPosition(i[3]||i[2]||Lf(e)),r.source.end.offset++;e[0][0]!=="word";)e.length===1&&this.unknownWord(e),r.raws.before+=e.shift()[1];for(r.source.start=this.getPosition(e[0][2]),r.prop="";e.length;){let f=e[0][0];if(f===":"||f==="space"||f==="comment")break;r.prop+=e.shift()[1]}r.raws.between="";let s;for(;e.length;)if(s=e.shift(),s[0]===":"){r.raws.between+=s[1];break}else s[0]==="word"&&/\w/.test(s[1])&&this.unknownWord([s]),r.raws.between+=s[1];(r.prop[0]==="_"||r.prop[0]==="*")&&(r.raws.before+=r.prop[0],r.prop=r.prop.slice(1));let o=[],a;for(;e.length&&(a=e[0][0],!(a!=="space"&&a!=="comment"));)o.push(e.shift());this.precheckMissedSemicolon(e);for(let f=e.length-1;f>=0;f--){if(s=e[f],s[1].toLowerCase()==="!important"){r.important=!0;let u=this.stringFrom(e,f);u=this.spacesFromEnd(e)+u,u!==" !important"&&(r.raws.important=u);break}else if(s[1].toLowerCase()==="important"){let u=e.slice(0),h="";for(let c=f;c>0;c--){let d=u[c][0];if(h.trim().startsWith("!")&&d!=="space")break;h=u.pop()[1]+h}h.trim().startsWith("!")&&(r.important=!0,r.raws.important=h,e=u)}if(s[0]!=="space"&&s[0]!=="comment")break}e.some(f=>f[0]!=="space"&&f[0]!=="comment")&&(r.raws.between+=o.map(f=>f[1]).join(""),o=[]),this.raw(r,"value",o.concat(e),t),r.value.includes(":")&&!t&&this.checkMissedSemicolon(e)}doubleColon(e){throw this.input.error("Double colon",{offset:e[2]},{offset:e[2]+e[1].length})}emptyRule(e){let t=new Ls;this.init(t,e[2]),t.selector="",t.raws.between="",this.current=t}end(e){this.current.nodes&&this.current.nodes.length&&(this.current.raws.semicolon=this.semicolon),this.semicolon=!1,this.current.raws.after=(this.current.raws.after||"")+this.spaces,this.spaces="",this.current.parent?(this.current.source.end=this.getPosition(e[2]),this.current.source.end.offset++,this.current=this.current.parent):this.unexpectedClose(e)}endFile(){this.current.parent&&this.unclosedBlock(),this.current.nodes&&this.current.nodes.length&&(this.current.raws.semicolon=this.semicolon),this.current.raws.after=(this.current.raws.after||"")+this.spaces,this.root.source.end=this.getPosition(this.tokenizer.position())}freeSemicolon(e){if(this.spaces+=e[1],this.current.nodes){let t=this.current.nodes[this.current.nodes.length-1];t&&t.type==="rule"&&!t.raws.ownSemicolon&&(t.raws.ownSemicolon=this.spaces,this.spaces="",t.source.end=this.getPosition(e[2]),t.source.end.offset+=t.raws.ownSemicolon.length)}}getPosition(e){let t=this.input.fromOffset(e);return{column:t.col,line:t.line,offset:e}}init(e,t){this.current.push(e),e.source={input:this.input,start:this.getPosition(t)},e.raws.before=this.spaces,this.spaces="",e.type!=="comment"&&(this.semicolon=!1)}other(e){let t=!1,r=null,i=!1,s=null,o=[],a=e[1].startsWith("--"),l=[],f=e;for(;f;){if(r=f[0],l.push(f),r==="("||r==="[")s||(s=f),o.push(r==="("?")":"]");else if(a&&i&&r==="{")s||(s=f),o.push("}");else if(o.length===0)if(r===";")if(i){this.decl(l,a);return}else break;else if(r==="{"){this.rule(l);return}else if(r==="}"){this.tokenizer.back(l.pop()),t=!0;break}else r===":"&&(i=!0);else r===o[o.length-1]&&(o.pop(),o.length===0&&(s=null));f=this.tokenizer.nextToken()}if(this.tokenizer.endOfFile()&&(t=!0),o.length>0&&this.unclosedBracket(s),t&&i){if(!a)for(;l.length&&(f=l[l.length-1][0],!(f!=="space"&&f!=="comment"));)this.tokenizer.back(l.pop());this.decl(l,a)}else this.unknownWord(l)}parse(){let e;for(;!this.tokenizer.endOfFile();)switch(e=this.tokenizer.nextToken(),e[0]){case"space":this.spaces+=e[1];break;case";":this.freeSemicolon(e);break;case"}":this.end(e);break;case"comment":this.comment(e);break;case"at-word":this.atrule(e);break;case"{":this.emptyRule(e);break;default:this.other(e);break}this.endFile()}precheckMissedSemicolon(){}raw(e,t,r,i){let s,o,a=r.length,l="",f=!0,u,h;for(let c=0;cd+m[1],"");e.raws[t]={raw:c,value:l}}e[t]=l}rule(e){e.pop();let t=new Ls;this.init(t,e[0][2]),t.raws.between=this.spacesAndCommentsFromEnd(e),this.raw(t,"selector",e),this.current=t}spacesAndCommentsFromEnd(e){let t,r="";for(;e.length&&(t=e[e.length-1][0],!(t!=="space"&&t!=="comment"));)r=e.pop()[1]+r;return r}spacesAndCommentsFromStart(e){let t,r="";for(;e.length&&(t=e[0][0],!(t!=="space"&&t!=="comment"));)r+=e.shift()[1];return r}spacesFromEnd(e){let t,r="";for(;e.length&&(t=e[e.length-1][0],t==="space");)r=e.pop()[1]+r;return r}stringFrom(e,t){let r="";for(let i=t;i{"use strict";var Of=mt(),If=hs(),Nf=Ns();function Xt(n,e){let t=new If(n,e),r=new Nf(t);try{r.parse()}catch(i){throw process.env.NODE_ENV!=="production"&&i.name==="CssSyntaxError"&&e&&e.from&&(/\.scss$/i.test(e.from)?i.message+=` +You tried to parse SCSS with the standard CSS parser; try again with the postcss-scss parser`:/\.sass/i.test(e.from)?i.message+=` +You tried to parse Sass with the standard CSS parser; try again with the postcss-sass parser`:/\.less$/i.test(e.from)&&(i.message+=` +You tried to parse Less with the standard CSS parser; try again with the postcss-less parser`)),i}return r.root}Ts.exports=Xt;Xt.default=Xt;Of.registerParse(Xt)});var we=b((Kh,Ms)=>{"use strict";var As=["nodebuffer","arraybuffer","fragments"],Ds=typeof Blob<"u";Ds&&As.push("blob");Ms.exports={BINARY_TYPES:As,EMPTY_BUFFER:Buffer.alloc(0),GUID:"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",hasBlob:Ds,kForOnEventAttribute:Symbol("kIsForOnEventAttribute"),kListener:Symbol("kListener"),kStatusCode:Symbol("status-code"),kWebSocket:Symbol("websocket"),NOOP:()=>{}}});var St=b((Jh,Kt)=>{"use strict";var{EMPTY_BUFFER:Tf}=we(),rn=Buffer[Symbol.species];function Rf(n,e){if(n.length===0)return Tf;if(n.length===1)return n[0];let t=Buffer.allocUnsafe(e),r=0;for(let i=0;i{"use strict";var Us=Symbol("kDone"),sn=Symbol("kRun"),on=class{constructor(e){this[Us]=()=>{this.pending--,this[sn]()},this.concurrency=e||1/0,this.jobs=[],this.pending=0}add(e){this.jobs.push(e),this[sn]()}[sn](){if(this.pending!==this.concurrency&&this.jobs.length){let e=this.jobs.shift();this.pending++,e(this[Us])}}};ks.exports=on});var xt=b((ed,qs)=>{"use strict";var vt=require("zlib"),zs=St(),Df=Bs(),{kStatusCode:Gs}=we(),Mf=Buffer[Symbol.species],Pf=Buffer.from([0,0,255,255]),Qt=Symbol("permessage-deflate"),ye=Symbol("total-length"),Xe=Symbol("callback"),be=Symbol("buffers"),Ke=Symbol("error"),Jt,ln=class{constructor(e,t,r){if(this._maxPayload=r|0,this._options=e||{},this._threshold=this._options.threshold!==void 0?this._options.threshold:1024,this._isServer=!!t,this._deflate=null,this._inflate=null,this.params=null,!Jt){let i=this._options.concurrencyLimit!==void 0?this._options.concurrencyLimit:10;Jt=new Df(i)}}static get extensionName(){return"permessage-deflate"}offer(){let e={};return this._options.serverNoContextTakeover&&(e.server_no_context_takeover=!0),this._options.clientNoContextTakeover&&(e.client_no_context_takeover=!0),this._options.serverMaxWindowBits&&(e.server_max_window_bits=this._options.serverMaxWindowBits),this._options.clientMaxWindowBits?e.client_max_window_bits=this._options.clientMaxWindowBits:this._options.clientMaxWindowBits==null&&(e.client_max_window_bits=!0),e}accept(e){return e=this.normalizeParams(e),this.params=this._isServer?this.acceptAsServer(e):this.acceptAsClient(e),this.params}cleanup(){if(this._inflate&&(this._inflate.close(),this._inflate=null),this._deflate){let e=this._deflate[Xe];this._deflate.close(),this._deflate=null,e&&e(new Error("The deflate stream was closed while data was being processed"))}}acceptAsServer(e){let t=this._options,r=e.find(i=>!(t.serverNoContextTakeover===!1&&i.server_no_context_takeover||i.server_max_window_bits&&(t.serverMaxWindowBits===!1||typeof t.serverMaxWindowBits=="number"&&t.serverMaxWindowBits>i.server_max_window_bits)||typeof t.clientMaxWindowBits=="number"&&!i.client_max_window_bits));if(!r)throw new Error("None of the extension offers can be accepted");return t.serverNoContextTakeover&&(r.server_no_context_takeover=!0),t.clientNoContextTakeover&&(r.client_no_context_takeover=!0),typeof t.serverMaxWindowBits=="number"&&(r.server_max_window_bits=t.serverMaxWindowBits),typeof t.clientMaxWindowBits=="number"?r.client_max_window_bits=t.clientMaxWindowBits:(r.client_max_window_bits===!0||t.clientMaxWindowBits===!1)&&delete r.client_max_window_bits,r}acceptAsClient(e){let t=e[0];if(this._options.clientNoContextTakeover===!1&&t.client_no_context_takeover)throw new Error('Unexpected parameter "client_no_context_takeover"');if(!t.client_max_window_bits)typeof this._options.clientMaxWindowBits=="number"&&(t.client_max_window_bits=this._options.clientMaxWindowBits);else if(this._options.clientMaxWindowBits===!1||typeof this._options.clientMaxWindowBits=="number"&&t.client_max_window_bits>this._options.clientMaxWindowBits)throw new Error('Unexpected or invalid parameter "client_max_window_bits"');return t}normalizeParams(e){return e.forEach(t=>{Object.keys(t).forEach(r=>{let i=t[r];if(i.length>1)throw new Error(`Parameter "${r}" must have only a single value`);if(i=i[0],r==="client_max_window_bits"){if(i!==!0){let s=+i;if(!Number.isInteger(s)||s<8||s>15)throw new TypeError(`Invalid value for parameter "${r}": ${i}`);i=s}else if(!this._isServer)throw new TypeError(`Invalid value for parameter "${r}": ${i}`)}else if(r==="server_max_window_bits"){let s=+i;if(!Number.isInteger(s)||s<8||s>15)throw new TypeError(`Invalid value for parameter "${r}": ${i}`);i=s}else if(r==="client_no_context_takeover"||r==="server_no_context_takeover"){if(i!==!0)throw new TypeError(`Invalid value for parameter "${r}": ${i}`)}else throw new Error(`Unknown parameter "${r}"`);t[r]=i})}),e}decompress(e,t,r){Jt.add(i=>{this._decompress(e,t,(s,o)=>{i(),r(s,o)})})}compress(e,t,r){Jt.add(i=>{this._compress(e,t,(s,o)=>{i(),r(s,o)})})}_decompress(e,t,r){let i=this._isServer?"client":"server";if(!this._inflate){let s=`${i}_max_window_bits`,o=typeof this.params[s]!="number"?vt.Z_DEFAULT_WINDOWBITS:this.params[s];this._inflate=vt.createInflateRaw({...this._options.zlibInflateOptions,windowBits:o}),this._inflate[Qt]=this,this._inflate[ye]=0,this._inflate[be]=[],this._inflate.on("error",Uf),this._inflate.on("data",Ws)}this._inflate[Xe]=r,this._inflate.write(e),t&&this._inflate.write(Pf),this._inflate.flush(()=>{let s=this._inflate[Ke];if(s){this._inflate.close(),this._inflate=null,r(s);return}let o=zs.concat(this._inflate[be],this._inflate[ye]);this._inflate._readableState.endEmitted?(this._inflate.close(),this._inflate=null):(this._inflate[ye]=0,this._inflate[be]=[],t&&this.params[`${i}_no_context_takeover`]&&this._inflate.reset()),r(null,o)})}_compress(e,t,r){let i=this._isServer?"server":"client";if(!this._deflate){let s=`${i}_max_window_bits`,o=typeof this.params[s]!="number"?vt.Z_DEFAULT_WINDOWBITS:this.params[s];this._deflate=vt.createDeflateRaw({...this._options.zlibDeflateOptions,windowBits:o}),this._deflate[ye]=0,this._deflate[be]=[],this._deflate.on("data",Ff)}this._deflate[Xe]=r,this._deflate.write(e),this._deflate.flush(vt.Z_SYNC_FLUSH,()=>{if(!this._deflate)return;let s=zs.concat(this._deflate[be],this._deflate[ye]);t&&(s=new Mf(s.buffer,s.byteOffset,s.length-4)),this._deflate[Xe]=null,this._deflate[ye]=0,this._deflate[be]=[],t&&this.params[`${i}_no_context_takeover`]&&this._deflate.reset(),r(null,s)})}};qs.exports=ln;function Ff(n){this[be].push(n),this[ye]+=n.length}function Ws(n){if(this[ye]+=n.length,this[Qt]._maxPayload<1||this[ye]<=this[Qt]._maxPayload){this[be].push(n);return}this[Ke]=new RangeError("Max payload size exceeded"),this[Ke].code="WS_ERR_UNSUPPORTED_MESSAGE_LENGTH",this[Ke][Gs]=1009,this.removeListener("data",Ws),this.reset()}function Uf(n){if(this[Qt]._inflate=null,this[Ke]){this[Xe](this[Ke]);return}n[Gs]=1007,this[Xe](n)}});var Je=b((td,er)=>{"use strict";var{isUtf8:js}=require("buffer"),{hasBlob:kf}=we(),Bf=[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,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0];function zf(n){return n>=1e3&&n<=1014&&n!==1004&&n!==1005&&n!==1006||n>=3e3&&n<=4999}function an(n){let e=n.length,t=0;for(;t=e||(n[t+1]&192)!==128||(n[t+2]&192)!==128||n[t]===224&&(n[t+1]&224)===128||n[t]===237&&(n[t+1]&224)===160)return!1;t+=3}else if((n[t]&248)===240){if(t+3>=e||(n[t+1]&192)!==128||(n[t+2]&192)!==128||(n[t+3]&192)!==128||n[t]===240&&(n[t+1]&240)===128||n[t]===244&&n[t+1]>143||n[t]>244)return!1;t+=4}else return!1;return!0}function Gf(n){return kf&&typeof n=="object"&&typeof n.arrayBuffer=="function"&&typeof n.type=="string"&&typeof n.stream=="function"&&(n[Symbol.toStringTag]==="Blob"||n[Symbol.toStringTag]==="File")}er.exports={isBlob:Gf,isValidStatusCode:zf,isValidUTF8:an,tokenChars:Bf};if(js)er.exports.isValidUTF8=function(n){return n.length<24?an(n):js(n)};else if(!process.env.WS_NO_UTF_8_VALIDATE)try{let n=require("utf-8-validate");er.exports.isValidUTF8=function(e){return e.length<32?an(e):n(e)}}catch{}});var dn=b((rd,Ks)=>{"use strict";var{Writable:Wf}=require("stream"),$s=xt(),{BINARY_TYPES:qf,EMPTY_BUFFER:Vs,kStatusCode:jf,kWebSocket:$f}=we(),{concat:fn,toArrayBuffer:Vf,unmask:Hf}=St(),{isValidStatusCode:Zf,isValidUTF8:Hs}=Je(),tr=Buffer[Symbol.species],ne=0,Zs=1,Ys=2,Xs=3,un=4,cn=5,rr=6,hn=class extends Wf{constructor(e={}){super(),this._allowSynchronousEvents=e.allowSynchronousEvents!==void 0?e.allowSynchronousEvents:!0,this._binaryType=e.binaryType||qf[0],this._extensions=e.extensions||{},this._isServer=!!e.isServer,this._maxPayload=e.maxPayload|0,this._skipUTF8Validation=!!e.skipUTF8Validation,this[$f]=void 0,this._bufferedBytes=0,this._buffers=[],this._compressed=!1,this._payloadLength=0,this._mask=void 0,this._fragmented=0,this._masked=!1,this._fin=!1,this._opcode=0,this._totalPayloadLength=0,this._messageLength=0,this._fragments=[],this._errored=!1,this._loop=!1,this._state=ne}_write(e,t,r){if(this._opcode===8&&this._state==ne)return r();this._bufferedBytes+=e.length,this._buffers.push(e),this.startLoop(r)}consume(e){if(this._bufferedBytes-=e,e===this._buffers[0].length)return this._buffers.shift();if(e=r.length?t.set(this._buffers.shift(),i):(t.set(new Uint8Array(r.buffer,r.byteOffset,e),i),this._buffers[0]=new tr(r.buffer,r.byteOffset+e,r.length-e)),e-=r.length}while(e>0);return t}startLoop(e){this._loop=!0;do switch(this._state){case ne:this.getInfo(e);break;case Zs:this.getPayloadLength16(e);break;case Ys:this.getPayloadLength64(e);break;case Xs:this.getMask();break;case un:this.getData(e);break;case cn:case rr:this._loop=!1;return}while(this._loop);this._errored||e()}getInfo(e){if(this._bufferedBytes<2){this._loop=!1;return}let t=this.consume(2);if((t[0]&48)!==0){let i=this.createError(RangeError,"RSV2 and RSV3 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_2_3");e(i);return}let r=(t[0]&64)===64;if(r&&!this._extensions[$s.extensionName]){let i=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");e(i);return}if(this._fin=(t[0]&128)===128,this._opcode=t[0]&15,this._payloadLength=t[1]&127,this._opcode===0){if(r){let i=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");e(i);return}if(!this._fragmented){let i=this.createError(RangeError,"invalid opcode 0",!0,1002,"WS_ERR_INVALID_OPCODE");e(i);return}this._opcode=this._fragmented}else if(this._opcode===1||this._opcode===2){if(this._fragmented){let i=this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,"WS_ERR_INVALID_OPCODE");e(i);return}this._compressed=r}else if(this._opcode>7&&this._opcode<11){if(!this._fin){let i=this.createError(RangeError,"FIN must be set",!0,1002,"WS_ERR_EXPECTED_FIN");e(i);return}if(r){let i=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");e(i);return}if(this._payloadLength>125||this._opcode===8&&this._payloadLength===1){let i=this.createError(RangeError,`invalid payload length ${this._payloadLength}`,!0,1002,"WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH");e(i);return}}else{let i=this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,"WS_ERR_INVALID_OPCODE");e(i);return}if(!this._fin&&!this._fragmented&&(this._fragmented=this._opcode),this._masked=(t[1]&128)===128,this._isServer){if(!this._masked){let i=this.createError(RangeError,"MASK must be set",!0,1002,"WS_ERR_EXPECTED_MASK");e(i);return}}else if(this._masked){let i=this.createError(RangeError,"MASK must be clear",!0,1002,"WS_ERR_UNEXPECTED_MASK");e(i);return}this._payloadLength===126?this._state=Zs:this._payloadLength===127?this._state=Ys:this.haveLength(e)}getPayloadLength16(e){if(this._bufferedBytes<2){this._loop=!1;return}this._payloadLength=this.consume(2).readUInt16BE(0),this.haveLength(e)}getPayloadLength64(e){if(this._bufferedBytes<8){this._loop=!1;return}let t=this.consume(8),r=t.readUInt32BE(0);if(r>Math.pow(2,21)-1){let i=this.createError(RangeError,"Unsupported WebSocket frame: payload length > 2^53 - 1",!1,1009,"WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH");e(i);return}this._payloadLength=r*Math.pow(2,32)+t.readUInt32BE(4),this.haveLength(e)}haveLength(e){if(this._payloadLength&&this._opcode<8&&(this._totalPayloadLength+=this._payloadLength,this._totalPayloadLength>this._maxPayload&&this._maxPayload>0)){let t=this.createError(RangeError,"Max payload size exceeded",!1,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH");e(t);return}this._masked?this._state=Xs:this._state=un}getMask(){if(this._bufferedBytes<4){this._loop=!1;return}this._mask=this.consume(4),this._state=un}getData(e){let t=Vs;if(this._payloadLength){if(this._bufferedBytes7){this.controlMessage(t,e);return}if(this._compressed){this._state=cn,this.decompress(t,e);return}t.length&&(this._messageLength=this._totalPayloadLength,this._fragments.push(t)),this.dataMessage(e)}decompress(e,t){this._extensions[$s.extensionName].decompress(e,this._fin,(i,s)=>{if(i)return t(i);if(s.length){if(this._messageLength+=s.length,this._messageLength>this._maxPayload&&this._maxPayload>0){let o=this.createError(RangeError,"Max payload size exceeded",!1,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH");t(o);return}this._fragments.push(s)}this.dataMessage(t),this._state===ne&&this.startLoop(t)})}dataMessage(e){if(!this._fin){this._state=ne;return}let t=this._messageLength,r=this._fragments;if(this._totalPayloadLength=0,this._messageLength=0,this._fragmented=0,this._fragments=[],this._opcode===2){let i;this._binaryType==="nodebuffer"?i=fn(r,t):this._binaryType==="arraybuffer"?i=Vf(fn(r,t)):this._binaryType==="blob"?i=new Blob(r):i=r,this._allowSynchronousEvents?(this.emit("message",i,!0),this._state=ne):(this._state=rr,setImmediate(()=>{this.emit("message",i,!0),this._state=ne,this.startLoop(e)}))}else{let i=fn(r,t);if(!this._skipUTF8Validation&&!Hs(i)){let s=this.createError(Error,"invalid UTF-8 sequence",!0,1007,"WS_ERR_INVALID_UTF8");e(s);return}this._state===cn||this._allowSynchronousEvents?(this.emit("message",i,!1),this._state=ne):(this._state=rr,setImmediate(()=>{this.emit("message",i,!1),this._state=ne,this.startLoop(e)}))}}controlMessage(e,t){if(this._opcode===8){if(e.length===0)this._loop=!1,this.emit("conclude",1005,Vs),this.end();else{let r=e.readUInt16BE(0);if(!Zf(r)){let s=this.createError(RangeError,`invalid status code ${r}`,!0,1002,"WS_ERR_INVALID_CLOSE_CODE");t(s);return}let i=new tr(e.buffer,e.byteOffset+2,e.length-2);if(!this._skipUTF8Validation&&!Hs(i)){let s=this.createError(Error,"invalid UTF-8 sequence",!0,1007,"WS_ERR_INVALID_UTF8");t(s);return}this._loop=!1,this.emit("conclude",r,i),this.end()}this._state=ne;return}this._allowSynchronousEvents?(this.emit(this._opcode===9?"ping":"pong",e),this._state=ne):(this._state=rr,setImmediate(()=>{this.emit(this._opcode===9?"ping":"pong",e),this._state=ne,this.startLoop(t)}))}createError(e,t,r,i,s){this._loop=!1,this._errored=!0;let o=new e(r?`Invalid WebSocket frame: ${t}`:t);return Error.captureStackTrace(o,this.createError),o.code=s,o[jf]=i,o}};Ks.exports=hn});var gn=b((id,eo)=>{"use strict";var{Duplex:nd}=require("stream"),{randomFillSync:Yf}=require("crypto"),Js=xt(),{EMPTY_BUFFER:Xf,kWebSocket:Kf,NOOP:Jf}=we(),{isBlob:Qe,isValidStatusCode:Qf}=Je(),{mask:Qs,toBuffer:Ue}=St(),ie=Symbol("kByteLength"),eu=Buffer.alloc(4),nr=8*1024,ke,et=nr,de=0,tu=1,ru=2,pn=class n{constructor(e,t,r){this._extensions=t||{},r&&(this._generateMask=r,this._maskBuffer=Buffer.alloc(4)),this._socket=e,this._firstFragment=!0,this._compress=!1,this._bufferedBytes=0,this._queue=[],this._state=de,this.onerror=Jf,this[Kf]=void 0}static frame(e,t){let r,i=!1,s=2,o=!1;t.mask&&(r=t.maskBuffer||eu,t.generateMask?t.generateMask(r):(et===nr&&(ke===void 0&&(ke=Buffer.alloc(nr)),Yf(ke,0,nr),et=0),r[0]=ke[et++],r[1]=ke[et++],r[2]=ke[et++],r[3]=ke[et++]),o=(r[0]|r[1]|r[2]|r[3])===0,s=6);let a;typeof e=="string"?(!t.mask||o)&&t[ie]!==void 0?a=t[ie]:(e=Buffer.from(e),a=e.length):(a=e.length,i=t.mask&&t.readOnly&&!o);let l=a;a>=65536?(s+=8,l=127):a>125&&(s+=2,l=126);let f=Buffer.allocUnsafe(i?a+s:s);return f[0]=t.fin?t.opcode|128:t.opcode,t.rsv1&&(f[0]|=64),f[1]=l,l===126?f.writeUInt16BE(a,2):l===127&&(f[2]=f[3]=0,f.writeUIntBE(a,4,6)),t.mask?(f[1]|=128,f[s-4]=r[0],f[s-3]=r[1],f[s-2]=r[2],f[s-1]=r[3],o?[f,e]:i?(Qs(e,r,f,s,a),[f]):(Qs(e,r,e,0,a),[f,e])):[f,e]}close(e,t,r,i){let s;if(e===void 0)s=Xf;else{if(typeof e!="number"||!Qf(e))throw new TypeError("First argument must be a valid error code number");if(t===void 0||!t.length)s=Buffer.allocUnsafe(2),s.writeUInt16BE(e,0);else{let a=Buffer.byteLength(t);if(a>123)throw new RangeError("The message must not be greater than 123 bytes");s=Buffer.allocUnsafe(2+a),s.writeUInt16BE(e,0),typeof t=="string"?s.write(t,2):s.set(t,2)}}let o={[ie]:s.length,fin:!0,generateMask:this._generateMask,mask:r,maskBuffer:this._maskBuffer,opcode:8,readOnly:!1,rsv1:!1};this._state!==de?this.enqueue([this.dispatch,s,!1,o,i]):this.sendFrame(n.frame(s,o),i)}ping(e,t,r){let i,s;if(typeof e=="string"?(i=Buffer.byteLength(e),s=!1):Qe(e)?(i=e.size,s=!1):(e=Ue(e),i=e.length,s=Ue.readOnly),i>125)throw new RangeError("The data size must not be greater than 125 bytes");let o={[ie]:i,fin:!0,generateMask:this._generateMask,mask:t,maskBuffer:this._maskBuffer,opcode:9,readOnly:s,rsv1:!1};Qe(e)?this._state!==de?this.enqueue([this.getBlobData,e,!1,o,r]):this.getBlobData(e,!1,o,r):this._state!==de?this.enqueue([this.dispatch,e,!1,o,r]):this.sendFrame(n.frame(e,o),r)}pong(e,t,r){let i,s;if(typeof e=="string"?(i=Buffer.byteLength(e),s=!1):Qe(e)?(i=e.size,s=!1):(e=Ue(e),i=e.length,s=Ue.readOnly),i>125)throw new RangeError("The data size must not be greater than 125 bytes");let o={[ie]:i,fin:!0,generateMask:this._generateMask,mask:t,maskBuffer:this._maskBuffer,opcode:10,readOnly:s,rsv1:!1};Qe(e)?this._state!==de?this.enqueue([this.getBlobData,e,!1,o,r]):this.getBlobData(e,!1,o,r):this._state!==de?this.enqueue([this.dispatch,e,!1,o,r]):this.sendFrame(n.frame(e,o),r)}send(e,t,r){let i=this._extensions[Js.extensionName],s=t.binary?2:1,o=t.compress,a,l;typeof e=="string"?(a=Buffer.byteLength(e),l=!1):Qe(e)?(a=e.size,l=!1):(e=Ue(e),a=e.length,l=Ue.readOnly),this._firstFragment?(this._firstFragment=!1,o&&i&&i.params[i._isServer?"server_no_context_takeover":"client_no_context_takeover"]&&(o=a>=i._threshold),this._compress=o):(o=!1,s=0),t.fin&&(this._firstFragment=!0);let f={[ie]:a,fin:t.fin,generateMask:this._generateMask,mask:t.mask,maskBuffer:this._maskBuffer,opcode:s,readOnly:l,rsv1:o};Qe(e)?this._state!==de?this.enqueue([this.getBlobData,e,this._compress,f,r]):this.getBlobData(e,this._compress,f,r):this._state!==de?this.enqueue([this.dispatch,e,this._compress,f,r]):this.dispatch(e,this._compress,f,r)}getBlobData(e,t,r,i){this._bufferedBytes+=r[ie],this._state=ru,e.arrayBuffer().then(s=>{if(this._socket.destroyed){let a=new Error("The socket was closed while the blob was being read");process.nextTick(mn,this,a,i);return}this._bufferedBytes-=r[ie];let o=Ue(s);t?this.dispatch(o,t,r,i):(this._state=de,this.sendFrame(n.frame(o,r),i),this.dequeue())}).catch(s=>{process.nextTick(nu,this,s,i)})}dispatch(e,t,r,i){if(!t){this.sendFrame(n.frame(e,r),i);return}let s=this._extensions[Js.extensionName];this._bufferedBytes+=r[ie],this._state=tu,s.compress(e,r.fin,(o,a)=>{if(this._socket.destroyed){let l=new Error("The socket was closed while data was being compressed");mn(this,l,i);return}this._bufferedBytes-=r[ie],this._state=de,r.readOnly=!1,this.sendFrame(n.frame(a,r),i),this.dequeue()})}dequeue(){for(;this._state===de&&this._queue.length;){let e=this._queue.shift();this._bufferedBytes-=e[3][ie],Reflect.apply(e[0],this,e.slice(1))}}enqueue(e){this._bufferedBytes+=e[3][ie],this._queue.push(e)}sendFrame(e,t){e.length===2?(this._socket.cork(),this._socket.write(e[0]),this._socket.write(e[1],t),this._socket.uncork()):this._socket.write(e[0],t)}};eo.exports=pn;function mn(n,e,t){typeof t=="function"&&t(e);for(let r=0;r{"use strict";var{kForOnEventAttribute:Ct,kListener:_n}=we(),to=Symbol("kCode"),ro=Symbol("kData"),no=Symbol("kError"),io=Symbol("kMessage"),so=Symbol("kReason"),tt=Symbol("kTarget"),oo=Symbol("kType"),lo=Symbol("kWasClean"),Se=class{constructor(e){this[tt]=null,this[oo]=e}get target(){return this[tt]}get type(){return this[oo]}};Object.defineProperty(Se.prototype,"target",{enumerable:!0});Object.defineProperty(Se.prototype,"type",{enumerable:!0});var Be=class extends Se{constructor(e,t={}){super(e),this[to]=t.code===void 0?0:t.code,this[so]=t.reason===void 0?"":t.reason,this[lo]=t.wasClean===void 0?!1:t.wasClean}get code(){return this[to]}get reason(){return this[so]}get wasClean(){return this[lo]}};Object.defineProperty(Be.prototype,"code",{enumerable:!0});Object.defineProperty(Be.prototype,"reason",{enumerable:!0});Object.defineProperty(Be.prototype,"wasClean",{enumerable:!0});var rt=class extends Se{constructor(e,t={}){super(e),this[no]=t.error===void 0?null:t.error,this[io]=t.message===void 0?"":t.message}get error(){return this[no]}get message(){return this[io]}};Object.defineProperty(rt.prototype,"error",{enumerable:!0});Object.defineProperty(rt.prototype,"message",{enumerable:!0});var bt=class extends Se{constructor(e,t={}){super(e),this[ro]=t.data===void 0?null:t.data}get data(){return this[ro]}};Object.defineProperty(bt.prototype,"data",{enumerable:!0});var iu={addEventListener(n,e,t={}){for(let i of this.listeners(n))if(!t[Ct]&&i[_n]===e&&!i[Ct])return;let r;if(n==="message")r=function(s,o){let a=new bt("message",{data:o?s:s.toString()});a[tt]=this,ir(e,this,a)};else if(n==="close")r=function(s,o){let a=new Be("close",{code:s,reason:o.toString(),wasClean:this._closeFrameReceived&&this._closeFrameSent});a[tt]=this,ir(e,this,a)};else if(n==="error")r=function(s){let o=new rt("error",{error:s,message:s.message});o[tt]=this,ir(e,this,o)};else if(n==="open")r=function(){let s=new Se("open");s[tt]=this,ir(e,this,s)};else return;r[Ct]=!!t[Ct],r[_n]=e,t.once?this.once(n,r):this.on(n,r)},removeEventListener(n,e){for(let t of this.listeners(n))if(t[_n]===e&&!t[Ct]){this.removeListener(n,t);break}}};ao.exports={CloseEvent:Be,ErrorEvent:rt,Event:Se,EventTarget:iu,MessageEvent:bt};function ir(n,e,t){typeof n=="object"&&n.handleEvent?n.handleEvent.call(n,t):n.call(e,t)}});var En=b((od,uo)=>{"use strict";var{tokenChars:Lt}=Je();function me(n,e,t){n[e]===void 0?n[e]=[t]:n[e].push(t)}function su(n){let e=Object.create(null),t=Object.create(null),r=!1,i=!1,s=!1,o,a,l=-1,f=-1,u=-1,h=0;for(;h{let t=n[e];return Array.isArray(t)||(t=[t]),t.map(r=>[e].concat(Object.keys(r).map(i=>{let s=r[i];return Array.isArray(s)||(s=[s]),s.map(o=>o===!0?i:`${i}=${o}`).join("; ")})).join("; ")).join(", ")}).join(", ")}uo.exports={format:ou,parse:su}});var ar=b((fd,xo)=>{"use strict";var lu=require("events"),au=require("https"),fu=require("http"),po=require("net"),uu=require("tls"),{randomBytes:cu,createHash:hu}=require("crypto"),{Duplex:ld,Readable:ad}=require("stream"),{URL:wn}=require("url"),Le=xt(),du=dn(),pu=gn(),{isBlob:mu}=Je(),{BINARY_TYPES:co,EMPTY_BUFFER:sr,GUID:gu,kForOnEventAttribute:yn,kListener:_u,kStatusCode:Eu,kWebSocket:V,NOOP:mo}=we(),{EventTarget:{addEventListener:wu,removeEventListener:yu}}=fo(),{format:Su,parse:vu}=En(),{toBuffer:xu}=St(),Cu=30*1e3,go=Symbol("kAborted"),Sn=[8,13],ve=["CONNECTING","OPEN","CLOSING","CLOSED"],bu=/^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/,U=class n extends lu{constructor(e,t,r){super(),this._binaryType=co[0],this._closeCode=1006,this._closeFrameReceived=!1,this._closeFrameSent=!1,this._closeMessage=sr,this._closeTimer=null,this._errorEmitted=!1,this._extensions={},this._paused=!1,this._protocol="",this._readyState=n.CONNECTING,this._receiver=null,this._sender=null,this._socket=null,e!==null?(this._bufferedAmount=0,this._isServer=!1,this._redirects=0,t===void 0?t=[]:Array.isArray(t)||(typeof t=="object"&&t!==null?(r=t,t=[]):t=[t]),_o(this,e,t,r)):(this._autoPong=r.autoPong,this._isServer=!0)}get binaryType(){return this._binaryType}set binaryType(e){co.includes(e)&&(this._binaryType=e,this._receiver&&(this._receiver._binaryType=e))}get bufferedAmount(){return this._socket?this._socket._writableState.length+this._sender._bufferedBytes:this._bufferedAmount}get extensions(){return Object.keys(this._extensions).join()}get isPaused(){return this._paused}get onclose(){return null}get onerror(){return null}get onopen(){return null}get onmessage(){return null}get protocol(){return this._protocol}get readyState(){return this._readyState}get url(){return this._url}setSocket(e,t,r){let i=new du({allowSynchronousEvents:r.allowSynchronousEvents,binaryType:this.binaryType,extensions:this._extensions,isServer:this._isServer,maxPayload:r.maxPayload,skipUTF8Validation:r.skipUTF8Validation}),s=new pu(e,this._extensions,r.generateMask);this._receiver=i,this._sender=s,this._socket=e,i[V]=this,s[V]=this,e[V]=this,i.on("conclude",Iu),i.on("drain",Nu),i.on("error",Tu),i.on("message",Ru),i.on("ping",Au),i.on("pong",Du),s.onerror=Mu,e.setTimeout&&e.setTimeout(0),e.setNoDelay&&e.setNoDelay(),t.length>0&&e.unshift(t),e.on("close",yo),e.on("data",lr),e.on("end",So),e.on("error",vo),this._readyState=n.OPEN,this.emit("open")}emitClose(){if(!this._socket){this._readyState=n.CLOSED,this.emit("close",this._closeCode,this._closeMessage);return}this._extensions[Le.extensionName]&&this._extensions[Le.extensionName].cleanup(),this._receiver.removeAllListeners(),this._readyState=n.CLOSED,this.emit("close",this._closeCode,this._closeMessage)}close(e,t){if(this.readyState!==n.CLOSED){if(this.readyState===n.CONNECTING){ee(this,this._req,"WebSocket was closed before the connection was established");return}if(this.readyState===n.CLOSING){this._closeFrameSent&&(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end();return}this._readyState=n.CLOSING,this._sender.close(e,t,!this._isServer,r=>{r||(this._closeFrameSent=!0,(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end())}),wo(this)}}pause(){this.readyState===n.CONNECTING||this.readyState===n.CLOSED||(this._paused=!0,this._socket.pause())}ping(e,t,r){if(this.readyState===n.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof e=="function"?(r=e,e=t=void 0):typeof t=="function"&&(r=t,t=void 0),typeof e=="number"&&(e=e.toString()),this.readyState!==n.OPEN){vn(this,e,r);return}t===void 0&&(t=!this._isServer),this._sender.ping(e||sr,t,r)}pong(e,t,r){if(this.readyState===n.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof e=="function"?(r=e,e=t=void 0):typeof t=="function"&&(r=t,t=void 0),typeof e=="number"&&(e=e.toString()),this.readyState!==n.OPEN){vn(this,e,r);return}t===void 0&&(t=!this._isServer),this._sender.pong(e||sr,t,r)}resume(){this.readyState===n.CONNECTING||this.readyState===n.CLOSED||(this._paused=!1,this._receiver._writableState.needDrain||this._socket.resume())}send(e,t,r){if(this.readyState===n.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof t=="function"&&(r=t,t={}),typeof e=="number"&&(e=e.toString()),this.readyState!==n.OPEN){vn(this,e,r);return}let i={binary:typeof e!="string",mask:!this._isServer,compress:!0,fin:!0,...t};this._extensions[Le.extensionName]||(i.compress=!1),this._sender.send(e||sr,i,r)}terminate(){if(this.readyState!==n.CLOSED){if(this.readyState===n.CONNECTING){ee(this,this._req,"WebSocket was closed before the connection was established");return}this._socket&&(this._readyState=n.CLOSING,this._socket.destroy())}}};Object.defineProperty(U,"CONNECTING",{enumerable:!0,value:ve.indexOf("CONNECTING")});Object.defineProperty(U.prototype,"CONNECTING",{enumerable:!0,value:ve.indexOf("CONNECTING")});Object.defineProperty(U,"OPEN",{enumerable:!0,value:ve.indexOf("OPEN")});Object.defineProperty(U.prototype,"OPEN",{enumerable:!0,value:ve.indexOf("OPEN")});Object.defineProperty(U,"CLOSING",{enumerable:!0,value:ve.indexOf("CLOSING")});Object.defineProperty(U.prototype,"CLOSING",{enumerable:!0,value:ve.indexOf("CLOSING")});Object.defineProperty(U,"CLOSED",{enumerable:!0,value:ve.indexOf("CLOSED")});Object.defineProperty(U.prototype,"CLOSED",{enumerable:!0,value:ve.indexOf("CLOSED")});["binaryType","bufferedAmount","extensions","isPaused","protocol","readyState","url"].forEach(n=>{Object.defineProperty(U.prototype,n,{enumerable:!0})});["open","error","close","message"].forEach(n=>{Object.defineProperty(U.prototype,`on${n}`,{enumerable:!0,get(){for(let e of this.listeners(n))if(e[yn])return e[_u];return null},set(e){for(let t of this.listeners(n))if(t[yn]){this.removeListener(n,t);break}typeof e=="function"&&this.addEventListener(n,e,{[yn]:!0})}})});U.prototype.addEventListener=wu;U.prototype.removeEventListener=yu;xo.exports=U;function _o(n,e,t,r){let i={allowSynchronousEvents:!0,autoPong:!0,protocolVersion:Sn[1],maxPayload:104857600,skipUTF8Validation:!1,perMessageDeflate:!0,followRedirects:!1,maxRedirects:10,...r,socketPath:void 0,hostname:void 0,protocol:void 0,timeout:void 0,method:"GET",host:void 0,path:void 0,port:void 0};if(n._autoPong=i.autoPong,!Sn.includes(i.protocolVersion))throw new RangeError(`Unsupported protocol version: ${i.protocolVersion} (supported versions: ${Sn.join(", ")})`);let s;if(e instanceof wn)s=e;else try{s=new wn(e)}catch{throw new SyntaxError(`Invalid URL: ${e}`)}s.protocol==="http:"?s.protocol="ws:":s.protocol==="https:"&&(s.protocol="wss:"),n._url=s.href;let o=s.protocol==="wss:",a=s.protocol==="ws+unix:",l;if(s.protocol!=="ws:"&&!o&&!a?l=`The URL's protocol must be one of "ws:", "wss:", "http:", "https:", or "ws+unix:"`:a&&!s.pathname?l="The URL's pathname is empty":s.hash&&(l="The URL contains a fragment identifier"),l){let p=new SyntaxError(l);if(n._redirects===0)throw p;or(n,p);return}let f=o?443:80,u=cu(16).toString("base64"),h=o?au.request:fu.request,c=new Set,d;if(i.createConnection=i.createConnection||(o?Ou:Lu),i.defaultPort=i.defaultPort||f,i.port=s.port||f,i.host=s.hostname.startsWith("[")?s.hostname.slice(1,-1):s.hostname,i.headers={...i.headers,"Sec-WebSocket-Version":i.protocolVersion,"Sec-WebSocket-Key":u,Connection:"Upgrade",Upgrade:"websocket"},i.path=s.pathname+s.search,i.timeout=i.handshakeTimeout,i.perMessageDeflate&&(d=new Le(i.perMessageDeflate!==!0?i.perMessageDeflate:{},!1,i.maxPayload),i.headers["Sec-WebSocket-Extensions"]=Su({[Le.extensionName]:d.offer()})),t.length){for(let p of t){if(typeof p!="string"||!bu.test(p)||c.has(p))throw new SyntaxError("An invalid or duplicated subprotocol was specified");c.add(p)}i.headers["Sec-WebSocket-Protocol"]=t.join(",")}if(i.origin&&(i.protocolVersion<13?i.headers["Sec-WebSocket-Origin"]=i.origin:i.headers.Origin=i.origin),(s.username||s.password)&&(i.auth=`${s.username}:${s.password}`),a){let p=i.path.split(":");i.socketPath=p[0],i.path=p[1]}let m;if(i.followRedirects){if(n._redirects===0){n._originalIpc=a,n._originalSecure=o,n._originalHostOrSocketPath=a?i.socketPath:s.host;let p=r&&r.headers;if(r={...r,headers:{}},p)for(let[_,v]of Object.entries(p))r.headers[_.toLowerCase()]=v}else if(n.listenerCount("redirect")===0){let p=a?n._originalIpc?i.socketPath===n._originalHostOrSocketPath:!1:n._originalIpc?!1:s.host===n._originalHostOrSocketPath;(!p||n._originalSecure&&!o)&&(delete i.headers.authorization,delete i.headers.cookie,p||delete i.headers.host,i.auth=void 0)}i.auth&&!r.headers.authorization&&(r.headers.authorization="Basic "+Buffer.from(i.auth).toString("base64")),m=n._req=h(i),n._redirects&&n.emit("redirect",n.url,m)}else m=n._req=h(i);i.timeout&&m.on("timeout",()=>{ee(n,m,"Opening handshake has timed out")}),m.on("error",p=>{m===null||m[go]||(m=n._req=null,or(n,p))}),m.on("response",p=>{let _=p.headers.location,v=p.statusCode;if(_&&i.followRedirects&&v>=300&&v<400){if(++n._redirects>i.maxRedirects){ee(n,m,"Maximum redirects exceeded");return}m.abort();let C;try{C=new wn(_,e)}catch{let L=new SyntaxError(`Invalid URL: ${_}`);or(n,L);return}_o(n,C,t,r)}else n.emit("unexpected-response",m,p)||ee(n,m,`Unexpected server response: ${p.statusCode}`)}),m.on("upgrade",(p,_,v)=>{if(n.emit("upgrade",p),n.readyState!==U.CONNECTING)return;m=n._req=null;let C=p.headers.upgrade;if(C===void 0||C.toLowerCase()!=="websocket"){ee(n,_,"Invalid Upgrade header");return}let I=hu("sha1").update(u+gu).digest("base64");if(p.headers["sec-websocket-accept"]!==I){ee(n,_,"Invalid Sec-WebSocket-Accept header");return}let L=p.headers["sec-websocket-protocol"],R;if(L!==void 0?c.size?c.has(L)||(R="Server sent an invalid subprotocol"):R="Server sent a subprotocol but none was requested":c.size&&(R="Server sent no subprotocol"),R){ee(n,_,R);return}L&&(n._protocol=L);let O=p.headers["sec-websocket-extensions"];if(O!==void 0){if(!d){ee(n,_,"Server sent a Sec-WebSocket-Extensions header but no extension was requested");return}let B;try{B=vu(O)}catch{ee(n,_,"Invalid Sec-WebSocket-Extensions header");return}let P=Object.keys(B);if(P.length!==1||P[0]!==Le.extensionName){ee(n,_,"Server indicated an extension that was not requested");return}try{d.accept(B[Le.extensionName])}catch{ee(n,_,"Invalid Sec-WebSocket-Extensions header");return}n._extensions[Le.extensionName]=d}n.setSocket(_,v,{allowSynchronousEvents:i.allowSynchronousEvents,generateMask:i.generateMask,maxPayload:i.maxPayload,skipUTF8Validation:i.skipUTF8Validation})}),i.finishRequest?i.finishRequest(m,n):m.end()}function or(n,e){n._readyState=U.CLOSING,n._errorEmitted=!0,n.emit("error",e),n.emitClose()}function Lu(n){return n.path=n.socketPath,po.connect(n)}function Ou(n){return n.path=void 0,!n.servername&&n.servername!==""&&(n.servername=po.isIP(n.host)?"":n.host),uu.connect(n)}function ee(n,e,t){n._readyState=U.CLOSING;let r=new Error(t);Error.captureStackTrace(r,ee),e.setHeader?(e[go]=!0,e.abort(),e.socket&&!e.socket.destroyed&&e.socket.destroy(),process.nextTick(or,n,r)):(e.destroy(r),e.once("error",n.emit.bind(n,"error")),e.once("close",n.emitClose.bind(n)))}function vn(n,e,t){if(e){let r=mu(e)?e.size:xu(e).length;n._socket?n._sender._bufferedBytes+=r:n._bufferedAmount+=r}if(t){let r=new Error(`WebSocket is not open: readyState ${n.readyState} (${ve[n.readyState]})`);process.nextTick(t,r)}}function Iu(n,e){let t=this[V];t._closeFrameReceived=!0,t._closeMessage=e,t._closeCode=n,t._socket[V]!==void 0&&(t._socket.removeListener("data",lr),process.nextTick(Eo,t._socket),n===1005?t.close():t.close(n,e))}function Nu(){let n=this[V];n.isPaused||n._socket.resume()}function Tu(n){let e=this[V];e._socket[V]!==void 0&&(e._socket.removeListener("data",lr),process.nextTick(Eo,e._socket),e.close(n[Eu])),e._errorEmitted||(e._errorEmitted=!0,e.emit("error",n))}function ho(){this[V].emitClose()}function Ru(n,e){this[V].emit("message",n,e)}function Au(n){let e=this[V];e._autoPong&&e.pong(n,!this._isServer,mo),e.emit("ping",n)}function Du(n){this[V].emit("pong",n)}function Eo(n){n.resume()}function Mu(n){let e=this[V];e.readyState!==U.CLOSED&&(e.readyState===U.OPEN&&(e._readyState=U.CLOSING,wo(e)),this._socket.end(),e._errorEmitted||(e._errorEmitted=!0,e.emit("error",n)))}function wo(n){n._closeTimer=setTimeout(n._socket.destroy.bind(n._socket),Cu)}function yo(){let n=this[V];this.removeListener("close",yo),this.removeListener("data",lr),this.removeListener("end",So),n._readyState=U.CLOSING;let e;!this._readableState.endEmitted&&!n._closeFrameReceived&&!n._receiver._writableState.errorEmitted&&(e=n._socket.read())!==null&&n._receiver.write(e),n._receiver.end(),this[V]=void 0,clearTimeout(n._closeTimer),n._receiver._writableState.finished||n._receiver._writableState.errorEmitted?n.emitClose():(n._receiver.on("error",ho),n._receiver.on("finish",ho))}function lr(n){this[V]._receiver.write(n)||this.pause()}function So(){let n=this[V];n._readyState=U.CLOSING,n._receiver.end(),this.end()}function vo(){let n=this[V];this.removeListener("error",vo),this.on("error",mo),n&&(n._readyState=U.CLOSING,this.destroy())}});var Oo=b((cd,Lo)=>{"use strict";var ud=ar(),{Duplex:Pu}=require("stream");function Co(n){n.emit("close")}function Fu(){!this.destroyed&&this._writableState.finished&&this.destroy()}function bo(n){this.removeListener("error",bo),this.destroy(),this.listenerCount("error")===0&&this.emit("error",n)}function Uu(n,e){let t=!0,r=new Pu({...e,autoDestroy:!1,emitClose:!1,objectMode:!1,writableObjectMode:!1});return n.on("message",function(s,o){let a=!o&&r._readableState.objectMode?s.toString():s;r.push(a)||n.pause()}),n.once("error",function(s){r.destroyed||(t=!1,r.destroy(s))}),n.once("close",function(){r.destroyed||r.push(null)}),r._destroy=function(i,s){if(n.readyState===n.CLOSED){s(i),process.nextTick(Co,r);return}let o=!1;n.once("error",function(l){o=!0,s(l)}),n.once("close",function(){o||s(i),process.nextTick(Co,r)}),t&&n.terminate()},r._final=function(i){if(n.readyState===n.CONNECTING){n.once("open",function(){r._final(i)});return}n._socket!==null&&(n._socket._writableState.finished?(i(),r._readableState.endEmitted&&r.destroy()):(n._socket.once("finish",function(){i()}),n.close()))},r._read=function(){n.isPaused&&n.resume()},r._write=function(i,s,o){if(n.readyState===n.CONNECTING){n.once("open",function(){r._write(i,s,o)});return}n.send(i,o)},r.on("end",Fu),r.on("error",bo),r}Lo.exports=Uu});var No=b((hd,Io)=>{"use strict";var{tokenChars:ku}=Je();function Bu(n){let e=new Set,t=-1,r=-1,i=0;for(i;i{"use strict";var zu=require("events"),fr=require("http"),{Duplex:dd}=require("stream"),{createHash:Gu}=require("crypto"),To=En(),ze=xt(),Wu=No(),qu=ar(),{GUID:ju,kWebSocket:$u}=we(),Vu=/^[+/0-9A-Za-z]{22}==$/,Ro=0,Ao=1,Mo=2,xn=class extends zu{constructor(e,t){if(super(),e={allowSynchronousEvents:!0,autoPong:!0,maxPayload:100*1024*1024,skipUTF8Validation:!1,perMessageDeflate:!1,handleProtocols:null,clientTracking:!0,verifyClient:null,noServer:!1,backlog:null,server:null,host:null,path:null,port:null,WebSocket:qu,...e},e.port==null&&!e.server&&!e.noServer||e.port!=null&&(e.server||e.noServer)||e.server&&e.noServer)throw new TypeError('One and only one of the "port", "server", or "noServer" options must be specified');if(e.port!=null?(this._server=fr.createServer((r,i)=>{let s=fr.STATUS_CODES[426];i.writeHead(426,{"Content-Length":s.length,"Content-Type":"text/plain"}),i.end(s)}),this._server.listen(e.port,e.host,e.backlog,t)):e.server&&(this._server=e.server),this._server){let r=this.emit.bind(this,"connection");this._removeListeners=Hu(this._server,{listening:this.emit.bind(this,"listening"),error:this.emit.bind(this,"error"),upgrade:(i,s,o)=>{this.handleUpgrade(i,s,o,r)}})}e.perMessageDeflate===!0&&(e.perMessageDeflate={}),e.clientTracking&&(this.clients=new Set,this._shouldEmitClose=!1),this.options=e,this._state=Ro}address(){if(this.options.noServer)throw new Error('The server is operating in "noServer" mode');return this._server?this._server.address():null}close(e){if(this._state===Mo){e&&this.once("close",()=>{e(new Error("The server is not running"))}),process.nextTick(Ot,this);return}if(e&&this.once("close",e),this._state!==Ao)if(this._state=Ao,this.options.noServer||this.options.server)this._server&&(this._removeListeners(),this._removeListeners=this._server=null),this.clients?this.clients.size?this._shouldEmitClose=!0:process.nextTick(Ot,this):process.nextTick(Ot,this);else{let t=this._server;this._removeListeners(),this._removeListeners=this._server=null,t.close(()=>{Ot(this)})}}shouldHandle(e){if(this.options.path){let t=e.url.indexOf("?");if((t!==-1?e.url.slice(0,t):e.url)!==this.options.path)return!1}return!0}handleUpgrade(e,t,r,i){t.on("error",Do);let s=e.headers["sec-websocket-key"],o=e.headers.upgrade,a=+e.headers["sec-websocket-version"];if(e.method!=="GET"){Ge(this,e,t,405,"Invalid HTTP method");return}if(o===void 0||o.toLowerCase()!=="websocket"){Ge(this,e,t,400,"Invalid Upgrade header");return}if(s===void 0||!Vu.test(s)){Ge(this,e,t,400,"Missing or invalid Sec-WebSocket-Key header");return}if(a!==13&&a!==8){Ge(this,e,t,400,"Missing or invalid Sec-WebSocket-Version header",{"Sec-WebSocket-Version":"13, 8"});return}if(!this.shouldHandle(e)){It(t,400);return}let l=e.headers["sec-websocket-protocol"],f=new Set;if(l!==void 0)try{f=Wu.parse(l)}catch{Ge(this,e,t,400,"Invalid Sec-WebSocket-Protocol header");return}let u=e.headers["sec-websocket-extensions"],h={};if(this.options.perMessageDeflate&&u!==void 0){let c=new ze(this.options.perMessageDeflate,!0,this.options.maxPayload);try{let d=To.parse(u);d[ze.extensionName]&&(c.accept(d[ze.extensionName]),h[ze.extensionName]=c)}catch{Ge(this,e,t,400,"Invalid or unacceptable Sec-WebSocket-Extensions header");return}}if(this.options.verifyClient){let c={origin:e.headers[`${a===8?"sec-websocket-origin":"origin"}`],secure:!!(e.socket.authorized||e.socket.encrypted),req:e};if(this.options.verifyClient.length===2){this.options.verifyClient(c,(d,m,p,_)=>{if(!d)return It(t,m||401,p,_);this.completeUpgrade(h,s,f,e,t,r,i)});return}if(!this.options.verifyClient(c))return It(t,401)}this.completeUpgrade(h,s,f,e,t,r,i)}completeUpgrade(e,t,r,i,s,o,a){if(!s.readable||!s.writable)return s.destroy();if(s[$u])throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration");if(this._state>Ro)return It(s,503);let f=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${Gu("sha1").update(t+ju).digest("base64")}`],u=new this.options.WebSocket(null,void 0,this.options);if(r.size){let h=this.options.handleProtocols?this.options.handleProtocols(r,i):r.values().next().value;h&&(f.push(`Sec-WebSocket-Protocol: ${h}`),u._protocol=h)}if(e[ze.extensionName]){let h=e[ze.extensionName].params,c=To.format({[ze.extensionName]:[h]});f.push(`Sec-WebSocket-Extensions: ${c}`),u._extensions=e}this.emit("headers",f,i),s.write(f.concat(`\r +`).join(`\r +`)),s.removeListener("error",Do),u.setSocket(s,o,{allowSynchronousEvents:this.options.allowSynchronousEvents,maxPayload:this.options.maxPayload,skipUTF8Validation:this.options.skipUTF8Validation}),this.clients&&(this.clients.add(u),u.on("close",()=>{this.clients.delete(u),this._shouldEmitClose&&!this.clients.size&&process.nextTick(Ot,this)})),a(u,i)}};Po.exports=xn;function Hu(n,e){for(let t of Object.keys(e))n.on(t,e[t]);return function(){for(let r of Object.keys(e))n.removeListener(r,e[r])}}function Ot(n){n._state=Mo,n.emit("close")}function Do(){this.destroy()}function It(n,e,t,r){t=t||fr.STATUS_CODES[e],r={Connection:"close","Content-Type":"text/html","Content-Length":Buffer.byteLength(t),...r},n.once("finish",n.destroy),n.end(`HTTP/1.1 ${e} ${fr.STATUS_CODES[e]}\r +`+Object.keys(r).map(i=>`${i}: ${r[i]}`).join(`\r +`)+`\r +\r +`+t)}function Ge(n,e,t,r,i,s){if(n.listenerCount("wsClientError")){let o=new Error(i);Error.captureStackTrace(o,Ge),n.emit("wsClientError",o,t,e)}else It(t,r,i,s)}});var qo=b((gd,Wo)=>{"use strict";Wo.exports=zo;function zo(n,e,t){n instanceof RegExp&&(n=Bo(n,t)),e instanceof RegExp&&(e=Bo(e,t));var r=Go(n,e,t);return r&&{start:r[0],end:r[1],pre:t.slice(0,r[0]),body:t.slice(r[0]+n.length,r[1]),post:t.slice(r[1]+e.length)}}function Bo(n,e){var t=e.match(n);return t?t[0]:null}zo.range=Go;function Go(n,e,t){var r,i,s,o,a,l=t.indexOf(n),f=t.indexOf(e,l+1),u=l;if(l>=0&&f>0){if(n===e)return[l,f];for(r=[],s=t.length;u>=0&&!a;)u==l?(r.push(u),l=t.indexOf(n,u+1)):r.length==1?a=[r.pop(),f]:(i=r.pop(),i=0?l:f;r.length&&(a=[s,o])}return a}});var Ko=b((_d,Xo)=>{var jo=qo();Xo.exports=ec;var $o="\0SLASH"+Math.random()+"\0",Vo="\0OPEN"+Math.random()+"\0",bn="\0CLOSE"+Math.random()+"\0",Ho="\0COMMA"+Math.random()+"\0",Zo="\0PERIOD"+Math.random()+"\0";function Cn(n){return parseInt(n,10)==n?parseInt(n,10):n.charCodeAt(0)}function Ju(n){return n.split("\\\\").join($o).split("\\{").join(Vo).split("\\}").join(bn).split("\\,").join(Ho).split("\\.").join(Zo)}function Qu(n){return n.split($o).join("\\").split(Vo).join("{").split(bn).join("}").split(Ho).join(",").split(Zo).join(".")}function Yo(n){if(!n)return[""];var e=[],t=jo("{","}",n);if(!t)return n.split(",");var r=t.pre,i=t.body,s=t.post,o=r.split(",");o[o.length-1]+="{"+i+"}";var a=Yo(s);return s.length&&(o[o.length-1]+=a.shift(),o.push.apply(o,a)),e.push.apply(e,o),e}function ec(n){return n?(n.substr(0,2)==="{}"&&(n="\\{\\}"+n.substr(2)),Nt(Ju(n),!0).map(Qu)):[]}function tc(n){return"{"+n+"}"}function rc(n){return/^-?0\d/.test(n)}function nc(n,e){return n<=e}function ic(n,e){return n>=e}function Nt(n,e){var t=[],r=jo("{","}",n);if(!r)return[n];var i=r.pre,s=r.post.length?Nt(r.post,!1):[""];if(/\$$/.test(r.pre))for(var o=0;o=0;if(!u&&!h)return r.post.match(/,(?!,).*\}/)?(n=r.pre+"{"+r.body+bn+r.post,Nt(n)):[n];var c;if(u)c=r.body.split(/\.\./);else if(c=Yo(r.body),c.length===1&&(c=Nt(c[0],!1).map(tc),c.length===1))return s.map(function(G){return r.pre+c[0]+G});var d;if(u){var m=Cn(c[0]),p=Cn(c[1]),_=Math.max(c[0].length,c[1].length),v=c.length==3?Math.abs(Cn(c[2])):1,C=nc,I=p0){var P=new Array(B+1).join("0");R<0?O="-"+P+O.slice(1):O=P+O}}d.push(O)}}else{d=[];for(var A=0;A{"use strict";Object.defineProperty(Tn,"__esModule",{value:!0});Tn.default=jc;var At="diff-sequences",X=0,Dt=(n,e,t,r,i)=>{let s=0;for(;n{let s=0;for(;n<=e&&t<=r&&i(e,r);)e-=1,r-=1,s+=1;return s},In=(n,e,t,r,i,s,o)=>{let a=0,l=-n,f=s[a],u=f;s[a]+=Dt(f+1,e,r+f-l+1,t,i);let h=n{let a=0,l=n,f=s[a],u=f;s[a]-=Mt(e,f-1,t,r+f-l-1,i);let h=n{let h=r-e,c=t-e,m=i-r-c,p=-m-(n-1),_=-m+(n-1),v=X,C=n{let h=i-t,c=t-e,m=i-r-c,p=m-n,_=m+n,v=X,C=n{let f=r-e,u=i-t,h=t-e,c=i-r,d=c-h,m=h,p=h;if(o[0]=e-1,a[0]=t,d%2===0){let _=(n||d)/2,v=(h+c)/2;for(let C=1;C<=v;C+=1)if(m=In(C,t,i,f,s,o,m),C<_)p=ul(C,e,r,u,s,a,p);else if(Wc(C,e,t,r,i,s,o,m,a,p,l))return}else{let _=((n||d)+1)/2,v=(h+c+1)/2,C=1;for(m=In(C,t,i,f,s,o,m),C+=1;C<=v;C+=1)if(p=ul(C-1,e,r,u,s,a,p),C<_)m=In(C,t,i,f,s,o,m);else if(Gc(C,e,t,r,i,s,o,m,a,p,l))return}throw new Error(`${At}: no overlap aStart=${e} aEnd=${t} bStart=${r} bEnd=${i}`)},Nn=(n,e,t,r,i,s,o,a,l,f)=>{if(i-r{G(te,w,g)},isCommon:(te,g)=>fe(g,te)}}let P=e,A=t;e=r,t=i,r=P,i=A}let{foundSubsequence:u,isCommon:h}=o[s?1:0];qc(n,e,t,r,i,h,a,l,f);let{nChangePreceding:c,aEndPreceding:d,bEndPreceding:m,nCommonPreceding:p,aCommonPreceding:_,bCommonPreceding:v,nCommonFollowing:C,aCommonFollowing:I,bCommonFollowing:L,nChangeFollowing:R,aStartFollowing:O,bStartFollowing:B}=f;e{if(typeof e!="number")throw new TypeError(`${At}: ${n} typeof ${typeof e} is not a number`);if(!Number.isSafeInteger(e))throw new RangeError(`${At}: ${n} value ${e} is not a safe integer`);if(e<0)throw new RangeError(`${At}: ${n} value ${e} is a negative integer`)},hl=(n,e)=>{let t=typeof e;if(t!=="function")throw new TypeError(`${At}: ${n} typeof ${t} is not a function`)};function jc(n,e,t,r){cl("aLength",n),cl("bLength",e),hl("isCommon",t),hl("foundSubsequence",r);let i=Dt(0,n,0,e,t);if(i!==0&&r(i,0,0),n!==i||e!==i){let s=i,o=i,a=Mt(s,n-1,o,e-1,t),l=n-a,f=e-a,u=i+a;n!==u&&e!==u&&Nn(0,s,l,o,f,!1,[{foundSubsequence:r,isCommon:t}],[X],[X],{aCommonFollowing:X,aCommonPreceding:X,aEndPreceding:X,aStartFollowing:X,bCommonFollowing:X,bCommonPreceding:X,bEndPreceding:X,bStartFollowing:X,nChangeFollowing:X,nChangePreceding:X,nCommonFollowing:X,nCommonPreceding:X}),a!==0&&r(a,l,f)}}});var vl=b((Qd,Sl)=>{"use strict";function Xc(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}var Kc=new Int32Array([0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117]);function yl(n){if(Buffer.isBuffer(n))return n;if(typeof n=="number")return Buffer.alloc(n);if(typeof n=="string")return Buffer.from(n);throw new Error("input must be buffer, number, or string, received "+typeof n)}function Jc(n){let e=yl(4);return e.writeInt32BE(n,0),e}function Dn(n,e){n=yl(n),Buffer.isBuffer(e)&&(e=e.readUInt32BE(0));let t=~~e^-1;for(var r=0;r>>8;return t^-1}function Mn(){return Jc(Dn.apply(null,arguments))}Mn.signed=function(){return Dn.apply(null,arguments)};Mn.unsigned=function(){return Dn.apply(null,arguments)>>>0};var Qc=Mn,eh=Xc(Qc);Sl.exports=eh});var zl=b(Gn=>{var xl=require("fs"),gr=require("stream").Transform,Ll=require("stream").PassThrough,Ol=require("zlib"),Bn=require("util"),th=require("events").EventEmitter,rh=require("events").errorMonitor,Il=vl();Gn.ZipFile=Te;Gn.dateToDosDateTime=Bl;Bn.inherits(Te,th);function Te(){this.outputStream=new Ll,this.entries=[],this.outputStreamCursor=0,this.ended=!1,this.allDone=!1,this.forceZip64Eocd=!1,this.errored=!1,this.on(rh,function(){this.errored=!0})}Te.prototype.addFile=function(n,e,t){var r=this;if(e=Er(e,!1),t==null&&(t={}),!_r(r)){var i=new D(e,!1,t);r.entries.push(i),xl.stat(n,function(s,o){if(s)return r.emit("error",s);if(!o.isFile())return r.emit("error",new Error("not a file: "+n));i.uncompressedSize=o.size,t.mtime==null&&i.setLastModDate(o.mtime),t.mode==null&&i.setFileAttributesMode(o.mode),i.setFileDataPumpFunction(function(){var a=xl.createReadStream(n);i.state=D.FILE_DATA_IN_PROGRESS,a.on("error",function(l){r.emit("error",l)}),Nl(r,i,a)}),Ne(r)})}};Te.prototype.addReadStream=function(n,e,t){this.addReadStreamLazy(e,t,function(r){r(null,n)})};Te.prototype.addReadStreamLazy=function(n,e,t){var r=this;if(typeof e=="function"&&(t=e,e=null),e==null&&(e={}),n=Er(n,!1),!_r(r)){var i=new D(n,!1,e);r.entries.push(i),i.setFileDataPumpFunction(function(){i.state=D.FILE_DATA_IN_PROGRESS,t(function(s,o){if(s)return r.emit("error",s);Nl(r,i,o)})}),Ne(r)}};Te.prototype.addBuffer=function(n,e,t){var r=this;if(e=Er(e,!1),n.length>1073741823)throw new Error("buffer too large: "+n.length+" > 1073741823");if(t==null&&(t={}),t.size!=null)throw new Error("options.size not allowed");if(_r(r))return;var i=new D(e,!1,t);i.uncompressedSize=n.length,i.crc32=Il.unsigned(n),i.crcAndFileSizeKnown=!0,r.entries.push(i),i.compressionLevel===0?s(n):Ol.deflateRaw(n,{level:i.compressionLevel},function(o,a){s(a)});function s(o){i.compressedSize=o.length,i.setFileDataPumpFunction(function(){We(r,o),We(r,i.getDataDescriptor()),i.state=D.FILE_DATA_DONE,setImmediate(function(){Ne(r)})}),Ne(r)}};Te.prototype.addEmptyDirectory=function(n,e){var t=this;if(n=Er(n,!0),e==null&&(e={}),e.size!=null)throw new Error("options.size not allowed");if(e.compress!=null)throw new Error("options.compress not allowed");if(e.compressionLevel!=null)throw new Error("options.compressionLevel not allowed");if(!_r(t)){var r=new D(n,!0,e);t.entries.push(r),r.setFileDataPumpFunction(function(){We(t,r.getDataDescriptor()),r.state=D.FILE_DATA_DONE,Ne(t)}),Ne(t)}};var nh=Ie([80,75,5,6]);Te.prototype.end=function(n,e){if(typeof n=="function"&&(e=n,n=null),n==null&&(n={}),!this.ended&&(this.ended=!0,!this.errored)){if(this.calculatedTotalSizeCallback=e,this.forceZip64Eocd=!!n.forceZip64Format,n.comment){if(typeof n.comment=="string"?this.comment=lh(n.comment):this.comment=n.comment,this.comment.length>65535)throw new Error("comment is too large");if(Pt(this.comment,nh))throw new Error("comment contains end of central directory record signature")}else this.comment=Ft;Ne(this)}};function We(n,e){n.outputStream.write(e),n.outputStreamCursor+=e.length}function Nl(n,e,t){var r=new zn,i=new mr,s=e.compressionLevel!==0?new Ol.DeflateRaw({level:e.compressionLevel}):new Ll,o=new mr;t.pipe(r).pipe(i).pipe(s).pipe(o).pipe(n.outputStream,{end:!1}),o.on("end",function(){if(e.crc32=r.crc32,e.uncompressedSize==null)e.uncompressedSize=i.byteCount;else if(e.uncompressedSize!==i.byteCount)return n.emit("error",new Error("file data stream has unexpected number of bytes"));e.compressedSize=o.byteCount,n.outputStreamCursor+=e.compressedSize,We(n,e.getDataDescriptor()),e.state=D.FILE_DATA_DONE,Ne(n)})}function ih(n){if(n.compress!=null&&n.compressionLevel!=null&&!!n.compress!=!!n.compressionLevel)throw new Error("conflicting settings for compress and compressionLevel");return n.compressionLevel!=null?n.compressionLevel:n.compress===!1?0:6}function Ne(n){if(n.allDone||n.errored)return;if(n.ended&&n.calculatedTotalSizeCallback!=null){var e=sh(n);e!=null&&(n.calculatedTotalSizeCallback(e),n.calculatedTotalSizeCallback=null)}var t=r();function r(){for(var s=0;s=D.READY_TO_PUMP_FILE_DATA){if(i.uncompressedSize==null)return-1}else if(i.uncompressedSize==null)return null;i.relativeOffsetOfLocalHeader=e;var s=i.useZip64Format();e+=Tl+i.utf8FileName.length,e+=i.uncompressedSize,i.crcAndFileSizeKnown||(s?e+=Ul:e+=Fl),t+=kl+i.utf8FileName.length+i.fileComment.length,i.forceDosTimestamp||(t+=Fn),s&&(t+=Un)}var o=0;return(n.forceZip64Eocd||n.entries.length>=65535||t>=65535||e>=4294967295)&&(o+=dr+Pn),o+=pr+n.comment.length,e+t+o}function _r(n){if(n.ended)throw new Error("cannot add entries after calling end()");return!!n.errored}var dr=56,Pn=20,pr=22;function oh(n,e){var t=!1,r=n.entries.length;(n.forceZip64Eocd||n.entries.length>=65535)&&(r=65535,t=!0);var i=n.outputStreamCursor-n.offsetOfStartOfCentralDirectory,s=i;(n.forceZip64Eocd||i>=4294967295)&&(s=4294967295,t=!0);var o=n.offsetOfStartOfCentralDirectory;if((n.forceZip64Eocd||n.offsetOfStartOfCentralDirectory>=4294967295)&&(o=4294967295,t=!0),e)return t?dr+Pn+pr:pr;var a=J(pr+n.comment.length);if(a.writeUInt32LE(101010256,0),a.writeUInt16LE(0,4),a.writeUInt16LE(0,6),a.writeUInt16LE(r,8),a.writeUInt16LE(r,10),a.writeUInt32LE(s,12),a.writeUInt32LE(o,16),a.writeUInt16LE(n.comment.length,20),n.comment.copy(a,22),!t)return a;var l=J(dr);l.writeUInt32LE(101075792,0),pe(l,dr-12,4),l.writeUInt16LE(Dl,12),l.writeUInt16LE(Al,14),l.writeUInt32LE(0,16),l.writeUInt32LE(0,20),pe(l,n.entries.length,24),pe(l,n.entries.length,32),pe(l,i,40),pe(l,n.offsetOfStartOfCentralDirectory,48);var f=J(Pn);return f.writeUInt32LE(117853008,0),f.writeUInt32LE(0,4),pe(f,n.outputStreamCursor,8),f.writeUInt32LE(1,16),Buffer.concat([l,f,a])}function Er(n,e){if(n==="")throw new Error("empty metadataPath");if(n=n.replace(/\\/g,"/"),/^[a-zA-Z]:/.test(n)||/^\//.test(n))throw new Error("absolute path: "+n);if(n.split("/").indexOf("..")!==-1)throw new Error("invalid relative path: "+n);var t=/\/$/.test(n);if(e)t||(n+="/");else if(t)throw new Error("file path cannot end with '/': "+n);return n}var Ft=J(0);function D(n,e,t){if(this.utf8FileName=Ie(n),this.utf8FileName.length>65535)throw new Error("utf8 file name too long. "+utf8FileName.length+" > 65535");if(this.isDirectory=e,this.state=D.WAITING_FOR_METADATA,this.setLastModDate(t.mtime!=null?t.mtime:new Date),this.forceDosTimestamp=!!t.forceDosTimestamp,t.mode!=null?this.setFileAttributesMode(t.mode):this.setFileAttributesMode(e?16893:33204),e?(this.crcAndFileSizeKnown=!0,this.crc32=0,this.uncompressedSize=0,this.compressedSize=0):(this.crcAndFileSizeKnown=!1,this.crc32=null,this.uncompressedSize=null,this.compressedSize=null,t.size!=null&&(this.uncompressedSize=t.size)),e?this.compressionLevel=0:this.compressionLevel=ih(t),this.forceZip64Format=!!t.forceZip64Format,t.fileComment){if(typeof t.fileComment=="string"?this.fileComment=Ie(t.fileComment,"utf-8"):this.fileComment=t.fileComment,this.fileComment.length>65535)throw new Error("fileComment is too large")}else this.fileComment=Ft}D.WAITING_FOR_METADATA=0;D.READY_TO_PUMP_FILE_DATA=1;D.FILE_DATA_IN_PROGRESS=2;D.FILE_DATA_DONE=3;D.prototype.setLastModDate=function(n){this.mtime=n;var e=Bl(n);this.lastModFileTime=e.time,this.lastModFileDate=e.date};D.prototype.setFileAttributesMode=function(n){if((n&65535)!==n)throw new Error("invalid mode. expected: 0 <= "+n+" <= 65535");this.externalFileAttributes=n<<16>>>0};D.prototype.setFileDataPumpFunction=function(n){this.doFileDataPump=n,this.state=D.READY_TO_PUMP_FILE_DATA};D.prototype.useZip64Format=function(){return this.forceZip64Format||this.uncompressedSize!=null&&this.uncompressedSize>4294967294||this.compressedSize!=null&&this.compressedSize>4294967294||this.relativeOffsetOfLocalHeader!=null&&this.relativeOffsetOfLocalHeader>4294967294};var Tl=30,Rl=20,Al=45,Dl=831,Ml=2048,Pl=8;D.prototype.getLocalFileHeader=function(){var n=0,e=0,t=0;this.crcAndFileSizeKnown&&(n=this.crc32,e=this.compressedSize,t=this.uncompressedSize);var r=J(Tl),i=Ml;return this.crcAndFileSizeKnown||(i|=Pl),r.writeUInt32LE(67324752,0),r.writeUInt16LE(Rl,4),r.writeUInt16LE(i,6),r.writeUInt16LE(this.getCompressionMethod(),8),r.writeUInt16LE(this.lastModFileTime,10),r.writeUInt16LE(this.lastModFileDate,12),r.writeUInt32LE(n,14),r.writeUInt32LE(e,18),r.writeUInt32LE(t,22),r.writeUInt16LE(this.utf8FileName.length,26),r.writeUInt16LE(0,28),Buffer.concat([r,this.utf8FileName])};var Fl=16,Ul=24;D.prototype.getDataDescriptor=function(){if(this.crcAndFileSizeKnown)return Ft;if(this.useZip64Format()){var n=J(Ul);return n.writeUInt32LE(134695760,0),n.writeUInt32LE(this.crc32,4),pe(n,this.compressedSize,8),pe(n,this.uncompressedSize,16),n}else{var n=J(Fl);return n.writeUInt32LE(134695760,0),n.writeUInt32LE(this.crc32,4),n.writeUInt32LE(this.compressedSize,8),n.writeUInt32LE(this.uncompressedSize,12),n}};var kl=46,Fn=9,Un=28;D.prototype.getCentralDirectoryRecord=function(){var n=J(kl),e=Ml;this.crcAndFileSizeKnown||(e|=Pl);var t=Ft;if(!this.forceDosTimestamp){t=J(Fn),t.writeUInt16LE(21589,0),t.writeUInt16LE(Fn-4,2);var r=1,i=2;t.writeUInt8(r|i,4);var s=Math.floor(this.mtime.getTime()/1e3);s<-2147483648&&(s=-2147483648),s>2147483647&&(s=2147483647),t.writeUInt32LE(s,5)}var o=this.compressedSize,a=this.uncompressedSize,l=this.relativeOffsetOfLocalHeader,f=Rl,u=Ft;return this.useZip64Format()&&(o=4294967295,a=4294967295,l=4294967295,f=Al,u=J(Un),u.writeUInt16LE(1,0),u.writeUInt16LE(Un-4,2),pe(u,this.uncompressedSize,4),pe(u,this.compressedSize,12),pe(u,this.relativeOffsetOfLocalHeader,20)),n.writeUInt32LE(33639248,0),n.writeUInt16LE(Dl,4),n.writeUInt16LE(f,6),n.writeUInt16LE(e,8),n.writeUInt16LE(this.getCompressionMethod(),10),n.writeUInt16LE(this.lastModFileTime,12),n.writeUInt16LE(this.lastModFileDate,14),n.writeUInt32LE(this.crc32,16),n.writeUInt32LE(o,20),n.writeUInt32LE(a,24),n.writeUInt16LE(this.utf8FileName.length,28),n.writeUInt16LE(t.length+u.length,30),n.writeUInt16LE(this.fileComment.length,32),n.writeUInt16LE(0,34),n.writeUInt16LE(0,36),n.writeUInt32LE(this.externalFileAttributes,38),n.writeUInt32LE(l,42),Buffer.concat([n,this.utf8FileName,t,u,this.fileComment])};D.prototype.getCompressionMethod=function(){var n=0,e=8;return this.compressionLevel===0?n:e};var Cl=new Date(1980,0,1),bl=new Date(2107,11,31,23,59,58);function Bl(n){nbl&&(n=bl);var e=0;e|=n.getDate()&31,e|=(n.getMonth()+1&15)<<5,e|=(n.getFullYear()-1980&127)<<9;var t=0;return t|=Math.floor(n.getSeconds()/2),t|=(n.getMinutes()&63)<<5,t|=(n.getHours()&31)<<11,{date:e,time:t}}function pe(n,e,t){var r=Math.floor(e/4294967296),i=e%4294967296;n.writeUInt32LE(i,t),n.writeUInt32LE(r,t+4)}Bn.inherits(mr,gr);function mr(n){gr.call(this,n),this.byteCount=0}mr.prototype._transform=function(n,e,t){this.byteCount+=n.length,t(null,n)};Bn.inherits(zn,gr);function zn(n){gr.call(this,n),this.crc32=0}zn.prototype._transform=function(n,e,t){this.crc32=Il.unsigned(n,this.crc32),t(null,n)};var kn="\0\u263A\u263B\u2665\u2666\u2663\u2660\u2022\u25D8\u25CB\u25D9\u2642\u2640\u266A\u266B\u263C\u25BA\u25C4\u2195\u203C\xB6\xA7\u25AC\u21A8\u2191\u2193\u2192\u2190\u221F\u2194\u25B2\u25BC !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u2302\xC7\xFC\xE9\xE2\xE4\xE0\xE5\xE7\xEA\xEB\xE8\xEF\xEE\xEC\xC4\xC5\xC9\xE6\xC6\xF4\xF6\xF2\xFB\xF9\xFF\xD6\xDC\xA2\xA3\xA5\u20A7\u0192\xE1\xED\xF3\xFA\xF1\xD1\xAA\xBA\xBF\u2310\xAC\xBD\xBC\xA1\xAB\xBB\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u03B1\xDF\u0393\u03C0\u03A3\u03C3\xB5\u03C4\u03A6\u0398\u03A9\u03B4\u221E\u03C6\u03B5\u2229\u2261\xB1\u2265\u2264\u2320\u2321\xF7\u2248\xB0\u2219\xB7\u221A\u207F\xB2\u25A0\xA0";if(kn.length!==256)throw new Error("assertion failure");var hr=null;function lh(n){if(/^[\x20-\x7e]*$/.test(n))return Ie(n,"utf-8");if(hr==null){hr={};for(var e=0;e{var le=require("fs"),ah=require("util"),ot=require("path"),Zn=require("events"),Gl=require("zlib"),jl=require("stream"),E={LOCHDR:30,LOCSIG:67324752,LOCVER:4,LOCFLG:6,LOCHOW:8,LOCTIM:10,LOCCRC:14,LOCSIZ:18,LOCLEN:22,LOCNAM:26,LOCEXT:28,EXTSIG:134695760,EXTHDR:16,EXTCRC:4,EXTSIZ:8,EXTLEN:12,CENHDR:46,CENSIG:33639248,CENVEM:4,CENVER:6,CENFLG:8,CENHOW:10,CENTIM:12,CENCRC:16,CENSIZ:20,CENLEN:24,CENNAM:28,CENEXT:30,CENCOM:32,CENDSK:34,CENATT:36,CENATX:38,CENOFF:42,ENDHDR:22,ENDSIG:101010256,ENDSIGFIRST:80,ENDSUB:8,ENDTOT:10,ENDSIZ:12,ENDOFF:16,ENDCOM:20,MAXFILECOMMENT:65535,ENDL64HDR:20,ENDL64SIG:117853008,ENDL64SIGFIRST:80,ENDL64OFS:8,END64HDR:56,END64SIG:101075792,END64SIGFIRST:80,END64SUB:24,END64TOT:32,END64SIZ:40,END64OFF:48,STORED:0,SHRUNK:1,REDUCED1:2,REDUCED2:3,REDUCED3:4,REDUCED4:5,IMPLODED:6,DEFLATED:8,ENHANCED_DEFLATED:9,PKWARE:10,BZIP2:12,LZMA:14,IBM_TERSE:18,IBM_LZ77:19,FLG_ENC:0,FLG_COMP1:1,FLG_COMP2:2,FLG_DESC:4,FLG_ENH:8,FLG_STR:16,FLG_LNG:1024,FLG_MSK:4096,FLG_ENTRY_ENC:1,EF_ID:0,EF_SIZE:2,ID_ZIP64:1,ID_AVINFO:7,ID_PFS:8,ID_OS2:9,ID_NTFS:10,ID_OPENVMS:12,ID_UNIX:13,ID_FORK:14,ID_PATCH:15,ID_X509_PKCS7:20,ID_X509_CERTID_F:21,ID_X509_CERTID_C:22,ID_STRONGENC:23,ID_RECORD_MGT:24,ID_X509_PKCS7_RL:25,ID_IBM1:101,ID_IBM2:102,ID_POSZIP:18064,EF_ZIP64_OR_32:4294967295,EF_ZIP64_OR_16:65535},Me=function(n){let e,t,r,i,s,o,l=this,f=n.storeEntries!==!1?{}:null,u=n.file,h=n.nameEncoding?new TextDecoder(n.nameEncoding):null;c();function c(){n.fd?(e=n.fd,d()):le.open(u,"r",(g,w)=>{if(g)return l.emit("error",g);e=w,d()})}function d(){le.fstat(e,(g,w)=>{if(g)return l.emit("error",g);t=w.size,r=n.chunkSize||Math.round(t/1e3),r=Math.max(Math.min(r,Math.min(128*1024,t)),Math.min(1024,t)),p()})}function m(g,w){if(g||!w)return l.emit("error",g||new Error("Archive read error"));let x=i.lastPos,y=x-i.win.position,T=i.win.buffer,N=i.minPos;for(;--x>=N&&--y>=0;)if(T.length-y>=4&&T[y]===i.firstByte&&T.readUInt32LE(y)===i.sig){i.lastBufferPosition=y,i.lastBytesRead=w,i.complete();return}if(x===N)return l.emit("error",new Error("Bad archive"));if(i.lastPos=x+1,i.chunkSize*=2,x<=N)return l.emit("error",new Error("Bad archive"));let F=Math.min(i.chunkSize,x-N);i.win.expandLeft(F,m)}function p(){let g=Math.min(E.ENDHDR+E.MAXFILECOMMENT,t);i={win:new wr(e),totalReadLength:g,minPos:t-g,lastPos:t,chunkSize:Math.min(1024,r),firstByte:E.ENDSIGFIRST,sig:E.ENDSIG,complete:_},i.win.read(t-i.chunkSize,i.chunkSize,m)}function _(){let g=i.win.buffer,w=i.lastBufferPosition;try{s=new Wn,s.read(g.slice(w,w+E.ENDHDR)),s.headerOffset=i.win.position+w,s.commentLength?l.comment=g.slice(w+E.ENDHDR,w+E.ENDHDR+s.commentLength).toString():l.comment=null,l.entriesCount=s.volumeEntries,l.centralDirectory=s,s.volumeEntries===E.EF_ZIP64_OR_16&&s.totalEntries===E.EF_ZIP64_OR_16||s.size===E.EF_ZIP64_OR_32||s.offset===E.EF_ZIP64_OR_32?v():(i={},L())}catch(x){l.emit("error",x)}}function v(){let g=E.ENDL64HDR;i.lastBufferPosition>g?(i.lastBufferPosition-=g,C()):(i={win:i.win,totalReadLength:g,minPos:i.win.position-g,lastPos:i.win.position,chunkSize:i.chunkSize,firstByte:E.ENDL64SIGFIRST,sig:E.ENDL64SIG,complete:C},i.win.read(i.lastPos-i.chunkSize,i.chunkSize,m))}function C(){let g=i.win.buffer,w=new qn;w.read(g.slice(i.lastBufferPosition,i.lastBufferPosition+E.ENDL64HDR));let x=t-w.headerOffset;i={win:i.win,totalReadLength:x,minPos:w.headerOffset,lastPos:i.lastPos,chunkSize:i.chunkSize,firstByte:E.END64SIGFIRST,sig:E.END64SIG,complete:I},i.win.read(t-i.chunkSize,i.chunkSize,m)}function I(){let g=i.win.buffer,w=new jn;w.read(g.slice(i.lastBufferPosition,i.lastBufferPosition+E.END64HDR)),l.centralDirectory.volumeEntries=w.volumeEntries,l.centralDirectory.totalEntries=w.totalEntries,l.centralDirectory.size=w.size,l.centralDirectory.offset=w.offset,l.entriesCount=w.volumeEntries,i={},L()}function L(){i={win:new wr(e),pos:s.offset,chunkSize:r,entriesLeft:s.volumeEntries},i.win.read(i.pos,Math.min(r,t-i.pos),R)}function R(g,w){if(g||!w)return l.emit("error",g||new Error("Entries read error"));let x=i.pos-i.win.position,y=i.entry,T=i.win.buffer,N=T.length;try{for(;i.entriesLeft>0;){y||(y=new $n,y.readHeader(T,x),y.headerOffset=i.win.position+x,i.entry=y,i.pos+=E.CENHDR,x+=E.CENHDR);let F=y.fnameLen+y.extraLen+y.comLen,q=F+(i.entriesLeft>1?E.CENHDR:0);if(N-x{if(x)return w(x);let T=B(y),N=new Vn(e,T,y.compressedSize);if(y.method!==E.STORED)if(y.method===E.DEFLATED)N=N.pipe(Gl.createInflateRaw());else return w(new Error("Unknown compression method: "+y.method));P(y)&&(N=N.pipe(new Hn(N,y.crc,y.size))),w(null,N)},!1)},this.entryDataSync=function(g){let w=null;if(this.openEntry(g,(y,T)=>{w=y,g=T},!0),w)throw w;let x=Buffer.alloc(g.compressedSize);if(new Ae(e,x,0,g.compressedSize,B(g),y=>{w=y}).read(!0),w)throw w;if(g.method!==E.STORED)if(g.method===E.DEFLATED||g.method===E.ENHANCED_DEFLATED)x=Gl.inflateRawSync(x);else throw new Error("Unknown compression method: "+g.method);if(x.length!==g.size)throw new Error("Invalid size");return P(g)&&new yr(g.crc,g.size).data(x),x},this.openEntry=function(g,w,x){if(typeof g=="string"&&(O(),g=f[g],!g))return w(new Error("Entry not found"));if(!g.isFile)return w(new Error("Entry is not file"));if(!e)return w(new Error("Archive closed"));let y=Buffer.alloc(E.LOCHDR);new Ae(e,y,0,y.length,g.offset,T=>{if(T)return w(T);let N;try{g.readDataHeader(y),g.encrypted&&(N=new Error("Entry encrypted"))}catch(F){N=F}w(N,g)}).read(x)};function B(g){return g.offset+E.LOCHDR+g.fnameLen+g.extraLen}function P(g){return(g.flags&8)!==8}function A(g,w,x){l.stream(g,(y,T)=>{if(y)x(y);else{let N,F;T.on("error",q=>{F=q,N&&(T.unpipe(N),N.close(()=>{x(q)}))}),le.open(w,"w",(q,ue)=>{if(q)return x(q);if(F){le.close(e,()=>{x(F)});return}N=le.createWriteStream(w,{fd:ue}),N.on("finish",()=>{l.emit("extract",g,w),F||x()}),T.pipe(N)})}})}function G(g,w,x){if(!w.length)return x();let y=w.shift();y=ot.join(g,ot.join(...y)),le.mkdir(y,{recursive:!0},T=>{if(T&&T.code!=="EEXIST")return x(T);G(g,w,x)})}function fe(g,w,x,y,T){if(!x.length)return y(null,T);let N=x.shift(),F=ot.join(g,N.name.replace(w,""));A(N,F,q=>{if(q)return y(q,T);fe(g,w,x,y,T+1)})}this.extract=function(g,w,x){let y=g||"";if(typeof g=="string"&&(g=this.entry(g),g?y=g.name:y.length&&y[y.length-1]!=="/"&&(y+="/")),!g||g.isDirectory){let T=[],N=[],F={};for(let q in f)if(Object.prototype.hasOwnProperty.call(f,q)&&q.lastIndexOf(y,0)===0){let ue=q.replace(y,""),Xn=f[q];if(Xn.isFile&&(T.push(Xn),ue=ot.dirname(ue)),ue&&!F[ue]&&ue!=="."){F[ue]=!0;let xe=ue.split("/").filter(lt=>lt);for(xe.length&&N.push(xe);xe.length>1;){xe=xe.slice(0,xe.length-1);let lt=xe.join("/");if(F[lt]||lt===".")break;F[lt]=!0,N.push(xe)}}}N.sort((q,ue)=>q.length-ue.length),N.length?G(w,N,q=>{q?x(q):fe(w,y,T,x,0)}):fe(w,y,T,x,0)}else le.stat(w,(T,N)=>{N&&N.isDirectory()?A(g,ot.join(w,ot.basename(g.name)),x):A(g,w,x)})},this.close=function(g){o||!e?(o=!0,g&&g()):(o=!0,le.close(e,w=>{e=null,g&&g(w)}))};let te=Zn.EventEmitter.prototype.emit;this.emit=function(...g){if(!o)return te.call(this,...g)}};Me.setFs=function(n){le=n};Me.debugLog=(...n)=>{Me.debug&&console.log(...n)};ah.inherits(Me,Zn.EventEmitter);var Re=Symbol("zip");Me.async=class extends Zn.EventEmitter{constructor(e){super();let t=new Me(e);t.on("entry",r=>this.emit("entry",r)),t.on("extract",(r,i)=>this.emit("extract",r,i)),this[Re]=new Promise((r,i)=>{t.on("ready",()=>{t.removeListener("error",i),r(t)}),t.on("error",i)})}get entriesCount(){return this[Re].then(e=>e.entriesCount)}get comment(){return this[Re].then(e=>e.comment)}async entry(e){return(await this[Re]).entry(e)}async entries(){return(await this[Re]).entries()}async stream(e){let t=await this[Re];return new Promise((r,i)=>{t.stream(e,(s,o)=>{s?i(s):r(o)})})}async entryData(e){let t=await this.stream(e);return new Promise((r,i)=>{let s=[];t.on("data",o=>s.push(o)),t.on("end",()=>{r(Buffer.concat(s))}),t.on("error",o=>{t.removeAllListeners("end"),i(o)})})}async extract(e,t){let r=await this[Re];return new Promise((i,s)=>{r.extract(e,t,(o,a)=>{o?s(o):i(a)})})}async close(){let e=await this[Re];return new Promise((t,r)=>{e.close(i=>{i?r(i):t()})})}};var Wn=class{read(e){if(e.length!==E.ENDHDR||e.readUInt32LE(0)!==E.ENDSIG)throw new Error("Invalid central directory");this.volumeEntries=e.readUInt16LE(E.ENDSUB),this.totalEntries=e.readUInt16LE(E.ENDTOT),this.size=e.readUInt32LE(E.ENDSIZ),this.offset=e.readUInt32LE(E.ENDOFF),this.commentLength=e.readUInt16LE(E.ENDCOM)}},qn=class{read(e){if(e.length!==E.ENDL64HDR||e.readUInt32LE(0)!==E.ENDL64SIG)throw new Error("Invalid zip64 central directory locator");this.headerOffset=De(e,E.ENDSUB)}},jn=class{read(e){if(e.length!==E.END64HDR||e.readUInt32LE(0)!==E.END64SIG)throw new Error("Invalid central directory");this.volumeEntries=De(e,E.END64SUB),this.totalEntries=De(e,E.END64TOT),this.size=De(e,E.END64SIZ),this.offset=De(e,E.END64OFF)}},$n=class{readHeader(e,t){if(e.length=8&&this.size===E.EF_ZIP64_OR_32&&(this.size=De(e,t),t+=8,r-=8),r>=8&&this.compressedSize===E.EF_ZIP64_OR_32&&(this.compressedSize=De(e,t),t+=8,r-=8),r>=8&&this.offset===E.EF_ZIP64_OR_32&&(this.offset=De(e,t),t+=8,r-=8),r>=4&&this.diskStart===E.EF_ZIP64_OR_16&&(this.diskStart=e.readUInt32LE(t))}get encrypted(){return(this.flags&E.FLG_ENTRY_ENC)===E.FLG_ENTRY_ENC}get isFile(){return!this.isDirectory}},Ae=class{constructor(e,t,r,i,s,o){this.fd=e,this.buffer=t,this.offset=r,this.length=i,this.position=s,this.callback=o,this.bytesRead=0,this.waiting=!1}read(e){Me.debugLog("read",this.position,this.bytesRead,this.length,this.offset),this.waiting=!0;let t;if(e){let r=0;try{r=le.readSync(this.fd,this.buffer,this.offset+this.bytesRead,this.length-this.bytesRead,this.position+this.bytesRead)}catch(i){t=i}this.readCallback(e,t,t?r:null)}else le.read(this.fd,this.buffer,this.offset+this.bytesRead,this.length-this.bytesRead,this.position+this.bytesRead,this.readCallback.bind(this,e))}readCallback(e,t,r){if(typeof r=="number"&&(this.bytesRead+=r),t||!r||this.bytesRead===this.length)return this.waiting=!1,this.callback(t,this.bytesRead);this.read(e)}},wr=class{constructor(e){this.position=0,this.buffer=Buffer.alloc(0),this.fd=e,this.fsOp=null}checkOp(){if(this.fsOp&&this.fsOp.waiting)throw new Error("Operation in progress")}read(e,t,r){this.checkOp(),this.buffer.length{this.emit("error",i)})}_transform(e,t,r){let i;try{this.verify.data(e)}catch(s){i=s}r(i,e)}},yr=class n{constructor(e,t){this.crc=e,this.size=t,this.state={crc:-1,size:0}}data(e){let t=n.getCrcTable(),r=this.state.crc,i=0,s=e.length;for(;--s>=0;)r=t[(r^e[i++])&255]^r>>>8;if(this.state.crc=r,this.state.size+=e.length,this.state.size>=this.size){let o=Buffer.alloc(4);if(o.writeInt32LE(~this.state.crc&4294967295,0),r=o.readUInt32LE(0),r!==this.crc)throw new Error("Invalid CRC");if(this.state.size!==this.size)throw new Error("Invalid size")}}static getCrcTable(){let e=n.crcTable;if(!e){n.crcTable=e=[];let t=Buffer.alloc(4);for(let r=0;r<256;r++){let i=r;for(let s=8;--s>=0;)(i&1)!==0?i=3988292384^i>>>1:i=i>>>1;i<0&&(t.writeInt32LE(i,0),i=t.readUInt32LE(0)),e[r]=i}}return e}};function Wl(n,e){let t=ql(n,16),r=ql(e,16),i={h:parseInt(t.slice(0,5).join(""),2),m:parseInt(t.slice(5,11).join(""),2),s:parseInt(t.slice(11,16).join(""),2)*2,Y:parseInt(r.slice(0,7).join(""),2)+1980,M:parseInt(r.slice(7,11).join(""),2),D:parseInt(r.slice(11,16).join(""),2)},s=[i.Y,i.M,i.D].join("-")+" "+[i.h,i.m,i.s].join(":")+" GMT+0";return new Date(s).getTime()}function ql(n,e){let t=(n>>>0).toString(2);for(;t.lengthQl.async,WebSocket:()=>ko,ZipFile:()=>Jl.ZipFile,convertSourceMap:()=>dh,decode:()=>ni,diffSequence:()=>Kl.default,findUpSync:()=>wl,minimatch:()=>Z,parseCss:()=>Xl.default,supportsColor:()=>Yl});module.exports=oa(ph);var dh=j(Qn());var ma=44;var ei="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",ga=new Uint8Array(64),ri=new Uint8Array(128);for(let n=0;n>>=1,s&&(t=-2147483648|-t),e+t}function ti(n,e){return n.pos>=e?!1:n.peek()!==ma}var _h=1024*16;var _a=class{constructor(n){this.pos=0,this.buffer=n}next(){return this.buffer.charCodeAt(this.pos++)}peek(){return this.buffer.charCodeAt(this.pos)}indexOf(n){let{buffer:e,pos:t}=this,r=e.indexOf(n,t);return r===-1?e.length:r}};function ni(n){let{length:e}=n,t=new _a(n),r=[],i=0,s=0,o=0,a=0,l=0;do{let f=t.indexOf(";"),u=[],h=!0,c=0;for(i=0;t.pos{if(typeof n!="string")throw new TypeError("invalid pattern");if(n.length>65536)throw new TypeError("pattern is too long")};var sc={"[:alnum:]":["\\p{L}\\p{Nl}\\p{Nd}",!0],"[:alpha:]":["\\p{L}\\p{Nl}",!0],"[:ascii:]":["\\x00-\\x7f",!1],"[:blank:]":["\\p{Zs}\\t",!0],"[:cntrl:]":["\\p{Cc}",!0],"[:digit:]":["\\p{Nd}",!0],"[:graph:]":["\\p{Z}\\p{C}",!0,!0],"[:lower:]":["\\p{Ll}",!0],"[:print:]":["\\p{C}",!0],"[:punct:]":["\\p{P}",!0],"[:space:]":["\\p{Z}\\t\\r\\n\\v\\f",!0],"[:upper:]":["\\p{Lu}",!0],"[:word:]":["\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}",!0],"[:xdigit:]":["A-Fa-f0-9",!1]},Rt=n=>n.replace(/[[\]\\-]/g,"\\$&"),oc=n=>n.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),Jo=n=>n.join(""),Qo=(n,e)=>{let t=e;if(n.charAt(t)!=="[")throw new Error("not in a brace expression");let r=[],i=[],s=t+1,o=!1,a=!1,l=!1,f=!1,u=t,h="";e:for(;sh?r.push(Rt(h)+"-"+Rt(p)):p===h&&r.push(Rt(p)),h="",s++;continue}if(n.startsWith("-]",s+1)){r.push(Rt(p+"-")),s+=2;continue}if(n.startsWith("-",s+1)){h=p,s+=2;continue}r.push(Rt(p)),s++}if(ue?n.replace(/\[([^\/\\])\]/g,"$1"):n.replace(/((?!\\).|^)\[([^\/\\])\]/g,"$1$2").replace(/\\([^\/])/g,"$1");var lc=new Set(["!","?","+","*","@"]),el=n=>lc.has(n),ac="(?!(?:^|/)\\.\\.?(?:$|/))",ur="(?!\\.)",fc=new Set(["[","."]),uc=new Set(["..","."]),cc=new Set("().*{}+?[]^$\\!"),hc=n=>n.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),Ln="[^/]",tl=Ln+"*?",rl=Ln+"+?",nt=class n{type;#r;#n;#s=!1;#e=[];#t;#o;#a;#l=!1;#i;#f;#c=!1;constructor(e,t,r={}){this.type=e,e&&(this.#n=!0),this.#t=t,this.#r=this.#t?this.#t.#r:this,this.#i=this.#r===this?r:this.#r.#i,this.#a=this.#r===this?[]:this.#r.#a,e==="!"&&!this.#r.#l&&this.#a.push(this),this.#o=this.#t?this.#t.#e.length:0}get hasMagic(){if(this.#n!==void 0)return this.#n;for(let e of this.#e)if(typeof e!="string"&&(e.type||e.hasMagic))return this.#n=!0;return this.#n}toString(){return this.#f!==void 0?this.#f:this.type?this.#f=this.type+"("+this.#e.map(e=>String(e)).join("|")+")":this.#f=this.#e.map(e=>String(e)).join("")}#d(){if(this!==this.#r)throw new Error("should only call on root");if(this.#l)return this;this.toString(),this.#l=!0;let e;for(;e=this.#a.pop();){if(e.type!=="!")continue;let t=e,r=t.#t;for(;r;){for(let i=t.#o+1;!r.type&&itypeof r=="string"?r:r.toJSON()):[this.type,...this.#e.map(r=>r.toJSON())];return this.isStart()&&!this.type&&e.unshift([]),this.isEnd()&&(this===this.#r||this.#r.#l&&((t=this.#t)==null?void 0:t.type)==="!")&&e.push({}),e}isStart(){var t;if(this.#r===this)return!0;if(!((t=this.#t)!=null&&t.isStart()))return!1;if(this.#o===0)return!0;let e=this.#t;for(let r=0;r{let[p,_,v,C]=typeof m=="string"?n.#p(m,this.#n,f):m.toRegExpSource(e);return this.#n=this.#n||v,this.#s=this.#s||C,p}).join(""),h="";if(this.isStart()&&typeof this.#e[0]=="string"&&!(this.#e.length===1&&uc.has(this.#e[0]))){let p=fc,_=t&&p.has(u.charAt(0))||u.startsWith("\\.")&&p.has(u.charAt(2))||u.startsWith("\\.\\.")&&p.has(u.charAt(4)),v=!t&&!e&&p.has(u.charAt(0));h=_?ac:v?ur:""}let c="";return this.isEnd()&&this.#r.#l&&((l=this.#t)==null?void 0:l.type)==="!"&&(c="(?:$|\\/)"),[h+u+c,Oe(u),this.#n=!!this.#n,this.#s]}let r=this.type==="*"||this.type==="+",i=this.type==="!"?"(?:(?!(?:":"(?:",s=this.#h(t);if(this.isStart()&&this.isEnd()&&!s&&this.type!=="!"){let f=this.toString();return this.#e=[f],this.type=null,this.#n=void 0,[f,Oe(this.toString()),!1,!1]}let o=!r||e||t||!ur?"":this.#h(!0);o===s&&(o=""),o&&(s=`(?:${s})(?:${o})*?`);let a="";if(this.type==="!"&&this.#c)a=(this.isStart()&&!t?ur:"")+rl;else{let f=this.type==="!"?"))"+(this.isStart()&&!t&&!e?ur:"")+tl+")":this.type==="@"?")":this.type==="?"?")?":this.type==="+"&&o?")":this.type==="*"&&o?")?":`)${this.type}`;a=i+s+f}return[a,Oe(s),this.#n=!!this.#n,this.#s]}#h(e){return this.#e.map(t=>{if(typeof t=="string")throw new Error("string type in extglob ast??");let[r,i,s,o]=t.toRegExpSource(e);return this.#s=this.#s||o,r}).filter(t=>!(this.isStart()&&this.isEnd())||!!t).join("|")}static#p(e,t,r=!1){let i=!1,s="",o=!1;for(let a=0;ae?n.replace(/[?*()[\]]/g,"[$&]"):n.replace(/[?*()[\]\\]/g,"\\$&");var Z=(n,e,t={})=>(Tt(e),!t.nocomment&&e.charAt(0)==="#"?!1:new it(e,t).match(n)),dc=/^\*+([^+@!?\*\[\(]*)$/,pc=n=>e=>!e.startsWith(".")&&e.endsWith(n),mc=n=>e=>e.endsWith(n),gc=n=>(n=n.toLowerCase(),e=>!e.startsWith(".")&&e.toLowerCase().endsWith(n)),_c=n=>(n=n.toLowerCase(),e=>e.toLowerCase().endsWith(n)),Ec=/^\*+\.\*+$/,wc=n=>!n.startsWith(".")&&n.includes("."),yc=n=>n!=="."&&n!==".."&&n.includes("."),Sc=/^\.\*+$/,vc=n=>n!=="."&&n!==".."&&n.startsWith("."),xc=/^\*+$/,Cc=n=>n.length!==0&&!n.startsWith("."),bc=n=>n.length!==0&&n!=="."&&n!=="..",Lc=/^\?+([^+@!?\*\[\(]*)?$/,Oc=([n,e=""])=>{let t=ol([n]);return e?(e=e.toLowerCase(),r=>t(r)&&r.toLowerCase().endsWith(e)):t},Ic=([n,e=""])=>{let t=ll([n]);return e?(e=e.toLowerCase(),r=>t(r)&&r.toLowerCase().endsWith(e)):t},Nc=([n,e=""])=>{let t=ll([n]);return e?r=>t(r)&&r.endsWith(e):t},Tc=([n,e=""])=>{let t=ol([n]);return e?r=>t(r)&&r.endsWith(e):t},ol=([n])=>{let e=n.length;return t=>t.length===e&&!t.startsWith(".")},ll=([n])=>{let e=n.length;return t=>t.length===e&&t!=="."&&t!==".."},al=typeof process=="object"&&process?typeof process.env=="object"&&process.env&&process.env.__MINIMATCH_TESTING_PLATFORM__||process.platform:"posix",nl={win32:{sep:"\\"},posix:{sep:"/"}},Rc=al==="win32"?nl.win32.sep:nl.posix.sep;Z.sep=Rc;var oe=Symbol("globstar **");Z.GLOBSTAR=oe;var Ac="[^/]",Dc=Ac+"*?",Mc="(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?",Pc="(?:(?!(?:\\/|^)\\.).)*?",Fc=(n,e={})=>t=>Z(t,n,e);Z.filter=Fc;var se=(n,e={})=>Object.assign({},n,e),Uc=n=>{if(!n||typeof n!="object"||!Object.keys(n).length)return Z;let e=Z;return Object.assign((r,i,s={})=>e(r,i,se(n,s)),{Minimatch:class extends e.Minimatch{constructor(i,s={}){super(i,se(n,s))}static defaults(i){return e.defaults(se(n,i)).Minimatch}},AST:class extends e.AST{constructor(i,s,o={}){super(i,s,se(n,o))}static fromGlob(i,s={}){return e.AST.fromGlob(i,se(n,s))}},unescape:(r,i={})=>e.unescape(r,se(n,i)),escape:(r,i={})=>e.escape(r,se(n,i)),filter:(r,i={})=>e.filter(r,se(n,i)),defaults:r=>e.defaults(se(n,r)),makeRe:(r,i={})=>e.makeRe(r,se(n,i)),braceExpand:(r,i={})=>e.braceExpand(r,se(n,i)),match:(r,i,s={})=>e.match(r,i,se(n,s)),sep:e.sep,GLOBSTAR:oe})};Z.defaults=Uc;var fl=(n,e={})=>(Tt(n),e.nobrace||!/\{(?:(?!\{).)*\}/.test(n)?[n]:(0,sl.default)(n));Z.braceExpand=fl;var kc=(n,e={})=>new it(n,e).makeRe();Z.makeRe=kc;var Bc=(n,e,t={})=>{let r=new it(e,t);return n=n.filter(i=>r.match(i)),r.options.nonull&&!n.length&&n.push(e),n};Z.match=Bc;var il=/[?*]|[+@!]\(.*?\)|\[|\]/,zc=n=>n.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),it=class{options;set;pattern;windowsPathsNoEscape;nonegate;negate;comment;empty;preserveMultipleSlashes;partial;globSet;globParts;nocase;isWindows;platform;windowsNoMagicRoot;regexp;constructor(e,t={}){Tt(e),t=t||{},this.options=t,this.pattern=e,this.platform=t.platform||al,this.isWindows=this.platform==="win32",this.windowsPathsNoEscape=!!t.windowsPathsNoEscape||t.allowWindowsEscape===!1,this.windowsPathsNoEscape&&(this.pattern=this.pattern.replace(/\\/g,"/")),this.preserveMultipleSlashes=!!t.preserveMultipleSlashes,this.regexp=null,this.negate=!1,this.nonegate=!!t.nonegate,this.comment=!1,this.empty=!1,this.partial=!!t.partial,this.nocase=!!this.options.nocase,this.windowsNoMagicRoot=t.windowsNoMagicRoot!==void 0?t.windowsNoMagicRoot:!!(this.isWindows&&this.nocase),this.globSet=[],this.globParts=[],this.set=[],this.make()}hasMagic(){if(this.options.magicalBraces&&this.set.length>1)return!0;for(let e of this.set)for(let t of e)if(typeof t!="string")return!0;return!1}debug(...e){}make(){let e=this.pattern,t=this.options;if(!t.nocomment&&e.charAt(0)==="#"){this.comment=!0;return}if(!e){this.empty=!0;return}this.parseNegate(),this.globSet=[...new Set(this.braceExpand())],t.debug&&(this.debug=(...s)=>console.error(...s)),this.debug(this.pattern,this.globSet);let r=this.globSet.map(s=>this.slashSplit(s));this.globParts=this.preprocess(r),this.debug(this.pattern,this.globParts);let i=this.globParts.map((s,o,a)=>{if(this.isWindows&&this.windowsNoMagicRoot){let l=s[0]===""&&s[1]===""&&(s[2]==="?"||!il.test(s[2]))&&!il.test(s[3]),f=/^[a-z]:/i.test(s[0]);if(l)return[...s.slice(0,4),...s.slice(4).map(u=>this.parse(u))];if(f)return[s[0],...s.slice(1).map(u=>this.parse(u))]}return s.map(l=>this.parse(l))});if(this.debug(this.pattern,i),this.set=i.filter(s=>s.indexOf(!1)===-1),this.isWindows)for(let s=0;s=2?(e=this.firstPhasePreProcess(e),e=this.secondPhasePreProcess(e)):t>=1?e=this.levelOneOptimize(e):e=this.adjascentGlobstarOptimize(e),e}adjascentGlobstarOptimize(e){return e.map(t=>{let r=-1;for(;(r=t.indexOf("**",r+1))!==-1;){let i=r;for(;t[i+1]==="**";)i++;i!==r&&t.splice(r,i-r)}return t})}levelOneOptimize(e){return e.map(t=>(t=t.reduce((r,i)=>{let s=r[r.length-1];return i==="**"&&s==="**"?r:i===".."&&s&&s!==".."&&s!=="."&&s!=="**"?(r.pop(),r):(r.push(i),r)},[]),t.length===0?[""]:t))}levelTwoFileOptimize(e){Array.isArray(e)||(e=this.slashSplit(e));let t=!1;do{if(t=!1,!this.preserveMultipleSlashes){for(let i=1;ii&&r.splice(i+1,o-i);let a=r[i+1],l=r[i+2],f=r[i+3];if(a!==".."||!l||l==="."||l===".."||!f||f==="."||f==="..")continue;t=!0,r.splice(i,1);let u=r.slice(0);u[i]="**",e.push(u),i--}if(!this.preserveMultipleSlashes){for(let o=1;ot.length)}partsMatch(e,t,r=!1){let i=0,s=0,o=[],a="";for(;iI?t=t.slice(L):I>L&&(e=e.slice(I)))}}let{optimizationLevel:s=1}=this.options;s>=2&&(e=this.levelTwoFileOptimize(e)),this.debug("matchOne",this,{file:e,pattern:t}),this.debug("matchOne",e.length,t.length);for(var o=0,a=0,l=e.length,f=t.length;o>> no match, partial?`,e,c,t,d),c===l))}let p;if(typeof u=="string"?(p=h===u,this.debug("string match",u,h,p)):(p=u.test(h),this.debug("pattern match",u,h,p)),!p)return!1}if(o===l&&a===f)return!0;if(o===l)return r;if(a===f)return o===l-1&&e[o]==="";throw new Error("wtf?")}braceExpand(){return fl(this.pattern,this.options)}parse(e){Tt(e);let t=this.options;if(e==="**")return oe;if(e==="")return"";let r,i=null;(r=e.match(xc))?i=t.dot?bc:Cc:(r=e.match(dc))?i=(t.nocase?t.dot?_c:gc:t.dot?mc:pc)(r[1]):(r=e.match(Lc))?i=(t.nocase?t.dot?Ic:Oc:t.dot?Nc:Tc)(r):(r=e.match(Ec))?i=t.dot?yc:wc:(r=e.match(Sc))&&(i=vc);let s=nt.fromGlob(e,this.options).toMMPattern();return i&&typeof s=="object"&&Reflect.defineProperty(s,"test",{value:i}),s}makeRe(){if(this.regexp||this.regexp===!1)return this.regexp;let e=this.set;if(!e.length)return this.regexp=!1,this.regexp;let t=this.options,r=t.noglobstar?Dc:t.dot?Mc:Pc,i=new Set(t.nocase?["i"]:[]),s=e.map(l=>{let f=l.map(u=>{if(u instanceof RegExp)for(let h of u.flags.split(""))i.add(h);return typeof u=="string"?zc(u):u===oe?oe:u._src});return f.forEach((u,h)=>{let c=f[h+1],d=f[h-1];u!==oe||d===oe||(d===void 0?c!==void 0&&c!==oe?f[h+1]="(?:\\/|"+r+"\\/)?"+c:f[h]=r:c===void 0?f[h-1]=d+"(?:\\/|"+r+")?":c!==oe&&(f[h-1]=d+"(?:\\/|\\/"+r+"\\/)"+c,f[h+1]=oe))}),f.filter(u=>u!==oe).join("/")}).join("|"),[o,a]=e.length>1?["(?:",")"]:["",""];s="^"+o+s+a+"$",this.negate&&(s="^(?!"+s+").+$");try{this.regexp=new RegExp(s,[...i].join(""))}catch{this.regexp=!1}return this.regexp}slashSplit(e){return this.preserveMultipleSlashes?e.split("/"):this.isWindows&&/^\/\/[^\/]+/.test(e)?["",...e.split(/\/+/)]:e.split(/\/+/)}match(e,t=this.partial){if(this.debug("match",e,this.pattern),this.comment)return!1;if(this.empty)return e==="";if(e==="/"&&t)return!0;let r=this.options;this.isWindows&&(e=e.split("\\").join("/"));let i=this.slashSplit(e);this.debug(this.pattern,"split",i);let s=this.set;this.debug(this.pattern,"set",s);let o=i[i.length-1];if(!o)for(let a=i.length-2;!o&&a>=0;a--)o=i[a];for(let a=0;ae[_l[n]](),Hc=n=>n instanceof URL?(0,gl.fileURLToPath)(n):n;function Rn(n,{cwd:e=pl.default.cwd(),type:t="file",allowSymlinks:r=!0}={}){$c(t),e=Hc(e);let i=r?cr.default.statSync:cr.default.lstatSync;for(let s of n)try{let o=i(ml.default.resolve(e,s),{throwIfNoEntry:!1});if(!o)continue;if(Vc(t,o))return s}catch{}}var El=require("node:url");function An(n){return n instanceof URL?(0,El.fileURLToPath)(n):n}var Zc=Symbol("findUpStop");function Yc(n,e={}){let t=st.default.resolve(An(e.cwd)??""),{root:r}=st.default.parse(t),i=st.default.resolve(t,An(e.stopAt)??r),s=e.limit??Number.POSITIVE_INFINITY,o=[n].flat(),a=f=>{if(typeof n!="function")return Rn(o,f);let u=n(f.cwd);return typeof u=="string"?Rn([u],f):u},l=[];for(;;){let f=a({...e,cwd:t});if(f===Zc||(f&&l.push(st.default.resolve(t,f)),t===i||l.length>=s))break;t=st.default.dirname(t)}return l}function wl(n,e={}){return Yc(n,{...e,limit:1})[0]}var Jl=j(zl()),Ql=j(Vl());var vr=j(require("node:process"),1),Zl=j(require("node:os"),1),Yn=j(require("node:tty"),1);function ae(n,e=globalThis.Deno?globalThis.Deno.args:vr.default.argv){let t=n.startsWith("-")?"":n.length===1?"-":"--",r=e.indexOf(t+n),i=e.indexOf("--");return r!==-1&&(i===-1||r=2,has16m:n>=3}}function ch(n,{streamIsTTY:e,sniffFlags:t=!0}={}){let r=fh();r!==void 0&&(Sr=r);let i=t?Sr:r;if(i===0)return 0;if(t){if(ae("color=16m")||ae("color=full")||ae("color=truecolor"))return 3;if(ae("color=256"))return 2}if("TF_BUILD"in k&&"AGENT_NAME"in k)return 1;if(n&&!e&&i===void 0)return 0;let s=i||0;if(k.TERM==="dumb")return s;if(vr.default.platform==="win32"){let o=Zl.default.release().split(".");return Number(o[0])>=10&&Number(o[2])>=10586?Number(o[2])>=14931?3:2:1}if("CI"in k)return["GITHUB_ACTIONS","GITEA_ACTIONS","CIRCLECI"].some(o=>o in k)?3:["TRAVIS","APPVEYOR","GITLAB_CI","BUILDKITE","DRONE"].some(o=>o in k)||k.CI_NAME==="codeship"?1:s;if("TEAMCITY_VERSION"in k)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(k.TEAMCITY_VERSION)?1:0;if(k.COLORTERM==="truecolor"||k.TERM==="xterm-kitty"||k.TERM==="xterm-ghostty"||k.TERM==="wezterm")return 3;if("TERM_PROGRAM"in k){let o=Number.parseInt((k.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(k.TERM_PROGRAM){case"iTerm.app":return o>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(k.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(k.TERM)||"COLORTERM"in k?1:s}function Hl(n,e={}){let t=ch(n,{streamIsTTY:n&&n.isTTY,...e});return uh(t)}var hh={stdout:Hl({isTTY:Yn.default.isatty(1)}),stderr:Hl({isTTY:Yn.default.isatty(2)})},Yl=hh;0&&(module.exports={StreamZip,WebSocket,ZipFile,convertSourceMap,decode,diffSequence,findUpSync,minimatch,parseCss,supportsColor}); diff --git a/node_modules/monocart-coverage-reports/lib/platform/concurrency.js b/node_modules/monocart-coverage-reports/lib/platform/concurrency.js new file mode 100644 index 0000000..0a280d7 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/platform/concurrency.js @@ -0,0 +1,74 @@ +class Concurrency { + + constructor(maxCount = 10) { + this.maxCount = maxCount; + this.list = []; + } + + addItem(item) { + this.list.push(item); + } + + addList(list) { + this.list = this.list.concat(list); + } + + start(handler) { + // must be async function + if (typeof handler !== 'function') { + return; + } + this.handler = handler; + this.count = 0; + return new Promise((resolve) => { + this.resolve = resolve; + this.next(); + }); + } + + next() { + // console.log(`list: ${this.list.length} count: ${this.count}`); + + // if has clear + if (!this.resolve) { + return; + } + + if (!this.list.length) { + // no list but has in progress count + if (this.count > 0) { + return; + } + // all finish + this.resolve(); + this.clear(); + return; + } + + // out of concurrency count, just wait + if (this.count >= this.maxCount) { + return; + } + + const item = this.list.shift(); + this.count += 1; + + // async handler + this.handler(item).finally(() => { + this.count -= 1; + this.next(); + }); + + this.next(); + } + + clear() { + this.list = []; + this.handler = null; + this.count = 0; + this.resolve = null; + } + +} + +module.exports = Concurrency; diff --git a/node_modules/monocart-coverage-reports/lib/platform/share.js b/node_modules/monocart-coverage-reports/lib/platform/share.js new file mode 100644 index 0000000..ef5fb6e --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/platform/share.js @@ -0,0 +1,538 @@ +const Util = { + + hasOwn: function(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); + }, + + isNull: function(input) { + if (input === null || typeof input === 'undefined') { + return true; + } + return false; + }, + + uid: function(len = 20, prefix = '') { + const dict = '0123456789abcdefghijklmnopqrstuvwxyz'; + const dictLen = dict.length; + let str = prefix; + while (len--) { + str += dict[Math.random() * dictLen | 0]; + } + return str; + }, + + zero: function(s, l = 2) { + s = `${s}`; + return s.padStart(l, '0'); + }, + + isNum: function(num) { + if (typeof num !== 'number' || isNaN(num)) { + return false; + } + const isInvalid = function(n) { + if (n === Number.MAX_VALUE || n === Number.MIN_VALUE || n === Number.NEGATIVE_INFINITY || n === Number.POSITIVE_INFINITY) { + return true; + } + return false; + }; + if (isInvalid(num)) { + return false; + } + return true; + }, + + toNum: function(num, toInt) { + if (typeof (num) !== 'number') { + num = parseFloat(num); + } + if (isNaN(num)) { + num = 0; + } + if (toInt) { + num = Math.round(num); + } + return num; + }, + + isList: function(data) { + if (data && data instanceof Array && data.length > 0) { + return true; + } + return false; + }, + + toList: function(data, separator) { + if (data instanceof Array) { + return data; + } + if (typeof data === 'string' && (typeof separator === 'string' || separator instanceof RegExp)) { + return data.split(separator).map((str) => str.trim()).filter((str) => str); + } + if (typeof data === 'undefined' || data === null) { + return []; + } + return [data]; + }, + + forEach: function(rootList, callback) { + const isBreak = (res) => { + return res === 'break' || res === false; + }; + const forList = (list, parent) => { + if (!Util.isList(list)) { + return; + } + for (const item of list) { + const result = callback(item, parent); + if (isBreak(result)) { + return result; + } + const subResult = forList(item.subs, item); + if (isBreak(subResult)) { + return subResult; + } + } + }; + forList(rootList); + }, + + // \ to / + formatPath: function(str) { + if (str) { + str = str.replace(/\\/g, '/'); + } + return str; + }, + + getCurrentTrendInfo: (data) => { + + const { + date, duration, summary + } = data; + + const info = { + date, + duration + }; + + Object.keys(summary).forEach((k) => { + const item = summary[k]; + info[k] = item.value; + }); + + return info; + }, + + isTagItem: (item) => { + if (item.type === 'case' || (item.type === 'suite' && item.suiteType === 'describe')) { + return true; + } + return false; + }, + + delay: function(ms) { + return new Promise((resolve) => { + if (ms) { + setTimeout(resolve, ms); + } else { + setImmediate(resolve); + } + }); + }, + + // ============================================================================= + + getMetrics: (metrics, type) => { + const istanbulMetrics = ['statements', 'branches', 'functions', 'lines']; + const v8Metrics = ['bytes'].concat(istanbulMetrics); + const allMetrics = type === 'istanbul' ? istanbulMetrics : v8Metrics; + let list = allMetrics; + if (Util.isList(metrics)) { + const newList = list.filter((k) => metrics.includes(k)); + if (newList.length) { + list = newList; + } + } + return list; + }, + + generatePercentChart: function(percent) { + return `
`; + }, + + getStatus: (value, watermarks) => { + if (!watermarks) { + return 'unknown'; + } + if (value < watermarks[0]) { + return 'low'; + } + if (value < watermarks[1]) { + return 'medium'; + } + return 'high'; + }, + + isJsonType: (contentType) => { + if (contentType) { + if (contentType === 'application/json' || contentType === 'json') { + return true; + } + } + return false; + }, + + isMarkdownType: (contentType) => { + if (contentType) { + if (contentType === 'text/markdown' || contentType === 'markdown') { + return true; + } + } + return false; + }, + + isTextType: (contentType) => { + if (contentType) { + if (contentType.startsWith('text')) { + return true; + } + if (Util.isMarkdownType(contentType)) { + return true; + } + if (Util.isJsonType(contentType)) { + return true; + } + } + return false; + }, + + isBlank: (codeStr) => { + if (typeof codeStr === 'string') { + const blankBlock = /\S/; + return !blankBlock.test(codeStr); + } + return false; + }, + + findInRanges: (startPos, endPos, rangeList, startKey = 'start', endKey = 'end') => { + if (!Util.isList(rangeList)) { + return; + } + + // rangeList should be sorted by startKey, but seems useless here + const list = rangeList.filter((it) => startPos >= it[startKey] && endPos <= it[endKey]); + if (!list.length) { + return; + } + + // could be multiple results, but seems no case for now + // if (list.length > 1) { + // console.log('==============', list); + // } + + return list[0]; + }, + + getRangeLines: (sLoc, eLoc) => { + + const lines = []; + + // invalid location order + if (sLoc.line > eLoc.line) { + return lines; + } + + // nothing middle + if (sLoc.line === eLoc.line && sLoc.column >= eLoc.column) { + return lines; + } + + const addStart = () => { + + // nothing start + if (sLoc.column >= sLoc.length) { + return; + } + + const entire = sLoc.column <= sLoc.indent; + lines.push({ + line: sLoc.line, + entire, + pieces: { + start: sLoc.column, + end: sLoc.length + } + }); + }; + + const addMiddle = () => { + + const start = sLoc.column <= sLoc.indent; + const end = Util.isBlank(eLoc.text.slice(eLoc.column)); + const entire = start && end; + // same line + lines.push({ + line: sLoc.line, + entire, + pieces: { + start: sLoc.column, + end: eLoc.column + } + }); + }; + + const addEnd = () => { + + // nothing end + if (eLoc.column === 0) { + return; + } + + // pieces in indent, ignored + if (eLoc.column <= eLoc.indent) { + return; + } + + const rightText = eLoc.text.slice(eLoc.column); + + // right text is blank or only ";" (few cases) + const entire = Util.isBlank(rightText) || rightText.trim() === ';'; + lines.push({ + line: eLoc.line, + entire, + pieces: { + start: eLoc.indent, + end: eLoc.column + } + }); + }; + + // same line, single line + if (sLoc.line === eLoc.line) { + + addMiddle(); + + } else { + // multiple lines + + addStart(); + + // always entire for middle lines + const lineStart = sLoc.line + 1; + const lineEnd = eLoc.line; + if (lineEnd > lineStart) { + for (let i = lineStart; i < lineEnd; i++) { + lines.push({ + line: i, + entire: true + // no pieces for entire line + }); + } + } + + // check end + addEnd(); + } + + return lines; + }, + + initLineCoverage: (lineItem) => { + lineItem.coveredCount = 1; + lineItem.uncoveredEntire = null; + lineItem.uncoveredPieces = []; + }, + + updateLinesCoverage: (lines, count, lineMap) => { + lines.forEach((it) => { + const lineItem = lineMap.get(it.line); + if (!lineItem) { + // not found line, could be comment or blank line + return; + } + + if (lineItem.ignored) { + return; + } + + it.count = count; + + // default is covered, so only focus on + // 1, biggest covered count + // 2, uncovered entire and pieces + if (count > 0) { + lineItem.coveredCount = Math.max(lineItem.coveredCount, count); + return; + } + + if (it.entire) { + lineItem.uncoveredEntire = it; + } else { + lineItem.uncoveredPieces.push(it); + } + + }); + + }, + + // ============================================================================= + // svg + + dFixed: (num, fixed = 1) => { + if (Number.isInteger(num)) { + return num; + } + return Util.toNum(Util.toNum(num).toFixed(fixed)); + }, + + pxFixed: (num) => { + const floor = Math.floor(num); + if (num < floor + 0.5) { + return floor + 0.5; + } + return floor + 1.5; + }, + + point: (px, py) => { + return `${Util.dFixed(px)},${Util.dFixed(py)}`; + }, + + capitalizeFirstLetter: (string) => { + return string.charAt(0).toUpperCase() + string.slice(1); + }, + + jsonParse: function(str) { + + if (typeof str !== 'string') { + return null; + } + + if (!str) { + return null; + } + + let json = null; + + // remove BOM \ufeff + // str = str.replace(/^\uFEFF/, ''); + + try { + json = JSON.parse(str); + } catch (e) { + // console.log(e); + } + + return json; + }, + + // ============================================================================= + // formatter + + // number + NF: function(v) { + if (typeof v === 'number' && v) { + return v.toLocaleString(); + } + return v; + }, + + // percent + PF: function(v, t = 1, digits = 1, unit = '%', space = '') { + v = Util.toNum(v); + t = Util.toNum(t); + let per = 0; + if (t) { + per = v / t; + } + const perStr = (per * 100).toFixed(digits); + if (unit) { + return perStr + space + unit; + } + return parseFloat(perStr); + }, + + PSF: function(v, t = 1, digits = 1) { + return Util.PF(v, t, digits, '%', ' '); + }, + + PNF: function(v, t = 1, digits = 1) { + return Util.PF(v, t, digits, ''); + }, + + // byte + BF: function(v, places = 1, space = '') { + v = Util.toNum(v, true); + if (v === 0) { + return `0${space}B`; + } + let prefix = ''; + if (v < 0) { + v = Math.abs(v); + prefix = '-'; + } + + const base = 1024; + const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + for (let i = 0, l = units.length; i < l; i++) { + const min = Math.pow(base, i); + const max = Math.pow(base, i + 1); + if (v > min && v < max) { + const unit = units[i]; + v = prefix + parseFloat((v / min).toFixed(places)) + space + unit; + break; + } + } + return v; + }, + + BSF: function(v, places = 1) { + return Util.BF(v, places, ' '); + }, + + // time + TF: function(v, space = '') { + const ms = Util.toNum(v, true); + + if (ms < 1000) { + return `${ms}${space}ms`; + } + + if (ms < 60 * 1000) { + const ss = parseFloat((ms / 1000).toFixed(1)); + return `${ss}${space}s`; + } + + const s = Math.round(ms / 1000); + + const m = 60; + const h = m * 60; + const d = h * 24; + + if (s < h) { + const minutes = Math.floor(s / m); + const seconds = s - minutes * m; + return `${minutes}${space}m ${seconds}${space}s`; + } + + if (s < d) { + const hours = Math.floor(s / h); + const minutes = Math.floor((s - hours * h) / m); + const seconds = s - hours * h - minutes * m; + return `${hours}${space}h ${minutes}${space}m ${seconds}${space}s`; + } + + const days = Math.floor(s / d); + const hours = Math.floor((s - days * d) / h); + const minutes = Math.floor((s - days * d - hours * h) / m); + const seconds = s - days * d - hours * h - minutes * m; + return `${days}${space}d ${hours}${space}h ${minutes}${space}m ${seconds}${space}s`; + }, + + TSF: function(v) { + return Util.TF(v, ' '); + } +}; + + +module.exports = Util; diff --git a/node_modules/monocart-coverage-reports/lib/register/hooks.js b/node_modules/monocart-coverage-reports/lib/register/hooks.js new file mode 100644 index 0000000..64a1cf5 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/register/hooks.js @@ -0,0 +1,58 @@ +const fs = require('fs'); +const path = require('path'); +const Util = require('../utils/util.js'); +const { convertSourceMap } = require('../packages/monocart-coverage-vendor.js'); + +function saveFile(url, source, dir) { + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { + recursive: true + }); + } + + const id = Util.calculateSha1(url + source); + const filePath = path.resolve(dir, `source-${id}.json`); + if (!fs.existsSync(filePath)) { + fs.writeFileSync(filePath, JSON.stringify({ + url, + source + })); + } + +} + +function saveSource(url, loaded, dir) { + + // filter node modules + if (url.startsWith('node:')) { + return; + } + + const { source, format } = loaded; + if (typeof source !== 'string' || !['module', 'commonjs'].includes(format)) { + // no source or wrong format + return; + } + + if (!convertSourceMap.mapFileCommentRegex.test(source)) { + // no sourcemap + return; + } + + saveFile(url, source, dir); + +} + +async function load(url, context, nextLoad) { + const loaded = await nextLoad(url, context); + const dir = process.env.NODE_V8_COVERAGE; + if (dir) { + // only for coverage enabled + saveSource(url, loaded, dir); + } + return loaded; +} + +module.exports = { + load +}; diff --git a/node_modules/monocart-coverage-reports/lib/register/hooks.mjs b/node_modules/monocart-coverage-reports/lib/register/hooks.mjs new file mode 100644 index 0000000..53e4357 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/register/hooks.mjs @@ -0,0 +1,3 @@ +import { load } from './hooks.js'; + +export { load }; diff --git a/node_modules/monocart-coverage-reports/lib/register/register.js b/node_modules/monocart-coverage-reports/lib/register/register.js new file mode 100644 index 0000000..87a14e1 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/register/register.js @@ -0,0 +1,4 @@ +const { register } = require('module'); +const { pathToFileURL } = require('url'); + +register('./hooks.js', pathToFileURL(__filename)); diff --git a/node_modules/monocart-coverage-reports/lib/register/register.mjs b/node_modules/monocart-coverage-reports/lib/register/register.mjs new file mode 100644 index 0000000..bee37a5 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/register/register.mjs @@ -0,0 +1,3 @@ +import { register } from 'module'; + +register('./hooks.mjs', import.meta.url); diff --git a/node_modules/monocart-coverage-reports/lib/utils/dedupe.js b/node_modules/monocart-coverage-reports/lib/utils/dedupe.js new file mode 100644 index 0000000..8a74ece --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/utils/dedupe.js @@ -0,0 +1,123 @@ +/** + * The ranges are first ordered by ascending `startOffset` and then by descending `endOffset`. + * This corresponds to a pre-order tree traversal. + */ + +const sortRanges = (ranges) => { + ranges.sort((a, b) => { + if (a.start === b.start) { + return b.end - a.end; + } + return a.start - b.start; + }); +}; + +const filterRanges = (ranges) => { + // remove start = end + return ranges.filter((range) => range.start < range.end); +}; + +// apply directly to css ranges +const dedupeFlatRanges = (ranges) => { + + ranges = filterRanges(ranges); + + if (ranges.length < 2) { + return ranges; + } + + sortRanges(ranges); + + ranges.reduce((prevRange, range) => { + + // same start + if (range.start === prevRange.start) { + range.dedupe = true; + // equal prev + if (range.end === prevRange.end) { + return prevRange; + } + + // less than prev end after new sort + + return prevRange; + } + + // already in the range + if (range.end <= prevRange.end) { + range.dedupe = true; + return prevRange; + } + + // collected, update the end + if (range.start <= prevRange.end) { + range.dedupe = true; + prevRange.end = range.end; + return prevRange; + } + + return range; + }); + + ranges = ranges.filter((it) => !it.dedupe); + + return ranges; +}; + +const mergeRangesWith = (ranges, comparer, handler) => { + + // ranges format + // { start: 0, end: 6, ... } + + ranges = filterRanges(ranges); + + if (ranges.length < 2) { + return ranges; + } + + sortRanges(ranges); + + let hasDedupe = false; + + // merge count for same range + ranges.reduce((lastRange, range) => { + if (comparer(lastRange, range)) { + range.dedupe = true; + + handler(lastRange, range); + + hasDedupe = true; + + return lastRange; + } + return range; + }); + + if (hasDedupe) { + // console.log(ranges); + ranges = ranges.filter((it) => !it.dedupe); + } + + // console.log('ranges length after', ranges.length); + + return ranges; +}; + +// apply to js count ranges +const dedupeCountRanges = (ranges) => { + const comparer = (lastRange, range) => { + return lastRange.start === range.start && lastRange.end === range.end; + }; + const handler = (lastRange, range) => { + lastRange.count += range.count; + }; + return mergeRangesWith(ranges, comparer, handler); +}; + + +module.exports = { + sortRanges, + dedupeFlatRanges, + mergeRangesWith, + dedupeCountRanges +}; diff --git a/node_modules/monocart-coverage-reports/lib/utils/gc.js b/node_modules/monocart-coverage-reports/lib/utils/gc.js new file mode 100644 index 0000000..316337d --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/utils/gc.js @@ -0,0 +1,9 @@ +const v8 = require('node:v8'); +const vm = require('node:vm'); + +if (typeof global.gc !== 'function') { + v8.setFlagsFromString('--expose_gc'); + global.gc = vm.runInNewContext('gc'); +} + +module.exports = global.gc; diff --git a/node_modules/monocart-coverage-reports/lib/utils/markdown.js b/node_modules/monocart-coverage-reports/lib/utils/markdown.js new file mode 100644 index 0000000..d29d708 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/utils/markdown.js @@ -0,0 +1,132 @@ +const os = require('os'); + +const renderLine = (ls, padding) => { + const spacing = ''.padEnd(padding, ' '); + const line = ls.join(`${spacing}|${spacing}`); + return `|${spacing}${line}${spacing}|`; +}; + +const renderCell = (cellValue, column) => { + + // To include a pipe | as content within your cell, use a \ before the pipe: + cellValue = cellValue.split(/\\?\|/g).join('\\|'); + const valueWidth = cellValue.length; + const width = column.width; + + if (width <= valueWidth) { + return cellValue; + } + + const spacingWidth = width - valueWidth; + const spacing = ''.padEnd(spacingWidth, ' '); + + const align = column.align; + + if (align === 'right') { + return spacing + cellValue; + } + + if (align === 'center') { + const l = Math.round(spacingWidth * 0.5); + const r = spacingWidth - l; + const spacingL = ''.padEnd(l, ' '); + const spacingR = ''.padEnd(r, ' '); + return spacingL + cellValue + spacingR; + + } + + return cellValue + spacing; +}; + +const renderHyphen = (column) => { + const width = column.width; + const align = column.align; + if (align === 'right') { + return ':'.padStart(width, '-'); + } + if (align === 'center') { + const hyphen = ''.padEnd(width - 2, '-'); + return `:${hyphen}:`; + } + // default to left + return ':'.padEnd(width, '-'); +}; + +const markdownGrid = (data) => { + + const options = { + name: '', + padding: 1, + nullPlaceholder: '', + ... data.options + }; + + const padding = options.padding; + + // console.log(data, options); + + const lines = []; + + if (options.name) { + lines.push(`## ${options.name}`); + } + + // init columns + const columns = data.columns.map((item) => { + if (typeof item === 'string') { + item = { + name: item + }; + } + const column = { + ... item + }; + column.name = `${column.name}`; + if (typeof column.width !== 'number') { + column.width = column.name.length; + } + column.width = Math.max(column.width, 3); + return column; + }); + + // header + const headers = []; + columns.forEach((column) => { + headers.push(renderCell(column.name, column)); + }); + lines.push(renderLine(headers, padding)); + + const hyphens = []; + columns.forEach((column) => { + hyphens.push(renderHyphen(column)); + }); + lines.push(renderLine(hyphens, padding)); + + // rows + data.rows.forEach((row) => { + const cells = []; + columns.forEach((column, i) => { + let cellValue = ''; + if (Array.isArray(row)) { + cellValue += row[i]; + } else { + let v = row[column.id]; + if (typeof v === 'undefined' || v === null) { + v = options.nullPlaceholder; + } + if (column.formatter) { + v = column.formatter(v, row, column); + } + cellValue += v; + } + cells.push(renderCell(cellValue, column)); + }); + lines.push(renderLine(cells, padding)); + }); + + return lines.join(os.EOL) + os.EOL; + +}; + + +module.exports = markdownGrid; diff --git a/node_modules/monocart-coverage-reports/lib/utils/merge/merge.js b/node_modules/monocart-coverage-reports/lib/utils/merge/merge.js new file mode 100644 index 0000000..098983c --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/utils/merge/merge.js @@ -0,0 +1,439 @@ +/** + * The `mergeV8Coverage` was extracted from following repos for fixing several issues + * https://github.com/bcoe/v8-coverage + * https://github.com/demurgos/v8-coverage + */ + +const RangeTree = require('./range-tree.js'); + + +/** + * Compares two range coverages. + * + * The ranges are first ordered by ascending `startOffset` and then by + * descending `endOffset`. + * This corresponds to a pre-order tree traversal. + */ +function compareRangeCovs(a, b) { + if (a.startOffset !== b.startOffset) { + return a.startOffset - b.startOffset; + } + return b.endOffset - a.endOffset; +} + +/** + * Compares two function coverages. + * + * The result corresponds to the comparison of the root ranges. + */ +function compareFunctionCovs(a, b) { + return compareRangeCovs(a.ranges[0], b.ranges[0]); +} + +/** + * @precodition `ranges` are well-formed and pre-order sorted + */ +function fromSortedRanges(ranges) { + let root; + // Stack of parent trees and parent counts. + const stack = []; + for (const range of ranges) { + const node = new RangeTree(range.startOffset, range.endOffset, range.count, []); + if (!root) { + root = node; + stack.push([node, range.count]); + continue; + } + let parent; + let parentCount; + while (true) { + [parent, parentCount] = stack[stack.length - 1]; + // assert: `top !== undefined` (the ranges are sorted) + if (range.startOffset < parent.end) { + break; + } else { + stack.pop(); + } + + // prevent crash when v8 incorrectly merges static_initializer's + if (stack.length === 0) { + break; + } + } + node.delta -= parentCount; + parent.children.push(node); + stack.push([node, range.count]); + } + return root; +} + +/** + * Normalizes a function coverage. + * + * Sorts the ranges (pre-order sort). + * TODO: Tree-based normalization of the ranges. + * + * @param funcCov Function coverage to normalize. + */ +function normalizeFunctionCov(funcCov) { + funcCov.ranges.sort(compareRangeCovs); + const tree = fromSortedRanges(funcCov.ranges); + tree.normalize(); + funcCov.ranges = tree.toRanges(); +} + +/** + * Normalizes a script coverage. + * + * Sorts the function by root range (pre-order sort). + * This does not normalize the function coverages. + * + * @param scriptCov Script coverage to normalize. + */ +function normalizeScriptCov(scriptCov) { + scriptCov.functions.sort(compareFunctionCovs); +} + + +/** + * Normalizes a script coverage deeply. + * + * Normalizes the function coverages deeply, then normalizes the script coverage + * itself. + * + * @param scriptCov Script coverage to normalize. + */ +function deepNormalizeScriptCov(scriptCov) { + for (const funcCov of scriptCov.functions) { + normalizeFunctionCov(funcCov); + } + normalizeScriptCov(scriptCov); +} + + +/** + * Returns a string representation of the root range of the function. + * + * This string can be used to match function with same root range. + * The string is derived from the start and end offsets of the root range of + * the function. + * This assumes that `ranges` is non-empty (true for valid function coverages). + * + * @param funcCov Function coverage with the range to stringify + * @internal + */ +function stringifyFunctionRootRange(funcCov) { + const rootRange = funcCov.ranges[0]; + return `${rootRange.startOffset.toString(10)};${rootRange.endOffset.toString(10)}`; +} + + +function insertChild(parentToNested, parentIndex, tree) { + let nested = parentToNested.get(parentIndex); + if (!nested) { + nested = []; + parentToNested.set(parentIndex, nested); + } + nested.push(tree); +} + +function nextChild(openRange, parentToNested) { + const matchingTrees = []; + + for (const nested of parentToNested.values()) { + if (nested.length === 1 && nested[0].start === openRange.start && nested[0].end === openRange.end) { + matchingTrees.push(nested[0]); + } else { + matchingTrees.push(new RangeTree( + openRange.start, + openRange.end, + 0, + nested + )); + } + } + parentToNested.clear(); + return mergeRangeTrees(matchingTrees); +} + +class StartEventQueue { + + constructor(queue) { + this.queue = queue; + this.nextIndex = 0; + this.pendingOffset = 0; + this.pendingTrees = null; + } + + setPendingOffset(offset) { + this.pendingOffset = offset; + } + + pushPendingTree(tree) { + if (this.pendingTrees === null) { + this.pendingTrees = []; + } + this.pendingTrees.push(tree); + } + + next() { + const pendingTrees = this.pendingTrees; + const nextEvent = this.queue[this.nextIndex]; + if (pendingTrees === null) { + this.nextIndex++; + return nextEvent; + } + if (!nextEvent) { + this.pendingTrees = null; + return { + offset: this.pendingOffset, + trees: pendingTrees + }; + } + if (this.pendingOffset < nextEvent.offset) { + this.pendingTrees = null; + return { + offset: this.pendingOffset, + trees: pendingTrees + }; + } + if (this.pendingOffset === nextEvent.offset) { + this.pendingTrees = null; + for (const tree of pendingTrees) { + nextEvent.trees.push(tree); + } + } + this.nextIndex++; + return nextEvent; + + + } +} + +function fromParentTrees(parentTrees) { + const startToTrees = new Map(); + for (const [parentIndex, parentTree] of parentTrees.entries()) { + for (const child of parentTree.children) { + let trees = startToTrees.get(child.start); + if (!trees) { + trees = []; + startToTrees.set(child.start, trees); + } + trees.push({ + parentIndex, + tree: child + }); + } + } + const queue = []; + for (const [startOffset, trees] of startToTrees) { + queue.push({ + offset: startOffset, + trees + }); + } + queue.sort((a, b) => { + return a.offset - b.offset; + }); + return new StartEventQueue(queue); +} + +// eslint-disable-next-line complexity +function mergeRangeTreeChildren(parentTrees) { + const result = []; + const startEventQueue = fromParentTrees(parentTrees); + const parentToNested = new Map(); + let openRange = null; + + while (true) { + const event = startEventQueue.next(); + if (!event) { + break; + } + + if (openRange !== null && openRange.end <= event.offset) { + result.push(nextChild(openRange, parentToNested)); + openRange = null; + } + + if (openRange === null) { + let openRangeEnd = event.offset + 1; + for (const { parentIndex, tree } of event.trees) { + openRangeEnd = Math.max(openRangeEnd, tree.end); + insertChild(parentToNested, parentIndex, tree); + } + startEventQueue.setPendingOffset(openRangeEnd); + openRange = { + start: event.offset, end: openRangeEnd + }; + } else { + for (const { parentIndex, tree } of event.trees) { + if (tree.end > openRange.end) { + const right = tree.split(openRange.end); + startEventQueue.pushPendingTree({ + parentIndex, + tree: right + }); + } + insertChild(parentToNested, parentIndex, tree); + } + } + } + if (openRange !== null) { + result.push(nextChild(openRange, parentToNested)); + } + + return result; +} + +/** + * @precondition Same `start` and `end` for all the trees + */ +function mergeRangeTrees(trees) { + if (trees.length <= 1) { + return trees[0]; + } + const first = trees[0]; + let delta = 0; + for (const tree of trees) { + delta += tree.delta; + } + const children = mergeRangeTreeChildren(trees); + return new RangeTree(first.start, first.end, delta, children); +} + +/** + * Merges a list of matching function coverages. + * + * Functions are matching if their root ranges have the same span. + * The result is normalized. + * The input values may be mutated, it is not safe to use them after passing + * them to this function. + * The computation is synchronous. + * + * @param funcCovs Function coverages to merge. + * @return Merged function coverage, or `undefined` if the input list was empty. + */ +function mergeFunctionCovs(funcCovs) { + if (funcCovs.length === 0) { + return; + } + + if (funcCovs.length === 1) { + const merged = funcCovs[0]; + normalizeFunctionCov(merged); + return merged; + } + + const first = funcCovs[0]; + const functionName = first.functionName; + // assert: `first.ranges.length > 0` + const startOffset = first.ranges[0].startOffset; + const endOffset = first.ranges[0].endOffset; + let count = 0; + + const trees = []; + for (const funcCov of funcCovs) { + // assert: `funcCov.ranges.length > 0` + // assert: `funcCov.ranges` is sorted + count += typeof funcCov.count === 'number' ? funcCov.count : funcCov.ranges[0].count; + if (funcCov.isBlockCoverage) { + trees.push(fromSortedRanges(funcCov.ranges)); + } + } + + let isBlockCoverage; + let ranges; + if (trees.length > 0) { + isBlockCoverage = true; + const mergedTree = mergeRangeTrees(trees); + mergedTree.normalize(); + ranges = mergedTree.toRanges(); + } else { + isBlockCoverage = false; + ranges = [{ + startOffset, + endOffset, + count + }]; + } + + const merged = { + functionName, + ranges, + isBlockCoverage + }; + if (count !== ranges[0].count) { + merged.count = count; + } + // assert: `merged` is normalized + return merged; +} + + +/** + * Merges a list of matching script coverages. + * + * Scripts are matching if they have the same `url`. + * The result is normalized. + * The input values may be mutated, it is not safe to use them after passing + * them to this function. + * The computation is synchronous. + * + * @param scriptCovs Process coverages to merge. + * @return Merged script coverage, or `undefined` if the input list was empty. + */ + +// eslint-disable-next-line complexity +function mergeV8Coverage(scriptCovs) { + if (!Array.isArray(scriptCovs)) { + return { + functions: [] + }; + } + + if (scriptCovs.length === 0) { + return { + functions: [] + }; + } + + if (scriptCovs.length === 1) { + const merged = scriptCovs[0]; + deepNormalizeScriptCov(merged); + return merged; + } + + + const rangeToFuncs = new Map(); + for (const scriptCov of scriptCovs) { + for (const funcCov of scriptCov.functions) { + const rootRange = stringifyFunctionRootRange(funcCov); + let funcCovs = rangeToFuncs.get(rootRange); + if (!funcCovs) { + funcCovs = []; + rangeToFuncs.set(rootRange, funcCovs); + } + funcCovs.push(funcCov); + } + } + + const functions = []; + for (const funcCovs of rangeToFuncs.values()) { + // assert: `funcCovs.length > 0` + const block = mergeFunctionCovs(funcCovs); + if (block) { + functions.push(block); + } + } + + const merged = { + functions + }; + normalizeScriptCov(merged); + return merged; +} + +module.exports = { + mergeV8Coverage +}; diff --git a/node_modules/monocart-coverage-reports/lib/utils/merge/range-tree.js b/node_modules/monocart-coverage-reports/lib/utils/merge/range-tree.js new file mode 100644 index 0000000..baffb48 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/utils/merge/range-tree.js @@ -0,0 +1,123 @@ +class RangeTree { + + constructor( + start, + end, + delta, + children + ) { + this.start = start; + this.end = end; + this.delta = delta; + this.children = children; + } + + // eslint-disable-next-line complexity + normalize() { + const children = []; + let curEnd; + let head; + const tail = []; + for (const child of this.children) { + if (!head) { + head = child; + } else if (child.delta === head.delta && child.start === curEnd) { + tail.push(child); + } else { + endChain(); + head = child; + } + curEnd = child.end; + } + if (head) { + endChain(); + } + + if (children.length === 1) { + const child = children[0]; + if (child.start === this.start && child.end === this.end) { + this.delta += child.delta; + this.children = child.children; + // `.lazyCount` is zero for both (both are after normalization) + return; + } + } + + this.children = children; + + function endChain() { + if (tail.length !== 0) { + head.end = tail[tail.length - 1].end; + for (const tailTree of tail) { + for (const subChild of tailTree.children) { + subChild.delta += tailTree.delta - head.delta; + head.children.push(subChild); + } + } + tail.length = 0; + } + head.normalize(); + children.push(head); + } + } + + /** + * @precondition `tree.start < value && value < tree.end` + * @return RangeTree Right part + */ + split(value) { + let leftChildLen = this.children.length; + let mid; + + // TODO(perf): Binary search (check overhead) + for (let i = 0; i < this.children.length; i++) { + const child = this.children[i]; + if (child.start < value && value < child.end) { + mid = child.split(value); + leftChildLen = i + 1; + break; + } else if (child.start >= value) { + leftChildLen = i; + break; + } + } + + const rightLen = this.children.length - leftChildLen; + const rightChildren = this.children.splice(leftChildLen, rightLen); + if (mid) { + rightChildren.unshift(mid); + } + const result = new RangeTree( + value, + this.end, + this.delta, + rightChildren + ); + this.end = value; + return result; + } + + /** + * Get the range coverages corresponding to the tree. + * + * The ranges are pre-order sorted. + */ + toRanges() { + const ranges = []; + // Stack of parent trees and counts. + const stack = [[this, 0]]; + while (stack.length > 0) { + const [cur, parentCount] = stack.pop(); + const count = parentCount + cur.delta; + ranges.push({ + startOffset: cur.start, endOffset: cur.end, count + }); + for (let i = cur.children.length - 1; i >= 0; i--) { + stack.push([cur.children[i], count]); + } + } + return ranges; + } +} + +module.exports = RangeTree; diff --git a/node_modules/monocart-coverage-reports/lib/utils/request.js b/node_modules/monocart-coverage-reports/lib/utils/request.js new file mode 100644 index 0000000..2aca224 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/utils/request.js @@ -0,0 +1,86 @@ +const http = require('http'); +const https = require('https'); + +// minimal http request for get sourcemap json +// https://nodejs.org/docs/latest/api/http.html#httprequesturl-options-callback +const request = (url, options) => { + + const HTTP = url.startsWith('https') ? https : http; + // console.log('request', url); + + return new Promise((resolve) => { + + // get method only + HTTP.get(url, options, (res) => { + const { statusCode } = res; + + // Any 2xx status code signals a successful response but here we're only checking for 200. + if (statusCode !== 200) { + // Consume response data to free up memory + res.resume(); + const resErr = new Error(`Request Failed. Status Code: ${statusCode}`); + resolve([resErr]); + return; + } + + res.setEncoding('utf8'); + + let rawData = ''; + res.on('data', (chunk) => { + rawData += chunk; + }); + + res.on('end', () => { + + let dataErr; + let data = rawData; + + // parse json + const contentType = res.headers['content-type']; + if ((/^application\/json/).test(contentType)) { + try { + data = JSON.parse(rawData); + } catch (e) { + dataErr = e; + } + } + + res.data = data; + resolve([dataErr, res]); + + }); + + }).on('error', (httpErr) => { + + resolve([httpErr]); + + }); + + }); +}; + +module.exports = async (url, options = {}) => { + let urlErr; + let urlObj; + try { + urlObj = new URL(url); + } catch (err) { + // console.error('error url', input); + urlErr = err; + } + + if (urlErr) { + return [urlErr]; + } + + const [err, res] = await request(urlObj.toString(), options); + if (err) { + // replace localhost to 127.0.0.1 + // ECONNREFUSED on NodeJS 18 https://github.com/node-fetch/node-fetch/issues/1624 + if (urlObj.hostname === 'localhost') { + urlObj.hostname = '127.0.0.1'; + return request(urlObj.toString(), options); + } + } + return [err, res]; +}; diff --git a/node_modules/monocart-coverage-reports/lib/utils/snapshot.js b/node_modules/monocart-coverage-reports/lib/utils/snapshot.js new file mode 100644 index 0000000..9b6df01 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/utils/snapshot.js @@ -0,0 +1,348 @@ +const CG = require('console-grid'); +const EC = require('eight-colors'); + +const Util = require('./util.js'); + +const mergeSingleSubGroups = (item) => { + + if (!item.subs) { + return; + } + if (item.subs.length === 1) { + const sub = item.subs[0]; + if (!sub.subs) { + return; + } + item.name = [item.name, sub.name].filter((it) => it).join('/'); + item.subs = sub.subs; + mergeSingleSubGroups(item); + return; + } + + item.subs.forEach((sub) => { + mergeSingleSubGroups(sub); + }); + +}; + +const getGroupedRows = (flatRows) => { + let groups = []; + flatRows.forEach((file) => { + const pathList = file.name.split('/'); + const lastName = pathList.pop(); + let subs = groups; + pathList.forEach((key) => { + const item = subs.find((it) => it.name === key && it.subs); + if (item) { + subs = item.subs; + return; + } + const sub = { + name: key, + subs: [] + }; + subs.push(sub); + subs = sub.subs; + }); + + let filename = lastName; + if (file.nameStatus) { + filename = Util.getColorStrByStatus(lastName, file.nameStatus, 'ansicode'); + } + file.name = filename; + subs.push(file); + }); + const group = { + subs: groups + }; + mergeSingleSubGroups(group); + if (group.name) { + groups = [group]; + } + return groups; +}; + +// ============================================================ + +const diffUncoveredLines = (list) => { + const [oldStr, newStr] = list; + + const oldList = oldStr.split(','); + const newList = newStr.split(','); + + const oldColor = oldList.map((it) => { + if (newList.includes(it)) { + return it; + } + return EC.green(it); + }).join(','); + + const newColor = newList.map((it) => { + if (oldList.includes(it)) { + return it; + } + return EC.red(it); + }).join(','); + + return [oldColor, newColor]; +}; + +const getDiffMessage = (results, columns, diffOptions) => { + const flatRows = []; + results.forEach((it) => { + if (!it.change && diffOptions.skipEqual) { + return; + } + flatRows.push(it); + }); + + const rows = getGroupedRows(flatRows); + + const addedList = []; + Util.forEach(rows, (it, parent) => { + if (!it.change) { + return; + } + // add color + if (it.change === '-' || it.change === '+') { + columns.forEach((c) => { + const k = c.id; + let v = it[k]; + if (k === 'name') { + v = `${it.change} ${v}`; + } + it[k] = EC.red(v); + }); + return; + } + + // diff + const cloneRow = {}; + columns.forEach((c) => { + const k = c.id; + let v = it[k]; + if (Array.isArray(v)) { + if (k === 'uncoveredLines') { + v = diffUncoveredLines(v); + } else { + v = [EC.green(v[0]), EC.red(v[1])]; + } + it[k] = v[0]; + cloneRow[k] = v[1]; + return; + } + it[k] = v; + cloneRow[k] = ''; + }); + + addedList.push({ + subs: parent ? parent.subs : rows, + row: it, + cloneRow + }); + + }); + + addedList.forEach((it) => { + const { + subs, row, cloneRow + } = it; + const i = subs.findIndex((r) => r === row); + subs.splice(i + 1, 0, cloneRow); + }); + + // add innerBorder for summary + const summaryIndex = rows.findIndex((it) => it.isSummary); + if (summaryIndex !== -1) { + rows.splice(summaryIndex, 0, { + innerBorder: true + }); + } + + const lines = CG({ + options: { + silent: true, + nullPlaceholder: '', + defaultMaxWidth: diffOptions.maxCols + }, + columns, + rows + }); + + return lines.join('\n'); +}; + + +// ============================================================ + +const getSnapshot = (reportData) => { + const { + summary, files, type + } = reportData; + const snapshot = { + type, + summary: {}, + files: {} + }; + + const addPercent = (target, fromSummary) => { + Object.keys(fromSummary).forEach((k) => { + let percent = fromSummary[k].pct; + if (typeof percent === 'number') { + percent = Util.PSF(percent, 100, 2); + } + target[k] = percent; + }); + }; + + addPercent(snapshot.summary, summary); + + files.sort((a, b) => { + if (a.sourcePath > b.sourcePath) { + return 1; + } + return -1; + }); + files.forEach((file) => { + // do NOT add debug file + if (file.debug) { + return; + } + const fileSummary = {}; + addPercent(fileSummary, file.summary); + fileSummary.uncoveredLines = Util.getUncoveredLines(file.data.lines); + + // no extras for istanbul + const extras = file.data.extras; + fileSummary.extras = Object.keys(extras).map((k) => { + return k + extras[k]; + }).join(','); + + snapshot.files[file.sourcePath] = fileSummary; + }); + + return snapshot; +}; + +const diffSnapshot = (oldData, newData, diffOptions) => { + + diffOptions = { + skipEqual: true, + showSummary: true, + maxCols: 50, + metrics: [], + ... diffOptions + }; + + let change = false; + const results = []; + + const metrics = Util.getMetrics(diffOptions.metrics, oldData.type); + const columns = [{ + id: 'name', + name: 'Name' + }, ... metrics.map((m) => { + return { + id: m, + name: Util.capitalizeFirstLetter(m), + align: 'right' + }; + }), { + id: 'uncoveredLines', + name: 'Uncovered Lines' + }]; + + const keys = columns.map((it) => it.id).filter((it) => it !== 'name'); + const oFiles = oldData.files; + const nFiles = newData.files; + + Object.keys(oFiles).forEach((oPath) => { + + const oSummary = oFiles[oPath]; + + const diffResult = { + name: oPath + }; + keys.forEach((k) => { + diffResult[k] = oSummary[k]; + }); + + const nSummary = nFiles[oPath]; + if (nSummary) { + + let fileChange = false; + keys.forEach((k) => { + const oValue = oSummary[k]; + const nValue = nSummary[k]; + if (oValue !== nValue) { + change = true; + fileChange = true; + diffResult[k] = [oValue, nValue]; + } + }); + + diffResult.change = fileChange; + + } else { + change = true; + diffResult.change = '-'; + } + + results.push(diffResult); + + }); + + // added + Object.keys(nFiles).forEach((nPath) => { + const oSummary = oFiles[nPath]; + if (oSummary) { + return; + } + const nSummary = nFiles[nPath]; + const diffResult = { + name: nPath, + change: '+' + }; + change = true; + keys.forEach((k) => { + diffResult[k] = nSummary[k]; + }); + results.push(diffResult); + }); + + if (diffOptions.showSummary) { + const oSummary = oldData.summary; + const nSummary = newData.summary; + const diffResult = { + name: 'Summary', + isSummary: true, + change: false + }; + keys.forEach((k) => { + const oValue = oSummary[k]; + const nValue = nSummary[k]; + if (oValue === nValue) { + diffResult[k] = oValue; + } else { + change = true; + diffResult.change = true; + diffResult[k] = [oValue, nValue]; + } + }); + results.push(diffResult); + } + + const message = getDiffMessage(results, columns, diffOptions); + + return { + change, + results, + message + }; +}; + +module.exports = { + getGroupedRows, + getSnapshot, + diffSnapshot +}; diff --git a/node_modules/monocart-coverage-reports/lib/utils/source-path.js b/node_modules/monocart-coverage-reports/lib/utils/source-path.js new file mode 100644 index 0000000..2164039 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/utils/source-path.js @@ -0,0 +1,251 @@ +const fs = require('fs'); +const path = require('path'); +const { fileURLToPath, pathToFileURL } = require('url'); +const Util = require('./util.js'); + +const resolveSourceRootUrl = (sourceName, sourceRoot) => { + // prepend sourceRoot + if (sourceRoot && !sourceName.startsWith(sourceRoot)) { + if (!sourceRoot.endsWith('/')) { + sourceRoot += '/'; + } + return sourceRoot + sourceName; + } + return sourceName; +}; + +const resolveAnonymousUrl = (url, index, type) => { + if (url) { + return url; + } + // anonymous scripts will have __playwright_evaluation_script__ as their URL. + const list = ['anonymous']; + if (index) { + list.push(`-${index}`); + } + if (type) { + list.push(`.${type}`); + } + return list.join(''); +}; + +const normalizePathDir = (sourcePath) => { + + // decodeURI("%20") to space + let str = decodeURI(`${sourcePath}`); + str = str.replace(/\\/g, '/'); + + // remove / of start, end or double, ./ ../ + return str.split('/').map((it) => { + it = it.trim(); + // remove illegal characters except / + it = it.replace(/[\\:*?"<>|]/g, ''); + // keep space + // it = it.replace(/\s+/g, '-'); + return it; + }).filter((item) => { + if (!item || item === '.' || item === '..') { + return false; + } + return true; + }).join('/'); +}; + +const betterFileURLToPath = (url) => { + try { + url = fileURLToPath(url); + } catch (e) { + url = decodeURIComponent(url); + url = fileURLToPath(url); + } + return url; +}; + +const normalizeSourcePath = (sourceUrl, baseDir) => { + + // includes anonymous and everything + + // file url + if (sourceUrl.startsWith('file:')) { + const relPath = Util.relativePath(betterFileURLToPath(sourceUrl), baseDir); + return normalizePathDir(relPath); + } + + // absolute path + // c:\\workspace\test\\selenium.spec.js true + // c://a.js true + // c:\\a.js true + // C:/a.js true + // /a.js true + + // a.js false + // ws://a.js false + // file://a.js false + // http://a.com/a.js false + // webpack://src/a.js false + + if (path.isAbsolute(sourceUrl)) { + const relPath = Util.relativePath(sourceUrl, baseDir); + return normalizePathDir(relPath); + } + + // ws://a.js + // http://127.0.0:8080/a.js + // https://127.0.0:8080/a.js?v=1 + // webpack://coverage-v8/./test/mock/src/branch/branch.js + // webpack://monocart-v8/../starfall-cli/node_modules/css-loader/dist/runtime/api.js + + // url http/https/webpack + const urlObj = Util.resolveUrl(sourceUrl); + if (urlObj) { + let host = urlObj.host; + // remove : before port, : can not be a part of dir + host = host.replace(':', '-'); + + // always start with '/' + const pathname = urlObj.pathname; + + let p = host + pathname; + // webpack://monocart-v8/packages/v8/src/app.vue?5cc4 + if (urlObj.search) { + p += `-${urlObj.search}`; + } + + return normalizePathDir(p); + } + + // relative path + const fileUrl = pathToFileURL(sourceUrl).toString(); + const relPath = Util.relativePath(betterFileURLToPath(fileUrl), baseDir); + return normalizePathDir(relPath); +}; + +const getSourceType = (sourcePath) => { + let ext = path.extname(sourcePath); + let type = 'js'; + if (ext) { + ext = ext.slice(1); + const reg = /^[a-z0-9]+$/; + if (reg.test(ext)) { + type = ext; + } + } + return type; +}; + + +// ======================================================================================================== + +const getSourcePathReplacer = (options) => { + const input = options.sourcePath; + if (typeof input === 'function') { + return input; + } + // object replace key with value + if (input && typeof input === 'object') { + const keys = Object.keys(input).filter((k) => typeof input[k] === 'string'); + if (keys.length) { + return (filePath) => { + keys.forEach((k) => { + filePath = filePath.replace(k, input[k]); + }); + return filePath; + }; + } + } +}; + +// ======================================================================================================== + +const initIstanbulSourcePath = (coverageData, fileSources, options) => { + + const sourcePathReplacer = getSourcePathReplacer(options); + + const newCoverage = {}; + // eslint-disable-next-line complexity + Object.keys(coverageData).forEach((sourcePath) => { + // previous coverage and source + const item = coverageData[sourcePath]; + let source = fileSources[sourcePath]; + + // source could be empty string '' + if (typeof source !== 'string') { + // read source with original source path first + source = Util.readFileSync(sourcePath); + if (typeof source === 'string') { + fileSources[sourcePath] = source; + } + } + + if (!fs.existsSync(sourcePath)) { + sourcePath = normalizePathDir(sourcePath); + } + + // new source path, second is source url + if (sourcePathReplacer) { + const newSourcePath = sourcePathReplacer(sourcePath, item); + if (typeof newSourcePath === 'string' && newSourcePath) { + sourcePath = newSourcePath; + } + } + + // update source path + if (item.data) { + item.data.path = sourcePath; + } else { + // from v8 + item.path = sourcePath; + } + + newCoverage[sourcePath] = item; + // update source for the new path + if (typeof source === 'string') { + fileSources[sourcePath] = source; + } + }); + + // console.log(Object.keys(fileSources)); + // console.log(newCoverage); + + return newCoverage; +}; + +// ======================================================================================================== + +const initSourceMapSourcesPath = (fileUrls, sourceMap, distFile, options) => { + + const baseDir = options.baseDir; + const sourcePathReplacer = getSourcePathReplacer(options); + + sourceMap.sources = sourceMap.sources.map((sourceName, i) => { + + let sourceUrl = resolveSourceRootUrl(sourceName, sourceMap.sourceRoot); + sourceUrl = resolveAnonymousUrl(sourceUrl, i + 1, 'js'); + let sourcePath = normalizeSourcePath(sourceUrl, baseDir); + // console.log(sourceUrl, sourcePath); + + if (sourcePathReplacer) { + // sourcePath could be a filename only, may using distFile to get full path + const newSourcePath = sourcePathReplacer(sourcePath, { + url: sourceUrl, + distFile + }); + if (typeof newSourcePath === 'string' && newSourcePath) { + sourcePath = newSourcePath; + } + } + + fileUrls[sourcePath] = sourceUrl; + return sourcePath; + }); + +}; + +module.exports = { + resolveAnonymousUrl, + normalizeSourcePath, + getSourceType, + getSourcePathReplacer, + initIstanbulSourcePath, + initSourceMapSourcesPath +}; diff --git a/node_modules/monocart-coverage-reports/lib/utils/util.js b/node_modules/monocart-coverage-reports/lib/utils/util.js new file mode 100644 index 0000000..08f75b6 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/utils/util.js @@ -0,0 +1,963 @@ +const fs = require('fs'); +const { writeFile, readFile } = require('fs/promises'); +const path = require('path'); +const os = require('os'); +const crypto = require('crypto'); + +const EC = require('eight-colors'); +const CG = require('console-grid'); +const acornWalk = require('acorn-walk'); + +const Share = require('../platform/share.js'); +const request = require('./request.js'); +const version = require('../../package.json').version; +const markdownGrid = require('./markdown.js'); +const { mergeV8Coverage } = require('./merge/merge.js'); +const gc = require('./gc.js'); + +const { + findUpSync, supportsColor, minimatch +} = require('../packages/monocart-coverage-vendor.js'); + +// https://github.com/chalk/supports-color +// disabled color if Terminal stdout does not support color +if (!supportsColor.stdout) { + EC.disabled = true; +} + +const Util = { + version, + + ... Share, + + EC, + CG, + + root: process.cwd(), + + request, + markdownGrid, + mergeV8Coverage, + + forceGC: () => { + gc(); + }, + + relativePath: function(p, root) { + p = `${p}`; + root = `${root || Util.root}`; + let rp = path.relative(root, p); + rp = Util.formatPath(rp); + return rp; + }, + + replace: function(str, obj, defaultValue) { + str = `${str}`; + if (!obj) { + return str; + } + str = str.replace(/\{([^}{]+)\}/g, function(match, key) { + if (!Util.hasOwn(obj, key)) { + if (typeof (defaultValue) !== 'undefined') { + return defaultValue; + } + return match; + } + let val = obj[key]; + if (typeof (val) === 'function') { + val = val(obj, key); + } + if (typeof (val) === 'undefined') { + val = ''; + } + return val; + }); + return str; + }, + + strToObj: (str) => { + if (typeof str === 'string') { + str = str.trim(); + if (str.startsWith('{') && str.endsWith('}')) { + let fun; + let err; + try { + fun = new Function(`return ${str}`); + } catch (e) { + err = e; + } + if (!err) { + const obj = fun(); + if (obj && typeof obj === 'object') { + return obj; + } + } + } + } + }, + + calculateSha1: (buffer) => { + const hash = crypto.createHash('sha1'); + hash.update(buffer); + return hash.digest('hex'); + }, + + checkCoverageData: (data) => { + if (!data) { + return false; + } + if (Array.isArray(data) && data.length) { + return true; + } + if (Object.keys(data).length) { + return true; + } + return false; + }, + + resolveUrl: (input, base) => { + let url; + let err; + try { + url = new URL(input, base); + } catch (e) { + err = e; + } + if (err) { + // console.error('error url', input); + return; + } + return url; + }, + + resolveWatermarks: (defaultWatermarks, watermarks) => { + if (watermarks) { + if (Array.isArray(watermarks)) { + Object.keys(defaultWatermarks).forEach((k) => { + defaultWatermarks[k] = watermarks; + }); + } else { + Object.assign(defaultWatermarks, watermarks); + } + } + return defaultWatermarks; + }, + + resolveReportPath: (options, htmlPathHandler) => { + + let reportPath = options.reportPath; + if (typeof reportPath === 'function') { + reportPath = reportPath(); + } + + if (typeof reportPath === 'string') { + if (reportPath) { + const p = path.resolve(options.outputDir, reportPath); + return Util.relativePath(p); + } + // empty + return reportPath; + } + // using default html path as report path + return htmlPathHandler(); + }, + + getCacheFileInfo: (type, id, cacheDir) => { + const cacheName = `${type}-${id}.json`; + const cachePath = path.resolve(cacheDir, cacheName); + return { + cacheName, + cachePath + }; + }, + + betterMinimatch: (str, pattern) => { + str = `${str}`; + pattern = `${pattern}`; + + if (pattern === '*') { + return true; + } + + // includes first + if (str.includes(pattern)) { + return true; + } + + // with minimatch + if (minimatch(str, pattern)) { + return true; + } + + // after decode url + str = decodeURIComponent(str); + + if (str.includes(pattern)) { + return true; + } + + if (minimatch(str, pattern)) { + return true; + } + + return false; + }, + + // eslint-disable-next-line complexity + getEntryFilter: (options) => { + // for entry.url + + if (options.entryFilterHandler) { + return options.entryFilterHandler; + } + + let input = options.entryFilter || options.filter; + + // for function handler + if (typeof input === 'function') { + options.entryFilterHandler = input; + return input; + } + + // for single minimatch pattern + if (input && typeof input === 'string') { + // string to multiple patterns "{...}" + // mcr npx mocha --entryFilter {'**/node_modules/**':false,'**/src/*.js':true} + // mcr npx mocha --entryFilter "{'**/node_modules/**': false, '**/src/*.js': true}" + const obj = Util.strToObj(input); + if (obj) { + input = obj; + } else { + const handler = (entry) => { + return Util.betterMinimatch(entry.url, input); + }; + options.entryFilterHandler = handler; + return handler; + } + } + + // for patterns + if (input && typeof input === 'object') { + const patterns = Object.keys(input); + const handler = (entry) => { + const url = entry.url; + for (const pattern of patterns) { + if (Util.betterMinimatch(url, pattern)) { + return input[pattern]; + } + } + // false if not matched + }; + options.entryFilterHandler = handler; + return handler; + } + + // default + const handler = () => true; + options.entryFilterHandler = handler; + return handler; + }, + + // eslint-disable-next-line complexity + getSourceFilter: (options) => { + // for sourcePath + + if (options.sourceFilterHandler) { + return options.sourceFilterHandler; + } + + let input = options.sourceFilter || options.filter; + + // for function handler + if (typeof input === 'function') { + options.sourceFilterHandler = input; + return input; + } + + // for single minimatch pattern + if (input && typeof input === 'string') { + // string to multiple patterns "{...}" + // mcr npx mocha --sourceFilter {'**/node_modules/**':false,'**/src/*.js':true} + // mcr npx mocha --sourceFilter "{'**/node_modules/**': false, '**/src/*.js': true}" + const obj = Util.strToObj(input); + if (obj) { + input = obj; + } else { + const handler = (sourcePath) => { + return Util.betterMinimatch(sourcePath, input); + }; + options.sourceFilterHandler = handler; + return handler; + } + } + + // for patterns + if (input && typeof input === 'object') { + const patterns = Object.keys(input); + const handler = (sourcePath) => { + for (const pattern of patterns) { + if (Util.betterMinimatch(sourcePath, pattern)) { + return input[pattern]; + } + } + // false if not matched + }; + options.sourceFilterHandler = handler; + return handler; + } + + // default + const handler = () => true; + options.sourceFilterHandler = handler; + return handler; + }, + + setEmptyV8Coverage: (entry) => { + if (entry.type === 'css') { + // empty css + if (!entry.ranges) { + entry.ranges = []; + } + } else { + // empty js + if (!entry.functions) { + entry.functions = [{ + functionName: '', + ranges: [{ + startOffset: 0, + endOffset: entry.source ? entry.source.length : 0, + count: 0 + }] + }]; + } + } + }, + + saveSourceCacheFile: async (sourceData, options, fileCache) => { + const { cacheName, cachePath } = Util.getCacheFileInfo('source', sourceData.id, options.cacheDir); + + // file cache for add() to generate() + if (fileCache) { + fileCache.set(cacheName, sourceData); + } + + await Util.writeFile(cachePath, JSON.stringify(sourceData)); + + // save source and sourcemap file for debug + // https://evanw.github.io/source-map-visualization + if (options.sourceMap && sourceData.sourceMap) { + const filePath = cachePath.slice(0, -5); + await Util.writeFile(`${filePath}.js`, sourceData.source); + await Util.writeFile(`${filePath}.js.map`, JSON.stringify(sourceData.sourceMap)); + } + }, + + findUpConfig: (customConfigFile) => { + if (customConfigFile) { + if (fs.existsSync(customConfigFile)) { + return customConfigFile; + } + // custom config not found + return; + } + + const defaultConfigList = [ + 'mcr.config.js', + 'mcr.config.cjs', + 'mcr.config.mjs', + 'mcr.config.json', + 'mcr.config.ts' + ]; + + const configPath = findUpSync(defaultConfigList); + if (configPath) { + return configPath; + } + + // default config not found + }, + + getEOL: function(content) { + if (!content) { + return os.EOL; + } + const nIndex = content.lastIndexOf('\n'); + if (nIndex === -1) { + return os.EOL; + } + if (content.substr(nIndex - 1, 1) === '\r') { + return '\r\n'; + } + return '\n'; + }, + + visitAst: (rootNode, visitors) => { + const baseVisitor = acornWalk.base; + const parents = [rootNode]; + const visitor = (node, st, override) => { + const type = override || node.type; + // console.log('visit', node.type, override, parents.length); + const handler = visitors[type]; + if (handler) { + const res = handler(node, parents); + if (res === 'break') { + return; + } + } + const isNew = node !== parents[parents.length - 1]; + if (isNew) { + parents.push(node); + } + baseVisitor[type](node, st, visitor); + if (isNew) { + parents.pop(); + } + }; + visitor(rootNode); + }, + + updateOffsetToLocation: (locator, loc) => { + const sLoc = locator.offsetToLocation(loc.start); + loc.start = { + line: sLoc.line, + column: sLoc.column + }; + const eLoc = locator.offsetToLocation(loc.end); + loc.end = { + line: eLoc.line, + column: eLoc.column + }; + }, + + // offset key + sortOffsetRanges: (ranges) => { + ranges.sort((a, b) => { + if (a.startOffset === b.startOffset) { + return a.endOffset - b.endOffset; + } + return a.startOffset - b.startOffset; + }); + }, + + + forEachFile: function(dir, extList, callback) { + if (!fs.existsSync(dir)) { + return; + } + // all exts, full name, ext + const isMatched = (name) => !Util.isList(extList) || extList.includes(name) || extList.includes(path.extname(name)); + const subDirs = []; + const subDirHandler = () => { + if (!subDirs.length) { + return; + } + + for (const subDir of subDirs) { + const res = Util.forEachFile(subDir, extList, callback); + if (res === 'break') { + return; + } + } + }; + + const list = fs.readdirSync(dir); + for (const name of list) { + const abs = path.resolve(dir, name); + + const info = fs.lstatSync(abs); + if (info.isSymbolicLink()) { + continue; + } + + if (info.isDirectory()) { + subDirs.push(abs); + continue; + } + + if (info.isFile() && isMatched(name)) { + const res = callback(name, dir); + if (res === 'break') { + return; + } + } + + } + + subDirHandler(); + + }, + + readFileSync: function(filePath) { + if (fs.existsSync(filePath)) { + let buf; + try { + // Returns: | + buf = fs.readFileSync(filePath); + if (Buffer.isBuffer(buf)) { + return buf.toString('utf8'); + } + } catch (e) { + // ignore + } + return buf; + } + }, + + readFile: async (filePath) => { + if (fs.existsSync(filePath)) { + const buf = await readFile(filePath).catch((e) => { + Util.logError(`read file: ${filePath} ${e.message || e}`); + }); + if (Buffer.isBuffer(buf)) { + return buf.toString('utf8'); + } + return buf; + } + }, + + readJson: async (jsonPath) => { + const content = await Util.readFile(jsonPath); + if (content) { + return JSON.parse(content); + } + }, + + writeFileSync: function(filePath, content) { + if (!fs.existsSync(filePath)) { + const p = path.dirname(filePath); + if (!fs.existsSync(p)) { + fs.mkdirSync(p, { + recursive: true + }); + } + } + fs.writeFileSync(filePath, content); + }, + + writeFile: async (filePath, content) => { + if (!fs.existsSync(filePath)) { + const p = path.dirname(filePath); + if (!fs.existsSync(p)) { + fs.mkdirSync(p, { + recursive: true + }); + } + } + await writeFile(filePath, content).catch((e) => { + Util.logError(`write file: ${filePath} ${e.message || e}`); + }); + }, + + rmSync: (p) => { + if (!fs.existsSync(p)) { + return; + } + try { + fs.rmSync(p, { + recursive: true, + force: true, + maxRetries: 10 + }); + } catch (err) { + console.log(err.message); + } + }, + + normalizeColorType: (color) => { + return `${color}`.trim().toLowerCase(); + }, + + normalizeMaxCols: (maxCols, min = 1) => { + if (Util.isNum(maxCols)) { + return Math.max(maxCols, min); + } + }, + + getColorStrByStatus: (str, status, color = '') => { + + const colorHandlers = { + 'ansicode': () => { + if (status === 'low') { + return EC.red(str); + } + if (status === 'medium') { + return EC.yellow(str); + } + if (status === 'high') { + return EC.green(str); + } + return str; + }, + 'unicode': () => { + if (status === 'low') { + return `🔴 ${str}`; + } + if (status === 'medium') { + return `🟡 ${str}`; + } + if (status === 'high') { + return `🟢 ${str}`; + } + return str; + }, + 'html': () => { + if (status === 'low') { + return `${str}`; + } + if (status === 'medium') { + return `${str}`; + } + if (status === 'high') { + return `${str}`; + } + return str; + }, + 'tex': () => { + const texStr = str.replace(/%/g, '\\\\%'); + if (status === 'low') { + return `$\\color{red}{\\textsf{${texStr}}}$`; + } + if (status === 'medium') { + return `$\\color{orange}{\\textsf{${texStr}}}$`; + } + if (status === 'high') { + return `$\\color{green}{\\textsf{${texStr}}}$`; + } + return str; + } + }; + + const handler = colorHandlers[color]; + if (handler) { + return handler(); + } + // no color + return str; + }, + + getUncoveredLines: (dataLines, color = '') => { + + const lines = []; + + let startLine; + let endLine; + + const getHtmlColor = (c) => { + return c === 'yellow' ? 'orange' : c; + }; + + const getAnsiLink = () => { + if (startLine.value !== 'red' && endLine.value !== 'red' && endLine.line - startLine.line === 1) { + return EC.yellow('-'); + } + return EC.red('-'); + }; + + const getHtmlLink = () => { + if (startLine.value !== 'red' && endLine.value !== 'red' && endLine.line - startLine.line === 1) { + return '-'; + } + return '-'; + }; + + const addRangeItem = () => { + if (color === 'ansicode') { + lines.push(EC[startLine.value](startLine.line) + getAnsiLink() + EC[endLine.value](endLine.line)); + return; + } + + if (color === 'html') { + lines.push(`${startLine.line}${getHtmlLink()}${endLine.line}`); + return; + } + + // no color + lines.push(`${startLine.line}-${endLine.line}`); + + }; + + const addStartItem = () => { + if (color === 'ansicode') { + lines.push(EC[startLine.value](startLine.line)); + return; + } + + if (color === 'html') { + lines.push(`${startLine.line}`); + return; + } + + // no color + lines.push(startLine.line); + + }; + + const addLines = () => { + if (!startLine) { + return; + } + if (endLine) { + // range + addRangeItem(); + startLine = null; + endLine = null; + } else { + // only start + addStartItem(); + startLine = null; + } + }; + + const setLines = (line, value) => { + if (startLine) { + endLine = { + line, + value + }; + return; + } + startLine = { + line, + value + }; + }; + + Object.keys(dataLines).forEach((line) => { + const count = dataLines[line]; + if (count === 0) { + setLines(line, 'red'); + return; + } + // 0 < count < 1 + if (typeof count === 'string') { + setLines(line, 'yellow'); + return; + } + // count >= 1 + addLines(); + }); + addLines(); + + return lines.join(','); + }, + + // skip \s and comments + fixSourceRange: (locator, start, end) => { + + let fixedStart = start; + let fixedEnd = end; + + const rangeText = locator.getSlice(start, end); + + let text = rangeText; + + // ======================================= + // handle end first + const oldLen = text.length; + text = text.trimEnd(); + const newLen = text.length; + if (newLen < oldLen) { + fixedEnd -= oldLen - newLen; + } + + // ======================================= + // handle start + + const comments = locator.lineParser.commentParser.comments; + + let startOffset = 0; + + // never start in a comment, skip to comment end + const inComment = comments.find((it) => start > it.start && start < it.end); + if (inComment) { + startOffset = inComment.end - start; + // next text + text = text.slice(startOffset); + } + + while (startOffset < newLen) { + + const beforeLen = text.length; + text = text.trimStart(); + const afterLen = text.length; + if (afterLen === beforeLen) { + // no indent + break; + } + + const indentLen = beforeLen - afterLen; + + startOffset += indentLen; + + // no comments + if (!comments.length) { + break; + } + + const nextPos = start + startOffset; + const comment = comments.find((it) => it.start === nextPos); + if (!comment) { + break; + } + + const commentLen = comment.end - comment.start; + + startOffset += commentLen; + + // next text + text = text.slice(commentLen); + + } + + // It should never be possible to start with } + if (rangeText[startOffset] === '}') { + startOffset += 1; + } + + fixedStart = start + startOffset; + + return { + fixedStart, + fixedEnd + }; + }, + + cmpVersion: (v1, v2) => { + const [strMajor1, strMinor1, strPatch1] = `${v1}`.split('.'); + const [strMajor2, strMinor2, strPatch2] = `${v2}`.split('.'); + const strList = [strMajor1, strMinor1, strPatch1, strMajor2, strMinor2, strPatch2]; + const list = strList.map((str) => Util.toNum(parseInt(str))); + const [major1, minor1, patch1, major2, minor2, patch2] = list; + if (major1 === major2) { + if (minor1 === minor2) { + return patch1 - patch2; + } + return minor1 - minor2; + } + return major1 - major2; + }, + + // ========================================================================================== + + loggingLevels: { + off: 0, + error: 10, + info: 20, + debug: 30 + }, + loggingLevel: 20, + + isDebug: () => { + return Util.loggingType === 'debug'; + }, + + initLoggingLevel: (level) => { + + const types = { + off: 'off', + error: 'error', + info: 'info', + debug: 'debug' + }; + + level = level || process.env.MCR_LOGGING; + + const type = types[level] || types.info; + Util.loggingType = type; + Util.loggingLevel = Util.loggingLevels[type]; + + // console.log('========================================='); + // console.log(from, Util.loggingType, Util.loggingLevel); + + return type; + }, + + logError: (message) => { + if (Util.loggingLevel < Util.loggingLevels.error) { + return; + } + EC.logRed(`[MCR] ${message}`); + }, + + logInfo: (message) => { + if (Util.loggingLevel < Util.loggingLevels.info) { + return; + } + console.log(`[MCR] ${message}`); + }, + + // grid is info level + logGrid: (gridData) => { + if (Util.loggingLevel < Util.loggingLevels.info) { + return; + } + CG(gridData); + }, + + logDebug: (message) => { + if (Util.loggingLevel < Util.loggingLevels.debug) { + return; + } + console.log(`[MCR] ${message}`); + }, + + logFilter: (message, lengthBefore, lengthAfter) => { + if (Util.loggingLevel < Util.loggingLevels.debug) { + return; + } + if (lengthAfter < lengthBefore) { + lengthBefore = EC.yellow(lengthBefore); + lengthAfter = EC.yellow(lengthAfter); + } + console.log(`[MCR] ${message} before ${lengthBefore} => after ${lengthAfter}`); + }, + + setGC: (threshold) => { + if (!Util.isNum(threshold)) { + threshold = 1024; + } + Util.gcThreshold = threshold; + }, + + getMemory: () => { + const { heapUsed } = process.memoryUsage(); + const memory = parseFloat((heapUsed / 1024 ** 2).toFixed(1)); + return memory; + }, + + // time is debug level, fix the log info, for checking snapshot + logTime: (message, time_start) => { + + // memory gc + let memory = Util.getMemory(); + if (Util.gcThreshold && Util.gcThreshold < memory) { + Util.forceGC(); + } + + if (Util.loggingLevel < Util.loggingLevels.debug && !process.env.MCR_LOG_TIME) { + return; + } + const duration = Date.now() - time_start; + const durationH = Util.TF(duration); + const ls = [`[MCR] ${message}`]; + + memory = Util.getMemory(); + ls.push(` (memory: ${memory}MB)`); + + // time + ls.push(' ('); + if (duration <= 100) { + ls.push(EC.green(durationH)); + } else if (duration < 500) { + ls.push(EC.yellow(durationH)); + } else { + ls.push(EC.red(durationH)); + } + ls.push(')'); + + console.log(ls.join('')); + } + +}; + +module.exports = Util; diff --git a/node_modules/monocart-coverage-reports/lib/v8/v8-summary.js b/node_modules/monocart-coverage-reports/lib/v8/v8-summary.js new file mode 100644 index 0000000..3c9a49d --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/v8/v8-summary.js @@ -0,0 +1,138 @@ +const Util = require('../utils/util.js'); + +// both css and js +const getV8SummaryBytes = (item) => { + const source = item.source; + const total = source.length; + + // for empty coverage + if (item.empty) { + return { + total, + covered: 0 + }; + } + + const uncoveredBytes = item.data.bytes.filter((range) => range.count === 0); + + let uncovered = 0; + + let endPos = 0; + uncoveredBytes.forEach((range) => { + if (range.ignored) { + return; + } + + const { start, end } = range; + + if (start > endPos) { + uncovered += end - start; + endPos = end; + return; + } + + if (end <= endPos) { + return; + } + + uncovered += end - endPos; + endPos = end; + + }); + + const covered = total - uncovered; + + // console.log(item) + + return { + total, + covered + }; +}; + +// calculate uncovered, pct, status +const calculatePctAndStatus = (item, watermarks) => { + Object.keys(item).forEach((k) => { + const indicateData = item[k]; + indicateData.uncovered = indicateData.total - indicateData.covered; + + let pct = ''; + let status = 'unknown'; + + if (indicateData.total) { + pct = Util.PNF(indicateData.covered, indicateData.total, 2); + status = Util.getStatus(pct, watermarks[k]); + } + + indicateData.pct = pct; + indicateData.status = status; + + }); +}; + +const getV8Summary = (v8list, watermarks) => { + + // get bytes summary + v8list.forEach((entry) => { + entry.summary.bytes = getV8SummaryBytes(entry); + }); + + // overall summary + const summary = { + bytes: { + total: 0, + covered: 0 + }, + statements: { + total: 0, + covered: 0 + }, + branches: { + total: 0, + covered: 0 + }, + functions: { + total: 0, + covered: 0 + }, + lines: { + total: 0, + covered: 0, + blank: 0, + comment: 0 + } + }; + + v8list.forEach((entry) => { + const entrySummary = entry.summary; + calculatePctAndStatus(entrySummary, watermarks); + + // do NOT add debug file + if (entry.debug) { + return; + } + + Object.keys(entrySummary).forEach((k) => { + const indicateData = entrySummary[k]; + if (!indicateData) { + return; + } + summary[k].total += indicateData.total; + summary[k].covered += indicateData.covered; + + if (k === 'lines') { + summary[k].blank += indicateData.blank; + summary[k].comment += indicateData.comment; + } + }); + }); + + // calculate overall summary + calculatePctAndStatus(summary, watermarks); + + return summary; +}; + +module.exports = { + getV8Summary +}; diff --git a/node_modules/monocart-coverage-reports/lib/v8/v8.js b/node_modules/monocart-coverage-reports/lib/v8/v8.js new file mode 100644 index 0000000..28afae0 --- /dev/null +++ b/node_modules/monocart-coverage-reports/lib/v8/v8.js @@ -0,0 +1,343 @@ +const EC = require('eight-colors'); +const Util = require('../utils/util.js'); +const { getV8Summary } = require('./v8-summary.js'); +const { dedupeFlatRanges } = require('../utils/dedupe.js'); +const { + resolveAnonymousUrl, normalizeSourcePath, getSourcePathReplacer +} = require('../utils/source-path.js'); +const { collectSourceMaps } = require('../converter/collect-source-maps.js'); + +const { v8Report } = require('../reports/v8.js'); +const { v8JsonReport } = require('../reports/v8-json.js'); +const { customReport } = require('../reports/custom.js'); + +const getWrapperSource = (offset, source) => { + // NO \n because it break line number in mappings + let startStr = ''; + if (offset >= 4) { + // fill comments + const spaces = ''.padEnd(offset - 4, '*'); + startStr = `/*${spaces}*/`; + } else { + // fill spaces (should no chance) + startStr += ''.padEnd(offset, ' '); + } + return startStr + source; +}; + +const initV8ListAndSourcemap = async (mcr, v8list) => { + + const { options, fileCache } = mcr; + + // entry filter + const entryFilter = Util.getEntryFilter(options); + + const lengthBefore = v8list.length; + v8list = v8list.filter(entryFilter); + const lengthAfter = v8list.length; + Util.logFilter('entry filter (add):', lengthBefore, lengthAfter); + + // filter no source or text + // init type and css source from text + // keep functions + v8list = v8list.filter((entry) => { + + // console.log(entry.url); + + if (typeof entry.source === 'string' && entry.functions) { + entry.type = 'js'; + return true; + } + if (typeof entry.text === 'string' && entry.ranges) { + entry.type = 'css'; + return true; + } + // allow empty coverage + if (entry.empty) { + if (!['js', 'css'].includes(entry.type)) { + entry.type = 'js'; + } + return true; + } + + // 404 css, text will be empty + Util.logDebug(EC.red(`Invalid source or coverage data: ${entry.url}`)); + // console.log(entry); + }); + + // onEntry hook + // after filter but before init, because id depends source and sourcePath + const onEntry = options.onEntry; + if (typeof onEntry === 'function') { + for (const entry of v8list) { + await onEntry(entry); + } + } + + const sourcePathReplacer = getSourcePathReplacer(options); + + const baseDir = options.baseDir; + + // init id, sourcePath + v8list = v8list.map((entry, i) => { + + // it could be a empty file + let source = `${entry.source || entry.text || ''}`; + + // fix source with script offset + let scriptOffset; + const offset = Util.toNum(entry.scriptOffset, true); + if (offset > 0) { + scriptOffset = offset; + source = getWrapperSource(offset, source); + } + + const data = { + url: entry.url, + type: entry.type, + source, + // script offset >= 0, for vm script + scriptOffset, + // Manually Resolve the Sourcemap + sourceMap: entry.sourceMap, + // fake source with `lineLengths` + fake: entry.fake, + // empty coverage + empty: entry.empty, + // match source if using empty coverage + distFile: entry.distFile + }; + + // coverage info + if (data.type === 'css') { + data.ranges = entry.ranges; + } else { + data.functions = entry.functions; + } + + // resolve source path + const sourceUrl = resolveAnonymousUrl(data.url, i + 1, data.type); + let sourcePath = normalizeSourcePath(sourceUrl, baseDir); + if (sourcePathReplacer) { + const newSourcePath = sourcePathReplacer(sourcePath, data); + if (typeof newSourcePath === 'string' && newSourcePath) { + sourcePath = newSourcePath; + } + } + data.sourcePath = sourcePath; + // console.log(data.url, sourcePath); + + // calculate source id + data.id = Util.calculateSha1(sourcePath + data.source); + + return data; + }); + + // collect sourcemap first + const time_start = Date.now(); + const { sourceList, sourcemapList } = await collectSourceMaps(v8list, options); + if (sourcemapList.length) { + // debug level time + Util.logTime(`loaded sourcemaps: ${sourcemapList.length}`, time_start); + // console.log(smList); + } + + // save source list + for (const sourceData of sourceList) { + await Util.saveSourceCacheFile(sourceData, options, fileCache); + } + + return v8list; +}; + +// ======================================================================================================== + +// force to async +const mergeCssRanges = (itemList) => { + return new Promise((resolve) => { + + let concatRanges = []; + itemList.forEach((item) => { + concatRanges = concatRanges.concat(item.ranges); + }); + + // ranges: [ {start, end} ] + const ranges = dedupeFlatRanges(concatRanges); + + resolve(ranges); + }); +}; + +const mergeJsFunctions = async (itemList) => { + const res = await Util.mergeV8Coverage(itemList); + return res.functions; +}; + +const mergeV8DataList = async (dataList, options) => { + const allList = dataList.map((d) => d.data).flat(); + + // separate coverage and empty items + const coverageList = []; + const allEmptyList = []; + allList.forEach((it) => { + if (it.empty) { + allEmptyList.push(it); + } else { + coverageList.push(it); + } + }); + + // connect all functions and ranges + const itemMap = {}; + const sourcePathMap = {}; + const mergeMap = {}; + coverageList.forEach((item) => { + const { id, sourcePath } = item; + const prev = itemMap[id]; + if (prev) { + if (mergeMap[id]) { + mergeMap[id].push(item); + } else { + mergeMap[id] = [prev, item]; + } + } else { + itemMap[id] = item; + sourcePathMap[sourcePath] = item; + } + }); + + // merge functions and ranges + const mergeIds = Object.keys(mergeMap); + for (const id of mergeIds) { + const itemList = mergeMap[id]; + const item = itemMap[id]; + if (item.type === 'css') { + item.ranges = await mergeCssRanges(itemList); + } else { + item.functions = await mergeJsFunctions(itemList); + } + } + + // first time filter for empty, (not for sources) + // empty and not in item map + const emptyList = allEmptyList.filter((it) => { + if (itemMap[it.id]) { + return false; + } + if (sourcePathMap[it.sourcePath]) { + return false; + } + return true; + }); + + // merged list + empty list + const mergedList = Object.values(itemMap).concat(emptyList); + + return mergedList; +}; + +const mergeV8Coverage = async (dataList, sourceCache, options) => { + + const mergedList = await mergeV8DataList(dataList, options); + + // try to load coverage and source by id + for (const entry of mergedList) { + const json = sourceCache.get(entry.id); + if (json) { + entry.source = json.source; + entry.sourceMap = json.sourceMap; + } else { + Util.logError(`Not found source data: ${Util.relativePath(entry.sourcePath)}`); + entry.source = ''; + } + + // add empty coverage after source init + if (entry.empty) { + Util.setEmptyV8Coverage(entry); + } + + } + + // GC + sourceCache.clear(); + + return mergedList; +}; + +// ============================================================ + +const saveV8Report = async (v8list, options, istanbulReportPath) => { + + const defaultWatermarks = { + bytes: [50, 80], + statements: [50, 80], + branches: [50, 80], + functions: [50, 80], + lines: [50, 80] + }; + const watermarks = Util.resolveWatermarks(defaultWatermarks, options.watermarks); + + const summary = getV8Summary(v8list, watermarks); + + const reportData = { + type: 'v8', + // override with saved file path + reportPath: '', + version: Util.version, + name: options.name, + watermarks, + summary, + files: v8list + }; + + // v8 only reports + const buildInV8Reports = { + 'v8': v8Report, + 'v8-json': v8JsonReport + }; + + const outputs = {}; + const v8Group = options.reportGroup.get('v8'); + // could be no v8 only reports, but have `both` data reports + if (v8Group) { + for (const [reportName, reportOptions] of v8Group) { + const buildInHandler = buildInV8Reports[reportName]; + const t1 = Date.now(); + if (buildInHandler) { + outputs[reportName] = await buildInHandler(reportData, reportOptions, options); + } else { + outputs[reportName] = await customReport(reportName, reportData, reportOptions, options); + } + Util.logTime(`${EC.magenta('├')} [generate] saved report: ${reportName}`, t1); + } + } + + if (istanbulReportPath) { + outputs.istanbul = istanbulReportPath; + } + + // outputPath, should be html or json + const reportPath = Util.resolveReportPath(options, () => { + return outputs.v8 || outputs.istanbul || Object.values(outputs).filter((it) => it && typeof it === 'string').shift(); + }); + + const coverageResults = { + type: 'v8', + // html or json + reportPath, + version: Util.version, + name: options.name, + watermarks, + summary, + files: v8list + }; + + return coverageResults; +}; + +module.exports = { + initV8ListAndSourcemap, + mergeV8DataList, + mergeV8Coverage, + saveV8Report +}; diff --git a/node_modules/monocart-coverage-reports/package.json b/node_modules/monocart-coverage-reports/package.json new file mode 100644 index 0000000..9c4adfb --- /dev/null +++ b/node_modules/monocart-coverage-reports/package.json @@ -0,0 +1,133 @@ +{ + "name": "monocart-coverage-reports", + "version": "2.12.9", + "description": "A code coverage tool to generate native V8 reports or Istanbul reports.", + "main": "./lib/index.js", + "bin": { + "mcr": "./lib/cli.js" + }, + "exports": { + ".": { + "types": "./lib/index.d.ts", + "import": "./lib/index.mjs", + "require": "./lib/index.js" + }, + "./register": { + "import": "./lib/register/register.mjs", + "require": "./lib/register/register.js" + }, + "./converter": "./lib/converter/converter.js", + "./util": "./lib/utils/util.js", + "./package.json": "./package.json" + }, + "types": "./lib/index.d.ts", + "scripts": { + "build-test": "node ./test/build/build-test.js", + "build": "npx sf lint && npx sf b -p && npm run build-test", + "test-unit": "mocha --parallel test/unit/*.test.js", + "test-node-env": "cross-env NODE_V8_COVERAGE=.temp/v8-coverage-env node ./test/test-node-env.js && node ./test/generate-report.js", + "test-node-api": "cross-env NODE_V8_COVERAGE=.temp/v8-coverage-api node ./test/test-node-api.js", + "test-node-ins": "node ./test/test-node-ins.js", + "test-node-cdp": "node --inspect=9229 ./test/test-node-cdp.js", + "test-node-vm": "node ./test/test-node-vm.js", + "test-node-koa": "node ./test/test-node-koa.js", + "test-node-fgc": "node ./test/test-node-fgc.js", + "test-node": "node ./test/test.js --node", + "test-istanbul": "node ./test/test-istanbul.js", + "test-v8": "node ./test/test-v8.js", + "test-puppeteer": "node ./test/test-puppeteer.js", + "test-css": "node ./test/test-css.js", + "test-minify": "node ./test/test-minify.js", + "test-esbuild": "node ./test/test-esbuild.js", + "test-rollup": "node ./test/test-rollup.js", + "test-sections": "node ./test/test-sections.js", + "test-swc": "node ./test/test-swc.js", + "test-v8-and-istanbul": "node ./test/test-v8-and-istanbul.js", + "test-browser": "node ./test/test.js --browser", + "test-cli": "npx mcr node ./test/specs/node.test.js -c test/mcr.config.cli.js", + "test-demo": "node ./test/test-demo.js", + "test-merge": "node ./test/test-merge.js", + "test-merge-istanbul": "node ./test/test-merge-istanbul.js", + "test-merge-v8": "node ./test/test-merge-v8.js", + "test-merge-cli": "npx mcr merge -r console-details,v8 --inputDir .temp/code-coverage/raw --outputDir .temp/merge-cli", + "test-client": "node ./test/test-client.js", + "test-all": "node ./test/test.js", + "test-pr": "node --inspect=9230 ./test/test-pr.js", + "test": "npm run test-unit && npx mcr npm run test-all -c test/mcr.config.mcr.js && node ./scripts/docs.js", + "test:snap": "cross-env TEST_SNAPSHOT=true npm run test", + "dev": "npx sf d app", + "open": "node ./scripts/open.js", + "eol": "git rm -rf --cached . && git reset --hard HEAD", + "patch": "npm run build && npm run test && npx sf publish patch -r", + "beta": "npm version prerelease --preid=beta && npm run build && npm run test && npm publish --tag beta" + }, + "files": [ + "lib", + "README.zh-Hans.md" + ], + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/cenfun/monocart-coverage-reports.git" + }, + "dependencies": { + "acorn": "^8.15.0", + "acorn-loose": "^8.5.2", + "acorn-walk": "^8.3.4", + "commander": "^14.0.0", + "console-grid": "^2.2.3", + "eight-colors": "^1.3.1", + "foreground-child": "^3.3.1", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.2.0", + "lz-utils": "^2.1.0", + "monocart-locator": "^1.0.2" + }, + "devDependencies": { + "@actions/core": "^1.11.1", + "@actions/github": "^6.0.1", + "@jridgewell/sourcemap-codec": "^1.5.5", + "@jsdevtools/coverage-istanbul-loader": "^3.0.5", + "@rollup/plugin-commonjs": "^28.0.6", + "@rollup/plugin-typescript": "^12.1.4", + "async-tick": "^1.0.0", + "babel-loader": "^10.0.0", + "babel-plugin-istanbul": "^7.0.1", + "convert-source-map": "^2.0.0", + "cross-env": "^10.0.0", + "diff-sequences": "^29.6.3", + "esbuild": "^0.25.9", + "eslint": "~9.35.0", + "eslint-config-plus": "^2.0.3", + "eslint-plugin-html": "^8.1.3", + "eslint-plugin-vue": "^10.4.0", + "find-up": "^7.0.0", + "foreground-child": "^3.3.1", + "koa": "^3.0.1", + "koa-static-resolver": "^1.0.6", + "minimatch": "^9.0.5", + "mocha": "^11.7.2", + "monocart-code-viewer": "^1.1.5", + "monocart-formatter": "^3.0.1", + "node-stream-zip": "^1.15.0", + "open": "^10.2.0", + "playwright": "^1.55.0", + "postcss": "^8.5.6", + "puppeteer": "^24.19.0", + "rollup": "^4.50.1", + "starfall-cli": "^2.0.22", + "stylelint": "^16.24.0", + "stylelint-config-plus": "^1.1.4", + "supports-color": "^10.2.2", + "swc-loader": "^0.2.6", + "ts-loader": "^9.5.4", + "tsx": "^4.20.5", + "turbogrid": "^3.2.1", + "typescript": "^5.9.2", + "vine-ui": "^3.1.18", + "webpack": "^5.101.3", + "ws": "^8.18.3", + "yazl": "^3.3.1" + } +} diff --git a/node_modules/monocart-locator/LICENSE b/node_modules/monocart-locator/LICENSE new file mode 100644 index 0000000..6d8ec8b --- /dev/null +++ b/node_modules/monocart-locator/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 cenfun + +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/node_modules/monocart-locator/README.md b/node_modules/monocart-locator/README.md new file mode 100644 index 0000000..da45af8 --- /dev/null +++ b/node_modules/monocart-locator/README.md @@ -0,0 +1,26 @@ +# Monocart Locator +[![](https://img.shields.io/npm/v/monocart-locator)](https://www.npmjs.com/package/monocart-locator) +[![](https://badgen.net/npm/dw/monocart-locator)](https://www.npmjs.com/package/monocart-locator) +![](https://img.shields.io/github/license/cenfun/monocart-locator) + +> A Locator for the source code position between offset and line/column. + +## Features +- Position locator +- Line parser +- Comment parser + +## Install +```sh +npm i monocart-locator +``` + +## Usage +```js +const locator = new Locator(source); +console.log(locator.lines); +console.log(locator.comments); + +const offset = locator.locationToOffset({ line: 1, column: 1 }); +const loc = locator.offsetToLocation(10); +``` \ No newline at end of file diff --git a/node_modules/monocart-locator/lib/comment-parser.js b/node_modules/monocart-locator/lib/comment-parser.js new file mode 100644 index 0000000..b92b1e8 --- /dev/null +++ b/node_modules/monocart-locator/lib/comment-parser.js @@ -0,0 +1,154 @@ +class CommentParser { + + // eslint-disable-next-line complexity + constructor(source) { + + const comments = []; + + let tokenClose = null; + + let isComment = false; + let block = false; + let start = 0; + + let closeOffset = 0; + let commentOffset = 0; + + let quote; + const quoteClose = (currentCharacter) => { + if (currentCharacter === '\\') { + closeOffset = 1; + return false; + } + closeOffset = 0; + return currentCharacter === quote; + }; + + const lineClose = (currentCharacter, nextCharacter) => { + if (currentCharacter === '\r' && nextCharacter === '\n') { + closeOffset = 1; + return true; + } + closeOffset = 0; + return currentCharacter === '\n'; + }; + + const blockClose = (currentCharacter, nextCharacter) => { + if (currentCharacter === '*' && nextCharacter === '/') { + closeOffset = 1; + commentOffset = 2; + return true; + } + closeOffset = 0; + return false; + }; + + const len = source.length; + for (let i = 0; i < len; i++) { + const currentCharacter = source[i]; + const nextCharacter = source[i + 1]; + + if (tokenClose !== null) { + if (tokenClose(currentCharacter, nextCharacter)) { + if (isComment) { + comments.push({ + block, + start, + end: i + commentOffset + }); + } + tokenClose = null; + } + i += closeOffset; + continue; + } + + // string singleQuote doubleQuote backQuote + if (currentCharacter === "'" || currentCharacter === '"' || currentCharacter === '`') { + quote = currentCharacter; + isComment = false; + tokenClose = quoteClose; + continue; + } + + // line comments + if (currentCharacter === '/' && nextCharacter === '/') { + block = false; + isComment = true; + commentOffset = 0; + start = i; + tokenClose = lineClose; + i += 1; + continue; + } + + // block comments + if (currentCharacter === '/' && nextCharacter === '*') { + block = true; + isComment = true; + commentOffset = 0; + start = i; + tokenClose = blockClose; + i += 1; + } + + } + + if (tokenClose && isComment) { + comments.push({ + block, + start, + end: len + }); + } + + // add comment text + comments.forEach((it) => { + it.text = source.slice(it.start, it.end); + }); + + this.comments = comments; + + } + + isComment(start, end) { + if (!this.comments.length) { + return false; + } + const comment = this.findComment(start); + if (start >= comment.start && end <= comment.end) { + return true; + } + return false; + } + + findComment(position) { + const list = this.comments; + let start = 0; + let end = list.length - 1; + while (end - start > 1) { + const i = Math.floor((start + end) * 0.5); + const item = list[i]; + if (position < item.start) { + end = i; + continue; + } + if (position > item.end) { + start = i; + continue; + } + return list[i]; + } + // last two items, less is start + const endItem = list[end]; + if (position < endItem.start) { + return list[start]; + } + return list[end]; + + } + + +} + +module.exports = CommentParser; diff --git a/node_modules/monocart-locator/lib/index.d.ts b/node_modules/monocart-locator/lib/index.d.ts new file mode 100644 index 0000000..56ddab2 --- /dev/null +++ b/node_modules/monocart-locator/lib/index.d.ts @@ -0,0 +1,61 @@ +export type CommentItem = { + block: boolean; + start: number; + end: number; + text: string; +} + +export class CommentParser { + constructor(source: string); + comments: CommentItem[]; + isComment(start: number, end: number): boolean; +} + + +export type LineItem = { + /** 0-base */ + line: number; + + length: number; + indent: number; + + start: number; + end: number; + + blank?: boolean; + comment?: boolean; + + text: string; +} + +export class LineParser { + constructor(source: string); + lines: LineItem[]; + comments: CommentItem[]; + findLine(pos: number): LineItem; +} + + +export type LocationItem = LineItem & { + /** 1-base */ + line: number; + column: number; +} + +export class Locator { + constructor(source: string); + source: string; + lineParser: LineParser; + lines: LineItem[]; + comments: CommentItem[]; + + /** 1-base */ + locationToOffset(loc: LocationItem): number; + offsetToLocation(offset: number): LocationItem; + + getSlice(start: number, end?: number): string; + + /** 1-base to 0-base */ + getLine(line: number): LineItem; + +} \ No newline at end of file diff --git a/node_modules/monocart-locator/lib/index.js b/node_modules/monocart-locator/lib/index.js new file mode 100644 index 0000000..2fe90ae --- /dev/null +++ b/node_modules/monocart-locator/lib/index.js @@ -0,0 +1,10 @@ +const Locator = require('./locator.js'); +const LineParser = require('./line-parser.js'); +const CommentParser = require('./comment-parser.js'); + +module.exports = { + Locator, + LineParser, + CommentParser +}; + diff --git a/node_modules/monocart-locator/lib/index.mjs b/node_modules/monocart-locator/lib/index.mjs new file mode 100644 index 0000000..7fe9917 --- /dev/null +++ b/node_modules/monocart-locator/lib/index.mjs @@ -0,0 +1,3 @@ +export * from './index.js'; +import locator from './index.js'; +export default locator; diff --git a/node_modules/monocart-locator/lib/line-parser.js b/node_modules/monocart-locator/lib/line-parser.js new file mode 100644 index 0000000..dfb95ff --- /dev/null +++ b/node_modules/monocart-locator/lib/line-parser.js @@ -0,0 +1,100 @@ +const CommentParser = require('./comment-parser.js'); + +class LineParser { + constructor(content = '') { + let pos = 0; + + // force to string + if (typeof content !== 'string') { + content = `${content}`; + } + + const commentParser = new CommentParser(content); + this.commentParser = commentParser; + this.comments = commentParser.comments; + + // only \n, common on Linux and macOS + // \r\n, common on Windows + this.lines = content.split(/\n/).map((text, line) => { + + let n = 1; + // may ends with \r + const reg = /\r$/; + if (reg.test(text)) { + text = text.slice(0, -1); + n += 1; + } + + const length = text.length; + const start = pos; + const end = start + length; + + pos += length + n; + + // ============================= + const blankBlock = /\S/; + + let blank = false; + if (!blankBlock.test(text)) { + blank = true; + } + + // ============================= + let comment = false; + let indent = length; + if (!blank) { + indent = text.search(blankBlock); + + if (commentParser.isComment(start + indent, end)) { + comment = true; + } + + } + + // ============================= + + return { + line, + + length, + indent, + + start, + end, + + blank, + comment, + + text + }; + }); + } + + findLine(position) { + const list = this.lines; + let start = 0; + let end = list.length - 1; + while (end - start > 1) { + const i = Math.floor((start + end) * 0.5); + const item = list[i]; + if (position < item.start) { + end = i; + continue; + } + if (position > item.end) { + start = i; + continue; + } + return list[i]; + } + // last two items, less is start + const endItem = list[end]; + if (position < endItem.start) { + return list[start]; + } + return list[end]; + } + +} + +module.exports = LineParser; diff --git a/node_modules/monocart-locator/lib/locator.js b/node_modules/monocart-locator/lib/locator.js new file mode 100644 index 0000000..84368d0 --- /dev/null +++ b/node_modules/monocart-locator/lib/locator.js @@ -0,0 +1,53 @@ +const LineParser = require('./line-parser.js'); +class Locator { + constructor(source) { + this.source = source; + this.lineParser = new LineParser(source); + this.lines = this.lineParser.lines; + this.comments = this.lineParser.comments; + } + + // 1-base + locationToOffset(location) { + const { line, column } = location; + // 1-based + const lineInfo = this.lines[line - 1]; + if (lineInfo) { + if (column === Infinity) { + return lineInfo.start + lineInfo.length; + } + return lineInfo.start + Math.min(column, lineInfo.length); + } + return 0; + } + + // 1-base + offsetToLocation(offset) { + const lineInfo = this.lineParser.findLine(offset); + + // 1-base + const line = lineInfo.line + 1; + + const column = Math.min(Math.max(offset - lineInfo.start, 0), lineInfo.length); + + return { + ... lineInfo, + line, + column + }; + } + + getSlice(s, e) { + return this.source.slice(s, e); + } + + // 1-base + getLine(line) { + return this.lines[line - 1]; + } + + +} + +module.exports = Locator; + diff --git a/node_modules/monocart-locator/package.json b/node_modules/monocart-locator/package.json new file mode 100644 index 0000000..893f17a --- /dev/null +++ b/node_modules/monocart-locator/package.json @@ -0,0 +1,32 @@ +{ + "name": "monocart-locator", + "version": "1.0.2", + "description": "Monocart Locator", + "main": "./lib/index.js", + "exports": { + ".": { + "types": "./lib/index.d.ts", + "import": "./lib/index.mjs", + "require": "./lib/index.js", + "default": "./lib/index.js" + }, + "./package.json": "./package.json" + }, + "types": "./lib/index.d.ts", + "scripts": { + "test": "mocha", + "patch": "npm run test && sf publish patch" + }, + "files": [ + "lib" + ], + "license": "MIT", + "dependencies": {}, + "devDependencies": { + "console-grid": "^2.2.2", + "eight-colors": "^1.3.0", + "eslint": "^9.6.0", + "eslint-config-plus": "^2.0.2", + "mocha": "^10.5.2" + } +} diff --git a/node_modules/path-key/index.d.ts b/node_modules/path-key/index.d.ts new file mode 100644 index 0000000..7c575d1 --- /dev/null +++ b/node_modules/path-key/index.d.ts @@ -0,0 +1,40 @@ +/// + +declare namespace pathKey { + interface Options { + /** + Use a custom environment variables object. Default: [`process.env`](https://nodejs.org/api/process.html#process_process_env). + */ + readonly env?: {[key: string]: string | undefined}; + + /** + Get the PATH key for a specific platform. Default: [`process.platform`](https://nodejs.org/api/process.html#process_process_platform). + */ + readonly platform?: NodeJS.Platform; + } +} + +declare const pathKey: { + /** + Get the [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) environment variable key cross-platform. + + @example + ``` + import pathKey = require('path-key'); + + const key = pathKey(); + //=> 'PATH' + + const PATH = process.env[key]; + //=> '/usr/local/bin:/usr/bin:/bin' + ``` + */ + (options?: pathKey.Options): string; + + // TODO: Remove this for the next major release, refactor the whole definition to: + // declare function pathKey(options?: pathKey.Options): string; + // export = pathKey; + default: typeof pathKey; +}; + +export = pathKey; diff --git a/node_modules/path-key/index.js b/node_modules/path-key/index.js new file mode 100644 index 0000000..0cf6415 --- /dev/null +++ b/node_modules/path-key/index.js @@ -0,0 +1,16 @@ +'use strict'; + +const pathKey = (options = {}) => { + const environment = options.env || process.env; + const platform = options.platform || process.platform; + + if (platform !== 'win32') { + return 'PATH'; + } + + return Object.keys(environment).reverse().find(key => key.toUpperCase() === 'PATH') || 'Path'; +}; + +module.exports = pathKey; +// TODO: Remove this for the next major release +module.exports.default = pathKey; diff --git a/node_modules/path-key/license b/node_modules/path-key/license new file mode 100644 index 0000000..e7af2f7 --- /dev/null +++ b/node_modules/path-key/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +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/node_modules/path-key/package.json b/node_modules/path-key/package.json new file mode 100644 index 0000000..c8cbd38 --- /dev/null +++ b/node_modules/path-key/package.json @@ -0,0 +1,39 @@ +{ + "name": "path-key", + "version": "3.1.1", + "description": "Get the PATH environment variable key cross-platform", + "license": "MIT", + "repository": "sindresorhus/path-key", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "engines": { + "node": ">=8" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "path", + "key", + "environment", + "env", + "variable", + "var", + "get", + "cross-platform", + "windows" + ], + "devDependencies": { + "@types/node": "^11.13.0", + "ava": "^1.4.1", + "tsd": "^0.7.2", + "xo": "^0.24.0" + } +} diff --git a/node_modules/path-key/readme.md b/node_modules/path-key/readme.md new file mode 100644 index 0000000..a9052d7 --- /dev/null +++ b/node_modules/path-key/readme.md @@ -0,0 +1,61 @@ +# path-key [![Build Status](https://travis-ci.org/sindresorhus/path-key.svg?branch=master)](https://travis-ci.org/sindresorhus/path-key) + +> Get the [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) environment variable key cross-platform + +It's usually `PATH`, but on Windows it can be any casing like `Path`... + + +## Install + +``` +$ npm install path-key +``` + + +## Usage + +```js +const pathKey = require('path-key'); + +const key = pathKey(); +//=> 'PATH' + +const PATH = process.env[key]; +//=> '/usr/local/bin:/usr/bin:/bin' +``` + + +## API + +### pathKey(options?) + +#### options + +Type: `object` + +##### env + +Type: `object`
+Default: [`process.env`](https://nodejs.org/api/process.html#process_process_env) + +Use a custom environment variables object. + +#### platform + +Type: `string`
+Default: [`process.platform`](https://nodejs.org/api/process.html#process_process_platform) + +Get the PATH key for a specific platform. + + +--- + +
+ + Get professional support for this package with a Tidelift subscription + +
+ + Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. +
+
diff --git a/node_modules/semver/LICENSE b/node_modules/semver/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/semver/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, 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 THIS SOFTWARE. diff --git a/node_modules/semver/README.md b/node_modules/semver/README.md new file mode 100644 index 0000000..e9d1bc5 --- /dev/null +++ b/node_modules/semver/README.md @@ -0,0 +1,665 @@ +semver(1) -- The semantic versioner for npm +=========================================== + +## Install + +```bash +npm install semver +```` + +## Usage + +As a node module: + +```js +const semver = require('semver') + +semver.valid('1.2.3') // '1.2.3' +semver.valid('a.b.c') // null +semver.clean(' =v1.2.3 ') // '1.2.3' +semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true +semver.gt('1.2.3', '9.8.7') // false +semver.lt('1.2.3', '9.8.7') // true +semver.minVersion('>=1.0.0') // '1.0.0' +semver.valid(semver.coerce('v2')) // '2.0.0' +semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7' +``` + +You can also just load the module for the function that you care about if +you'd like to minimize your footprint. + +```js +// load the whole API at once in a single object +const semver = require('semver') + +// or just load the bits you need +// all of them listed here, just pick and choose what you want + +// classes +const SemVer = require('semver/classes/semver') +const Comparator = require('semver/classes/comparator') +const Range = require('semver/classes/range') + +// functions for working with versions +const semverParse = require('semver/functions/parse') +const semverValid = require('semver/functions/valid') +const semverClean = require('semver/functions/clean') +const semverInc = require('semver/functions/inc') +const semverDiff = require('semver/functions/diff') +const semverMajor = require('semver/functions/major') +const semverMinor = require('semver/functions/minor') +const semverPatch = require('semver/functions/patch') +const semverPrerelease = require('semver/functions/prerelease') +const semverCompare = require('semver/functions/compare') +const semverRcompare = require('semver/functions/rcompare') +const semverCompareLoose = require('semver/functions/compare-loose') +const semverCompareBuild = require('semver/functions/compare-build') +const semverSort = require('semver/functions/sort') +const semverRsort = require('semver/functions/rsort') + +// low-level comparators between versions +const semverGt = require('semver/functions/gt') +const semverLt = require('semver/functions/lt') +const semverEq = require('semver/functions/eq') +const semverNeq = require('semver/functions/neq') +const semverGte = require('semver/functions/gte') +const semverLte = require('semver/functions/lte') +const semverCmp = require('semver/functions/cmp') +const semverCoerce = require('semver/functions/coerce') + +// working with ranges +const semverSatisfies = require('semver/functions/satisfies') +const semverMaxSatisfying = require('semver/ranges/max-satisfying') +const semverMinSatisfying = require('semver/ranges/min-satisfying') +const semverToComparators = require('semver/ranges/to-comparators') +const semverMinVersion = require('semver/ranges/min-version') +const semverValidRange = require('semver/ranges/valid') +const semverOutside = require('semver/ranges/outside') +const semverGtr = require('semver/ranges/gtr') +const semverLtr = require('semver/ranges/ltr') +const semverIntersects = require('semver/ranges/intersects') +const semverSimplifyRange = require('semver/ranges/simplify') +const semverRangeSubset = require('semver/ranges/subset') +``` + +As a command-line utility: + +``` +$ semver -h + +A JavaScript implementation of the https://semver.org/ specification +Copyright Isaac Z. Schlueter + +Usage: semver [options] [ [...]] +Prints valid versions sorted by SemVer precedence + +Options: +-r --range + Print versions that match the specified range. + +-i --increment [] + Increment a version by the specified level. Level can + be one of: major, minor, patch, premajor, preminor, + prepatch, prerelease, or release. Default level is 'patch'. + Only one version may be specified. + +--preid + Identifier to be used to prefix premajor, preminor, + prepatch or prerelease version increments. + +-l --loose + Interpret versions and ranges loosely + +-n <0|1|false> + Base number for prerelease identifier (default: 0). + Use false to omit the number altogether. + +-p --include-prerelease + Always include prerelease versions in range matching + +-c --coerce + Coerce a string into SemVer if possible + (does not imply --loose) + +--rtl + Coerce version strings right to left + +--ltr + Coerce version strings left to right (default) + +Program exits successfully if any valid version satisfies +all supplied ranges, and prints all satisfying versions. + +If no satisfying versions are found, then exits failure. + +Versions are printed in ascending order, so supplying +multiple versions to the utility will just sort them. +``` + +## Versions + +A "version" is described by the `v2.0.0` specification found at +. + +A leading `"="` or `"v"` character is stripped off and ignored. +Support for stripping a leading "v" is kept for compatibility with `v1.0.0` of the SemVer +specification but should not be used anymore. + +## Ranges + +A `version range` is a set of `comparators` that specify versions +that satisfy the range. + +A `comparator` is composed of an `operator` and a `version`. The set +of primitive `operators` is: + +* `<` Less than +* `<=` Less than or equal to +* `>` Greater than +* `>=` Greater than or equal to +* `=` Equal. If no operator is specified, then equality is assumed, + so this operator is optional but MAY be included. + +For example, the comparator `>=1.2.7` would match the versions +`1.2.7`, `1.2.8`, `2.5.3`, and `1.3.9`, but not the versions `1.2.6` +or `1.1.0`. The comparator `>1` is equivalent to `>=2.0.0` and +would match the versions `2.0.0` and `3.1.0`, but not the versions +`1.0.1` or `1.1.0`. + +Comparators can be joined by whitespace to form a `comparator set`, +which is satisfied by the **intersection** of all of the comparators +it includes. + +A range is composed of one or more comparator sets, joined by `||`. A +version matches a range if and only if every comparator in at least +one of the `||`-separated comparator sets is satisfied by the version. + +For example, the range `>=1.2.7 <1.3.0` would match the versions +`1.2.7`, `1.2.8`, and `1.2.99`, but not the versions `1.2.6`, `1.3.0`, +or `1.1.0`. + +The range `1.2.7 || >=1.2.9 <2.0.0` would match the versions `1.2.7`, +`1.2.9`, and `1.4.6`, but not the versions `1.2.8` or `2.0.0`. + +### Prerelease Tags + +If a version has a prerelease tag (for example, `1.2.3-alpha.3`) then +it will only be allowed to satisfy comparator sets if at least one +comparator with the same `[major, minor, patch]` tuple also has a +prerelease tag. + +For example, the range `>1.2.3-alpha.3` would be allowed to match the +version `1.2.3-alpha.7`, but it would *not* be satisfied by +`3.4.5-alpha.9`, even though `3.4.5-alpha.9` is technically "greater +than" `1.2.3-alpha.3` according to the SemVer sort rules. The version +range only accepts prerelease tags on the `1.2.3` version. +Version `3.4.5` *would* satisfy the range because it does not have a +prerelease flag, and `3.4.5` is greater than `1.2.3-alpha.7`. + +The purpose of this behavior is twofold. First, prerelease versions +frequently are updated very quickly, and contain many breaking changes +that are (by the author's design) not yet fit for public consumption. +Therefore, by default, they are excluded from range-matching +semantics. + +Second, a user who has opted into using a prerelease version has +indicated the intent to use *that specific* set of +alpha/beta/rc versions. By including a prerelease tag in the range, +the user is indicating that they are aware of the risk. However, it +is still not appropriate to assume that they have opted into taking a +similar risk on the *next* set of prerelease versions. + +Note that this behavior can be suppressed (treating all prerelease +versions as if they were normal versions, for range-matching) +by setting the `includePrerelease` flag on the options +object to any +[functions](https://github.com/npm/node-semver#functions) that do +range matching. + +#### Prerelease Identifiers + +The method `.inc` takes an additional `identifier` string argument that +will append the value of the string as a prerelease identifier: + +```javascript +semver.inc('1.2.3', 'prerelease', 'beta') +// '1.2.4-beta.0' +``` + +command-line example: + +```bash +$ semver 1.2.3 -i prerelease --preid beta +1.2.4-beta.0 +``` + +Which then can be used to increment further: + +```bash +$ semver 1.2.4-beta.0 -i prerelease +1.2.4-beta.1 +``` + +To get out of the prerelease phase, use the `release` option: + +```bash +$ semver 1.2.4-beta.1 -i release +1.2.4 +``` + +#### Prerelease Identifier Base + +The method `.inc` takes an optional parameter 'identifierBase' string +that will let you let your prerelease number as zero-based or one-based. +Set to `false` to omit the prerelease number altogether. +If you do not specify this parameter, it will default to zero-based. + +```javascript +semver.inc('1.2.3', 'prerelease', 'beta', '1') +// '1.2.4-beta.1' +``` + +```javascript +semver.inc('1.2.3', 'prerelease', 'beta', false) +// '1.2.4-beta' +``` + +command-line example: + +```bash +$ semver 1.2.3 -i prerelease --preid beta -n 1 +1.2.4-beta.1 +``` + +```bash +$ semver 1.2.3 -i prerelease --preid beta -n false +1.2.4-beta +``` + +### Advanced Range Syntax + +Advanced range syntax desugars to primitive comparators in +deterministic ways. + +Advanced ranges may be combined in the same way as primitive +comparators using white space or `||`. + +#### Hyphen Ranges `X.Y.Z - A.B.C` + +Specifies an inclusive set. + +* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4` + +If a partial version is provided as the first version in the inclusive +range, then the missing pieces are replaced with zeroes. + +* `1.2 - 2.3.4` := `>=1.2.0 <=2.3.4` + +If a partial version is provided as the second version in the +inclusive range, then all versions that start with the supplied parts +of the tuple are accepted, but nothing that would be greater than the +provided tuple parts. + +* `1.2.3 - 2.3` := `>=1.2.3 <2.4.0-0` +* `1.2.3 - 2` := `>=1.2.3 <3.0.0-0` + +#### X-Ranges `1.2.x` `1.X` `1.2.*` `*` + +Any of `X`, `x`, or `*` may be used to "stand in" for one of the +numeric values in the `[major, minor, patch]` tuple. + +* `*` := `>=0.0.0` (Any non-prerelease version satisfies, unless + `includePrerelease` is specified, in which case any version at all + satisfies) +* `1.x` := `>=1.0.0 <2.0.0-0` (Matching major version) +* `1.2.x` := `>=1.2.0 <1.3.0-0` (Matching major and minor versions) + +A partial version range is treated as an X-Range, so the special +character is in fact optional. + +* `""` (empty string) := `*` := `>=0.0.0` +* `1` := `1.x.x` := `>=1.0.0 <2.0.0-0` +* `1.2` := `1.2.x` := `>=1.2.0 <1.3.0-0` + +#### Tilde Ranges `~1.2.3` `~1.2` `~1` + +Allows patch-level changes if a minor version is specified on the +comparator. Allows minor-level changes if not. + +* `~1.2.3` := `>=1.2.3 <1.(2+1).0` := `>=1.2.3 <1.3.0-0` +* `~1.2` := `>=1.2.0 <1.(2+1).0` := `>=1.2.0 <1.3.0-0` (Same as `1.2.x`) +* `~1` := `>=1.0.0 <(1+1).0.0` := `>=1.0.0 <2.0.0-0` (Same as `1.x`) +* `~0.2.3` := `>=0.2.3 <0.(2+1).0` := `>=0.2.3 <0.3.0-0` +* `~0.2` := `>=0.2.0 <0.(2+1).0` := `>=0.2.0 <0.3.0-0` (Same as `0.2.x`) +* `~0` := `>=0.0.0 <(0+1).0.0` := `>=0.0.0 <1.0.0-0` (Same as `0.x`) +* `~1.2.3-beta.2` := `>=1.2.3-beta.2 <1.3.0-0` Note that prereleases in + the `1.2.3` version will be allowed, if they are greater than or + equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but + `1.2.4-beta.2` would not, because it is a prerelease of a + different `[major, minor, patch]` tuple. + +#### Caret Ranges `^1.2.3` `^0.2.5` `^0.0.4` + +Allows changes that do not modify the left-most non-zero element in the +`[major, minor, patch]` tuple. In other words, this allows patch and +minor updates for versions `1.0.0` and above, patch updates for +versions `0.X >=0.1.0`, and *no* updates for versions `0.0.X`. + +Many authors treat a `0.x` version as if the `x` were the major +"breaking-change" indicator. + +Caret ranges are ideal when an author may make breaking changes +between `0.2.4` and `0.3.0` releases, which is a common practice. +However, it presumes that there will *not* be breaking changes between +`0.2.4` and `0.2.5`. It allows for changes that are presumed to be +additive (but non-breaking), according to commonly observed practices. + +* `^1.2.3` := `>=1.2.3 <2.0.0-0` +* `^0.2.3` := `>=0.2.3 <0.3.0-0` +* `^0.0.3` := `>=0.0.3 <0.0.4-0` +* `^1.2.3-beta.2` := `>=1.2.3-beta.2 <2.0.0-0` Note that prereleases in + the `1.2.3` version will be allowed, if they are greater than or + equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but + `1.2.4-beta.2` would not, because it is a prerelease of a + different `[major, minor, patch]` tuple. +* `^0.0.3-beta` := `>=0.0.3-beta <0.0.4-0` Note that prereleases in the + `0.0.3` version *only* will be allowed, if they are greater than or + equal to `beta`. So, `0.0.3-pr.2` would be allowed. + +When parsing caret ranges, a missing `patch` value desugars to the +number `0`, but will allow flexibility within that value, even if the +major and minor versions are both `0`. + +* `^1.2.x` := `>=1.2.0 <2.0.0-0` +* `^0.0.x` := `>=0.0.0 <0.1.0-0` +* `^0.0` := `>=0.0.0 <0.1.0-0` + +A missing `minor` and `patch` values will desugar to zero, but also +allow flexibility within those values, even if the major version is +zero. + +* `^1.x` := `>=1.0.0 <2.0.0-0` +* `^0.x` := `>=0.0.0 <1.0.0-0` + +### Range Grammar + +Putting all this together, here is a Backus-Naur grammar for ranges, +for the benefit of parser authors: + +```bnf +range-set ::= range ( logical-or range ) * +logical-or ::= ( ' ' ) * '||' ( ' ' ) * +range ::= hyphen | simple ( ' ' simple ) * | '' +hyphen ::= partial ' - ' partial +simple ::= primitive | partial | tilde | caret +primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial +partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )? +xr ::= 'x' | 'X' | '*' | nr +nr ::= '0' | ['1'-'9'] ( ['0'-'9'] ) * +tilde ::= '~' partial +caret ::= '^' partial +qualifier ::= ( '-' pre )? ( '+' build )? +pre ::= parts +build ::= parts +parts ::= part ( '.' part ) * +part ::= nr | [-0-9A-Za-z]+ +``` + +## Functions + +All methods and classes take a final `options` object argument. All +options in this object are `false` by default. The options supported +are: + +- `loose`: Be more forgiving about not-quite-valid semver strings. + (Any resulting output will always be 100% strict compliant, of + course.) For backwards compatibility reasons, if the `options` + argument is a boolean value instead of an object, it is interpreted + to be the `loose` param. +- `includePrerelease`: Set to suppress the [default + behavior](https://github.com/npm/node-semver#prerelease-tags) of + excluding prerelease tagged versions from ranges unless they are + explicitly opted into. + +Strict-mode Comparators and Ranges will be strict about the SemVer +strings that they parse. + +* `valid(v)`: Return the parsed version, or null if it's not valid. +* `inc(v, releaseType, options, identifier, identifierBase)`: + Return the version incremented by the release + type (`major`, `premajor`, `minor`, `preminor`, `patch`, + `prepatch`, `prerelease`, or `release`), or null if it's not valid + * `premajor` in one call will bump the version up to the next major + version and down to a prerelease of that major version. + `preminor`, and `prepatch` work the same way. + * If called from a non-prerelease version, `prerelease` will work the + same as `prepatch`. It increments the patch version and then makes a + prerelease. If the input version is already a prerelease it simply + increments it. + * `release` will remove any prerelease part of the version. + * `identifier` can be used to prefix `premajor`, `preminor`, + `prepatch`, or `prerelease` version increments. `identifierBase` + is the base to be used for the `prerelease` identifier. +* `prerelease(v)`: Returns an array of prerelease components, or null + if none exist. Example: `prerelease('1.2.3-alpha.1') -> ['alpha', 1]` +* `major(v)`: Return the major version number. +* `minor(v)`: Return the minor version number. +* `patch(v)`: Return the patch version number. +* `intersects(r1, r2, loose)`: Return true if the two supplied ranges + or comparators intersect. +* `parse(v)`: Attempt to parse a string as a semantic version, returning either + a `SemVer` object or `null`. + +### Comparison + +* `gt(v1, v2)`: `v1 > v2` +* `gte(v1, v2)`: `v1 >= v2` +* `lt(v1, v2)`: `v1 < v2` +* `lte(v1, v2)`: `v1 <= v2` +* `eq(v1, v2)`: `v1 == v2` This is true if they're logically equivalent, + even if they're not the same string. You already know how to + compare strings. +* `neq(v1, v2)`: `v1 != v2` The opposite of `eq`. +* `cmp(v1, comparator, v2)`: Pass in a comparison string, and it'll call + the corresponding function above. `"==="` and `"!=="` do simple + string comparison, but are included for completeness. Throws if an + invalid comparison string is provided. +* `compare(v1, v2)`: Return `0` if `v1 == v2`, or `1` if `v1` is greater, or `-1` if + `v2` is greater. Sorts in ascending order if passed to `Array.sort()`. +* `rcompare(v1, v2)`: The reverse of `compare`. Sorts an array of versions + in descending order when passed to `Array.sort()`. +* `compareBuild(v1, v2)`: The same as `compare` but considers `build` when two versions + are equal. Sorts in ascending order if passed to `Array.sort()`. +* `compareLoose(v1, v2)`: Short for `compare(v1, v2, { loose: true })`. +* `diff(v1, v2)`: Returns the difference between two versions by the release type + (`major`, `premajor`, `minor`, `preminor`, `patch`, `prepatch`, or `prerelease`), + or null if the versions are the same. + +### Sorting + +* `sort(versions)`: Returns a sorted array of versions based on the `compareBuild` + function. +* `rsort(versions)`: The reverse of `sort`. Returns an array of versions based on + the `compareBuild` function in descending order. + +### Comparators + +* `intersects(comparator)`: Return true if the comparators intersect + +### Ranges + +* `validRange(range)`: Return the valid range or null if it's not valid. +* `satisfies(version, range)`: Return true if the version satisfies the + range. +* `maxSatisfying(versions, range)`: Return the highest version in the list + that satisfies the range, or `null` if none of them do. +* `minSatisfying(versions, range)`: Return the lowest version in the list + that satisfies the range, or `null` if none of them do. +* `minVersion(range)`: Return the lowest version that can match + the given range. +* `gtr(version, range)`: Return `true` if the version is greater than all the + versions possible in the range. +* `ltr(version, range)`: Return `true` if the version is less than all the + versions possible in the range. +* `outside(version, range, hilo)`: Return true if the version is outside + the bounds of the range in either the high or low direction. The + `hilo` argument must be either the string `'>'` or `'<'`. (This is + the function called by `gtr` and `ltr`.) +* `intersects(range)`: Return true if any of the range comparators intersect. +* `simplifyRange(versions, range)`: Return a "simplified" range that + matches the same items in the `versions` list as the range specified. Note + that it does *not* guarantee that it would match the same versions in all + cases, only for the set of versions provided. This is useful when + generating ranges by joining together multiple versions with `||` + programmatically, to provide the user with something a bit more + ergonomic. If the provided range is shorter in string-length than the + generated range, then that is returned. +* `subset(subRange, superRange)`: Return `true` if the `subRange` range is + entirely contained by the `superRange` range. + +Note that, since ranges may be non-contiguous, a version might not be +greater than a range, less than a range, *or* satisfy a range! For +example, the range `1.2 <1.2.9 || >2.0.0` would have a hole from `1.2.9` +until `2.0.0`, so version `1.2.10` would not be greater than the +range (because `2.0.1` satisfies, which is higher), nor less than the +range (since `1.2.8` satisfies, which is lower), and it also does not +satisfy the range. + +If you want to know if a version satisfies or does not satisfy a +range, use the `satisfies(version, range)` function. + +### Coercion + +* `coerce(version, options)`: Coerces a string to semver if possible + +This aims to provide a very forgiving translation of a non-semver string to +semver. It looks for the first digit in a string and consumes all +remaining characters which satisfy at least a partial semver (e.g., `1`, +`1.2`, `1.2.3`) up to the max permitted length (256 characters). Longer +versions are simply truncated (`4.6.3.9.2-alpha2` becomes `4.6.3`). All +surrounding text is simply ignored (`v3.4 replaces v3.3.1` becomes +`3.4.0`). Only text which lacks digits will fail coercion (`version one` +is not valid). The maximum length for any semver component considered for +coercion is 16 characters; longer components will be ignored +(`10000000000000000.4.7.4` becomes `4.7.4`). The maximum value for any +semver component is `Number.MAX_SAFE_INTEGER || (2**53 - 1)`; higher value +components are invalid (`9999999999999999.4.7.4` is likely invalid). + +If the `options.rtl` flag is set, then `coerce` will return the right-most +coercible tuple that does not share an ending index with a longer coercible +tuple. For example, `1.2.3.4` will return `2.3.4` in rtl mode, not +`4.0.0`. `1.2.3/4` will return `4.0.0`, because the `4` is not a part of +any other overlapping SemVer tuple. + +If the `options.includePrerelease` flag is set, then the `coerce` result will contain +prerelease and build parts of a version. For example, `1.2.3.4-rc.1+rev.2` +will preserve prerelease `rc.1` and build `rev.2` in the result. + +### Clean + +* `clean(version)`: Clean a string to be a valid semver if possible + +This will return a cleaned and trimmed semver version. If the provided +version is not valid a null will be returned. This does not work for +ranges. + +ex. +* `s.clean(' = v 2.1.5foo')`: `null` +* `s.clean(' = v 2.1.5foo', { loose: true })`: `'2.1.5-foo'` +* `s.clean(' = v 2.1.5-foo')`: `null` +* `s.clean(' = v 2.1.5-foo', { loose: true })`: `'2.1.5-foo'` +* `s.clean('=v2.1.5')`: `'2.1.5'` +* `s.clean(' =v2.1.5')`: `'2.1.5'` +* `s.clean(' 2.1.5 ')`: `'2.1.5'` +* `s.clean('~1.0.0')`: `null` + +## Constants + +As a convenience, helper constants are exported to provide information about what `node-semver` supports: + +### `RELEASE_TYPES` + +- major +- premajor +- minor +- preminor +- patch +- prepatch +- prerelease + +``` +const semver = require('semver'); + +if (semver.RELEASE_TYPES.includes(arbitraryUserInput)) { + console.log('This is a valid release type!'); +} else { + console.warn('This is NOT a valid release type!'); +} +``` + +### `SEMVER_SPEC_VERSION` + +2.0.0 + +``` +const semver = require('semver'); + +console.log('We are currently using the semver specification version:', semver.SEMVER_SPEC_VERSION); +``` + +## Exported Modules + + + +You may pull in just the part of this semver utility that you need if you +are sensitive to packing and tree-shaking concerns. The main +`require('semver')` export uses getter functions to lazily load the parts +of the API that are used. + +The following modules are available: + +* `require('semver')` +* `require('semver/classes')` +* `require('semver/classes/comparator')` +* `require('semver/classes/range')` +* `require('semver/classes/semver')` +* `require('semver/functions/clean')` +* `require('semver/functions/cmp')` +* `require('semver/functions/coerce')` +* `require('semver/functions/compare')` +* `require('semver/functions/compare-build')` +* `require('semver/functions/compare-loose')` +* `require('semver/functions/diff')` +* `require('semver/functions/eq')` +* `require('semver/functions/gt')` +* `require('semver/functions/gte')` +* `require('semver/functions/inc')` +* `require('semver/functions/lt')` +* `require('semver/functions/lte')` +* `require('semver/functions/major')` +* `require('semver/functions/minor')` +* `require('semver/functions/neq')` +* `require('semver/functions/parse')` +* `require('semver/functions/patch')` +* `require('semver/functions/prerelease')` +* `require('semver/functions/rcompare')` +* `require('semver/functions/rsort')` +* `require('semver/functions/satisfies')` +* `require('semver/functions/sort')` +* `require('semver/functions/valid')` +* `require('semver/ranges/gtr')` +* `require('semver/ranges/intersects')` +* `require('semver/ranges/ltr')` +* `require('semver/ranges/max-satisfying')` +* `require('semver/ranges/min-satisfying')` +* `require('semver/ranges/min-version')` +* `require('semver/ranges/outside')` +* `require('semver/ranges/simplify')` +* `require('semver/ranges/subset')` +* `require('semver/ranges/to-comparators')` +* `require('semver/ranges/valid')` + diff --git a/node_modules/semver/bin/semver.js b/node_modules/semver/bin/semver.js new file mode 100755 index 0000000..d62bfc0 --- /dev/null +++ b/node_modules/semver/bin/semver.js @@ -0,0 +1,191 @@ +#!/usr/bin/env node +// Standalone semver comparison program. +// Exits successfully and prints matching version(s) if +// any supplied version is valid and passes all tests. + +'use strict' + +const argv = process.argv.slice(2) + +let versions = [] + +const range = [] + +let inc = null + +const version = require('../package.json').version + +let loose = false + +let includePrerelease = false + +let coerce = false + +let rtl = false + +let identifier + +let identifierBase + +const semver = require('../') +const parseOptions = require('../internal/parse-options') + +let reverse = false + +let options = {} + +const main = () => { + if (!argv.length) { + return help() + } + while (argv.length) { + let a = argv.shift() + const indexOfEqualSign = a.indexOf('=') + if (indexOfEqualSign !== -1) { + const value = a.slice(indexOfEqualSign + 1) + a = a.slice(0, indexOfEqualSign) + argv.unshift(value) + } + switch (a) { + case '-rv': case '-rev': case '--rev': case '--reverse': + reverse = true + break + case '-l': case '--loose': + loose = true + break + case '-p': case '--include-prerelease': + includePrerelease = true + break + case '-v': case '--version': + versions.push(argv.shift()) + break + case '-i': case '--inc': case '--increment': + switch (argv[0]) { + case 'major': case 'minor': case 'patch': case 'prerelease': + case 'premajor': case 'preminor': case 'prepatch': + case 'release': + inc = argv.shift() + break + default: + inc = 'patch' + break + } + break + case '--preid': + identifier = argv.shift() + break + case '-r': case '--range': + range.push(argv.shift()) + break + case '-n': + identifierBase = argv.shift() + if (identifierBase === 'false') { + identifierBase = false + } + break + case '-c': case '--coerce': + coerce = true + break + case '--rtl': + rtl = true + break + case '--ltr': + rtl = false + break + case '-h': case '--help': case '-?': + return help() + default: + versions.push(a) + break + } + } + + options = parseOptions({ loose, includePrerelease, rtl }) + + versions = versions.map((v) => { + return coerce ? (semver.coerce(v, options) || { version: v }).version : v + }).filter((v) => { + return semver.valid(v, options) + }) + if (!versions.length) { + return fail() + } + if (inc && (versions.length !== 1 || range.length)) { + return failInc() + } + + for (let i = 0, l = range.length; i < l; i++) { + versions = versions.filter((v) => { + return semver.satisfies(v, range[i], options) + }) + if (!versions.length) { + return fail() + } + } + versions + .sort((a, b) => semver[reverse ? 'rcompare' : 'compare'](a, b, options)) + .map(v => semver.clean(v, options)) + .map(v => inc ? semver.inc(v, inc, options, identifier, identifierBase) : v) + .forEach(v => console.log(v)) +} + +const failInc = () => { + console.error('--inc can only be used on a single version with no range') + fail() +} + +const fail = () => process.exit(1) + +const help = () => console.log( +`SemVer ${version} + +A JavaScript implementation of the https://semver.org/ specification +Copyright Isaac Z. Schlueter + +Usage: semver [options] [ [...]] +Prints valid versions sorted by SemVer precedence + +Options: +-r --range + Print versions that match the specified range. + +-i --increment [] + Increment a version by the specified level. Level can + be one of: major, minor, patch, premajor, preminor, + prepatch, prerelease, or release. Default level is 'patch'. + Only one version may be specified. + +--preid + Identifier to be used to prefix premajor, preminor, + prepatch or prerelease version increments. + +-l --loose + Interpret versions and ranges loosely + +-p --include-prerelease + Always include prerelease versions in range matching + +-c --coerce + Coerce a string into SemVer if possible + (does not imply --loose) + +--rtl + Coerce version strings right to left + +--ltr + Coerce version strings left to right (default) + +-n + Base number to be used for the prerelease identifier. + Can be either 0 or 1, or false to omit the number altogether. + Defaults to 0. + +Program exits successfully if any valid version satisfies +all supplied ranges, and prints all satisfying versions. + +If no satisfying versions are found, then exits failure. + +Versions are printed in ascending order, so supplying +multiple versions to the utility will just sort them.`) + +main() diff --git a/node_modules/semver/classes/comparator.js b/node_modules/semver/classes/comparator.js new file mode 100644 index 0000000..647c1f0 --- /dev/null +++ b/node_modules/semver/classes/comparator.js @@ -0,0 +1,143 @@ +'use strict' + +const ANY = Symbol('SemVer ANY') +// hoisted class for cyclic dependency +class Comparator { + static get ANY () { + return ANY + } + + constructor (comp, options) { + options = parseOptions(options) + + if (comp instanceof Comparator) { + if (comp.loose === !!options.loose) { + return comp + } else { + comp = comp.value + } + } + + comp = comp.trim().split(/\s+/).join(' ') + debug('comparator', comp, options) + this.options = options + this.loose = !!options.loose + this.parse(comp) + + if (this.semver === ANY) { + this.value = '' + } else { + this.value = this.operator + this.semver.version + } + + debug('comp', this) + } + + parse (comp) { + const r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] + const m = comp.match(r) + + if (!m) { + throw new TypeError(`Invalid comparator: ${comp}`) + } + + this.operator = m[1] !== undefined ? m[1] : '' + if (this.operator === '=') { + this.operator = '' + } + + // if it literally is just '>' or '' then allow anything. + if (!m[2]) { + this.semver = ANY + } else { + this.semver = new SemVer(m[2], this.options.loose) + } + } + + toString () { + return this.value + } + + test (version) { + debug('Comparator.test', version, this.options.loose) + + if (this.semver === ANY || version === ANY) { + return true + } + + if (typeof version === 'string') { + try { + version = new SemVer(version, this.options) + } catch (er) { + return false + } + } + + return cmp(version, this.operator, this.semver, this.options) + } + + intersects (comp, options) { + if (!(comp instanceof Comparator)) { + throw new TypeError('a Comparator is required') + } + + if (this.operator === '') { + if (this.value === '') { + return true + } + return new Range(comp.value, options).test(this.value) + } else if (comp.operator === '') { + if (comp.value === '') { + return true + } + return new Range(this.value, options).test(comp.semver) + } + + options = parseOptions(options) + + // Special cases where nothing can possibly be lower + if (options.includePrerelease && + (this.value === '<0.0.0-0' || comp.value === '<0.0.0-0')) { + return false + } + if (!options.includePrerelease && + (this.value.startsWith('<0.0.0') || comp.value.startsWith('<0.0.0'))) { + return false + } + + // Same direction increasing (> or >=) + if (this.operator.startsWith('>') && comp.operator.startsWith('>')) { + return true + } + // Same direction decreasing (< or <=) + if (this.operator.startsWith('<') && comp.operator.startsWith('<')) { + return true + } + // same SemVer and both sides are inclusive (<= or >=) + if ( + (this.semver.version === comp.semver.version) && + this.operator.includes('=') && comp.operator.includes('=')) { + return true + } + // opposite directions less than + if (cmp(this.semver, '<', comp.semver, options) && + this.operator.startsWith('>') && comp.operator.startsWith('<')) { + return true + } + // opposite directions greater than + if (cmp(this.semver, '>', comp.semver, options) && + this.operator.startsWith('<') && comp.operator.startsWith('>')) { + return true + } + return false + } +} + +module.exports = Comparator + +const parseOptions = require('../internal/parse-options') +const { safeRe: re, t } = require('../internal/re') +const cmp = require('../functions/cmp') +const debug = require('../internal/debug') +const SemVer = require('./semver') +const Range = require('./range') diff --git a/node_modules/semver/classes/index.js b/node_modules/semver/classes/index.js new file mode 100644 index 0000000..91c24ec --- /dev/null +++ b/node_modules/semver/classes/index.js @@ -0,0 +1,7 @@ +'use strict' + +module.exports = { + SemVer: require('./semver.js'), + Range: require('./range.js'), + Comparator: require('./comparator.js'), +} diff --git a/node_modules/semver/classes/range.js b/node_modules/semver/classes/range.js new file mode 100644 index 0000000..94629ce --- /dev/null +++ b/node_modules/semver/classes/range.js @@ -0,0 +1,557 @@ +'use strict' + +const SPACE_CHARACTERS = /\s+/g + +// hoisted class for cyclic dependency +class Range { + constructor (range, options) { + options = parseOptions(options) + + if (range instanceof Range) { + if ( + range.loose === !!options.loose && + range.includePrerelease === !!options.includePrerelease + ) { + return range + } else { + return new Range(range.raw, options) + } + } + + if (range instanceof Comparator) { + // just put it in the set and return + this.raw = range.value + this.set = [[range]] + this.formatted = undefined + return this + } + + this.options = options + this.loose = !!options.loose + this.includePrerelease = !!options.includePrerelease + + // First reduce all whitespace as much as possible so we do not have to rely + // on potentially slow regexes like \s*. This is then stored and used for + // future error messages as well. + this.raw = range.trim().replace(SPACE_CHARACTERS, ' ') + + // First, split on || + this.set = this.raw + .split('||') + // map the range to a 2d array of comparators + .map(r => this.parseRange(r.trim())) + // throw out any comparator lists that are empty + // this generally means that it was not a valid range, which is allowed + // in loose mode, but will still throw if the WHOLE range is invalid. + .filter(c => c.length) + + if (!this.set.length) { + throw new TypeError(`Invalid SemVer Range: ${this.raw}`) + } + + // if we have any that are not the null set, throw out null sets. + if (this.set.length > 1) { + // keep the first one, in case they're all null sets + const first = this.set[0] + this.set = this.set.filter(c => !isNullSet(c[0])) + if (this.set.length === 0) { + this.set = [first] + } else if (this.set.length > 1) { + // if we have any that are *, then the range is just * + for (const c of this.set) { + if (c.length === 1 && isAny(c[0])) { + this.set = [c] + break + } + } + } + } + + this.formatted = undefined + } + + get range () { + if (this.formatted === undefined) { + this.formatted = '' + for (let i = 0; i < this.set.length; i++) { + if (i > 0) { + this.formatted += '||' + } + const comps = this.set[i] + for (let k = 0; k < comps.length; k++) { + if (k > 0) { + this.formatted += ' ' + } + this.formatted += comps[k].toString().trim() + } + } + } + return this.formatted + } + + format () { + return this.range + } + + toString () { + return this.range + } + + parseRange (range) { + // memoize range parsing for performance. + // this is a very hot path, and fully deterministic. + const memoOpts = + (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | + (this.options.loose && FLAG_LOOSE) + const memoKey = memoOpts + ':' + range + const cached = cache.get(memoKey) + if (cached) { + return cached + } + + const loose = this.options.loose + // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE] + range = range.replace(hr, hyphenReplace(this.options.includePrerelease)) + debug('hyphen replace', range) + + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace) + debug('comparator trim', range) + + // `~ 1.2.3` => `~1.2.3` + range = range.replace(re[t.TILDETRIM], tildeTrimReplace) + debug('tilde trim', range) + + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[t.CARETTRIM], caretTrimReplace) + debug('caret trim', range) + + // At this point, the range is completely trimmed and + // ready to be split into comparators. + + let rangeList = range + .split(' ') + .map(comp => parseComparator(comp, this.options)) + .join(' ') + .split(/\s+/) + // >=0.0.0 is equivalent to * + .map(comp => replaceGTE0(comp, this.options)) + + if (loose) { + // in loose mode, throw out any that are not valid comparators + rangeList = rangeList.filter(comp => { + debug('loose invalid filter', comp, this.options) + return !!comp.match(re[t.COMPARATORLOOSE]) + }) + } + debug('range list', rangeList) + + // if any comparators are the null set, then replace with JUST null set + // if more than one comparator, remove any * comparators + // also, don't include the same comparator more than once + const rangeMap = new Map() + const comparators = rangeList.map(comp => new Comparator(comp, this.options)) + for (const comp of comparators) { + if (isNullSet(comp)) { + return [comp] + } + rangeMap.set(comp.value, comp) + } + if (rangeMap.size > 1 && rangeMap.has('')) { + rangeMap.delete('') + } + + const result = [...rangeMap.values()] + cache.set(memoKey, result) + return result + } + + intersects (range, options) { + if (!(range instanceof Range)) { + throw new TypeError('a Range is required') + } + + return this.set.some((thisComparators) => { + return ( + isSatisfiable(thisComparators, options) && + range.set.some((rangeComparators) => { + return ( + isSatisfiable(rangeComparators, options) && + thisComparators.every((thisComparator) => { + return rangeComparators.every((rangeComparator) => { + return thisComparator.intersects(rangeComparator, options) + }) + }) + ) + }) + ) + }) + } + + // if ANY of the sets match ALL of its comparators, then pass + test (version) { + if (!version) { + return false + } + + if (typeof version === 'string') { + try { + version = new SemVer(version, this.options) + } catch (er) { + return false + } + } + + for (let i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version, this.options)) { + return true + } + } + return false + } +} + +module.exports = Range + +const LRU = require('../internal/lrucache') +const cache = new LRU() + +const parseOptions = require('../internal/parse-options') +const Comparator = require('./comparator') +const debug = require('../internal/debug') +const SemVer = require('./semver') +const { + safeRe: re, + t, + comparatorTrimReplace, + tildeTrimReplace, + caretTrimReplace, +} = require('../internal/re') +const { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = require('../internal/constants') + +const isNullSet = c => c.value === '<0.0.0-0' +const isAny = c => c.value === '' + +// take a set of comparators and determine whether there +// exists a version which can satisfy it +const isSatisfiable = (comparators, options) => { + let result = true + const remainingComparators = comparators.slice() + let testComparator = remainingComparators.pop() + + while (result && remainingComparators.length) { + result = remainingComparators.every((otherComparator) => { + return testComparator.intersects(otherComparator, options) + }) + + testComparator = remainingComparators.pop() + } + + return result +} + +// comprised of xranges, tildes, stars, and gtlt's at this point. +// already replaced the hyphen ranges +// turn into a set of JUST comparators. +const parseComparator = (comp, options) => { + comp = comp.replace(re[t.BUILD], '') + debug('comp', comp, options) + comp = replaceCarets(comp, options) + debug('caret', comp) + comp = replaceTildes(comp, options) + debug('tildes', comp) + comp = replaceXRanges(comp, options) + debug('xrange', comp) + comp = replaceStars(comp, options) + debug('stars', comp) + return comp +} + +const isX = id => !id || id.toLowerCase() === 'x' || id === '*' + +// ~, ~> --> * (any, kinda silly) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0-0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0-0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0-0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0 +// ~0.0.1 --> >=0.0.1 <0.1.0-0 +const replaceTildes = (comp, options) => { + return comp + .trim() + .split(/\s+/) + .map((c) => replaceTilde(c, options)) + .join(' ') +} + +const replaceTilde = (comp, options) => { + const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE] + return comp.replace(r, (_, M, m, p, pr) => { + debug('tilde', comp, _, M, m, p, pr) + let ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = `>=${M}.0.0 <${+M + 1}.0.0-0` + } else if (isX(p)) { + // ~1.2 == >=1.2.0 <1.3.0-0 + ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0` + } else if (pr) { + debug('replaceTilde pr', pr) + ret = `>=${M}.${m}.${p}-${pr + } <${M}.${+m + 1}.0-0` + } else { + // ~1.2.3 == >=1.2.3 <1.3.0-0 + ret = `>=${M}.${m}.${p + } <${M}.${+m + 1}.0-0` + } + + debug('tilde return', ret) + return ret + }) +} + +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0-0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0-0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0-0 +// ^1.2.3 --> >=1.2.3 <2.0.0-0 +// ^1.2.0 --> >=1.2.0 <2.0.0-0 +// ^0.0.1 --> >=0.0.1 <0.0.2-0 +// ^0.1.0 --> >=0.1.0 <0.2.0-0 +const replaceCarets = (comp, options) => { + return comp + .trim() + .split(/\s+/) + .map((c) => replaceCaret(c, options)) + .join(' ') +} + +const replaceCaret = (comp, options) => { + debug('caret', comp, options) + const r = options.loose ? re[t.CARETLOOSE] : re[t.CARET] + const z = options.includePrerelease ? '-0' : '' + return comp.replace(r, (_, M, m, p, pr) => { + debug('caret', comp, _, M, m, p, pr) + let ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0` + } else if (isX(p)) { + if (M === '0') { + ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0` + } else { + ret = `>=${M}.${m}.0${z} <${+M + 1}.0.0-0` + } + } else if (pr) { + debug('replaceCaret pr', pr) + if (M === '0') { + if (m === '0') { + ret = `>=${M}.${m}.${p}-${pr + } <${M}.${m}.${+p + 1}-0` + } else { + ret = `>=${M}.${m}.${p}-${pr + } <${M}.${+m + 1}.0-0` + } + } else { + ret = `>=${M}.${m}.${p}-${pr + } <${+M + 1}.0.0-0` + } + } else { + debug('no pr') + if (M === '0') { + if (m === '0') { + ret = `>=${M}.${m}.${p + }${z} <${M}.${m}.${+p + 1}-0` + } else { + ret = `>=${M}.${m}.${p + }${z} <${M}.${+m + 1}.0-0` + } + } else { + ret = `>=${M}.${m}.${p + } <${+M + 1}.0.0-0` + } + } + + debug('caret return', ret) + return ret + }) +} + +const replaceXRanges = (comp, options) => { + debug('replaceXRanges', comp, options) + return comp + .split(/\s+/) + .map((c) => replaceXRange(c, options)) + .join(' ') +} + +const replaceXRange = (comp, options) => { + comp = comp.trim() + const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE] + return comp.replace(r, (ret, gtlt, M, m, p, pr) => { + debug('xRange', comp, ret, gtlt, M, m, p, pr) + const xM = isX(M) + const xm = xM || isX(m) + const xp = xm || isX(p) + const anyX = xp + + if (gtlt === '=' && anyX) { + gtlt = '' + } + + // if we're including prereleases in the match, then we need + // to fix this to -0, the lowest possible prerelease value + pr = options.includePrerelease ? '-0' : '' + + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0-0' + } else { + // nothing is forbidden + ret = '*' + } + } else if (gtlt && anyX) { + // we know patch is an x, because we have any x at all. + // replace X with 0 + if (xm) { + m = 0 + } + p = 0 + + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + gtlt = '>=' + if (xm) { + M = +M + 1 + m = 0 + p = 0 + } else { + m = +m + 1 + p = 0 + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<' + if (xm) { + M = +M + 1 + } else { + m = +m + 1 + } + } + + if (gtlt === '<') { + pr = '-0' + } + + ret = `${gtlt + M}.${m}.${p}${pr}` + } else if (xm) { + ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0` + } else if (xp) { + ret = `>=${M}.${m}.0${pr + } <${M}.${+m + 1}.0-0` + } + + debug('xRange return', ret) + + return ret + }) +} + +// Because * is AND-ed with everything else in the comparator, +// and '' means "any version", just remove the *s entirely. +const replaceStars = (comp, options) => { + debug('replaceStars', comp, options) + // Looseness is ignored here. star is always as loose as it gets! + return comp + .trim() + .replace(re[t.STAR], '') +} + +const replaceGTE0 = (comp, options) => { + debug('replaceGTE0', comp, options) + return comp + .trim() + .replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], '') +} + +// This function is passed to string.replace(re[t.HYPHENRANGE]) +// M, m, patch, prerelease, build +// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +// 1.2.3 - 3.4 => >=1.2.0 <3.5.0-0 Any 3.4.x will do +// 1.2 - 3.4 => >=1.2.0 <3.5.0-0 +// TODO build? +const hyphenReplace = incPr => ($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr) => { + if (isX(fM)) { + from = '' + } else if (isX(fm)) { + from = `>=${fM}.0.0${incPr ? '-0' : ''}` + } else if (isX(fp)) { + from = `>=${fM}.${fm}.0${incPr ? '-0' : ''}` + } else if (fpr) { + from = `>=${from}` + } else { + from = `>=${from}${incPr ? '-0' : ''}` + } + + if (isX(tM)) { + to = '' + } else if (isX(tm)) { + to = `<${+tM + 1}.0.0-0` + } else if (isX(tp)) { + to = `<${tM}.${+tm + 1}.0-0` + } else if (tpr) { + to = `<=${tM}.${tm}.${tp}-${tpr}` + } else if (incPr) { + to = `<${tM}.${tm}.${+tp + 1}-0` + } else { + to = `<=${to}` + } + + return `${from} ${to}`.trim() +} + +const testSet = (set, version, options) => { + for (let i = 0; i < set.length; i++) { + if (!set[i].test(version)) { + return false + } + } + + if (version.prerelease.length && !options.includePrerelease) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (let i = 0; i < set.length; i++) { + debug(set[i].semver) + if (set[i].semver === Comparator.ANY) { + continue + } + + if (set[i].semver.prerelease.length > 0) { + const allowed = set[i].semver + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) { + return true + } + } + } + + // Version has a -pre, but it's not one of the ones we like. + return false + } + + return true +} diff --git a/node_modules/semver/classes/semver.js b/node_modules/semver/classes/semver.js new file mode 100644 index 0000000..92254be --- /dev/null +++ b/node_modules/semver/classes/semver.js @@ -0,0 +1,333 @@ +'use strict' + +const debug = require('../internal/debug') +const { MAX_LENGTH, MAX_SAFE_INTEGER } = require('../internal/constants') +const { safeRe: re, t } = require('../internal/re') + +const parseOptions = require('../internal/parse-options') +const { compareIdentifiers } = require('../internal/identifiers') +class SemVer { + constructor (version, options) { + options = parseOptions(options) + + if (version instanceof SemVer) { + if (version.loose === !!options.loose && + version.includePrerelease === !!options.includePrerelease) { + return version + } else { + version = version.version + } + } else if (typeof version !== 'string') { + throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`) + } + + if (version.length > MAX_LENGTH) { + throw new TypeError( + `version is longer than ${MAX_LENGTH} characters` + ) + } + + debug('SemVer', version, options) + this.options = options + this.loose = !!options.loose + // this isn't actually relevant for versions, but keep it so that we + // don't run into trouble passing this.options around. + this.includePrerelease = !!options.includePrerelease + + const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]) + + if (!m) { + throw new TypeError(`Invalid Version: ${version}`) + } + + this.raw = version + + // these are actually numbers + this.major = +m[1] + this.minor = +m[2] + this.patch = +m[3] + + if (this.major > MAX_SAFE_INTEGER || this.major < 0) { + throw new TypeError('Invalid major version') + } + + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { + throw new TypeError('Invalid minor version') + } + + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { + throw new TypeError('Invalid patch version') + } + + // numberify any prerelease numeric ids + if (!m[4]) { + this.prerelease = [] + } else { + this.prerelease = m[4].split('.').map((id) => { + if (/^[0-9]+$/.test(id)) { + const num = +id + if (num >= 0 && num < MAX_SAFE_INTEGER) { + return num + } + } + return id + }) + } + + this.build = m[5] ? m[5].split('.') : [] + this.format() + } + + format () { + this.version = `${this.major}.${this.minor}.${this.patch}` + if (this.prerelease.length) { + this.version += `-${this.prerelease.join('.')}` + } + return this.version + } + + toString () { + return this.version + } + + compare (other) { + debug('SemVer.compare', this.version, this.options, other) + if (!(other instanceof SemVer)) { + if (typeof other === 'string' && other === this.version) { + return 0 + } + other = new SemVer(other, this.options) + } + + if (other.version === this.version) { + return 0 + } + + return this.compareMain(other) || this.comparePre(other) + } + + compareMain (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + if (this.major < other.major) { + return -1 + } + if (this.major > other.major) { + return 1 + } + if (this.minor < other.minor) { + return -1 + } + if (this.minor > other.minor) { + return 1 + } + if (this.patch < other.patch) { + return -1 + } + if (this.patch > other.patch) { + return 1 + } + return 0 + } + + comparePre (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + // NOT having a prerelease is > having one + if (this.prerelease.length && !other.prerelease.length) { + return -1 + } else if (!this.prerelease.length && other.prerelease.length) { + return 1 + } else if (!this.prerelease.length && !other.prerelease.length) { + return 0 + } + + let i = 0 + do { + const a = this.prerelease[i] + const b = other.prerelease[i] + debug('prerelease compare', i, a, b) + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) + } + + compareBuild (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + let i = 0 + do { + const a = this.build[i] + const b = other.build[i] + debug('build compare', i, a, b) + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) + } + + // preminor will bump the version up to the next minor release, and immediately + // down to pre-release. premajor and prepatch work the same way. + inc (release, identifier, identifierBase) { + if (release.startsWith('pre')) { + if (!identifier && identifierBase === false) { + throw new Error('invalid increment argument: identifier is empty') + } + // Avoid an invalid semver results + if (identifier) { + const match = `-${identifier}`.match(this.options.loose ? re[t.PRERELEASELOOSE] : re[t.PRERELEASE]) + if (!match || match[1] !== identifier) { + throw new Error(`invalid identifier: ${identifier}`) + } + } + } + + switch (release) { + case 'premajor': + this.prerelease.length = 0 + this.patch = 0 + this.minor = 0 + this.major++ + this.inc('pre', identifier, identifierBase) + break + case 'preminor': + this.prerelease.length = 0 + this.patch = 0 + this.minor++ + this.inc('pre', identifier, identifierBase) + break + case 'prepatch': + // If this is already a prerelease, it will bump to the next version + // drop any prereleases that might already exist, since they are not + // relevant at this point. + this.prerelease.length = 0 + this.inc('patch', identifier, identifierBase) + this.inc('pre', identifier, identifierBase) + break + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case 'prerelease': + if (this.prerelease.length === 0) { + this.inc('patch', identifier, identifierBase) + } + this.inc('pre', identifier, identifierBase) + break + case 'release': + if (this.prerelease.length === 0) { + throw new Error(`version ${this.raw} is not a prerelease`) + } + this.prerelease.length = 0 + break + + case 'major': + // If this is a pre-major version, bump up to the same major version. + // Otherwise increment major. + // 1.0.0-5 bumps to 1.0.0 + // 1.1.0 bumps to 2.0.0 + if ( + this.minor !== 0 || + this.patch !== 0 || + this.prerelease.length === 0 + ) { + this.major++ + } + this.minor = 0 + this.patch = 0 + this.prerelease = [] + break + case 'minor': + // If this is a pre-minor version, bump up to the same minor version. + // Otherwise increment minor. + // 1.2.0-5 bumps to 1.2.0 + // 1.2.1 bumps to 1.3.0 + if (this.patch !== 0 || this.prerelease.length === 0) { + this.minor++ + } + this.patch = 0 + this.prerelease = [] + break + case 'patch': + // If this is not a pre-release version, it will increment the patch. + // If it is a pre-release it will bump up to the same patch version. + // 1.2.0-5 patches to 1.2.0 + // 1.2.0 patches to 1.2.1 + if (this.prerelease.length === 0) { + this.patch++ + } + this.prerelease = [] + break + // This probably shouldn't be used publicly. + // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction. + case 'pre': { + const base = Number(identifierBase) ? 1 : 0 + + if (this.prerelease.length === 0) { + this.prerelease = [base] + } else { + let i = this.prerelease.length + while (--i >= 0) { + if (typeof this.prerelease[i] === 'number') { + this.prerelease[i]++ + i = -2 + } + } + if (i === -1) { + // didn't increment anything + if (identifier === this.prerelease.join('.') && identifierBase === false) { + throw new Error('invalid increment argument: identifier already exists') + } + this.prerelease.push(base) + } + } + if (identifier) { + // 1.2.0-beta.1 bumps to 1.2.0-beta.2, + // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + let prerelease = [identifier, base] + if (identifierBase === false) { + prerelease = [identifier] + } + if (compareIdentifiers(this.prerelease[0], identifier) === 0) { + if (isNaN(this.prerelease[1])) { + this.prerelease = prerelease + } + } else { + this.prerelease = prerelease + } + } + break + } + default: + throw new Error(`invalid increment argument: ${release}`) + } + this.raw = this.format() + if (this.build.length) { + this.raw += `+${this.build.join('.')}` + } + return this + } +} + +module.exports = SemVer diff --git a/node_modules/semver/functions/clean.js b/node_modules/semver/functions/clean.js new file mode 100644 index 0000000..79703d6 --- /dev/null +++ b/node_modules/semver/functions/clean.js @@ -0,0 +1,8 @@ +'use strict' + +const parse = require('./parse') +const clean = (version, options) => { + const s = parse(version.trim().replace(/^[=v]+/, ''), options) + return s ? s.version : null +} +module.exports = clean diff --git a/node_modules/semver/functions/cmp.js b/node_modules/semver/functions/cmp.js new file mode 100644 index 0000000..77487dc --- /dev/null +++ b/node_modules/semver/functions/cmp.js @@ -0,0 +1,54 @@ +'use strict' + +const eq = require('./eq') +const neq = require('./neq') +const gt = require('./gt') +const gte = require('./gte') +const lt = require('./lt') +const lte = require('./lte') + +const cmp = (a, op, b, loose) => { + switch (op) { + case '===': + if (typeof a === 'object') { + a = a.version + } + if (typeof b === 'object') { + b = b.version + } + return a === b + + case '!==': + if (typeof a === 'object') { + a = a.version + } + if (typeof b === 'object') { + b = b.version + } + return a !== b + + case '': + case '=': + case '==': + return eq(a, b, loose) + + case '!=': + return neq(a, b, loose) + + case '>': + return gt(a, b, loose) + + case '>=': + return gte(a, b, loose) + + case '<': + return lt(a, b, loose) + + case '<=': + return lte(a, b, loose) + + default: + throw new TypeError(`Invalid operator: ${op}`) + } +} +module.exports = cmp diff --git a/node_modules/semver/functions/coerce.js b/node_modules/semver/functions/coerce.js new file mode 100644 index 0000000..cfe0275 --- /dev/null +++ b/node_modules/semver/functions/coerce.js @@ -0,0 +1,62 @@ +'use strict' + +const SemVer = require('../classes/semver') +const parse = require('./parse') +const { safeRe: re, t } = require('../internal/re') + +const coerce = (version, options) => { + if (version instanceof SemVer) { + return version + } + + if (typeof version === 'number') { + version = String(version) + } + + if (typeof version !== 'string') { + return null + } + + options = options || {} + + let match = null + if (!options.rtl) { + match = version.match(options.includePrerelease ? re[t.COERCEFULL] : re[t.COERCE]) + } else { + // Find the right-most coercible string that does not share + // a terminus with a more left-ward coercible string. + // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' + // With includePrerelease option set, '1.2.3.4-rc' wants to coerce '2.3.4-rc', not '2.3.4' + // + // Walk through the string checking with a /g regexp + // Manually set the index so as to pick up overlapping matches. + // Stop when we get a match that ends at the string end, since no + // coercible string can be more right-ward without the same terminus. + const coerceRtlRegex = options.includePrerelease ? re[t.COERCERTLFULL] : re[t.COERCERTL] + let next + while ((next = coerceRtlRegex.exec(version)) && + (!match || match.index + match[0].length !== version.length) + ) { + if (!match || + next.index + next[0].length !== match.index + match[0].length) { + match = next + } + coerceRtlRegex.lastIndex = next.index + next[1].length + next[2].length + } + // leave it in a clean state + coerceRtlRegex.lastIndex = -1 + } + + if (match === null) { + return null + } + + const major = match[2] + const minor = match[3] || '0' + const patch = match[4] || '0' + const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : '' + const build = options.includePrerelease && match[6] ? `+${match[6]}` : '' + + return parse(`${major}.${minor}.${patch}${prerelease}${build}`, options) +} +module.exports = coerce diff --git a/node_modules/semver/functions/compare-build.js b/node_modules/semver/functions/compare-build.js new file mode 100644 index 0000000..99157cf --- /dev/null +++ b/node_modules/semver/functions/compare-build.js @@ -0,0 +1,9 @@ +'use strict' + +const SemVer = require('../classes/semver') +const compareBuild = (a, b, loose) => { + const versionA = new SemVer(a, loose) + const versionB = new SemVer(b, loose) + return versionA.compare(versionB) || versionA.compareBuild(versionB) +} +module.exports = compareBuild diff --git a/node_modules/semver/functions/compare-loose.js b/node_modules/semver/functions/compare-loose.js new file mode 100644 index 0000000..7531634 --- /dev/null +++ b/node_modules/semver/functions/compare-loose.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const compareLoose = (a, b) => compare(a, b, true) +module.exports = compareLoose diff --git a/node_modules/semver/functions/compare.js b/node_modules/semver/functions/compare.js new file mode 100644 index 0000000..63d8090 --- /dev/null +++ b/node_modules/semver/functions/compare.js @@ -0,0 +1,7 @@ +'use strict' + +const SemVer = require('../classes/semver') +const compare = (a, b, loose) => + new SemVer(a, loose).compare(new SemVer(b, loose)) + +module.exports = compare diff --git a/node_modules/semver/functions/diff.js b/node_modules/semver/functions/diff.js new file mode 100644 index 0000000..c99ab51 --- /dev/null +++ b/node_modules/semver/functions/diff.js @@ -0,0 +1,60 @@ +'use strict' + +const parse = require('./parse.js') + +const diff = (version1, version2) => { + const v1 = parse(version1, null, true) + const v2 = parse(version2, null, true) + const comparison = v1.compare(v2) + + if (comparison === 0) { + return null + } + + const v1Higher = comparison > 0 + const highVersion = v1Higher ? v1 : v2 + const lowVersion = v1Higher ? v2 : v1 + const highHasPre = !!highVersion.prerelease.length + const lowHasPre = !!lowVersion.prerelease.length + + if (lowHasPre && !highHasPre) { + // Going from prerelease -> no prerelease requires some special casing + + // If the low version has only a major, then it will always be a major + // Some examples: + // 1.0.0-1 -> 1.0.0 + // 1.0.0-1 -> 1.1.1 + // 1.0.0-1 -> 2.0.0 + if (!lowVersion.patch && !lowVersion.minor) { + return 'major' + } + + // If the main part has no difference + if (lowVersion.compareMain(highVersion) === 0) { + if (lowVersion.minor && !lowVersion.patch) { + return 'minor' + } + return 'patch' + } + } + + // add the `pre` prefix if we are going to a prerelease version + const prefix = highHasPre ? 'pre' : '' + + if (v1.major !== v2.major) { + return prefix + 'major' + } + + if (v1.minor !== v2.minor) { + return prefix + 'minor' + } + + if (v1.patch !== v2.patch) { + return prefix + 'patch' + } + + // high and low are prereleases + return 'prerelease' +} + +module.exports = diff diff --git a/node_modules/semver/functions/eq.js b/node_modules/semver/functions/eq.js new file mode 100644 index 0000000..5f0eead --- /dev/null +++ b/node_modules/semver/functions/eq.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const eq = (a, b, loose) => compare(a, b, loose) === 0 +module.exports = eq diff --git a/node_modules/semver/functions/gt.js b/node_modules/semver/functions/gt.js new file mode 100644 index 0000000..84a57dd --- /dev/null +++ b/node_modules/semver/functions/gt.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const gt = (a, b, loose) => compare(a, b, loose) > 0 +module.exports = gt diff --git a/node_modules/semver/functions/gte.js b/node_modules/semver/functions/gte.js new file mode 100644 index 0000000..7c52bdf --- /dev/null +++ b/node_modules/semver/functions/gte.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const gte = (a, b, loose) => compare(a, b, loose) >= 0 +module.exports = gte diff --git a/node_modules/semver/functions/inc.js b/node_modules/semver/functions/inc.js new file mode 100644 index 0000000..ff999e9 --- /dev/null +++ b/node_modules/semver/functions/inc.js @@ -0,0 +1,21 @@ +'use strict' + +const SemVer = require('../classes/semver') + +const inc = (version, release, options, identifier, identifierBase) => { + if (typeof (options) === 'string') { + identifierBase = identifier + identifier = options + options = undefined + } + + try { + return new SemVer( + version instanceof SemVer ? version.version : version, + options + ).inc(release, identifier, identifierBase).version + } catch (er) { + return null + } +} +module.exports = inc diff --git a/node_modules/semver/functions/lt.js b/node_modules/semver/functions/lt.js new file mode 100644 index 0000000..2fb32a0 --- /dev/null +++ b/node_modules/semver/functions/lt.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const lt = (a, b, loose) => compare(a, b, loose) < 0 +module.exports = lt diff --git a/node_modules/semver/functions/lte.js b/node_modules/semver/functions/lte.js new file mode 100644 index 0000000..da9ee8f --- /dev/null +++ b/node_modules/semver/functions/lte.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const lte = (a, b, loose) => compare(a, b, loose) <= 0 +module.exports = lte diff --git a/node_modules/semver/functions/major.js b/node_modules/semver/functions/major.js new file mode 100644 index 0000000..e6d08dc --- /dev/null +++ b/node_modules/semver/functions/major.js @@ -0,0 +1,5 @@ +'use strict' + +const SemVer = require('../classes/semver') +const major = (a, loose) => new SemVer(a, loose).major +module.exports = major diff --git a/node_modules/semver/functions/minor.js b/node_modules/semver/functions/minor.js new file mode 100644 index 0000000..9e70ffd --- /dev/null +++ b/node_modules/semver/functions/minor.js @@ -0,0 +1,5 @@ +'use strict' + +const SemVer = require('../classes/semver') +const minor = (a, loose) => new SemVer(a, loose).minor +module.exports = minor diff --git a/node_modules/semver/functions/neq.js b/node_modules/semver/functions/neq.js new file mode 100644 index 0000000..84326b7 --- /dev/null +++ b/node_modules/semver/functions/neq.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const neq = (a, b, loose) => compare(a, b, loose) !== 0 +module.exports = neq diff --git a/node_modules/semver/functions/parse.js b/node_modules/semver/functions/parse.js new file mode 100644 index 0000000..d544d33 --- /dev/null +++ b/node_modules/semver/functions/parse.js @@ -0,0 +1,18 @@ +'use strict' + +const SemVer = require('../classes/semver') +const parse = (version, options, throwErrors = false) => { + if (version instanceof SemVer) { + return version + } + try { + return new SemVer(version, options) + } catch (er) { + if (!throwErrors) { + return null + } + throw er + } +} + +module.exports = parse diff --git a/node_modules/semver/functions/patch.js b/node_modules/semver/functions/patch.js new file mode 100644 index 0000000..7675162 --- /dev/null +++ b/node_modules/semver/functions/patch.js @@ -0,0 +1,5 @@ +'use strict' + +const SemVer = require('../classes/semver') +const patch = (a, loose) => new SemVer(a, loose).patch +module.exports = patch diff --git a/node_modules/semver/functions/prerelease.js b/node_modules/semver/functions/prerelease.js new file mode 100644 index 0000000..b8fe1db --- /dev/null +++ b/node_modules/semver/functions/prerelease.js @@ -0,0 +1,8 @@ +'use strict' + +const parse = require('./parse') +const prerelease = (version, options) => { + const parsed = parse(version, options) + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null +} +module.exports = prerelease diff --git a/node_modules/semver/functions/rcompare.js b/node_modules/semver/functions/rcompare.js new file mode 100644 index 0000000..8e1c222 --- /dev/null +++ b/node_modules/semver/functions/rcompare.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const rcompare = (a, b, loose) => compare(b, a, loose) +module.exports = rcompare diff --git a/node_modules/semver/functions/rsort.js b/node_modules/semver/functions/rsort.js new file mode 100644 index 0000000..5d3d200 --- /dev/null +++ b/node_modules/semver/functions/rsort.js @@ -0,0 +1,5 @@ +'use strict' + +const compareBuild = require('./compare-build') +const rsort = (list, loose) => list.sort((a, b) => compareBuild(b, a, loose)) +module.exports = rsort diff --git a/node_modules/semver/functions/satisfies.js b/node_modules/semver/functions/satisfies.js new file mode 100644 index 0000000..a0264a2 --- /dev/null +++ b/node_modules/semver/functions/satisfies.js @@ -0,0 +1,12 @@ +'use strict' + +const Range = require('../classes/range') +const satisfies = (version, range, options) => { + try { + range = new Range(range, options) + } catch (er) { + return false + } + return range.test(version) +} +module.exports = satisfies diff --git a/node_modules/semver/functions/sort.js b/node_modules/semver/functions/sort.js new file mode 100644 index 0000000..edb24b1 --- /dev/null +++ b/node_modules/semver/functions/sort.js @@ -0,0 +1,5 @@ +'use strict' + +const compareBuild = require('./compare-build') +const sort = (list, loose) => list.sort((a, b) => compareBuild(a, b, loose)) +module.exports = sort diff --git a/node_modules/semver/functions/valid.js b/node_modules/semver/functions/valid.js new file mode 100644 index 0000000..0db67ed --- /dev/null +++ b/node_modules/semver/functions/valid.js @@ -0,0 +1,8 @@ +'use strict' + +const parse = require('./parse') +const valid = (version, options) => { + const v = parse(version, options) + return v ? v.version : null +} +module.exports = valid diff --git a/node_modules/semver/index.js b/node_modules/semver/index.js new file mode 100644 index 0000000..285662a --- /dev/null +++ b/node_modules/semver/index.js @@ -0,0 +1,91 @@ +'use strict' + +// just pre-load all the stuff that index.js lazily exports +const internalRe = require('./internal/re') +const constants = require('./internal/constants') +const SemVer = require('./classes/semver') +const identifiers = require('./internal/identifiers') +const parse = require('./functions/parse') +const valid = require('./functions/valid') +const clean = require('./functions/clean') +const inc = require('./functions/inc') +const diff = require('./functions/diff') +const major = require('./functions/major') +const minor = require('./functions/minor') +const patch = require('./functions/patch') +const prerelease = require('./functions/prerelease') +const compare = require('./functions/compare') +const rcompare = require('./functions/rcompare') +const compareLoose = require('./functions/compare-loose') +const compareBuild = require('./functions/compare-build') +const sort = require('./functions/sort') +const rsort = require('./functions/rsort') +const gt = require('./functions/gt') +const lt = require('./functions/lt') +const eq = require('./functions/eq') +const neq = require('./functions/neq') +const gte = require('./functions/gte') +const lte = require('./functions/lte') +const cmp = require('./functions/cmp') +const coerce = require('./functions/coerce') +const Comparator = require('./classes/comparator') +const Range = require('./classes/range') +const satisfies = require('./functions/satisfies') +const toComparators = require('./ranges/to-comparators') +const maxSatisfying = require('./ranges/max-satisfying') +const minSatisfying = require('./ranges/min-satisfying') +const minVersion = require('./ranges/min-version') +const validRange = require('./ranges/valid') +const outside = require('./ranges/outside') +const gtr = require('./ranges/gtr') +const ltr = require('./ranges/ltr') +const intersects = require('./ranges/intersects') +const simplifyRange = require('./ranges/simplify') +const subset = require('./ranges/subset') +module.exports = { + parse, + valid, + clean, + inc, + diff, + major, + minor, + patch, + prerelease, + compare, + rcompare, + compareLoose, + compareBuild, + sort, + rsort, + gt, + lt, + eq, + neq, + gte, + lte, + cmp, + coerce, + Comparator, + Range, + satisfies, + toComparators, + maxSatisfying, + minSatisfying, + minVersion, + validRange, + outside, + gtr, + ltr, + intersects, + simplifyRange, + subset, + SemVer, + re: internalRe.re, + src: internalRe.src, + tokens: internalRe.t, + SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION, + RELEASE_TYPES: constants.RELEASE_TYPES, + compareIdentifiers: identifiers.compareIdentifiers, + rcompareIdentifiers: identifiers.rcompareIdentifiers, +} diff --git a/node_modules/semver/internal/constants.js b/node_modules/semver/internal/constants.js new file mode 100644 index 0000000..6d1db91 --- /dev/null +++ b/node_modules/semver/internal/constants.js @@ -0,0 +1,37 @@ +'use strict' + +// Note: this is the semver.org version of the spec that it implements +// Not necessarily the package version of this code. +const SEMVER_SPEC_VERSION = '2.0.0' + +const MAX_LENGTH = 256 +const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || +/* istanbul ignore next */ 9007199254740991 + +// Max safe segment length for coercion. +const MAX_SAFE_COMPONENT_LENGTH = 16 + +// Max safe length for a build identifier. The max length minus 6 characters for +// the shortest version with a build 0.0.0+BUILD. +const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6 + +const RELEASE_TYPES = [ + 'major', + 'premajor', + 'minor', + 'preminor', + 'patch', + 'prepatch', + 'prerelease', +] + +module.exports = { + MAX_LENGTH, + MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_SAFE_INTEGER, + RELEASE_TYPES, + SEMVER_SPEC_VERSION, + FLAG_INCLUDE_PRERELEASE: 0b001, + FLAG_LOOSE: 0b010, +} diff --git a/node_modules/semver/internal/debug.js b/node_modules/semver/internal/debug.js new file mode 100644 index 0000000..20d1e9d --- /dev/null +++ b/node_modules/semver/internal/debug.js @@ -0,0 +1,11 @@ +'use strict' + +const debug = ( + typeof process === 'object' && + process.env && + process.env.NODE_DEBUG && + /\bsemver\b/i.test(process.env.NODE_DEBUG) +) ? (...args) => console.error('SEMVER', ...args) + : () => {} + +module.exports = debug diff --git a/node_modules/semver/internal/identifiers.js b/node_modules/semver/internal/identifiers.js new file mode 100644 index 0000000..d053472 --- /dev/null +++ b/node_modules/semver/internal/identifiers.js @@ -0,0 +1,29 @@ +'use strict' + +const numeric = /^[0-9]+$/ +const compareIdentifiers = (a, b) => { + if (typeof a === 'number' && typeof b === 'number') { + return a === b ? 0 : a < b ? -1 : 1 + } + + const anum = numeric.test(a) + const bnum = numeric.test(b) + + if (anum && bnum) { + a = +a + b = +b + } + + return a === b ? 0 + : (anum && !bnum) ? -1 + : (bnum && !anum) ? 1 + : a < b ? -1 + : 1 +} + +const rcompareIdentifiers = (a, b) => compareIdentifiers(b, a) + +module.exports = { + compareIdentifiers, + rcompareIdentifiers, +} diff --git a/node_modules/semver/internal/lrucache.js b/node_modules/semver/internal/lrucache.js new file mode 100644 index 0000000..b8bf526 --- /dev/null +++ b/node_modules/semver/internal/lrucache.js @@ -0,0 +1,42 @@ +'use strict' + +class LRUCache { + constructor () { + this.max = 1000 + this.map = new Map() + } + + get (key) { + const value = this.map.get(key) + if (value === undefined) { + return undefined + } else { + // Remove the key from the map and add it to the end + this.map.delete(key) + this.map.set(key, value) + return value + } + } + + delete (key) { + return this.map.delete(key) + } + + set (key, value) { + const deleted = this.delete(key) + + if (!deleted && value !== undefined) { + // If cache is full, delete the least recently used item + if (this.map.size >= this.max) { + const firstKey = this.map.keys().next().value + this.delete(firstKey) + } + + this.map.set(key, value) + } + + return this + } +} + +module.exports = LRUCache diff --git a/node_modules/semver/internal/parse-options.js b/node_modules/semver/internal/parse-options.js new file mode 100644 index 0000000..5295454 --- /dev/null +++ b/node_modules/semver/internal/parse-options.js @@ -0,0 +1,17 @@ +'use strict' + +// parse out just the options we care about +const looseOption = Object.freeze({ loose: true }) +const emptyOpts = Object.freeze({ }) +const parseOptions = options => { + if (!options) { + return emptyOpts + } + + if (typeof options !== 'object') { + return looseOption + } + + return options +} +module.exports = parseOptions diff --git a/node_modules/semver/internal/re.js b/node_modules/semver/internal/re.js new file mode 100644 index 0000000..639fca8 --- /dev/null +++ b/node_modules/semver/internal/re.js @@ -0,0 +1,223 @@ +'use strict' + +const { + MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_LENGTH, +} = require('./constants') +const debug = require('./debug') +exports = module.exports = {} + +// The actual regexps go on exports.re +const re = exports.re = [] +const safeRe = exports.safeRe = [] +const src = exports.src = [] +const safeSrc = exports.safeSrc = [] +const t = exports.t = {} +let R = 0 + +const LETTERDASHNUMBER = '[a-zA-Z0-9-]' + +// Replace some greedy regex tokens to prevent regex dos issues. These regex are +// used internally via the safeRe object since all inputs in this library get +// normalized first to trim and collapse all extra whitespace. The original +// regexes are exported for userland consumption and lower level usage. A +// future breaking change could export the safer regex only with a note that +// all input should have extra whitespace removed. +const safeRegexReplacements = [ + ['\\s', 1], + ['\\d', MAX_LENGTH], + [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH], +] + +const makeSafeRegex = (value) => { + for (const [token, max] of safeRegexReplacements) { + value = value + .split(`${token}*`).join(`${token}{0,${max}}`) + .split(`${token}+`).join(`${token}{1,${max}}`) + } + return value +} + +const createToken = (name, value, isGlobal) => { + const safe = makeSafeRegex(value) + const index = R++ + debug(name, index, value) + t[name] = index + src[index] = value + safeSrc[index] = safe + re[index] = new RegExp(value, isGlobal ? 'g' : undefined) + safeRe[index] = new RegExp(safe, isGlobal ? 'g' : undefined) +} + +// The following Regular Expressions can be used for tokenizing, +// validating, and parsing SemVer version strings. + +// ## Numeric Identifier +// A single `0`, or a non-zero digit followed by zero or more digits. + +createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*') +createToken('NUMERICIDENTIFIERLOOSE', '\\d+') + +// ## Non-numeric Identifier +// Zero or more digits, followed by a letter or hyphen, and then zero or +// more letters, digits, or hyphens. + +createToken('NONNUMERICIDENTIFIER', `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`) + +// ## Main Version +// Three dot-separated numeric identifiers. + +createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` + + `(${src[t.NUMERICIDENTIFIER]})\\.` + + `(${src[t.NUMERICIDENTIFIER]})`) + +createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + + `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + + `(${src[t.NUMERICIDENTIFIERLOOSE]})`) + +// ## Pre-release Version Identifier +// A numeric identifier, or a non-numeric identifier. +// Non-numeric identifiers include numeric identifiers but can be longer. +// Therefore non-numeric identifiers must go first. + +createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NONNUMERICIDENTIFIER] +}|${src[t.NUMERICIDENTIFIER]})`) + +createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NONNUMERICIDENTIFIER] +}|${src[t.NUMERICIDENTIFIERLOOSE]})`) + +// ## Pre-release Version +// Hyphen, followed by one or more dot-separated pre-release version +// identifiers. + +createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER] +}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`) + +createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE] +}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`) + +// ## Build Metadata Identifier +// Any combination of digits, letters, or hyphens. + +createToken('BUILDIDENTIFIER', `${LETTERDASHNUMBER}+`) + +// ## Build Metadata +// Plus sign, followed by one or more period-separated build metadata +// identifiers. + +createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER] +}(?:\\.${src[t.BUILDIDENTIFIER]})*))`) + +// ## Full Version String +// A main version, followed optionally by a pre-release version and +// build metadata. + +// Note that the only major, minor, patch, and pre-release sections of +// the version string are capturing groups. The build metadata is not a +// capturing group, because it should not ever be used in version +// comparison. + +createToken('FULLPLAIN', `v?${src[t.MAINVERSION] +}${src[t.PRERELEASE]}?${ + src[t.BUILD]}?`) + +createToken('FULL', `^${src[t.FULLPLAIN]}$`) + +// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. +// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty +// common in the npm registry. +createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE] +}${src[t.PRERELEASELOOSE]}?${ + src[t.BUILD]}?`) + +createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`) + +createToken('GTLT', '((?:<|>)?=?)') + +// Something like "2.*" or "1.2.x". +// Note that "x.x" is a valid xRange identifer, meaning "any version" +// Only the first item is strictly required. +createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`) +createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`) + +createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + + `(?:${src[t.PRERELEASE]})?${ + src[t.BUILD]}?` + + `)?)?`) + +createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + + `(?:${src[t.PRERELEASELOOSE]})?${ + src[t.BUILD]}?` + + `)?)?`) + +createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`) +createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`) + +// Coercion. +// Extract anything that could conceivably be a part of a valid semver +createToken('COERCEPLAIN', `${'(^|[^\\d])' + + '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` + + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`) +createToken('COERCE', `${src[t.COERCEPLAIN]}(?:$|[^\\d])`) +createToken('COERCEFULL', src[t.COERCEPLAIN] + + `(?:${src[t.PRERELEASE]})?` + + `(?:${src[t.BUILD]})?` + + `(?:$|[^\\d])`) +createToken('COERCERTL', src[t.COERCE], true) +createToken('COERCERTLFULL', src[t.COERCEFULL], true) + +// Tilde ranges. +// Meaning is "reasonably at or greater than" +createToken('LONETILDE', '(?:~>?)') + +createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true) +exports.tildeTrimReplace = '$1~' + +createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`) +createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`) + +// Caret ranges. +// Meaning is "at least and backwards compatible with" +createToken('LONECARET', '(?:\\^)') + +createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true) +exports.caretTrimReplace = '$1^' + +createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`) +createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`) + +// A simple gt/lt/eq thing, or just "" to indicate "any version" +createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`) +createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`) + +// An expression to strip any whitespace between the gtlt and the thing +// it modifies, so that `> 1.2.3` ==> `>1.2.3` +createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT] +}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true) +exports.comparatorTrimReplace = '$1$2$3' + +// Something like `1.2.3 - 1.2.4` +// Note that these all use the loose form, because they'll be +// checked against either the strict or loose comparator form +// later. +createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` + + `\\s+-\\s+` + + `(${src[t.XRANGEPLAIN]})` + + `\\s*$`) + +createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` + + `\\s+-\\s+` + + `(${src[t.XRANGEPLAINLOOSE]})` + + `\\s*$`) + +// Star ranges basically just allow anything at all. +createToken('STAR', '(<|>)?=?\\s*\\*') +// >=0.0.0 is like a star +createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$') +createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$') diff --git a/node_modules/semver/package.json b/node_modules/semver/package.json new file mode 100644 index 0000000..a84de91 --- /dev/null +++ b/node_modules/semver/package.json @@ -0,0 +1,78 @@ +{ + "name": "semver", + "version": "7.7.4", + "description": "The semantic version parser used by npm.", + "main": "index.js", + "scripts": { + "test": "tap", + "snap": "tap", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "lintfix": "npm run eslint -- --fix", + "posttest": "npm run lint", + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" + }, + "devDependencies": { + "@npmcli/eslint-config": "^6.0.0", + "@npmcli/template-oss": "4.29.0", + "benchmark": "^2.1.4", + "tap": "^16.0.0" + }, + "license": "ISC", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/node-semver.git" + }, + "bin": { + "semver": "bin/semver.js" + }, + "files": [ + "bin/", + "lib/", + "classes/", + "functions/", + "internal/", + "ranges/", + "index.js", + "preload.js", + "range.bnf" + ], + "tap": { + "timeout": 30, + "coverage-map": "map.js", + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + }, + "engines": { + "node": ">=10" + }, + "author": "GitHub Inc.", + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.29.0", + "engines": ">=10", + "distPaths": [ + "classes/", + "functions/", + "internal/", + "ranges/", + "index.js", + "preload.js", + "range.bnf" + ], + "allowPaths": [ + "/classes/", + "/functions/", + "/internal/", + "/ranges/", + "/index.js", + "/preload.js", + "/range.bnf", + "/benchmarks" + ], + "publish": "true" + } +} diff --git a/node_modules/semver/preload.js b/node_modules/semver/preload.js new file mode 100644 index 0000000..e6c47b9 --- /dev/null +++ b/node_modules/semver/preload.js @@ -0,0 +1,4 @@ +'use strict' + +// XXX remove in v8 or beyond +module.exports = require('./index.js') diff --git a/node_modules/semver/range.bnf b/node_modules/semver/range.bnf new file mode 100644 index 0000000..d4c6ae0 --- /dev/null +++ b/node_modules/semver/range.bnf @@ -0,0 +1,16 @@ +range-set ::= range ( logical-or range ) * +logical-or ::= ( ' ' ) * '||' ( ' ' ) * +range ::= hyphen | simple ( ' ' simple ) * | '' +hyphen ::= partial ' - ' partial +simple ::= primitive | partial | tilde | caret +primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial +partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )? +xr ::= 'x' | 'X' | '*' | nr +nr ::= '0' | [1-9] ( [0-9] ) * +tilde ::= '~' partial +caret ::= '^' partial +qualifier ::= ( '-' pre )? ( '+' build )? +pre ::= parts +build ::= parts +parts ::= part ( '.' part ) * +part ::= nr | [-0-9A-Za-z]+ diff --git a/node_modules/semver/ranges/gtr.js b/node_modules/semver/ranges/gtr.js new file mode 100644 index 0000000..0e7601f --- /dev/null +++ b/node_modules/semver/ranges/gtr.js @@ -0,0 +1,6 @@ +'use strict' + +// Determine if version is greater than all the versions possible in the range. +const outside = require('./outside') +const gtr = (version, range, options) => outside(version, range, '>', options) +module.exports = gtr diff --git a/node_modules/semver/ranges/intersects.js b/node_modules/semver/ranges/intersects.js new file mode 100644 index 0000000..917be7e --- /dev/null +++ b/node_modules/semver/ranges/intersects.js @@ -0,0 +1,9 @@ +'use strict' + +const Range = require('../classes/range') +const intersects = (r1, r2, options) => { + r1 = new Range(r1, options) + r2 = new Range(r2, options) + return r1.intersects(r2, options) +} +module.exports = intersects diff --git a/node_modules/semver/ranges/ltr.js b/node_modules/semver/ranges/ltr.js new file mode 100644 index 0000000..aa5e568 --- /dev/null +++ b/node_modules/semver/ranges/ltr.js @@ -0,0 +1,6 @@ +'use strict' + +const outside = require('./outside') +// Determine if version is less than all the versions possible in the range +const ltr = (version, range, options) => outside(version, range, '<', options) +module.exports = ltr diff --git a/node_modules/semver/ranges/max-satisfying.js b/node_modules/semver/ranges/max-satisfying.js new file mode 100644 index 0000000..01fe5ae --- /dev/null +++ b/node_modules/semver/ranges/max-satisfying.js @@ -0,0 +1,27 @@ +'use strict' + +const SemVer = require('../classes/semver') +const Range = require('../classes/range') + +const maxSatisfying = (versions, range, options) => { + let max = null + let maxSV = null + let rangeObj = null + try { + rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach((v) => { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!max || maxSV.compare(v) === -1) { + // compare(max, v, true) + max = v + maxSV = new SemVer(max, options) + } + } + }) + return max +} +module.exports = maxSatisfying diff --git a/node_modules/semver/ranges/min-satisfying.js b/node_modules/semver/ranges/min-satisfying.js new file mode 100644 index 0000000..af89c8e --- /dev/null +++ b/node_modules/semver/ranges/min-satisfying.js @@ -0,0 +1,26 @@ +'use strict' + +const SemVer = require('../classes/semver') +const Range = require('../classes/range') +const minSatisfying = (versions, range, options) => { + let min = null + let minSV = null + let rangeObj = null + try { + rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach((v) => { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!min || minSV.compare(v) === 1) { + // compare(min, v, true) + min = v + minSV = new SemVer(min, options) + } + } + }) + return min +} +module.exports = minSatisfying diff --git a/node_modules/semver/ranges/min-version.js b/node_modules/semver/ranges/min-version.js new file mode 100644 index 0000000..09a65aa --- /dev/null +++ b/node_modules/semver/ranges/min-version.js @@ -0,0 +1,63 @@ +'use strict' + +const SemVer = require('../classes/semver') +const Range = require('../classes/range') +const gt = require('../functions/gt') + +const minVersion = (range, loose) => { + range = new Range(range, loose) + + let minver = new SemVer('0.0.0') + if (range.test(minver)) { + return minver + } + + minver = new SemVer('0.0.0-0') + if (range.test(minver)) { + return minver + } + + minver = null + for (let i = 0; i < range.set.length; ++i) { + const comparators = range.set[i] + + let setMin = null + comparators.forEach((comparator) => { + // Clone to avoid manipulating the comparator's semver object. + const compver = new SemVer(comparator.semver.version) + switch (comparator.operator) { + case '>': + if (compver.prerelease.length === 0) { + compver.patch++ + } else { + compver.prerelease.push(0) + } + compver.raw = compver.format() + /* fallthrough */ + case '': + case '>=': + if (!setMin || gt(compver, setMin)) { + setMin = compver + } + break + case '<': + case '<=': + /* Ignore maximum versions */ + break + /* istanbul ignore next */ + default: + throw new Error(`Unexpected operation: ${comparator.operator}`) + } + }) + if (setMin && (!minver || gt(minver, setMin))) { + minver = setMin + } + } + + if (minver && range.test(minver)) { + return minver + } + + return null +} +module.exports = minVersion diff --git a/node_modules/semver/ranges/outside.js b/node_modules/semver/ranges/outside.js new file mode 100644 index 0000000..ca74421 --- /dev/null +++ b/node_modules/semver/ranges/outside.js @@ -0,0 +1,82 @@ +'use strict' + +const SemVer = require('../classes/semver') +const Comparator = require('../classes/comparator') +const { ANY } = Comparator +const Range = require('../classes/range') +const satisfies = require('../functions/satisfies') +const gt = require('../functions/gt') +const lt = require('../functions/lt') +const lte = require('../functions/lte') +const gte = require('../functions/gte') + +const outside = (version, range, hilo, options) => { + version = new SemVer(version, options) + range = new Range(range, options) + + let gtfn, ltefn, ltfn, comp, ecomp + switch (hilo) { + case '>': + gtfn = gt + ltefn = lte + ltfn = lt + comp = '>' + ecomp = '>=' + break + case '<': + gtfn = lt + ltefn = gte + ltfn = gt + comp = '<' + ecomp = '<=' + break + default: + throw new TypeError('Must provide a hilo val of "<" or ">"') + } + + // If it satisfies the range it is not outside + if (satisfies(version, range, options)) { + return false + } + + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. + + for (let i = 0; i < range.set.length; ++i) { + const comparators = range.set[i] + + let high = null + let low = null + + comparators.forEach((comparator) => { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0') + } + high = high || comparator + low = low || comparator + if (gtfn(comparator.semver, high.semver, options)) { + high = comparator + } else if (ltfn(comparator.semver, low.semver, options)) { + low = comparator + } + }) + + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false + } + } + return true +} + +module.exports = outside diff --git a/node_modules/semver/ranges/simplify.js b/node_modules/semver/ranges/simplify.js new file mode 100644 index 0000000..262732e --- /dev/null +++ b/node_modules/semver/ranges/simplify.js @@ -0,0 +1,49 @@ +'use strict' + +// given a set of versions and a range, create a "simplified" range +// that includes the same versions that the original range does +// If the original range is shorter than the simplified one, return that. +const satisfies = require('../functions/satisfies.js') +const compare = require('../functions/compare.js') +module.exports = (versions, range, options) => { + const set = [] + let first = null + let prev = null + const v = versions.sort((a, b) => compare(a, b, options)) + for (const version of v) { + const included = satisfies(version, range, options) + if (included) { + prev = version + if (!first) { + first = version + } + } else { + if (prev) { + set.push([first, prev]) + } + prev = null + first = null + } + } + if (first) { + set.push([first, null]) + } + + const ranges = [] + for (const [min, max] of set) { + if (min === max) { + ranges.push(min) + } else if (!max && min === v[0]) { + ranges.push('*') + } else if (!max) { + ranges.push(`>=${min}`) + } else if (min === v[0]) { + ranges.push(`<=${max}`) + } else { + ranges.push(`${min} - ${max}`) + } + } + const simplified = ranges.join(' || ') + const original = typeof range.raw === 'string' ? range.raw : String(range) + return simplified.length < original.length ? simplified : range +} diff --git a/node_modules/semver/ranges/subset.js b/node_modules/semver/ranges/subset.js new file mode 100644 index 0000000..99f4321 --- /dev/null +++ b/node_modules/semver/ranges/subset.js @@ -0,0 +1,249 @@ +'use strict' + +const Range = require('../classes/range.js') +const Comparator = require('../classes/comparator.js') +const { ANY } = Comparator +const satisfies = require('../functions/satisfies.js') +const compare = require('../functions/compare.js') + +// Complex range `r1 || r2 || ...` is a subset of `R1 || R2 || ...` iff: +// - Every simple range `r1, r2, ...` is a null set, OR +// - Every simple range `r1, r2, ...` which is not a null set is a subset of +// some `R1, R2, ...` +// +// Simple range `c1 c2 ...` is a subset of simple range `C1 C2 ...` iff: +// - If c is only the ANY comparator +// - If C is only the ANY comparator, return true +// - Else if in prerelease mode, return false +// - else replace c with `[>=0.0.0]` +// - If C is only the ANY comparator +// - if in prerelease mode, return true +// - else replace C with `[>=0.0.0]` +// - Let EQ be the set of = comparators in c +// - If EQ is more than one, return true (null set) +// - Let GT be the highest > or >= comparator in c +// - Let LT be the lowest < or <= comparator in c +// - If GT and LT, and GT.semver > LT.semver, return true (null set) +// - If any C is a = range, and GT or LT are set, return false +// - If EQ +// - If GT, and EQ does not satisfy GT, return true (null set) +// - If LT, and EQ does not satisfy LT, return true (null set) +// - If EQ satisfies every C, return true +// - Else return false +// - If GT +// - If GT.semver is lower than any > or >= comp in C, return false +// - If GT is >=, and GT.semver does not satisfy every C, return false +// - If GT.semver has a prerelease, and not in prerelease mode +// - If no C has a prerelease and the GT.semver tuple, return false +// - If LT +// - If LT.semver is greater than any < or <= comp in C, return false +// - If LT is <=, and LT.semver does not satisfy every C, return false +// - If LT.semver has a prerelease, and not in prerelease mode +// - If no C has a prerelease and the LT.semver tuple, return false +// - Else return true + +const subset = (sub, dom, options = {}) => { + if (sub === dom) { + return true + } + + sub = new Range(sub, options) + dom = new Range(dom, options) + let sawNonNull = false + + OUTER: for (const simpleSub of sub.set) { + for (const simpleDom of dom.set) { + const isSub = simpleSubset(simpleSub, simpleDom, options) + sawNonNull = sawNonNull || isSub !== null + if (isSub) { + continue OUTER + } + } + // the null set is a subset of everything, but null simple ranges in + // a complex range should be ignored. so if we saw a non-null range, + // then we know this isn't a subset, but if EVERY simple range was null, + // then it is a subset. + if (sawNonNull) { + return false + } + } + return true +} + +const minimumVersionWithPreRelease = [new Comparator('>=0.0.0-0')] +const minimumVersion = [new Comparator('>=0.0.0')] + +const simpleSubset = (sub, dom, options) => { + if (sub === dom) { + return true + } + + if (sub.length === 1 && sub[0].semver === ANY) { + if (dom.length === 1 && dom[0].semver === ANY) { + return true + } else if (options.includePrerelease) { + sub = minimumVersionWithPreRelease + } else { + sub = minimumVersion + } + } + + if (dom.length === 1 && dom[0].semver === ANY) { + if (options.includePrerelease) { + return true + } else { + dom = minimumVersion + } + } + + const eqSet = new Set() + let gt, lt + for (const c of sub) { + if (c.operator === '>' || c.operator === '>=') { + gt = higherGT(gt, c, options) + } else if (c.operator === '<' || c.operator === '<=') { + lt = lowerLT(lt, c, options) + } else { + eqSet.add(c.semver) + } + } + + if (eqSet.size > 1) { + return null + } + + let gtltComp + if (gt && lt) { + gtltComp = compare(gt.semver, lt.semver, options) + if (gtltComp > 0) { + return null + } else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<=')) { + return null + } + } + + // will iterate one or zero times + for (const eq of eqSet) { + if (gt && !satisfies(eq, String(gt), options)) { + return null + } + + if (lt && !satisfies(eq, String(lt), options)) { + return null + } + + for (const c of dom) { + if (!satisfies(eq, String(c), options)) { + return false + } + } + + return true + } + + let higher, lower + let hasDomLT, hasDomGT + // if the subset has a prerelease, we need a comparator in the superset + // with the same tuple and a prerelease, or it's not a subset + let needDomLTPre = lt && + !options.includePrerelease && + lt.semver.prerelease.length ? lt.semver : false + let needDomGTPre = gt && + !options.includePrerelease && + gt.semver.prerelease.length ? gt.semver : false + // exception: <1.2.3-0 is the same as <1.2.3 + if (needDomLTPre && needDomLTPre.prerelease.length === 1 && + lt.operator === '<' && needDomLTPre.prerelease[0] === 0) { + needDomLTPre = false + } + + for (const c of dom) { + hasDomGT = hasDomGT || c.operator === '>' || c.operator === '>=' + hasDomLT = hasDomLT || c.operator === '<' || c.operator === '<=' + if (gt) { + if (needDomGTPre) { + if (c.semver.prerelease && c.semver.prerelease.length && + c.semver.major === needDomGTPre.major && + c.semver.minor === needDomGTPre.minor && + c.semver.patch === needDomGTPre.patch) { + needDomGTPre = false + } + } + if (c.operator === '>' || c.operator === '>=') { + higher = higherGT(gt, c, options) + if (higher === c && higher !== gt) { + return false + } + } else if (gt.operator === '>=' && !satisfies(gt.semver, String(c), options)) { + return false + } + } + if (lt) { + if (needDomLTPre) { + if (c.semver.prerelease && c.semver.prerelease.length && + c.semver.major === needDomLTPre.major && + c.semver.minor === needDomLTPre.minor && + c.semver.patch === needDomLTPre.patch) { + needDomLTPre = false + } + } + if (c.operator === '<' || c.operator === '<=') { + lower = lowerLT(lt, c, options) + if (lower === c && lower !== lt) { + return false + } + } else if (lt.operator === '<=' && !satisfies(lt.semver, String(c), options)) { + return false + } + } + if (!c.operator && (lt || gt) && gtltComp !== 0) { + return false + } + } + + // if there was a < or >, and nothing in the dom, then must be false + // UNLESS it was limited by another range in the other direction. + // Eg, >1.0.0 <1.0.1 is still a subset of <2.0.0 + if (gt && hasDomLT && !lt && gtltComp !== 0) { + return false + } + + if (lt && hasDomGT && !gt && gtltComp !== 0) { + return false + } + + // we needed a prerelease range in a specific tuple, but didn't get one + // then this isn't a subset. eg >=1.2.3-pre is not a subset of >=1.0.0, + // because it includes prereleases in the 1.2.3 tuple + if (needDomGTPre || needDomLTPre) { + return false + } + + return true +} + +// >=1.2.3 is lower than >1.2.3 +const higherGT = (a, b, options) => { + if (!a) { + return b + } + const comp = compare(a.semver, b.semver, options) + return comp > 0 ? a + : comp < 0 ? b + : b.operator === '>' && a.operator === '>=' ? b + : a +} + +// <=1.2.3 is higher than <1.2.3 +const lowerLT = (a, b, options) => { + if (!a) { + return b + } + const comp = compare(a.semver, b.semver, options) + return comp < 0 ? a + : comp > 0 ? b + : b.operator === '<' && a.operator === '<=' ? b + : a +} + +module.exports = subset diff --git a/node_modules/semver/ranges/to-comparators.js b/node_modules/semver/ranges/to-comparators.js new file mode 100644 index 0000000..5be2519 --- /dev/null +++ b/node_modules/semver/ranges/to-comparators.js @@ -0,0 +1,10 @@ +'use strict' + +const Range = require('../classes/range') + +// Mostly just for testing and legacy API reasons +const toComparators = (range, options) => + new Range(range, options).set + .map(comp => comp.map(c => c.value).join(' ').trim().split(' ')) + +module.exports = toComparators diff --git a/node_modules/semver/ranges/valid.js b/node_modules/semver/ranges/valid.js new file mode 100644 index 0000000..cc6b0e9 --- /dev/null +++ b/node_modules/semver/ranges/valid.js @@ -0,0 +1,13 @@ +'use strict' + +const Range = require('../classes/range') +const validRange = (range, options) => { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, options).range || '*' + } catch (er) { + return null + } +} +module.exports = validRange diff --git a/node_modules/shebang-command/index.js b/node_modules/shebang-command/index.js new file mode 100644 index 0000000..f35db30 --- /dev/null +++ b/node_modules/shebang-command/index.js @@ -0,0 +1,19 @@ +'use strict'; +const shebangRegex = require('shebang-regex'); + +module.exports = (string = '') => { + const match = string.match(shebangRegex); + + if (!match) { + return null; + } + + const [path, argument] = match[0].replace(/#! ?/, '').split(' '); + const binary = path.split('/').pop(); + + if (binary === 'env') { + return argument; + } + + return argument ? `${binary} ${argument}` : binary; +}; diff --git a/node_modules/shebang-command/license b/node_modules/shebang-command/license new file mode 100644 index 0000000..db6bc32 --- /dev/null +++ b/node_modules/shebang-command/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Kevin Mårtensson (github.com/kevva) + +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/node_modules/shebang-command/package.json b/node_modules/shebang-command/package.json new file mode 100644 index 0000000..18e3c04 --- /dev/null +++ b/node_modules/shebang-command/package.json @@ -0,0 +1,34 @@ +{ + "name": "shebang-command", + "version": "2.0.0", + "description": "Get the command from a shebang", + "license": "MIT", + "repository": "kevva/shebang-command", + "author": { + "name": "Kevin Mårtensson", + "email": "kevinmartensson@gmail.com", + "url": "github.com/kevva" + }, + "engines": { + "node": ">=8" + }, + "scripts": { + "test": "xo && ava" + }, + "files": [ + "index.js" + ], + "keywords": [ + "cmd", + "command", + "parse", + "shebang" + ], + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "devDependencies": { + "ava": "^2.3.0", + "xo": "^0.24.0" + } +} diff --git a/node_modules/shebang-command/readme.md b/node_modules/shebang-command/readme.md new file mode 100644 index 0000000..84feb44 --- /dev/null +++ b/node_modules/shebang-command/readme.md @@ -0,0 +1,34 @@ +# shebang-command [![Build Status](https://travis-ci.org/kevva/shebang-command.svg?branch=master)](https://travis-ci.org/kevva/shebang-command) + +> Get the command from a shebang + + +## Install + +``` +$ npm install shebang-command +``` + + +## Usage + +```js +const shebangCommand = require('shebang-command'); + +shebangCommand('#!/usr/bin/env node'); +//=> 'node' + +shebangCommand('#!/bin/bash'); +//=> 'bash' +``` + + +## API + +### shebangCommand(string) + +#### string + +Type: `string` + +String containing a shebang. diff --git a/node_modules/shebang-regex/index.d.ts b/node_modules/shebang-regex/index.d.ts new file mode 100644 index 0000000..61d034b --- /dev/null +++ b/node_modules/shebang-regex/index.d.ts @@ -0,0 +1,22 @@ +/** +Regular expression for matching a [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) line. + +@example +``` +import shebangRegex = require('shebang-regex'); + +const string = '#!/usr/bin/env node\nconsole.log("unicorns");'; + +shebangRegex.test(string); +//=> true + +shebangRegex.exec(string)[0]; +//=> '#!/usr/bin/env node' + +shebangRegex.exec(string)[1]; +//=> '/usr/bin/env node' +``` +*/ +declare const shebangRegex: RegExp; + +export = shebangRegex; diff --git a/node_modules/shebang-regex/index.js b/node_modules/shebang-regex/index.js new file mode 100644 index 0000000..63fc4a0 --- /dev/null +++ b/node_modules/shebang-regex/index.js @@ -0,0 +1,2 @@ +'use strict'; +module.exports = /^#!(.*)/; diff --git a/node_modules/shebang-regex/license b/node_modules/shebang-regex/license new file mode 100644 index 0000000..e7af2f7 --- /dev/null +++ b/node_modules/shebang-regex/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +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/node_modules/shebang-regex/package.json b/node_modules/shebang-regex/package.json new file mode 100644 index 0000000..00ab30f --- /dev/null +++ b/node_modules/shebang-regex/package.json @@ -0,0 +1,35 @@ +{ + "name": "shebang-regex", + "version": "3.0.0", + "description": "Regular expression for matching a shebang line", + "license": "MIT", + "repository": "sindresorhus/shebang-regex", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "engines": { + "node": ">=8" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "keywords": [ + "regex", + "regexp", + "shebang", + "match", + "test", + "line" + ], + "devDependencies": { + "ava": "^1.4.1", + "tsd": "^0.7.2", + "xo": "^0.24.0" + } +} diff --git a/node_modules/shebang-regex/readme.md b/node_modules/shebang-regex/readme.md new file mode 100644 index 0000000..5ecf863 --- /dev/null +++ b/node_modules/shebang-regex/readme.md @@ -0,0 +1,33 @@ +# shebang-regex [![Build Status](https://travis-ci.org/sindresorhus/shebang-regex.svg?branch=master)](https://travis-ci.org/sindresorhus/shebang-regex) + +> Regular expression for matching a [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) line + + +## Install + +``` +$ npm install shebang-regex +``` + + +## Usage + +```js +const shebangRegex = require('shebang-regex'); + +const string = '#!/usr/bin/env node\nconsole.log("unicorns");'; + +shebangRegex.test(string); +//=> true + +shebangRegex.exec(string)[0]; +//=> '#!/usr/bin/env node' + +shebangRegex.exec(string)[1]; +//=> '/usr/bin/env node' +``` + + +## License + +MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/signal-exit/LICENSE.txt b/node_modules/signal-exit/LICENSE.txt new file mode 100644 index 0000000..954f2fa --- /dev/null +++ b/node_modules/signal-exit/LICENSE.txt @@ -0,0 +1,16 @@ +The ISC License + +Copyright (c) 2015-2023 Benjamin Coe, Isaac Z. Schlueter, and Contributors + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice +appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE +LIABLE FOR ANY SPECIAL, DIRECT, 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 THIS SOFTWARE. diff --git a/node_modules/signal-exit/README.md b/node_modules/signal-exit/README.md new file mode 100644 index 0000000..c55cd45 --- /dev/null +++ b/node_modules/signal-exit/README.md @@ -0,0 +1,74 @@ +# signal-exit + +When you want to fire an event no matter how a process exits: + +- reaching the end of execution. +- explicitly having `process.exit(code)` called. +- having `process.kill(pid, sig)` called. +- receiving a fatal signal from outside the process + +Use `signal-exit`. + +```js +// Hybrid module, either works +import { onExit } from 'signal-exit' +// or: +// const { onExit } = require('signal-exit') + +onExit((code, signal) => { + console.log('process exited!', code, signal) +}) +``` + +## API + +`remove = onExit((code, signal) => {}, options)` + +The return value of the function is a function that will remove +the handler. + +Note that the function _only_ fires for signals if the signal +would cause the process to exit. That is, there are no other +listeners, and it is a fatal signal. + +If the global `process` object is not suitable for this purpose +(ie, it's unset, or doesn't have an `emit` method, etc.) then the +`onExit` function is a no-op that returns a no-op `remove` method. + +### Options + +- `alwaysLast`: Run this handler after any other signal or exit + handlers. This causes `process.emit` to be monkeypatched. + +### Capturing Signal Exits + +If the handler returns an exact boolean `true`, and the exit is a +due to signal, then the signal will be considered handled, and +will _not_ trigger a synthetic `process.kill(process.pid, +signal)` after firing the `onExit` handlers. + +In this case, it your responsibility as the caller to exit with a +signal (for example, by calling `process.kill()`) if you wish to +preserve the same exit status that would otherwise have occurred. +If you do not, then the process will likely exit gracefully with +status 0 at some point, assuming that no other terminating signal +or other exit trigger occurs. + +Prior to calling handlers, the `onExit` machinery is unloaded, so +any subsequent exits or signals will not be handled, even if the +signal is captured and the exit is thus prevented. + +Note that numeric code exits may indicate that the process is +already committed to exiting, for example due to a fatal +exception or unhandled promise rejection, and so there is no way to +prevent it safely. + +### Browser Fallback + +The `'signal-exit/browser'` module is the same fallback shim that +just doesn't do anything, but presents the same function +interface. + +Patches welcome to add something that hooks onto +`window.onbeforeunload` or similar, but it might just not be a +thing that makes sense there. diff --git a/node_modules/signal-exit/dist/cjs/browser.d.ts b/node_modules/signal-exit/dist/cjs/browser.d.ts new file mode 100644 index 0000000..90f2e3f --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/browser.d.ts @@ -0,0 +1,12 @@ +/** + * This is a browser shim that provides the same functional interface + * as the main node export, but it does nothing. + * @module + */ +import type { Handler } from './index.js'; +export declare const onExit: (cb: Handler, opts: { + alwaysLast?: boolean; +}) => () => void; +export declare const load: () => void; +export declare const unload: () => void; +//# sourceMappingURL=browser.d.ts.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/cjs/browser.d.ts.map b/node_modules/signal-exit/dist/cjs/browser.d.ts.map new file mode 100644 index 0000000..aacc1d3 --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/browser.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACzC,eAAO,MAAM,MAAM,EAAE,CACnB,EAAE,EAAE,OAAO,EACX,IAAI,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,KAC3B,MAAM,IAAqB,CAAA;AAChC,eAAO,MAAM,IAAI,YAAW,CAAA;AAC5B,eAAO,MAAM,MAAM,YAAW,CAAA"} \ No newline at end of file diff --git a/node_modules/signal-exit/dist/cjs/browser.js b/node_modules/signal-exit/dist/cjs/browser.js new file mode 100644 index 0000000..614fbf0 --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/browser.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.unload = exports.load = exports.onExit = void 0; +const onExit = () => () => { }; +exports.onExit = onExit; +const load = () => { }; +exports.load = load; +const unload = () => { }; +exports.unload = unload; +//# sourceMappingURL=browser.js.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/cjs/browser.js.map b/node_modules/signal-exit/dist/cjs/browser.js.map new file mode 100644 index 0000000..342cf2e --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/browser.js.map @@ -0,0 +1 @@ +{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":";;;AAMO,MAAM,MAAM,GAGD,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC,CAAA;AAHnB,QAAA,MAAM,UAGa;AACzB,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;AAAf,QAAA,IAAI,QAAW;AACrB,MAAM,MAAM,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;AAAjB,QAAA,MAAM,UAAW","sourcesContent":["/**\n * This is a browser shim that provides the same functional interface\n * as the main node export, but it does nothing.\n * @module\n */\nimport type { Handler } from './index.js'\nexport const onExit: (\n cb: Handler,\n opts: { alwaysLast?: boolean }\n) => () => void = () => () => {}\nexport const load = () => {}\nexport const unload = () => {}\n"]} \ No newline at end of file diff --git a/node_modules/signal-exit/dist/cjs/index.d.ts b/node_modules/signal-exit/dist/cjs/index.d.ts new file mode 100644 index 0000000..cabe9cf --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/index.d.ts @@ -0,0 +1,48 @@ +/// +import { signals } from './signals.js'; +export { signals }; +/** + * A function that takes an exit code and signal as arguments + * + * In the case of signal exits *only*, a return value of true + * will indicate that the signal is being handled, and we should + * not synthetically exit with the signal we received. Regardless + * of the handler return value, the handler is unloaded when an + * otherwise fatal signal is received, so you get exactly 1 shot + * at it, unless you add another onExit handler at that point. + * + * In the case of numeric code exits, we may already have committed + * to exiting the process, for example via a fatal exception or + * unhandled promise rejection, so it is impossible to stop safely. + */ +export type Handler = (code: number | null | undefined, signal: NodeJS.Signals | null) => true | void; +export declare const +/** + * Called when the process is exiting, whether via signal, explicit + * exit, or running out of stuff to do. + * + * If the global process object is not suitable for instrumentation, + * then this will be a no-op. + * + * Returns a function that may be used to unload signal-exit. + */ +onExit: (cb: Handler, opts?: { + alwaysLast?: boolean | undefined; +} | undefined) => () => void, +/** + * Load the listeners. Likely you never need to call this, unless + * doing a rather deep integration with signal-exit functionality. + * Mostly exposed for the benefit of testing. + * + * @internal + */ +load: () => void, +/** + * Unload the listeners. Likely you never need to call this, unless + * doing a rather deep integration with signal-exit functionality. + * Mostly exposed for the benefit of testing. + * + * @internal + */ +unload: () => void; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/cjs/index.d.ts.map b/node_modules/signal-exit/dist/cjs/index.d.ts.map new file mode 100644 index 0000000..f84594e --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,CAAA;AAuBlB;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,OAAO,GAAG,CACpB,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,KAC1B,IAAI,GAAG,IAAI,CAAA;AA8QhB,eAAO;AACL;;;;;;;;GAQG;AACH,MAAM,OAzMO,OAAO;;wBAPiD,IAAI;AAkNzE;;;;;;GAMG;AACH,IAAI;AAEJ;;;;;;GAMG;AACH,MAAM,YAGP,CAAA"} \ No newline at end of file diff --git a/node_modules/signal-exit/dist/cjs/index.js b/node_modules/signal-exit/dist/cjs/index.js new file mode 100644 index 0000000..797e674 --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/index.js @@ -0,0 +1,279 @@ +"use strict"; +var _a; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.unload = exports.load = exports.onExit = exports.signals = void 0; +// Note: since nyc uses this module to output coverage, any lines +// that are in the direct sync flow of nyc's outputCoverage are +// ignored, since we can never get coverage for them. +// grab a reference to node's real process object right away +const signals_js_1 = require("./signals.js"); +Object.defineProperty(exports, "signals", { enumerable: true, get: function () { return signals_js_1.signals; } }); +const processOk = (process) => !!process && + typeof process === 'object' && + typeof process.removeListener === 'function' && + typeof process.emit === 'function' && + typeof process.reallyExit === 'function' && + typeof process.listeners === 'function' && + typeof process.kill === 'function' && + typeof process.pid === 'number' && + typeof process.on === 'function'; +const kExitEmitter = Symbol.for('signal-exit emitter'); +const global = globalThis; +const ObjectDefineProperty = Object.defineProperty.bind(Object); +// teeny special purpose ee +class Emitter { + emitted = { + afterExit: false, + exit: false, + }; + listeners = { + afterExit: [], + exit: [], + }; + count = 0; + id = Math.random(); + constructor() { + if (global[kExitEmitter]) { + return global[kExitEmitter]; + } + ObjectDefineProperty(global, kExitEmitter, { + value: this, + writable: false, + enumerable: false, + configurable: false, + }); + } + on(ev, fn) { + this.listeners[ev].push(fn); + } + removeListener(ev, fn) { + const list = this.listeners[ev]; + const i = list.indexOf(fn); + /* c8 ignore start */ + if (i === -1) { + return; + } + /* c8 ignore stop */ + if (i === 0 && list.length === 1) { + list.length = 0; + } + else { + list.splice(i, 1); + } + } + emit(ev, code, signal) { + if (this.emitted[ev]) { + return false; + } + this.emitted[ev] = true; + let ret = false; + for (const fn of this.listeners[ev]) { + ret = fn(code, signal) === true || ret; + } + if (ev === 'exit') { + ret = this.emit('afterExit', code, signal) || ret; + } + return ret; + } +} +class SignalExitBase { +} +const signalExitWrap = (handler) => { + return { + onExit(cb, opts) { + return handler.onExit(cb, opts); + }, + load() { + return handler.load(); + }, + unload() { + return handler.unload(); + }, + }; +}; +class SignalExitFallback extends SignalExitBase { + onExit() { + return () => { }; + } + load() { } + unload() { } +} +class SignalExit extends SignalExitBase { + // "SIGHUP" throws an `ENOSYS` error on Windows, + // so use a supported signal instead + /* c8 ignore start */ + #hupSig = process.platform === 'win32' ? 'SIGINT' : 'SIGHUP'; + /* c8 ignore stop */ + #emitter = new Emitter(); + #process; + #originalProcessEmit; + #originalProcessReallyExit; + #sigListeners = {}; + #loaded = false; + constructor(process) { + super(); + this.#process = process; + // { : , ... } + this.#sigListeners = {}; + for (const sig of signals_js_1.signals) { + this.#sigListeners[sig] = () => { + // If there are no other listeners, an exit is coming! + // Simplest way: remove us and then re-send the signal. + // We know that this will kill the process, so we can + // safely emit now. + const listeners = this.#process.listeners(sig); + let { count } = this.#emitter; + // This is a workaround for the fact that signal-exit v3 and signal + // exit v4 are not aware of each other, and each will attempt to let + // the other handle it, so neither of them do. To correct this, we + // detect if we're the only handler *except* for previous versions + // of signal-exit, and increment by the count of listeners it has + // created. + /* c8 ignore start */ + const p = process; + if (typeof p.__signal_exit_emitter__ === 'object' && + typeof p.__signal_exit_emitter__.count === 'number') { + count += p.__signal_exit_emitter__.count; + } + /* c8 ignore stop */ + if (listeners.length === count) { + this.unload(); + const ret = this.#emitter.emit('exit', null, sig); + /* c8 ignore start */ + const s = sig === 'SIGHUP' ? this.#hupSig : sig; + if (!ret) + process.kill(process.pid, s); + /* c8 ignore stop */ + } + }; + } + this.#originalProcessReallyExit = process.reallyExit; + this.#originalProcessEmit = process.emit; + } + onExit(cb, opts) { + /* c8 ignore start */ + if (!processOk(this.#process)) { + return () => { }; + } + /* c8 ignore stop */ + if (this.#loaded === false) { + this.load(); + } + const ev = opts?.alwaysLast ? 'afterExit' : 'exit'; + this.#emitter.on(ev, cb); + return () => { + this.#emitter.removeListener(ev, cb); + if (this.#emitter.listeners['exit'].length === 0 && + this.#emitter.listeners['afterExit'].length === 0) { + this.unload(); + } + }; + } + load() { + if (this.#loaded) { + return; + } + this.#loaded = true; + // This is the number of onSignalExit's that are in play. + // It's important so that we can count the correct number of + // listeners on signals, and don't wait for the other one to + // handle it instead of us. + this.#emitter.count += 1; + for (const sig of signals_js_1.signals) { + try { + const fn = this.#sigListeners[sig]; + if (fn) + this.#process.on(sig, fn); + } + catch (_) { } + } + this.#process.emit = (ev, ...a) => { + return this.#processEmit(ev, ...a); + }; + this.#process.reallyExit = (code) => { + return this.#processReallyExit(code); + }; + } + unload() { + if (!this.#loaded) { + return; + } + this.#loaded = false; + signals_js_1.signals.forEach(sig => { + const listener = this.#sigListeners[sig]; + /* c8 ignore start */ + if (!listener) { + throw new Error('Listener not defined for signal: ' + sig); + } + /* c8 ignore stop */ + try { + this.#process.removeListener(sig, listener); + /* c8 ignore start */ + } + catch (_) { } + /* c8 ignore stop */ + }); + this.#process.emit = this.#originalProcessEmit; + this.#process.reallyExit = this.#originalProcessReallyExit; + this.#emitter.count -= 1; + } + #processReallyExit(code) { + /* c8 ignore start */ + if (!processOk(this.#process)) { + return 0; + } + this.#process.exitCode = code || 0; + /* c8 ignore stop */ + this.#emitter.emit('exit', this.#process.exitCode, null); + return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode); + } + #processEmit(ev, ...args) { + const og = this.#originalProcessEmit; + if (ev === 'exit' && processOk(this.#process)) { + if (typeof args[0] === 'number') { + this.#process.exitCode = args[0]; + /* c8 ignore start */ + } + /* c8 ignore start */ + const ret = og.call(this.#process, ev, ...args); + /* c8 ignore start */ + this.#emitter.emit('exit', this.#process.exitCode, null); + /* c8 ignore stop */ + return ret; + } + else { + return og.call(this.#process, ev, ...args); + } + } +} +const process = globalThis.process; +// wrap so that we call the method on the actual handler, without +// exporting it directly. +_a = signalExitWrap(processOk(process) ? new SignalExit(process) : new SignalExitFallback()), +/** + * Called when the process is exiting, whether via signal, explicit + * exit, or running out of stuff to do. + * + * If the global process object is not suitable for instrumentation, + * then this will be a no-op. + * + * Returns a function that may be used to unload signal-exit. + */ +exports.onExit = _a.onExit, +/** + * Load the listeners. Likely you never need to call this, unless + * doing a rather deep integration with signal-exit functionality. + * Mostly exposed for the benefit of testing. + * + * @internal + */ +exports.load = _a.load, +/** + * Unload the listeners. Likely you never need to call this, unless + * doing a rather deep integration with signal-exit functionality. + * Mostly exposed for the benefit of testing. + * + * @internal + */ +exports.unload = _a.unload; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/cjs/index.js.map b/node_modules/signal-exit/dist/cjs/index.js.map new file mode 100644 index 0000000..528e3cc --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Note: since nyc uses this module to output coverage, any lines\n// that are in the direct sync flow of nyc's outputCoverage are\n// ignored, since we can never get coverage for them.\n// grab a reference to node's real process object right away\nimport { signals } from './signals.js'\nexport { signals }\n\n// just a loosened process type so we can do some evil things\ntype ProcessRE = NodeJS.Process & {\n reallyExit: (code?: number | undefined | null) => any\n emit: (ev: string, ...a: any[]) => any\n}\n\nconst processOk = (process: any): process is ProcessRE =>\n !!process &&\n typeof process === 'object' &&\n typeof process.removeListener === 'function' &&\n typeof process.emit === 'function' &&\n typeof process.reallyExit === 'function' &&\n typeof process.listeners === 'function' &&\n typeof process.kill === 'function' &&\n typeof process.pid === 'number' &&\n typeof process.on === 'function'\n\nconst kExitEmitter = Symbol.for('signal-exit emitter')\nconst global: typeof globalThis & { [kExitEmitter]?: Emitter } = globalThis\nconst ObjectDefineProperty = Object.defineProperty.bind(Object)\n\n/**\n * A function that takes an exit code and signal as arguments\n *\n * In the case of signal exits *only*, a return value of true\n * will indicate that the signal is being handled, and we should\n * not synthetically exit with the signal we received. Regardless\n * of the handler return value, the handler is unloaded when an\n * otherwise fatal signal is received, so you get exactly 1 shot\n * at it, unless you add another onExit handler at that point.\n *\n * In the case of numeric code exits, we may already have committed\n * to exiting the process, for example via a fatal exception or\n * unhandled promise rejection, so it is impossible to stop safely.\n */\nexport type Handler = (\n code: number | null | undefined,\n signal: NodeJS.Signals | null\n) => true | void\ntype ExitEvent = 'afterExit' | 'exit'\ntype Emitted = { [k in ExitEvent]: boolean }\ntype Listeners = { [k in ExitEvent]: Handler[] }\n\n// teeny special purpose ee\nclass Emitter {\n emitted: Emitted = {\n afterExit: false,\n exit: false,\n }\n\n listeners: Listeners = {\n afterExit: [],\n exit: [],\n }\n\n count: number = 0\n id: number = Math.random()\n\n constructor() {\n if (global[kExitEmitter]) {\n return global[kExitEmitter]\n }\n ObjectDefineProperty(global, kExitEmitter, {\n value: this,\n writable: false,\n enumerable: false,\n configurable: false,\n })\n }\n\n on(ev: ExitEvent, fn: Handler) {\n this.listeners[ev].push(fn)\n }\n\n removeListener(ev: ExitEvent, fn: Handler) {\n const list = this.listeners[ev]\n const i = list.indexOf(fn)\n /* c8 ignore start */\n if (i === -1) {\n return\n }\n /* c8 ignore stop */\n if (i === 0 && list.length === 1) {\n list.length = 0\n } else {\n list.splice(i, 1)\n }\n }\n\n emit(\n ev: ExitEvent,\n code: number | null | undefined,\n signal: NodeJS.Signals | null\n ): boolean {\n if (this.emitted[ev]) {\n return false\n }\n this.emitted[ev] = true\n let ret: boolean = false\n for (const fn of this.listeners[ev]) {\n ret = fn(code, signal) === true || ret\n }\n if (ev === 'exit') {\n ret = this.emit('afterExit', code, signal) || ret\n }\n return ret\n }\n}\n\nabstract class SignalExitBase {\n abstract onExit(cb: Handler, opts?: { alwaysLast?: boolean }): () => void\n abstract load(): void\n abstract unload(): void\n}\n\nconst signalExitWrap = (handler: T) => {\n return {\n onExit(cb: Handler, opts?: { alwaysLast?: boolean }) {\n return handler.onExit(cb, opts)\n },\n load() {\n return handler.load()\n },\n unload() {\n return handler.unload()\n },\n }\n}\n\nclass SignalExitFallback extends SignalExitBase {\n onExit() {\n return () => {}\n }\n load() {}\n unload() {}\n}\n\nclass SignalExit extends SignalExitBase {\n // \"SIGHUP\" throws an `ENOSYS` error on Windows,\n // so use a supported signal instead\n /* c8 ignore start */\n #hupSig = process.platform === 'win32' ? 'SIGINT' : 'SIGHUP'\n /* c8 ignore stop */\n #emitter = new Emitter()\n #process: ProcessRE\n #originalProcessEmit: ProcessRE['emit']\n #originalProcessReallyExit: ProcessRE['reallyExit']\n\n #sigListeners: { [k in NodeJS.Signals]?: () => void } = {}\n #loaded: boolean = false\n\n constructor(process: ProcessRE) {\n super()\n this.#process = process\n // { : , ... }\n this.#sigListeners = {}\n for (const sig of signals) {\n this.#sigListeners[sig] = () => {\n // If there are no other listeners, an exit is coming!\n // Simplest way: remove us and then re-send the signal.\n // We know that this will kill the process, so we can\n // safely emit now.\n const listeners = this.#process.listeners(sig)\n let { count } = this.#emitter\n // This is a workaround for the fact that signal-exit v3 and signal\n // exit v4 are not aware of each other, and each will attempt to let\n // the other handle it, so neither of them do. To correct this, we\n // detect if we're the only handler *except* for previous versions\n // of signal-exit, and increment by the count of listeners it has\n // created.\n /* c8 ignore start */\n const p = process as unknown as {\n __signal_exit_emitter__?: { count: number }\n }\n if (\n typeof p.__signal_exit_emitter__ === 'object' &&\n typeof p.__signal_exit_emitter__.count === 'number'\n ) {\n count += p.__signal_exit_emitter__.count\n }\n /* c8 ignore stop */\n if (listeners.length === count) {\n this.unload()\n const ret = this.#emitter.emit('exit', null, sig)\n /* c8 ignore start */\n const s = sig === 'SIGHUP' ? this.#hupSig : sig\n if (!ret) process.kill(process.pid, s)\n /* c8 ignore stop */\n }\n }\n }\n\n this.#originalProcessReallyExit = process.reallyExit\n this.#originalProcessEmit = process.emit\n }\n\n onExit(cb: Handler, opts?: { alwaysLast?: boolean }) {\n /* c8 ignore start */\n if (!processOk(this.#process)) {\n return () => {}\n }\n /* c8 ignore stop */\n\n if (this.#loaded === false) {\n this.load()\n }\n\n const ev = opts?.alwaysLast ? 'afterExit' : 'exit'\n this.#emitter.on(ev, cb)\n return () => {\n this.#emitter.removeListener(ev, cb)\n if (\n this.#emitter.listeners['exit'].length === 0 &&\n this.#emitter.listeners['afterExit'].length === 0\n ) {\n this.unload()\n }\n }\n }\n\n load() {\n if (this.#loaded) {\n return\n }\n this.#loaded = true\n\n // This is the number of onSignalExit's that are in play.\n // It's important so that we can count the correct number of\n // listeners on signals, and don't wait for the other one to\n // handle it instead of us.\n this.#emitter.count += 1\n\n for (const sig of signals) {\n try {\n const fn = this.#sigListeners[sig]\n if (fn) this.#process.on(sig, fn)\n } catch (_) {}\n }\n\n this.#process.emit = (ev: string, ...a: any[]) => {\n return this.#processEmit(ev, ...a)\n }\n this.#process.reallyExit = (code?: number | null | undefined) => {\n return this.#processReallyExit(code)\n }\n }\n\n unload() {\n if (!this.#loaded) {\n return\n }\n this.#loaded = false\n\n signals.forEach(sig => {\n const listener = this.#sigListeners[sig]\n /* c8 ignore start */\n if (!listener) {\n throw new Error('Listener not defined for signal: ' + sig)\n }\n /* c8 ignore stop */\n try {\n this.#process.removeListener(sig, listener)\n /* c8 ignore start */\n } catch (_) {}\n /* c8 ignore stop */\n })\n this.#process.emit = this.#originalProcessEmit\n this.#process.reallyExit = this.#originalProcessReallyExit\n this.#emitter.count -= 1\n }\n\n #processReallyExit(code?: number | null | undefined) {\n /* c8 ignore start */\n if (!processOk(this.#process)) {\n return 0\n }\n this.#process.exitCode = code || 0\n /* c8 ignore stop */\n\n this.#emitter.emit('exit', this.#process.exitCode, null)\n return this.#originalProcessReallyExit.call(\n this.#process,\n this.#process.exitCode\n )\n }\n\n #processEmit(ev: string, ...args: any[]): any {\n const og = this.#originalProcessEmit\n if (ev === 'exit' && processOk(this.#process)) {\n if (typeof args[0] === 'number') {\n this.#process.exitCode = args[0]\n /* c8 ignore start */\n }\n /* c8 ignore start */\n const ret = og.call(this.#process, ev, ...args)\n /* c8 ignore start */\n this.#emitter.emit('exit', this.#process.exitCode, null)\n /* c8 ignore stop */\n return ret\n } else {\n return og.call(this.#process, ev, ...args)\n }\n }\n}\n\nconst process = globalThis.process\n// wrap so that we call the method on the actual handler, without\n// exporting it directly.\nexport const {\n /**\n * Called when the process is exiting, whether via signal, explicit\n * exit, or running out of stuff to do.\n *\n * If the global process object is not suitable for instrumentation,\n * then this will be a no-op.\n *\n * Returns a function that may be used to unload signal-exit.\n */\n onExit,\n\n /**\n * Load the listeners. Likely you never need to call this, unless\n * doing a rather deep integration with signal-exit functionality.\n * Mostly exposed for the benefit of testing.\n *\n * @internal\n */\n load,\n\n /**\n * Unload the listeners. Likely you never need to call this, unless\n * doing a rather deep integration with signal-exit functionality.\n * Mostly exposed for the benefit of testing.\n *\n * @internal\n */\n unload,\n} = signalExitWrap(\n processOk(process) ? new SignalExit(process) : new SignalExitFallback()\n)\n"]} \ No newline at end of file diff --git a/node_modules/signal-exit/dist/cjs/package.json b/node_modules/signal-exit/dist/cjs/package.json new file mode 100644 index 0000000..5bbefff --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/signal-exit/dist/cjs/signals.d.ts b/node_modules/signal-exit/dist/cjs/signals.d.ts new file mode 100644 index 0000000..3f01ef0 --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/signals.d.ts @@ -0,0 +1,29 @@ +/// +/** + * This is not the set of all possible signals. + * + * It IS, however, the set of all signals that trigger + * an exit on either Linux or BSD systems. Linux is a + * superset of the signal names supported on BSD, and + * the unknown signals just fail to register, so we can + * catch that easily enough. + * + * Windows signals are a different set, since there are + * signals that terminate Windows processes, but don't + * terminate (or don't even exist) on Posix systems. + * + * Don't bother with SIGKILL. It's uncatchable, which + * means that we can't fire any callbacks anyway. + * + * If a user does happen to register a handler on a non- + * fatal signal like SIGWINCH or something, and then + * exit, it'll end up firing `process.emit('exit')`, so + * the handler will be fired anyway. + * + * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised + * artificially, inherently leave the process in a + * state from which it is not safe to try and enter JS + * listeners. + */ +export declare const signals: NodeJS.Signals[]; +//# sourceMappingURL=signals.d.ts.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/cjs/signals.d.ts.map b/node_modules/signal-exit/dist/cjs/signals.d.ts.map new file mode 100644 index 0000000..891fe1e --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/signals.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../src/signals.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,OAAO,EAAO,CAAA"} \ No newline at end of file diff --git a/node_modules/signal-exit/dist/cjs/signals.js b/node_modules/signal-exit/dist/cjs/signals.js new file mode 100644 index 0000000..28afc50 --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/signals.js @@ -0,0 +1,42 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.signals = void 0; +/** + * This is not the set of all possible signals. + * + * It IS, however, the set of all signals that trigger + * an exit on either Linux or BSD systems. Linux is a + * superset of the signal names supported on BSD, and + * the unknown signals just fail to register, so we can + * catch that easily enough. + * + * Windows signals are a different set, since there are + * signals that terminate Windows processes, but don't + * terminate (or don't even exist) on Posix systems. + * + * Don't bother with SIGKILL. It's uncatchable, which + * means that we can't fire any callbacks anyway. + * + * If a user does happen to register a handler on a non- + * fatal signal like SIGWINCH or something, and then + * exit, it'll end up firing `process.emit('exit')`, so + * the handler will be fired anyway. + * + * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised + * artificially, inherently leave the process in a + * state from which it is not safe to try and enter JS + * listeners. + */ +exports.signals = []; +exports.signals.push('SIGHUP', 'SIGINT', 'SIGTERM'); +if (process.platform !== 'win32') { + exports.signals.push('SIGALRM', 'SIGABRT', 'SIGVTALRM', 'SIGXCPU', 'SIGXFSZ', 'SIGUSR2', 'SIGTRAP', 'SIGSYS', 'SIGQUIT', 'SIGIOT' + // should detect profiler and enable/disable accordingly. + // see #21 + // 'SIGPROF' + ); +} +if (process.platform === 'linux') { + exports.signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT'); +} +//# sourceMappingURL=signals.js.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/cjs/signals.js.map b/node_modules/signal-exit/dist/cjs/signals.js.map new file mode 100644 index 0000000..78c613f --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/signals.js.map @@ -0,0 +1 @@ +{"version":3,"file":"signals.js","sourceRoot":"","sources":["../../src/signals.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACU,QAAA,OAAO,GAAqB,EAAE,CAAA;AAC3C,eAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAA;AAE3C,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE;IAChC,eAAO,CAAC,IAAI,CACV,SAAS,EACT,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,QAAQ,EACR,SAAS,EACT,QAAQ;IACR,yDAAyD;IACzD,UAAU;IACV,YAAY;KACb,CAAA;CACF;AAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE;IAChC,eAAO,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAA;CACxD","sourcesContent":["/**\n * This is not the set of all possible signals.\n *\n * It IS, however, the set of all signals that trigger\n * an exit on either Linux or BSD systems. Linux is a\n * superset of the signal names supported on BSD, and\n * the unknown signals just fail to register, so we can\n * catch that easily enough.\n *\n * Windows signals are a different set, since there are\n * signals that terminate Windows processes, but don't\n * terminate (or don't even exist) on Posix systems.\n *\n * Don't bother with SIGKILL. It's uncatchable, which\n * means that we can't fire any callbacks anyway.\n *\n * If a user does happen to register a handler on a non-\n * fatal signal like SIGWINCH or something, and then\n * exit, it'll end up firing `process.emit('exit')`, so\n * the handler will be fired anyway.\n *\n * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised\n * artificially, inherently leave the process in a\n * state from which it is not safe to try and enter JS\n * listeners.\n */\nexport const signals: NodeJS.Signals[] = []\nsignals.push('SIGHUP', 'SIGINT', 'SIGTERM')\n\nif (process.platform !== 'win32') {\n signals.push(\n 'SIGALRM',\n 'SIGABRT',\n 'SIGVTALRM',\n 'SIGXCPU',\n 'SIGXFSZ',\n 'SIGUSR2',\n 'SIGTRAP',\n 'SIGSYS',\n 'SIGQUIT',\n 'SIGIOT'\n // should detect profiler and enable/disable accordingly.\n // see #21\n // 'SIGPROF'\n )\n}\n\nif (process.platform === 'linux') {\n signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT')\n}\n"]} \ No newline at end of file diff --git a/node_modules/signal-exit/dist/mjs/browser.d.ts b/node_modules/signal-exit/dist/mjs/browser.d.ts new file mode 100644 index 0000000..90f2e3f --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/browser.d.ts @@ -0,0 +1,12 @@ +/** + * This is a browser shim that provides the same functional interface + * as the main node export, but it does nothing. + * @module + */ +import type { Handler } from './index.js'; +export declare const onExit: (cb: Handler, opts: { + alwaysLast?: boolean; +}) => () => void; +export declare const load: () => void; +export declare const unload: () => void; +//# sourceMappingURL=browser.d.ts.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/mjs/browser.d.ts.map b/node_modules/signal-exit/dist/mjs/browser.d.ts.map new file mode 100644 index 0000000..aacc1d3 --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/browser.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACzC,eAAO,MAAM,MAAM,EAAE,CACnB,EAAE,EAAE,OAAO,EACX,IAAI,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,KAC3B,MAAM,IAAqB,CAAA;AAChC,eAAO,MAAM,IAAI,YAAW,CAAA;AAC5B,eAAO,MAAM,MAAM,YAAW,CAAA"} \ No newline at end of file diff --git a/node_modules/signal-exit/dist/mjs/browser.js b/node_modules/signal-exit/dist/mjs/browser.js new file mode 100644 index 0000000..9c5f9b9 --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/browser.js @@ -0,0 +1,4 @@ +export const onExit = () => () => { }; +export const load = () => { }; +export const unload = () => { }; +//# sourceMappingURL=browser.js.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/mjs/browser.js.map b/node_modules/signal-exit/dist/mjs/browser.js.map new file mode 100644 index 0000000..b3ff303 --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/browser.js.map @@ -0,0 +1 @@ +{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,MAAM,GAGD,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC,CAAA;AAChC,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;AAC5B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA","sourcesContent":["/**\n * This is a browser shim that provides the same functional interface\n * as the main node export, but it does nothing.\n * @module\n */\nimport type { Handler } from './index.js'\nexport const onExit: (\n cb: Handler,\n opts: { alwaysLast?: boolean }\n) => () => void = () => () => {}\nexport const load = () => {}\nexport const unload = () => {}\n"]} \ No newline at end of file diff --git a/node_modules/signal-exit/dist/mjs/index.d.ts b/node_modules/signal-exit/dist/mjs/index.d.ts new file mode 100644 index 0000000..cabe9cf --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/index.d.ts @@ -0,0 +1,48 @@ +/// +import { signals } from './signals.js'; +export { signals }; +/** + * A function that takes an exit code and signal as arguments + * + * In the case of signal exits *only*, a return value of true + * will indicate that the signal is being handled, and we should + * not synthetically exit with the signal we received. Regardless + * of the handler return value, the handler is unloaded when an + * otherwise fatal signal is received, so you get exactly 1 shot + * at it, unless you add another onExit handler at that point. + * + * In the case of numeric code exits, we may already have committed + * to exiting the process, for example via a fatal exception or + * unhandled promise rejection, so it is impossible to stop safely. + */ +export type Handler = (code: number | null | undefined, signal: NodeJS.Signals | null) => true | void; +export declare const +/** + * Called when the process is exiting, whether via signal, explicit + * exit, or running out of stuff to do. + * + * If the global process object is not suitable for instrumentation, + * then this will be a no-op. + * + * Returns a function that may be used to unload signal-exit. + */ +onExit: (cb: Handler, opts?: { + alwaysLast?: boolean | undefined; +} | undefined) => () => void, +/** + * Load the listeners. Likely you never need to call this, unless + * doing a rather deep integration with signal-exit functionality. + * Mostly exposed for the benefit of testing. + * + * @internal + */ +load: () => void, +/** + * Unload the listeners. Likely you never need to call this, unless + * doing a rather deep integration with signal-exit functionality. + * Mostly exposed for the benefit of testing. + * + * @internal + */ +unload: () => void; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/mjs/index.d.ts.map b/node_modules/signal-exit/dist/mjs/index.d.ts.map new file mode 100644 index 0000000..f84594e --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,CAAA;AAuBlB;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,OAAO,GAAG,CACpB,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,KAC1B,IAAI,GAAG,IAAI,CAAA;AA8QhB,eAAO;AACL;;;;;;;;GAQG;AACH,MAAM,OAzMO,OAAO;;wBAPiD,IAAI;AAkNzE;;;;;;GAMG;AACH,IAAI;AAEJ;;;;;;GAMG;AACH,MAAM,YAGP,CAAA"} \ No newline at end of file diff --git a/node_modules/signal-exit/dist/mjs/index.js b/node_modules/signal-exit/dist/mjs/index.js new file mode 100644 index 0000000..4a78bad --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/index.js @@ -0,0 +1,275 @@ +// Note: since nyc uses this module to output coverage, any lines +// that are in the direct sync flow of nyc's outputCoverage are +// ignored, since we can never get coverage for them. +// grab a reference to node's real process object right away +import { signals } from './signals.js'; +export { signals }; +const processOk = (process) => !!process && + typeof process === 'object' && + typeof process.removeListener === 'function' && + typeof process.emit === 'function' && + typeof process.reallyExit === 'function' && + typeof process.listeners === 'function' && + typeof process.kill === 'function' && + typeof process.pid === 'number' && + typeof process.on === 'function'; +const kExitEmitter = Symbol.for('signal-exit emitter'); +const global = globalThis; +const ObjectDefineProperty = Object.defineProperty.bind(Object); +// teeny special purpose ee +class Emitter { + emitted = { + afterExit: false, + exit: false, + }; + listeners = { + afterExit: [], + exit: [], + }; + count = 0; + id = Math.random(); + constructor() { + if (global[kExitEmitter]) { + return global[kExitEmitter]; + } + ObjectDefineProperty(global, kExitEmitter, { + value: this, + writable: false, + enumerable: false, + configurable: false, + }); + } + on(ev, fn) { + this.listeners[ev].push(fn); + } + removeListener(ev, fn) { + const list = this.listeners[ev]; + const i = list.indexOf(fn); + /* c8 ignore start */ + if (i === -1) { + return; + } + /* c8 ignore stop */ + if (i === 0 && list.length === 1) { + list.length = 0; + } + else { + list.splice(i, 1); + } + } + emit(ev, code, signal) { + if (this.emitted[ev]) { + return false; + } + this.emitted[ev] = true; + let ret = false; + for (const fn of this.listeners[ev]) { + ret = fn(code, signal) === true || ret; + } + if (ev === 'exit') { + ret = this.emit('afterExit', code, signal) || ret; + } + return ret; + } +} +class SignalExitBase { +} +const signalExitWrap = (handler) => { + return { + onExit(cb, opts) { + return handler.onExit(cb, opts); + }, + load() { + return handler.load(); + }, + unload() { + return handler.unload(); + }, + }; +}; +class SignalExitFallback extends SignalExitBase { + onExit() { + return () => { }; + } + load() { } + unload() { } +} +class SignalExit extends SignalExitBase { + // "SIGHUP" throws an `ENOSYS` error on Windows, + // so use a supported signal instead + /* c8 ignore start */ + #hupSig = process.platform === 'win32' ? 'SIGINT' : 'SIGHUP'; + /* c8 ignore stop */ + #emitter = new Emitter(); + #process; + #originalProcessEmit; + #originalProcessReallyExit; + #sigListeners = {}; + #loaded = false; + constructor(process) { + super(); + this.#process = process; + // { : , ... } + this.#sigListeners = {}; + for (const sig of signals) { + this.#sigListeners[sig] = () => { + // If there are no other listeners, an exit is coming! + // Simplest way: remove us and then re-send the signal. + // We know that this will kill the process, so we can + // safely emit now. + const listeners = this.#process.listeners(sig); + let { count } = this.#emitter; + // This is a workaround for the fact that signal-exit v3 and signal + // exit v4 are not aware of each other, and each will attempt to let + // the other handle it, so neither of them do. To correct this, we + // detect if we're the only handler *except* for previous versions + // of signal-exit, and increment by the count of listeners it has + // created. + /* c8 ignore start */ + const p = process; + if (typeof p.__signal_exit_emitter__ === 'object' && + typeof p.__signal_exit_emitter__.count === 'number') { + count += p.__signal_exit_emitter__.count; + } + /* c8 ignore stop */ + if (listeners.length === count) { + this.unload(); + const ret = this.#emitter.emit('exit', null, sig); + /* c8 ignore start */ + const s = sig === 'SIGHUP' ? this.#hupSig : sig; + if (!ret) + process.kill(process.pid, s); + /* c8 ignore stop */ + } + }; + } + this.#originalProcessReallyExit = process.reallyExit; + this.#originalProcessEmit = process.emit; + } + onExit(cb, opts) { + /* c8 ignore start */ + if (!processOk(this.#process)) { + return () => { }; + } + /* c8 ignore stop */ + if (this.#loaded === false) { + this.load(); + } + const ev = opts?.alwaysLast ? 'afterExit' : 'exit'; + this.#emitter.on(ev, cb); + return () => { + this.#emitter.removeListener(ev, cb); + if (this.#emitter.listeners['exit'].length === 0 && + this.#emitter.listeners['afterExit'].length === 0) { + this.unload(); + } + }; + } + load() { + if (this.#loaded) { + return; + } + this.#loaded = true; + // This is the number of onSignalExit's that are in play. + // It's important so that we can count the correct number of + // listeners on signals, and don't wait for the other one to + // handle it instead of us. + this.#emitter.count += 1; + for (const sig of signals) { + try { + const fn = this.#sigListeners[sig]; + if (fn) + this.#process.on(sig, fn); + } + catch (_) { } + } + this.#process.emit = (ev, ...a) => { + return this.#processEmit(ev, ...a); + }; + this.#process.reallyExit = (code) => { + return this.#processReallyExit(code); + }; + } + unload() { + if (!this.#loaded) { + return; + } + this.#loaded = false; + signals.forEach(sig => { + const listener = this.#sigListeners[sig]; + /* c8 ignore start */ + if (!listener) { + throw new Error('Listener not defined for signal: ' + sig); + } + /* c8 ignore stop */ + try { + this.#process.removeListener(sig, listener); + /* c8 ignore start */ + } + catch (_) { } + /* c8 ignore stop */ + }); + this.#process.emit = this.#originalProcessEmit; + this.#process.reallyExit = this.#originalProcessReallyExit; + this.#emitter.count -= 1; + } + #processReallyExit(code) { + /* c8 ignore start */ + if (!processOk(this.#process)) { + return 0; + } + this.#process.exitCode = code || 0; + /* c8 ignore stop */ + this.#emitter.emit('exit', this.#process.exitCode, null); + return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode); + } + #processEmit(ev, ...args) { + const og = this.#originalProcessEmit; + if (ev === 'exit' && processOk(this.#process)) { + if (typeof args[0] === 'number') { + this.#process.exitCode = args[0]; + /* c8 ignore start */ + } + /* c8 ignore start */ + const ret = og.call(this.#process, ev, ...args); + /* c8 ignore start */ + this.#emitter.emit('exit', this.#process.exitCode, null); + /* c8 ignore stop */ + return ret; + } + else { + return og.call(this.#process, ev, ...args); + } + } +} +const process = globalThis.process; +// wrap so that we call the method on the actual handler, without +// exporting it directly. +export const { +/** + * Called when the process is exiting, whether via signal, explicit + * exit, or running out of stuff to do. + * + * If the global process object is not suitable for instrumentation, + * then this will be a no-op. + * + * Returns a function that may be used to unload signal-exit. + */ +onExit, +/** + * Load the listeners. Likely you never need to call this, unless + * doing a rather deep integration with signal-exit functionality. + * Mostly exposed for the benefit of testing. + * + * @internal + */ +load, +/** + * Unload the listeners. Likely you never need to call this, unless + * doing a rather deep integration with signal-exit functionality. + * Mostly exposed for the benefit of testing. + * + * @internal + */ +unload, } = signalExitWrap(processOk(process) ? new SignalExit(process) : new SignalExitFallback()); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/mjs/index.js.map b/node_modules/signal-exit/dist/mjs/index.js.map new file mode 100644 index 0000000..3a7b76d --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,+DAA+D;AAC/D,qDAAqD;AACrD,4DAA4D;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,CAAA;AAQlB,MAAM,SAAS,GAAG,CAAC,OAAY,EAAwB,EAAE,CACvD,CAAC,CAAC,OAAO;IACT,OAAO,OAAO,KAAK,QAAQ;IAC3B,OAAO,OAAO,CAAC,cAAc,KAAK,UAAU;IAC5C,OAAO,OAAO,CAAC,IAAI,KAAK,UAAU;IAClC,OAAO,OAAO,CAAC,UAAU,KAAK,UAAU;IACxC,OAAO,OAAO,CAAC,SAAS,KAAK,UAAU;IACvC,OAAO,OAAO,CAAC,IAAI,KAAK,UAAU;IAClC,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ;IAC/B,OAAO,OAAO,CAAC,EAAE,KAAK,UAAU,CAAA;AAElC,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAA;AACtD,MAAM,MAAM,GAAqD,UAAU,CAAA;AAC3E,MAAM,oBAAoB,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;AAwB/D,2BAA2B;AAC3B,MAAM,OAAO;IACX,OAAO,GAAY;QACjB,SAAS,EAAE,KAAK;QAChB,IAAI,EAAE,KAAK;KACZ,CAAA;IAED,SAAS,GAAc;QACrB,SAAS,EAAE,EAAE;QACb,IAAI,EAAE,EAAE;KACT,CAAA;IAED,KAAK,GAAW,CAAC,CAAA;IACjB,EAAE,GAAW,IAAI,CAAC,MAAM,EAAE,CAAA;IAE1B;QACE,IAAI,MAAM,CAAC,YAAY,CAAC,EAAE;YACxB,OAAO,MAAM,CAAC,YAAY,CAAC,CAAA;SAC5B;QACD,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE;YACzC,KAAK,EAAE,IAAI;YACX,QAAQ,EAAE,KAAK;YACf,UAAU,EAAE,KAAK;YACjB,YAAY,EAAE,KAAK;SACpB,CAAC,CAAA;IACJ,CAAC;IAED,EAAE,CAAC,EAAa,EAAE,EAAW;QAC3B,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC7B,CAAC;IAED,cAAc,CAAC,EAAa,EAAE,EAAW;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;QAC/B,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAC1B,qBAAqB;QACrB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;YACZ,OAAM;SACP;QACD,oBAAoB;QACpB,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;YAChC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAA;SAChB;aAAM;YACL,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;SAClB;IACH,CAAC;IAED,IAAI,CACF,EAAa,EACb,IAA+B,EAC/B,MAA6B;QAE7B,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;YACpB,OAAO,KAAK,CAAA;SACb;QACD,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,CAAA;QACvB,IAAI,GAAG,GAAY,KAAK,CAAA;QACxB,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE;YACnC,GAAG,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,IAAI,IAAI,GAAG,CAAA;SACvC;QACD,IAAI,EAAE,KAAK,MAAM,EAAE;YACjB,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,CAAA;SAClD;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;CACF;AAED,MAAe,cAAc;CAI5B;AAED,MAAM,cAAc,GAAG,CAA2B,OAAU,EAAE,EAAE;IAC9D,OAAO;QACL,MAAM,CAAC,EAAW,EAAE,IAA+B;YACjD,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;QACjC,CAAC;QACD,IAAI;YACF,OAAO,OAAO,CAAC,IAAI,EAAE,CAAA;QACvB,CAAC;QACD,MAAM;YACJ,OAAO,OAAO,CAAC,MAAM,EAAE,CAAA;QACzB,CAAC;KACF,CAAA;AACH,CAAC,CAAA;AAED,MAAM,kBAAmB,SAAQ,cAAc;IAC7C,MAAM;QACJ,OAAO,GAAG,EAAE,GAAE,CAAC,CAAA;IACjB,CAAC;IACD,IAAI,KAAI,CAAC;IACT,MAAM,KAAI,CAAC;CACZ;AAED,MAAM,UAAW,SAAQ,cAAc;IACrC,gDAAgD;IAChD,oCAAoC;IACpC,qBAAqB;IACrB,OAAO,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAA;IAC5D,oBAAoB;IACpB,QAAQ,GAAG,IAAI,OAAO,EAAE,CAAA;IACxB,QAAQ,CAAW;IACnB,oBAAoB,CAAmB;IACvC,0BAA0B,CAAyB;IAEnD,aAAa,GAA2C,EAAE,CAAA;IAC1D,OAAO,GAAY,KAAK,CAAA;IAExB,YAAY,OAAkB;QAC5B,KAAK,EAAE,CAAA;QACP,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAA;QACvB,mCAAmC;QACnC,IAAI,CAAC,aAAa,GAAG,EAAE,CAAA;QACvB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE;YACzB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE;gBAC7B,sDAAsD;gBACtD,uDAAuD;gBACvD,qDAAqD;gBACrD,mBAAmB;gBACnB,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;gBAC9C,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAA;gBAC7B,mEAAmE;gBACnE,oEAAoE;gBACpE,kEAAkE;gBAClE,kEAAkE;gBAClE,iEAAiE;gBACjE,WAAW;gBACX,qBAAqB;gBACrB,MAAM,CAAC,GAAG,OAET,CAAA;gBACD,IACE,OAAO,CAAC,CAAC,uBAAuB,KAAK,QAAQ;oBAC7C,OAAO,CAAC,CAAC,uBAAuB,CAAC,KAAK,KAAK,QAAQ,EACnD;oBACA,KAAK,IAAI,CAAC,CAAC,uBAAuB,CAAC,KAAK,CAAA;iBACzC;gBACD,oBAAoB;gBACpB,IAAI,SAAS,CAAC,MAAM,KAAK,KAAK,EAAE;oBAC9B,IAAI,CAAC,MAAM,EAAE,CAAA;oBACb,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;oBACjD,qBAAqB;oBACrB,MAAM,CAAC,GAAG,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAA;oBAC/C,IAAI,CAAC,GAAG;wBAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;oBACtC,oBAAoB;iBACrB;YACH,CAAC,CAAA;SACF;QAED,IAAI,CAAC,0BAA0B,GAAG,OAAO,CAAC,UAAU,CAAA;QACpD,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAA;IAC1C,CAAC;IAED,MAAM,CAAC,EAAW,EAAE,IAA+B;QACjD,qBAAqB;QACrB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;YAC7B,OAAO,GAAG,EAAE,GAAE,CAAC,CAAA;SAChB;QACD,oBAAoB;QAEpB,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,EAAE;YAC1B,IAAI,CAAC,IAAI,EAAE,CAAA;SACZ;QAED,MAAM,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAA;QAClD,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;QACxB,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;YACpC,IACE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC;gBAC5C,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,EACjD;gBACA,IAAI,CAAC,MAAM,EAAE,CAAA;aACd;QACH,CAAC,CAAA;IACH,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,OAAM;SACP;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QAEnB,yDAAyD;QACzD,4DAA4D;QAC5D,4DAA4D;QAC5D,2BAA2B;QAC3B,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAA;QAExB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE;YACzB,IAAI;gBACF,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;gBAClC,IAAI,EAAE;oBAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;aAClC;YAAC,OAAO,CAAC,EAAE,GAAE;SACf;QAED,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAU,EAAE,GAAG,CAAQ,EAAE,EAAE;YAC/C,OAAO,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAA;QACpC,CAAC,CAAA;QACD,IAAI,CAAC,QAAQ,CAAC,UAAU,GAAG,CAAC,IAAgC,EAAE,EAAE;YAC9D,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAA;QACtC,CAAC,CAAA;IACH,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,OAAM;SACP;QACD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QAEpB,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;YACxC,qBAAqB;YACrB,IAAI,CAAC,QAAQ,EAAE;gBACb,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,GAAG,CAAC,CAAA;aAC3D;YACD,oBAAoB;YACpB,IAAI;gBACF,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;gBAC3C,qBAAqB;aACtB;YAAC,OAAO,CAAC,EAAE,GAAE;YACd,oBAAoB;QACtB,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,oBAAoB,CAAA;QAC9C,IAAI,CAAC,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC,0BAA0B,CAAA;QAC1D,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAA;IAC1B,CAAC;IAED,kBAAkB,CAAC,IAAgC;QACjD,qBAAqB;QACrB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;YAC7B,OAAO,CAAC,CAAA;SACT;QACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,GAAG,IAAI,IAAI,CAAC,CAAA;QAClC,oBAAoB;QAEpB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;QACxD,OAAO,IAAI,CAAC,0BAA0B,CAAC,IAAI,CACzC,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,QAAQ,CAAC,QAAQ,CACvB,CAAA;IACH,CAAC;IAED,YAAY,CAAC,EAAU,EAAE,GAAG,IAAW;QACrC,MAAM,EAAE,GAAG,IAAI,CAAC,oBAAoB,CAAA;QACpC,IAAI,EAAE,KAAK,MAAM,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;YAC7C,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;gBAC/B,IAAI,CAAC,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;gBAChC,qBAAqB;aACtB;YACD,qBAAqB;YACrB,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,CAAA;YAC/C,qBAAqB;YACrB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;YACxD,oBAAoB;YACpB,OAAO,GAAG,CAAA;SACX;aAAM;YACL,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,CAAA;SAC3C;IACH,CAAC;CACF;AAED,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAA;AAClC,iEAAiE;AACjE,yBAAyB;AACzB,MAAM,CAAC,MAAM;AACX;;;;;;;;GAQG;AACH,MAAM;AAEN;;;;;;GAMG;AACH,IAAI;AAEJ;;;;;;GAMG;AACH,MAAM,GACP,GAAG,cAAc,CAChB,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,kBAAkB,EAAE,CACxE,CAAA","sourcesContent":["// Note: since nyc uses this module to output coverage, any lines\n// that are in the direct sync flow of nyc's outputCoverage are\n// ignored, since we can never get coverage for them.\n// grab a reference to node's real process object right away\nimport { signals } from './signals.js'\nexport { signals }\n\n// just a loosened process type so we can do some evil things\ntype ProcessRE = NodeJS.Process & {\n reallyExit: (code?: number | undefined | null) => any\n emit: (ev: string, ...a: any[]) => any\n}\n\nconst processOk = (process: any): process is ProcessRE =>\n !!process &&\n typeof process === 'object' &&\n typeof process.removeListener === 'function' &&\n typeof process.emit === 'function' &&\n typeof process.reallyExit === 'function' &&\n typeof process.listeners === 'function' &&\n typeof process.kill === 'function' &&\n typeof process.pid === 'number' &&\n typeof process.on === 'function'\n\nconst kExitEmitter = Symbol.for('signal-exit emitter')\nconst global: typeof globalThis & { [kExitEmitter]?: Emitter } = globalThis\nconst ObjectDefineProperty = Object.defineProperty.bind(Object)\n\n/**\n * A function that takes an exit code and signal as arguments\n *\n * In the case of signal exits *only*, a return value of true\n * will indicate that the signal is being handled, and we should\n * not synthetically exit with the signal we received. Regardless\n * of the handler return value, the handler is unloaded when an\n * otherwise fatal signal is received, so you get exactly 1 shot\n * at it, unless you add another onExit handler at that point.\n *\n * In the case of numeric code exits, we may already have committed\n * to exiting the process, for example via a fatal exception or\n * unhandled promise rejection, so it is impossible to stop safely.\n */\nexport type Handler = (\n code: number | null | undefined,\n signal: NodeJS.Signals | null\n) => true | void\ntype ExitEvent = 'afterExit' | 'exit'\ntype Emitted = { [k in ExitEvent]: boolean }\ntype Listeners = { [k in ExitEvent]: Handler[] }\n\n// teeny special purpose ee\nclass Emitter {\n emitted: Emitted = {\n afterExit: false,\n exit: false,\n }\n\n listeners: Listeners = {\n afterExit: [],\n exit: [],\n }\n\n count: number = 0\n id: number = Math.random()\n\n constructor() {\n if (global[kExitEmitter]) {\n return global[kExitEmitter]\n }\n ObjectDefineProperty(global, kExitEmitter, {\n value: this,\n writable: false,\n enumerable: false,\n configurable: false,\n })\n }\n\n on(ev: ExitEvent, fn: Handler) {\n this.listeners[ev].push(fn)\n }\n\n removeListener(ev: ExitEvent, fn: Handler) {\n const list = this.listeners[ev]\n const i = list.indexOf(fn)\n /* c8 ignore start */\n if (i === -1) {\n return\n }\n /* c8 ignore stop */\n if (i === 0 && list.length === 1) {\n list.length = 0\n } else {\n list.splice(i, 1)\n }\n }\n\n emit(\n ev: ExitEvent,\n code: number | null | undefined,\n signal: NodeJS.Signals | null\n ): boolean {\n if (this.emitted[ev]) {\n return false\n }\n this.emitted[ev] = true\n let ret: boolean = false\n for (const fn of this.listeners[ev]) {\n ret = fn(code, signal) === true || ret\n }\n if (ev === 'exit') {\n ret = this.emit('afterExit', code, signal) || ret\n }\n return ret\n }\n}\n\nabstract class SignalExitBase {\n abstract onExit(cb: Handler, opts?: { alwaysLast?: boolean }): () => void\n abstract load(): void\n abstract unload(): void\n}\n\nconst signalExitWrap = (handler: T) => {\n return {\n onExit(cb: Handler, opts?: { alwaysLast?: boolean }) {\n return handler.onExit(cb, opts)\n },\n load() {\n return handler.load()\n },\n unload() {\n return handler.unload()\n },\n }\n}\n\nclass SignalExitFallback extends SignalExitBase {\n onExit() {\n return () => {}\n }\n load() {}\n unload() {}\n}\n\nclass SignalExit extends SignalExitBase {\n // \"SIGHUP\" throws an `ENOSYS` error on Windows,\n // so use a supported signal instead\n /* c8 ignore start */\n #hupSig = process.platform === 'win32' ? 'SIGINT' : 'SIGHUP'\n /* c8 ignore stop */\n #emitter = new Emitter()\n #process: ProcessRE\n #originalProcessEmit: ProcessRE['emit']\n #originalProcessReallyExit: ProcessRE['reallyExit']\n\n #sigListeners: { [k in NodeJS.Signals]?: () => void } = {}\n #loaded: boolean = false\n\n constructor(process: ProcessRE) {\n super()\n this.#process = process\n // { : , ... }\n this.#sigListeners = {}\n for (const sig of signals) {\n this.#sigListeners[sig] = () => {\n // If there are no other listeners, an exit is coming!\n // Simplest way: remove us and then re-send the signal.\n // We know that this will kill the process, so we can\n // safely emit now.\n const listeners = this.#process.listeners(sig)\n let { count } = this.#emitter\n // This is a workaround for the fact that signal-exit v3 and signal\n // exit v4 are not aware of each other, and each will attempt to let\n // the other handle it, so neither of them do. To correct this, we\n // detect if we're the only handler *except* for previous versions\n // of signal-exit, and increment by the count of listeners it has\n // created.\n /* c8 ignore start */\n const p = process as unknown as {\n __signal_exit_emitter__?: { count: number }\n }\n if (\n typeof p.__signal_exit_emitter__ === 'object' &&\n typeof p.__signal_exit_emitter__.count === 'number'\n ) {\n count += p.__signal_exit_emitter__.count\n }\n /* c8 ignore stop */\n if (listeners.length === count) {\n this.unload()\n const ret = this.#emitter.emit('exit', null, sig)\n /* c8 ignore start */\n const s = sig === 'SIGHUP' ? this.#hupSig : sig\n if (!ret) process.kill(process.pid, s)\n /* c8 ignore stop */\n }\n }\n }\n\n this.#originalProcessReallyExit = process.reallyExit\n this.#originalProcessEmit = process.emit\n }\n\n onExit(cb: Handler, opts?: { alwaysLast?: boolean }) {\n /* c8 ignore start */\n if (!processOk(this.#process)) {\n return () => {}\n }\n /* c8 ignore stop */\n\n if (this.#loaded === false) {\n this.load()\n }\n\n const ev = opts?.alwaysLast ? 'afterExit' : 'exit'\n this.#emitter.on(ev, cb)\n return () => {\n this.#emitter.removeListener(ev, cb)\n if (\n this.#emitter.listeners['exit'].length === 0 &&\n this.#emitter.listeners['afterExit'].length === 0\n ) {\n this.unload()\n }\n }\n }\n\n load() {\n if (this.#loaded) {\n return\n }\n this.#loaded = true\n\n // This is the number of onSignalExit's that are in play.\n // It's important so that we can count the correct number of\n // listeners on signals, and don't wait for the other one to\n // handle it instead of us.\n this.#emitter.count += 1\n\n for (const sig of signals) {\n try {\n const fn = this.#sigListeners[sig]\n if (fn) this.#process.on(sig, fn)\n } catch (_) {}\n }\n\n this.#process.emit = (ev: string, ...a: any[]) => {\n return this.#processEmit(ev, ...a)\n }\n this.#process.reallyExit = (code?: number | null | undefined) => {\n return this.#processReallyExit(code)\n }\n }\n\n unload() {\n if (!this.#loaded) {\n return\n }\n this.#loaded = false\n\n signals.forEach(sig => {\n const listener = this.#sigListeners[sig]\n /* c8 ignore start */\n if (!listener) {\n throw new Error('Listener not defined for signal: ' + sig)\n }\n /* c8 ignore stop */\n try {\n this.#process.removeListener(sig, listener)\n /* c8 ignore start */\n } catch (_) {}\n /* c8 ignore stop */\n })\n this.#process.emit = this.#originalProcessEmit\n this.#process.reallyExit = this.#originalProcessReallyExit\n this.#emitter.count -= 1\n }\n\n #processReallyExit(code?: number | null | undefined) {\n /* c8 ignore start */\n if (!processOk(this.#process)) {\n return 0\n }\n this.#process.exitCode = code || 0\n /* c8 ignore stop */\n\n this.#emitter.emit('exit', this.#process.exitCode, null)\n return this.#originalProcessReallyExit.call(\n this.#process,\n this.#process.exitCode\n )\n }\n\n #processEmit(ev: string, ...args: any[]): any {\n const og = this.#originalProcessEmit\n if (ev === 'exit' && processOk(this.#process)) {\n if (typeof args[0] === 'number') {\n this.#process.exitCode = args[0]\n /* c8 ignore start */\n }\n /* c8 ignore start */\n const ret = og.call(this.#process, ev, ...args)\n /* c8 ignore start */\n this.#emitter.emit('exit', this.#process.exitCode, null)\n /* c8 ignore stop */\n return ret\n } else {\n return og.call(this.#process, ev, ...args)\n }\n }\n}\n\nconst process = globalThis.process\n// wrap so that we call the method on the actual handler, without\n// exporting it directly.\nexport const {\n /**\n * Called when the process is exiting, whether via signal, explicit\n * exit, or running out of stuff to do.\n *\n * If the global process object is not suitable for instrumentation,\n * then this will be a no-op.\n *\n * Returns a function that may be used to unload signal-exit.\n */\n onExit,\n\n /**\n * Load the listeners. Likely you never need to call this, unless\n * doing a rather deep integration with signal-exit functionality.\n * Mostly exposed for the benefit of testing.\n *\n * @internal\n */\n load,\n\n /**\n * Unload the listeners. Likely you never need to call this, unless\n * doing a rather deep integration with signal-exit functionality.\n * Mostly exposed for the benefit of testing.\n *\n * @internal\n */\n unload,\n} = signalExitWrap(\n processOk(process) ? new SignalExit(process) : new SignalExitFallback()\n)\n"]} \ No newline at end of file diff --git a/node_modules/signal-exit/dist/mjs/package.json b/node_modules/signal-exit/dist/mjs/package.json new file mode 100644 index 0000000..3dbc1ca --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/signal-exit/dist/mjs/signals.d.ts b/node_modules/signal-exit/dist/mjs/signals.d.ts new file mode 100644 index 0000000..3f01ef0 --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/signals.d.ts @@ -0,0 +1,29 @@ +/// +/** + * This is not the set of all possible signals. + * + * It IS, however, the set of all signals that trigger + * an exit on either Linux or BSD systems. Linux is a + * superset of the signal names supported on BSD, and + * the unknown signals just fail to register, so we can + * catch that easily enough. + * + * Windows signals are a different set, since there are + * signals that terminate Windows processes, but don't + * terminate (or don't even exist) on Posix systems. + * + * Don't bother with SIGKILL. It's uncatchable, which + * means that we can't fire any callbacks anyway. + * + * If a user does happen to register a handler on a non- + * fatal signal like SIGWINCH or something, and then + * exit, it'll end up firing `process.emit('exit')`, so + * the handler will be fired anyway. + * + * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised + * artificially, inherently leave the process in a + * state from which it is not safe to try and enter JS + * listeners. + */ +export declare const signals: NodeJS.Signals[]; +//# sourceMappingURL=signals.d.ts.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/mjs/signals.d.ts.map b/node_modules/signal-exit/dist/mjs/signals.d.ts.map new file mode 100644 index 0000000..891fe1e --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/signals.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../src/signals.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,OAAO,EAAO,CAAA"} \ No newline at end of file diff --git a/node_modules/signal-exit/dist/mjs/signals.js b/node_modules/signal-exit/dist/mjs/signals.js new file mode 100644 index 0000000..7dbf15a --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/signals.js @@ -0,0 +1,39 @@ +/** + * This is not the set of all possible signals. + * + * It IS, however, the set of all signals that trigger + * an exit on either Linux or BSD systems. Linux is a + * superset of the signal names supported on BSD, and + * the unknown signals just fail to register, so we can + * catch that easily enough. + * + * Windows signals are a different set, since there are + * signals that terminate Windows processes, but don't + * terminate (or don't even exist) on Posix systems. + * + * Don't bother with SIGKILL. It's uncatchable, which + * means that we can't fire any callbacks anyway. + * + * If a user does happen to register a handler on a non- + * fatal signal like SIGWINCH or something, and then + * exit, it'll end up firing `process.emit('exit')`, so + * the handler will be fired anyway. + * + * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised + * artificially, inherently leave the process in a + * state from which it is not safe to try and enter JS + * listeners. + */ +export const signals = []; +signals.push('SIGHUP', 'SIGINT', 'SIGTERM'); +if (process.platform !== 'win32') { + signals.push('SIGALRM', 'SIGABRT', 'SIGVTALRM', 'SIGXCPU', 'SIGXFSZ', 'SIGUSR2', 'SIGTRAP', 'SIGSYS', 'SIGQUIT', 'SIGIOT' + // should detect profiler and enable/disable accordingly. + // see #21 + // 'SIGPROF' + ); +} +if (process.platform === 'linux') { + signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT'); +} +//# sourceMappingURL=signals.js.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/mjs/signals.js.map b/node_modules/signal-exit/dist/mjs/signals.js.map new file mode 100644 index 0000000..91008c9 --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/signals.js.map @@ -0,0 +1 @@ +{"version":3,"file":"signals.js","sourceRoot":"","sources":["../../src/signals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,MAAM,OAAO,GAAqB,EAAE,CAAA;AAC3C,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAA;AAE3C,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE;IAChC,OAAO,CAAC,IAAI,CACV,SAAS,EACT,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,QAAQ,EACR,SAAS,EACT,QAAQ;IACR,yDAAyD;IACzD,UAAU;IACV,YAAY;KACb,CAAA;CACF;AAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE;IAChC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAA;CACxD","sourcesContent":["/**\n * This is not the set of all possible signals.\n *\n * It IS, however, the set of all signals that trigger\n * an exit on either Linux or BSD systems. Linux is a\n * superset of the signal names supported on BSD, and\n * the unknown signals just fail to register, so we can\n * catch that easily enough.\n *\n * Windows signals are a different set, since there are\n * signals that terminate Windows processes, but don't\n * terminate (or don't even exist) on Posix systems.\n *\n * Don't bother with SIGKILL. It's uncatchable, which\n * means that we can't fire any callbacks anyway.\n *\n * If a user does happen to register a handler on a non-\n * fatal signal like SIGWINCH or something, and then\n * exit, it'll end up firing `process.emit('exit')`, so\n * the handler will be fired anyway.\n *\n * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised\n * artificially, inherently leave the process in a\n * state from which it is not safe to try and enter JS\n * listeners.\n */\nexport const signals: NodeJS.Signals[] = []\nsignals.push('SIGHUP', 'SIGINT', 'SIGTERM')\n\nif (process.platform !== 'win32') {\n signals.push(\n 'SIGALRM',\n 'SIGABRT',\n 'SIGVTALRM',\n 'SIGXCPU',\n 'SIGXFSZ',\n 'SIGUSR2',\n 'SIGTRAP',\n 'SIGSYS',\n 'SIGQUIT',\n 'SIGIOT'\n // should detect profiler and enable/disable accordingly.\n // see #21\n // 'SIGPROF'\n )\n}\n\nif (process.platform === 'linux') {\n signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT')\n}\n"]} \ No newline at end of file diff --git a/node_modules/signal-exit/package.json b/node_modules/signal-exit/package.json new file mode 100644 index 0000000..ac176ce --- /dev/null +++ b/node_modules/signal-exit/package.json @@ -0,0 +1,106 @@ +{ + "name": "signal-exit", + "version": "4.1.0", + "description": "when you want to fire an event no matter how a process exits.", + "main": "./dist/cjs/index.js", + "module": "./dist/mjs/index.js", + "browser": "./dist/mjs/browser.js", + "types": "./dist/mjs/index.d.ts", + "exports": { + ".": { + "import": { + "types": "./dist/mjs/index.d.ts", + "default": "./dist/mjs/index.js" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + }, + "./signals": { + "import": { + "types": "./dist/mjs/signals.d.ts", + "default": "./dist/mjs/signals.js" + }, + "require": { + "types": "./dist/cjs/signals.d.ts", + "default": "./dist/cjs/signals.js" + } + }, + "./browser": { + "import": { + "types": "./dist/mjs/browser.d.ts", + "default": "./dist/mjs/browser.js" + }, + "require": { + "types": "./dist/cjs/browser.d.ts", + "default": "./dist/cjs/browser.js" + } + } + }, + "files": [ + "dist" + ], + "engines": { + "node": ">=14" + }, + "repository": { + "type": "git", + "url": "https://github.com/tapjs/signal-exit.git" + }, + "keywords": [ + "signal", + "exit" + ], + "author": "Ben Coe ", + "license": "ISC", + "devDependencies": { + "@types/cross-spawn": "^6.0.2", + "@types/node": "^18.15.11", + "@types/signal-exit": "^3.0.1", + "@types/tap": "^15.0.8", + "c8": "^7.13.0", + "prettier": "^2.8.6", + "tap": "^16.3.4", + "ts-node": "^10.9.1", + "typedoc": "^0.23.28", + "typescript": "^5.0.2" + }, + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "preprepare": "rm -rf dist", + "prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json && bash ./scripts/fixup.sh", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "c8 tap", + "snap": "c8 tap", + "format": "prettier --write . --loglevel warn", + "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts" + }, + "prettier": { + "semi": false, + "printWidth": 75, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" + }, + "tap": { + "coverage": false, + "jobs": 1, + "node-arg": [ + "--no-warnings", + "--loader", + "ts-node/esm" + ], + "ts": false + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } +} diff --git a/node_modules/supports-color/browser.js b/node_modules/supports-color/browser.js new file mode 100644 index 0000000..62afa3a --- /dev/null +++ b/node_modules/supports-color/browser.js @@ -0,0 +1,5 @@ +'use strict'; +module.exports = { + stdout: false, + stderr: false +}; diff --git a/node_modules/supports-color/index.js b/node_modules/supports-color/index.js new file mode 100644 index 0000000..6fada39 --- /dev/null +++ b/node_modules/supports-color/index.js @@ -0,0 +1,135 @@ +'use strict'; +const os = require('os'); +const tty = require('tty'); +const hasFlag = require('has-flag'); + +const {env} = process; + +let forceColor; +if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false') || + hasFlag('color=never')) { + forceColor = 0; +} else if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + forceColor = 1; +} + +if ('FORCE_COLOR' in env) { + if (env.FORCE_COLOR === 'true') { + forceColor = 1; + } else if (env.FORCE_COLOR === 'false') { + forceColor = 0; + } else { + forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3); + } +} + +function translateLevel(level) { + if (level === 0) { + return false; + } + + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; +} + +function supportsColor(haveStream, streamIsTTY) { + if (forceColor === 0) { + return 0; + } + + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } + + if (hasFlag('color=256')) { + return 2; + } + + if (haveStream && !streamIsTTY && forceColor === undefined) { + return 0; + } + + const min = forceColor || 0; + + if (env.TERM === 'dumb') { + return min; + } + + if (process.platform === 'win32') { + // Windows 10 build 10586 is the first Windows release that supports 256 colors. + // Windows 10 build 14931 is the first release that supports 16m/TrueColor. + const osRelease = os.release().split('.'); + if ( + Number(osRelease[0]) >= 10 && + Number(osRelease[2]) >= 10586 + ) { + return Number(osRelease[2]) >= 14931 ? 3 : 2; + } + + return 1; + } + + if ('CI' in env) { + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } + + return min; + } + + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } + + if (env.COLORTERM === 'truecolor') { + return 3; + } + + if ('TERM_PROGRAM' in env) { + const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + + switch (env.TERM_PROGRAM) { + case 'iTerm.app': + return version >= 3 ? 3 : 2; + case 'Apple_Terminal': + return 2; + // No default + } + } + + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } + + if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } + + if ('COLORTERM' in env) { + return 1; + } + + return min; +} + +function getSupportLevel(stream) { + const level = supportsColor(stream, stream && stream.isTTY); + return translateLevel(level); +} + +module.exports = { + supportsColor: getSupportLevel, + stdout: translateLevel(supportsColor(true, tty.isatty(1))), + stderr: translateLevel(supportsColor(true, tty.isatty(2))) +}; diff --git a/node_modules/supports-color/license b/node_modules/supports-color/license new file mode 100644 index 0000000..e7af2f7 --- /dev/null +++ b/node_modules/supports-color/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +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/node_modules/supports-color/package.json b/node_modules/supports-color/package.json new file mode 100644 index 0000000..f7182ed --- /dev/null +++ b/node_modules/supports-color/package.json @@ -0,0 +1,53 @@ +{ + "name": "supports-color", + "version": "7.2.0", + "description": "Detect whether a terminal supports color", + "license": "MIT", + "repository": "chalk/supports-color", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "engines": { + "node": ">=8" + }, + "scripts": { + "test": "xo && ava" + }, + "files": [ + "index.js", + "browser.js" + ], + "keywords": [ + "color", + "colour", + "colors", + "terminal", + "console", + "cli", + "ansi", + "styles", + "tty", + "rgb", + "256", + "shell", + "xterm", + "command-line", + "support", + "supports", + "capability", + "detect", + "truecolor", + "16m" + ], + "dependencies": { + "has-flag": "^4.0.0" + }, + "devDependencies": { + "ava": "^1.4.1", + "import-fresh": "^3.0.0", + "xo": "^0.24.0" + }, + "browser": "browser.js" +} diff --git a/node_modules/supports-color/readme.md b/node_modules/supports-color/readme.md new file mode 100644 index 0000000..3654228 --- /dev/null +++ b/node_modules/supports-color/readme.md @@ -0,0 +1,76 @@ +# supports-color [![Build Status](https://travis-ci.org/chalk/supports-color.svg?branch=master)](https://travis-ci.org/chalk/supports-color) + +> Detect whether a terminal supports color + + +## Install + +``` +$ npm install supports-color +``` + + +## Usage + +```js +const supportsColor = require('supports-color'); + +if (supportsColor.stdout) { + console.log('Terminal stdout supports color'); +} + +if (supportsColor.stdout.has256) { + console.log('Terminal stdout supports 256 colors'); +} + +if (supportsColor.stderr.has16m) { + console.log('Terminal stderr supports 16 million colors (truecolor)'); +} +``` + + +## API + +Returns an `Object` with a `stdout` and `stderr` property for testing either streams. Each property is an `Object`, or `false` if color is not supported. + +The `stdout`/`stderr` objects specifies a level of support for color through a `.level` property and a corresponding flag: + +- `.level = 1` and `.hasBasic = true`: Basic color support (16 colors) +- `.level = 2` and `.has256 = true`: 256 color support +- `.level = 3` and `.has16m = true`: Truecolor support (16 million colors) + + +## Info + +It obeys the `--color` and `--no-color` CLI flags. + +For situations where using `--color` is not possible, use the environment variable `FORCE_COLOR=1` (level 1), `FORCE_COLOR=2` (level 2), or `FORCE_COLOR=3` (level 3) to forcefully enable color, or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks. + +Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively. + + +## Related + +- [supports-color-cli](https://github.com/chalk/supports-color-cli) - CLI for this module +- [chalk](https://github.com/chalk/chalk) - Terminal string styling done right + + +## Maintainers + +- [Sindre Sorhus](https://github.com/sindresorhus) +- [Josh Junon](https://github.com/qix-) + + +--- + +
+ + Get professional support for this package with a Tidelift subscription + +
+ + Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. +
+
+ +--- diff --git a/node_modules/which/CHANGELOG.md b/node_modules/which/CHANGELOG.md new file mode 100644 index 0000000..7fb1f20 --- /dev/null +++ b/node_modules/which/CHANGELOG.md @@ -0,0 +1,166 @@ +# Changes + + +## 2.0.2 + +* Rename bin to `node-which` + +## 2.0.1 + +* generate changelog and publish on version bump +* enforce 100% test coverage +* Promise interface + +## 2.0.0 + +* Parallel tests, modern JavaScript, and drop support for node < 8 + +## 1.3.1 + +* update deps +* update travis + +## v1.3.0 + +* Add nothrow option to which.sync +* update tap + +## v1.2.14 + +* appveyor: drop node 5 and 0.x +* travis-ci: add node 6, drop 0.x + +## v1.2.13 + +* test: Pass missing option to pass on windows +* update tap +* update isexe to 2.0.0 +* neveragain.tech pledge request + +## v1.2.12 + +* Removed unused require + +## v1.2.11 + +* Prevent changelog script from being included in package + +## v1.2.10 + +* Use env.PATH only, not env.Path + +## v1.2.9 + +* fix for paths starting with ../ +* Remove unused `is-absolute` module + +## v1.2.8 + +* bullet items in changelog that contain (but don't start with) # + +## v1.2.7 + +* strip 'update changelog' changelog entries out of changelog + +## v1.2.6 + +* make the changelog bulleted + +## v1.2.5 + +* make a changelog, and keep it up to date +* don't include tests in package +* Properly handle relative-path executables +* appveyor +* Attach error code to Not Found error +* Make tests pass on Windows + +## v1.2.4 + +* Fix typo + +## v1.2.3 + +* update isexe, fix regression in pathExt handling + +## v1.2.2 + +* update deps, use isexe module, test windows + +## v1.2.1 + +* Sometimes windows PATH entries are quoted +* Fixed a bug in the check for group and user mode bits. This bug was introduced during refactoring for supporting strict mode. +* doc cli + +## v1.2.0 + +* Add support for opt.all and -as cli flags +* test the bin +* update travis +* Allow checking for multiple programs in bin/which +* tap 2 + +## v1.1.2 + +* travis +* Refactored and fixed undefined error on Windows +* Support strict mode + +## v1.1.1 + +* test +g exes against secondary groups, if available +* Use windows exe semantics on cygwin & msys +* cwd should be first in path on win32, not last +* Handle lower-case 'env.Path' on Windows +* Update docs +* use single-quotes + +## v1.1.0 + +* Add tests, depend on is-absolute + +## v1.0.9 + +* which.js: root is allowed to execute files owned by anyone + +## v1.0.8 + +* don't use graceful-fs + +## v1.0.7 + +* add license to package.json + +## v1.0.6 + +* isc license + +## 1.0.5 + +* Awful typo + +## 1.0.4 + +* Test for path absoluteness properly +* win: Allow '' as a pathext if cmd has a . in it + +## 1.0.3 + +* Remove references to execPath +* Make `which.sync()` work on Windows by honoring the PATHEXT variable. +* Make `isExe()` always return true on Windows. +* MIT + +## 1.0.2 + +* Only files can be exes + +## 1.0.1 + +* Respect the PATHEXT env for win32 support +* should 0755 the bin +* binary +* guts +* package +* 1st diff --git a/node_modules/which/LICENSE b/node_modules/which/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/which/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, 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 THIS SOFTWARE. diff --git a/node_modules/which/README.md b/node_modules/which/README.md new file mode 100644 index 0000000..cd83350 --- /dev/null +++ b/node_modules/which/README.md @@ -0,0 +1,54 @@ +# which + +Like the unix `which` utility. + +Finds the first instance of a specified executable in the PATH +environment variable. Does not cache the results, so `hash -r` is not +needed when the PATH changes. + +## USAGE + +```javascript +var which = require('which') + +// async usage +which('node', function (er, resolvedPath) { + // er is returned if no "node" is found on the PATH + // if it is found, then the absolute path to the exec is returned +}) + +// or promise +which('node').then(resolvedPath => { ... }).catch(er => { ... not found ... }) + +// sync usage +// throws if not found +var resolved = which.sync('node') + +// if nothrow option is used, returns null if not found +resolved = which.sync('node', {nothrow: true}) + +// Pass options to override the PATH and PATHEXT environment vars. +which('node', { path: someOtherPath }, function (er, resolved) { + if (er) + throw er + console.log('found at %j', resolved) +}) +``` + +## CLI USAGE + +Same as the BSD `which(1)` binary. + +``` +usage: which [-as] program ... +``` + +## OPTIONS + +You may pass an options object as the second argument. + +- `path`: Use instead of the `PATH` environment variable. +- `pathExt`: Use instead of the `PATHEXT` environment variable. +- `all`: Return all matches, instead of just the first one. Note that + this means the function returns an array of strings instead of a + single string. diff --git a/node_modules/which/bin/node-which b/node_modules/which/bin/node-which new file mode 100755 index 0000000..7cee372 --- /dev/null +++ b/node_modules/which/bin/node-which @@ -0,0 +1,52 @@ +#!/usr/bin/env node +var which = require("../") +if (process.argv.length < 3) + usage() + +function usage () { + console.error('usage: which [-as] program ...') + process.exit(1) +} + +var all = false +var silent = false +var dashdash = false +var args = process.argv.slice(2).filter(function (arg) { + if (dashdash || !/^-/.test(arg)) + return true + + if (arg === '--') { + dashdash = true + return false + } + + var flags = arg.substr(1).split('') + for (var f = 0; f < flags.length; f++) { + var flag = flags[f] + switch (flag) { + case 's': + silent = true + break + case 'a': + all = true + break + default: + console.error('which: illegal option -- ' + flag) + usage() + } + } + return false +}) + +process.exit(args.reduce(function (pv, current) { + try { + var f = which.sync(current, { all: all }) + if (all) + f = f.join('\n') + if (!silent) + console.log(f) + return pv; + } catch (e) { + return 1; + } +}, 0)) diff --git a/node_modules/which/package.json b/node_modules/which/package.json new file mode 100644 index 0000000..97ad7fb --- /dev/null +++ b/node_modules/which/package.json @@ -0,0 +1,43 @@ +{ + "author": "Isaac Z. Schlueter (http://blog.izs.me)", + "name": "which", + "description": "Like which(1) unix command. Find the first instance of an executable in the PATH.", + "version": "2.0.2", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-which.git" + }, + "main": "which.js", + "bin": { + "node-which": "./bin/node-which" + }, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "devDependencies": { + "mkdirp": "^0.5.0", + "rimraf": "^2.6.2", + "tap": "^14.6.9" + }, + "scripts": { + "test": "tap", + "preversion": "npm test", + "postversion": "npm publish", + "prepublish": "npm run changelog", + "prechangelog": "bash gen-changelog.sh", + "changelog": "git add CHANGELOG.md", + "postchangelog": "git commit -m 'update changelog - '${npm_package_version}", + "postpublish": "git push origin --follow-tags" + }, + "files": [ + "which.js", + "bin/node-which" + ], + "tap": { + "check-coverage": true + }, + "engines": { + "node": ">= 8" + } +} diff --git a/node_modules/which/which.js b/node_modules/which/which.js new file mode 100644 index 0000000..82afffd --- /dev/null +++ b/node_modules/which/which.js @@ -0,0 +1,125 @@ +const isWindows = process.platform === 'win32' || + process.env.OSTYPE === 'cygwin' || + process.env.OSTYPE === 'msys' + +const path = require('path') +const COLON = isWindows ? ';' : ':' +const isexe = require('isexe') + +const getNotFoundError = (cmd) => + Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }) + +const getPathInfo = (cmd, opt) => { + const colon = opt.colon || COLON + + // If it has a slash, then we don't bother searching the pathenv. + // just check the file itself, and that's it. + const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [''] + : ( + [ + // windows always checks the cwd first + ...(isWindows ? [process.cwd()] : []), + ...(opt.path || process.env.PATH || + /* istanbul ignore next: very unusual */ '').split(colon), + ] + ) + const pathExtExe = isWindows + ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM' + : '' + const pathExt = isWindows ? pathExtExe.split(colon) : [''] + + if (isWindows) { + if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') + pathExt.unshift('') + } + + return { + pathEnv, + pathExt, + pathExtExe, + } +} + +const which = (cmd, opt, cb) => { + if (typeof opt === 'function') { + cb = opt + opt = {} + } + if (!opt) + opt = {} + + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) + const found = [] + + const step = i => new Promise((resolve, reject) => { + if (i === pathEnv.length) + return opt.all && found.length ? resolve(found) + : reject(getNotFoundError(cmd)) + + const ppRaw = pathEnv[i] + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw + + const pCmd = path.join(pathPart, cmd) + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd + + resolve(subStep(p, i, 0)) + }) + + const subStep = (p, i, ii) => new Promise((resolve, reject) => { + if (ii === pathExt.length) + return resolve(step(i + 1)) + const ext = pathExt[ii] + isexe(p + ext, { pathExt: pathExtExe }, (er, is) => { + if (!er && is) { + if (opt.all) + found.push(p + ext) + else + return resolve(p + ext) + } + return resolve(subStep(p, i, ii + 1)) + }) + }) + + return cb ? step(0).then(res => cb(null, res), cb) : step(0) +} + +const whichSync = (cmd, opt) => { + opt = opt || {} + + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) + const found = [] + + for (let i = 0; i < pathEnv.length; i ++) { + const ppRaw = pathEnv[i] + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw + + const pCmd = path.join(pathPart, cmd) + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd + + for (let j = 0; j < pathExt.length; j ++) { + const cur = p + pathExt[j] + try { + const is = isexe.sync(cur, { pathExt: pathExtExe }) + if (is) { + if (opt.all) + found.push(cur) + else + return cur + } + } catch (ex) {} + } + } + + if (opt.all && found.length) + return found + + if (opt.nothrow) + return null + + throw getNotFoundError(cmd) +} + +module.exports = which +which.sync = whichSync diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..9944530 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,287 @@ +{ + "name": "playwright_python_framework", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "monocart-coverage-reports": "^2.12.9" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-loose": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/acorn-loose/-/acorn-loose-8.5.2.tgz", + "integrity": "sha512-PPvV6g8UGMGgjrMu+n/f9E/tCSkNQ2Y97eFvuVdJfG11+xdIeDcLyNdC8SHcrHbRqkfwLASdplyR6B6sKM1U4A==", + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/console-grid": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/console-grid/-/console-grid-2.2.3.tgz", + "integrity": "sha512-+mecFacaFxGl+1G31IsCx41taUXuW2FxX+4xIE0TIPhgML+Jb9JFcBWGhhWerd1/vhScubdmHqTwOhB0KCUUAg==", + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eight-colors": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/eight-colors/-/eight-colors-1.3.3.tgz", + "integrity": "sha512-4B54S2Qi4pJjeHmCbDIsveQZWQ/TSSQng4ixYJ9/SYHHpeS5nYK0pzcHvWzWUfRsvJQjwoIENhAwqg59thQceg==", + "license": "MIT" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lz-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lz-utils/-/lz-utils-2.1.0.tgz", + "integrity": "sha512-CMkfimAypidTtWjNDxY8a1bc1mJdyEh04V2FfEQ5Zh8Nx4v7k850EYa+dOWGn9hKG5xOyHP5MkuduAZCTHRvJw==", + "license": "MIT" + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/monocart-coverage-reports": { + "version": "2.12.9", + "resolved": "https://registry.npmjs.org/monocart-coverage-reports/-/monocart-coverage-reports-2.12.9.tgz", + "integrity": "sha512-vtFqbC3Egl4nVa1FSIrQvMPO6HZtb9lo+3IW7/crdvrLNW2IH8lUsxaK0TsKNmMO2mhFWwqQywLV2CZelqPgwA==", + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0", + "acorn-loose": "^8.5.2", + "acorn-walk": "^8.3.4", + "commander": "^14.0.0", + "console-grid": "^2.2.3", + "eight-colors": "^1.3.1", + "foreground-child": "^3.3.1", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.2.0", + "lz-utils": "^2.1.0", + "monocart-locator": "^1.0.2" + }, + "bin": { + "mcr": "lib/cli.js" + } + }, + "node_modules/monocart-locator": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/monocart-locator/-/monocart-locator-1.0.2.tgz", + "integrity": "sha512-v8W5hJLcWMIxLCcSi/MHh+VeefI+ycFmGz23Froer9QzWjrbg4J3gFJBuI/T1VLNoYxF47bVPPxq8ZlNX4gVCw==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "license": "MIT", + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..27c7887 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "monocart-coverage-reports": "^2.12.9" + } +} diff --git a/pages/login_page.py b/pages/login_page.py new file mode 100644 index 0000000..2bd6e79 --- /dev/null +++ b/pages/login_page.py @@ -0,0 +1,20 @@ +# pages/login_page.py +from playwright.sync_api import Page, expect + +class LoginPage: + URL = "https://faruk-hasan.com/automation/login.html" + + def __init__(self, page: Page): + self.page = page + self.username = page.locator("#username") + self.password = page.locator("#password") + self.login_button = page.get_by_role("button", name="Login") + + def goto(self): + self.page.goto(self.URL, wait_until="domcontentloaded") + expect(self.page).to_have_title("Login - Automation Practice") + + def login(self, username: str, password: str): + self.username.fill(username) + self.password.fill(password) + self.login_button.click() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index b3049ae..399419b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ pytest>=8.0.0 playwright>=1.45.0 pytest-playwright>=0.5.0 python-dotenv>=1.0.1 +requests>=2.31.0 \ No newline at end of file diff --git a/tests/test_logged_in.py b/tests/test_logged_in.py index 5918ca9..b102a15 100644 --- a/tests/test_logged_in.py +++ b/tests/test_logged_in.py @@ -18,3 +18,13 @@ def test_logged_in_session(page: Page): print(f"\n[TEST] Verified logged-in session with title: {page.title()}") time.sleep(5) + +def test_counting_links(page: Page): + # Navigate directly to a page that requires you to be logged in + page.goto("https://faruk-hasan.com/automation/playwright-selenium-cypress-practice.html") + # Count the number of links on the page + links = page.locator("a") + expect(links).to_have_count(10) + link_count = links.count() + print(f"\n[TEST] Number of links on the page: {link_count}") + time.sleep(5) \ No newline at end of file From 5083b4953048cfaefdfac68982a6166bf6fbdfa4 Mon Sep 17 00:00:00 2001 From: Watson Date: Tue, 12 May 2026 20:04:41 -0400 Subject: [PATCH 2/3] Fixed the issue with the counting links. --- pages/login_page.py | 7 +------ tests/test_logged_in.py | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/pages/login_page.py b/pages/login_page.py index 2bd6e79..7b735c1 100644 --- a/pages/login_page.py +++ b/pages/login_page.py @@ -12,9 +12,4 @@ def __init__(self, page: Page): def goto(self): self.page.goto(self.URL, wait_until="domcontentloaded") - expect(self.page).to_have_title("Login - Automation Practice") - - def login(self, username: str, password: str): - self.username.fill(username) - self.password.fill(password) - self.login_button.click() \ No newline at end of file + expect(self.page).to_have_title("Login - Automation Practice") \ No newline at end of file diff --git a/tests/test_logged_in.py b/tests/test_logged_in.py index b102a15..6b841df 100644 --- a/tests/test_logged_in.py +++ b/tests/test_logged_in.py @@ -24,7 +24,7 @@ def test_counting_links(page: Page): page.goto("https://faruk-hasan.com/automation/playwright-selenium-cypress-practice.html") # Count the number of links on the page links = page.locator("a") - expect(links).to_have_count(10) + expect(links).to_have_count(14) link_count = links.count() print(f"\n[TEST] Number of links on the page: {link_count}") time.sleep(5) \ No newline at end of file From 932d9c8dfc01f03e4013eb3dba8b4224cdba1b18 Mon Sep 17 00:00:00 2001 From: Watson Date: Tue, 19 May 2026 19:43:03 -0400 Subject: [PATCH 3/3] Test --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 21e332c..2724d92 100644 --- a/README.md +++ b/README.md @@ -252,3 +252,5 @@ pytest -vv --html=reports/html/report.html --self-contained-html --- 🎉 You’re all set — the framework signs up, logs in, saves the session, and reuses it for fast, reliable tests. + +Watson Testing here :) \ No newline at end of file